Merge pull request 'Classgen: add error reporting and combine common classes' (#1784) from hsjobeki/clan-core:hsjobeki-main into main

This commit is contained in:
clan-bot
2024-07-19 11:07:06 +00:00
5 changed files with 48 additions and 25 deletions

View File

@@ -51,8 +51,10 @@ let
type = "object"; type = "object";
additionalProperties = false; additionalProperties = false;
properties = { properties = {
meta = meta = {
inventorySchema.properties.services.additionalProperties.additionalProperties.properties.meta; title = "service-meta";
} // inventorySchema.properties.services.additionalProperties.additionalProperties.properties.meta;
config = { config = {
title = "${moduleName}-config"; title = "${moduleName}-config";
default = { }; default = { };

View File

@@ -15,10 +15,10 @@ from .classes import (
Meta, Meta,
Service, Service,
ServiceBorgbackup, ServiceBorgbackup,
ServiceBorgbackupMeta,
ServiceBorgbackupRole, ServiceBorgbackupRole,
ServiceBorgbackupRoleClient, ServiceBorgbackupRoleClient,
ServiceBorgbackupRoleServer, ServiceBorgbackupRoleServer,
ServiceMeta,
) )
# Re export classes here # Re export classes here
@@ -30,7 +30,7 @@ __all__ = [
"Inventory", "Inventory",
"MachineDeploy", "MachineDeploy",
"ServiceBorgbackup", "ServiceBorgbackup",
"ServiceBorgbackupMeta", "ServiceMeta",
"ServiceBorgbackupRole", "ServiceBorgbackupRole",
"ServiceBorgbackupRoleClient", "ServiceBorgbackupRoleClient",
"ServiceBorgbackupRoleServer", "ServiceBorgbackupRoleServer",

View File

@@ -48,7 +48,7 @@ class ServiceBorgbackupMachine:
@dataclass @dataclass
class ServiceBorgbackupMeta: class ServiceMeta:
name: str name: str
description: str | None = field(default=None ) description: str | None = field(default=None )
icon: str | None = field(default=None ) icon: str | None = field(default=None )
@@ -78,7 +78,7 @@ class ServiceBorgbackupRole:
@dataclass @dataclass
class ServiceBorgbackup: class ServiceBorgbackup:
meta: ServiceBorgbackupMeta meta: ServiceMeta
roles: ServiceBorgbackupRole roles: ServiceBorgbackupRole
config: BorgbackupConfig = field(default_factory=BorgbackupConfig ) config: BorgbackupConfig = field(default_factory=BorgbackupConfig )
machines: dict[str, ServiceBorgbackupMachine] = field(default_factory=dict ) machines: dict[str, ServiceBorgbackupMachine] = field(default_factory=dict )
@@ -95,13 +95,6 @@ class ServicePackageMachine:
imports: list[str] = field(default_factory=list ) imports: list[str] = field(default_factory=list )
@dataclass
class ServicePackageMeta:
name: str
description: str | None = field(default=None )
icon: str | None = field(default=None )
@dataclass @dataclass
class ServicePackageRoleDefault: class ServicePackageRoleDefault:
config: PackagesConfig = field(default_factory=PackagesConfig ) config: PackagesConfig = field(default_factory=PackagesConfig )
@@ -117,7 +110,7 @@ class ServicePackageRole:
@dataclass @dataclass
class ServicePackage: class ServicePackage:
meta: ServicePackageMeta meta: ServiceMeta
roles: ServicePackageRole roles: ServicePackageRole
config: PackagesConfig = field(default_factory=PackagesConfig ) config: PackagesConfig = field(default_factory=PackagesConfig )
machines: dict[str, ServicePackageMachine] = field(default_factory=dict ) machines: dict[str, ServicePackageMachine] = field(default_factory=dict )
@@ -134,13 +127,6 @@ class ServiceSingleDiskMachine:
imports: list[str] = field(default_factory=list ) imports: list[str] = field(default_factory=list )
@dataclass
class ServiceSingleDiskMeta:
name: str
description: str | None = field(default=None )
icon: str | None = field(default=None )
@dataclass @dataclass
class ServiceSingleDiskRoleDefault: class ServiceSingleDiskRoleDefault:
config: SingleDiskConfig = field(default_factory=SingleDiskConfig ) config: SingleDiskConfig = field(default_factory=SingleDiskConfig )
@@ -156,7 +142,7 @@ class ServiceSingleDiskRole:
@dataclass @dataclass
class ServiceSingleDisk: class ServiceSingleDisk:
meta: ServiceSingleDiskMeta meta: ServiceMeta
roles: ServiceSingleDiskRole roles: ServiceSingleDiskRole
config: SingleDiskConfig = field(default_factory=SingleDiskConfig ) config: SingleDiskConfig = field(default_factory=SingleDiskConfig )
machines: dict[str, ServiceSingleDiskMachine] = field(default_factory=dict ) machines: dict[str, ServiceSingleDiskMachine] = field(default_factory=dict )

View File

@@ -10,10 +10,10 @@ from clan_cli.inventory import (
Machine, Machine,
MachineDeploy, MachineDeploy,
ServiceBorgbackup, ServiceBorgbackup,
ServiceBorgbackupMeta,
ServiceBorgbackupRole, ServiceBorgbackupRole,
ServiceBorgbackupRoleClient, ServiceBorgbackupRoleClient,
ServiceBorgbackupRoleServer, ServiceBorgbackupRoleServer,
ServiceMeta,
load_inventory, load_inventory,
save_inventory, save_inventory,
) )
@@ -71,7 +71,7 @@ def test_add_module_to_inventory(
inventory.services.borgbackup = { inventory.services.borgbackup = {
"borg1": ServiceBorgbackup( "borg1": ServiceBorgbackup(
meta=ServiceBorgbackupMeta(name="borg1"), meta=ServiceMeta(name="borg1"),
roles=ServiceBorgbackupRole( roles=ServiceBorgbackupRole(
client=ServiceBorgbackupRoleClient( client=ServiceBorgbackupRoleClient(
machines=["machine1"], machines=["machine1"],

View File

@@ -157,8 +157,43 @@ def generate_dataclass(schema: dict[str, Any], class_name: str = root_class) ->
elif "None" in str(serialised_types): elif "None" in str(serialised_types):
field_def = f"""{field_name}: {serialised_types} = field(default=None {f", metadata={field_meta}" if field_meta else ""})""" field_def = f"""{field_name}: {serialised_types} = field(default=None {f", metadata={field_meta}" if field_meta else ""})"""
fields_with_default.append(field_def) fields_with_default.append(field_def)
elif class_name.endswith("Config"):
# SingleDiskConfig
# PackagesConfig
# ...
# Config classes MUST always be optional
raise ValueError(
f"""
#################################################
Clan module '{class_name}' specifies a top-level option '{field_name}' without a default value.
To fix this:
- Add a default value to the option
lib.mkOption {{
type = lib.types.nullOr lib.types.str;
default = null; # <- Add a default value here
}};
# Other options
- make the field nullable
lib.mkOption {{
# ╔══════════════╗ <- Nullable type
type = lib.types.nullOr lib.types.str;
}};
- Use lib.types.attrsOf if suitable
- Use lib.types.listOf if suitable
Or report this problem to the clan team. So the class generator can be improved.
#################################################
"""
)
else: else:
# Field is not required and but also specifies no default value
required_fields.append(field_def) required_fields.append(field_def)
else: else:
required_fields.append(field_def) required_fields.append(field_def)