Преглед изворни кода

Merge PR #1637: Schema deprecation Phase 1 - Add warnings and migrate to self-contained templates

xcad пре 6 месеци
родитељ
комит
87e58ca0a4

+ 1 - 1
cli/__init__.py

@@ -2,6 +2,6 @@
 Boilerplates CLI - A sophisticated command-line tool for managing infrastructure boilerplates.
 """
 
-__version__ = "0.1.2"
+__version__ = "0.1.3"
 __author__ = "Christian Lempa"
 __description__ = "CLI tool for managing infrastructure boilerplates"

+ 62 - 0
cli/core/template/template.py

@@ -325,6 +325,7 @@ class Template:
         self.__used_variables: set[str] | None = None
         self.__variables: VariableCollection | None = None
         self.__template_files: list[TemplateFile] | None = None  # New attribute
+        self._schema_deprecation_warned: bool = False  # Track if deprecation warning shown
 
         try:
             # Find and parse the main template file (template.yaml or template.yml)
@@ -399,6 +400,10 @@ class Template:
     def _load_module_specs_for_schema(kind: str, schema_version: str) -> dict:
         """Load specifications from the corresponding module for a specific schema version.
 
+        DEPRECATION NOTICE (v0.1.3): Module schemas are being deprecated. Templates should define
+        all variables in their template.yaml spec section. In future versions, this method will
+        return an empty dict and templates will need to be self-contained.
+
         Uses LRU cache to avoid re-loading the same module spec multiple times.
         This significantly improves performance when listing many templates of the same kind.
 
@@ -469,6 +474,61 @@ class Template:
 
         return merged_spec
 
+    def _warn_about_inherited_variables(self, module_specs: dict, template_specs: dict) -> None:
+        """Warn about variables inherited from module schemas (deprecation warning).
+
+        DEPRECATION (v0.1.3): Templates should define all variables explicitly in template.yaml.
+        This method detects variables that are used in template files but come from module schemas,
+        and warns users to add them to the template spec.
+
+        Args:
+            module_specs: Variables defined in module schema
+            template_specs: Variables defined in template.yaml
+        """
+        # Skip if no module specs (already self-contained)
+        if not module_specs:
+            return
+
+        # Collect variables from module specs
+        module_vars = set()
+        for section_data in module_specs.values():
+            if isinstance(section_data, dict) and "vars" in section_data:
+                module_vars.update(section_data["vars"].keys())
+
+        # Collect variables explicitly defined in template
+        template_vars = set()
+        for section_data in (template_specs or {}).values():
+            if isinstance(section_data, dict) and "vars" in section_data:
+                template_vars.update(section_data["vars"].keys())
+
+        # Get variables actually used in template files
+        used_vars = self.used_variables
+
+        # Find variables that are:
+        # 1. Used in template files AND defined in module schema (inherited variables)
+        # 2. NOT explicitly defined in template.yaml (missing definitions)
+        # These are the problematic ones - the template relies on schema
+        inherited_vars = used_vars & module_vars
+        missing_definitions = inherited_vars - template_vars
+
+        # Only warn once per template (use a flag to avoid repeated warnings)
+        if missing_definitions and not self._schema_deprecation_warned:
+            self._schema_deprecation_warned = True
+            # Show first N variables in warning, full list in debug
+            max_shown_vars = 10
+            shown_vars = sorted(list(missing_definitions)[:max_shown_vars])
+            ellipsis = "..." if len(missing_definitions) > max_shown_vars else ""
+            logger.warning(
+                f"DEPRECATION WARNING: Template '{self.id}' uses {len(missing_definitions)} "
+                f"variable(s) from module schema without defining them in template.yaml. "
+                f"In future versions, all used variables must be defined in template.yaml. "
+                f"Missing definitions: {', '.join(shown_vars)}{ellipsis}"
+            )
+            logger.debug(
+                f"Template '{self.id}' should add these variable definitions to template.yaml spec: "
+                f"{sorted(missing_definitions)}"
+            )
+
     def _collect_template_files(self) -> None:
         """Collects all TemplateFile objects in the template directory."""
         template_files: list[TemplateFile] = []
@@ -881,6 +941,8 @@ class Template:
     @property
     def merged_specs(self) -> dict:
         if self.__merged_specs is None:
+            # Warn about inherited variables (deprecation)
+            self._warn_about_inherited_variables(self.module_specs, self.template_specs)
             self.__merged_specs = self._merge_specs(self.module_specs, self.template_specs)
         return self.__merged_specs
 

+ 38 - 0
library/compose/alloy/template.yaml

@@ -26,6 +26,19 @@ spec:
     vars:
       service_name:
         default: alloy
+      container_hostname:
+        description: Container internal hostname
+        type: str
+      restart_policy:
+        description: Container restart policy
+        type: enum
+        options:
+          - unless-stopped
+          - always
+          - on-failure
+          - 'no'
+        default: unless-stopped
+        required: true
   logs:
     title: Log Collection
     toggle: logs_enabled
@@ -76,5 +89,30 @@ spec:
         default: 12345
   traefik:
     vars:
+      traefik_enabled:
+        description: Enable Traefik reverse proxy integration
+        type: bool
+        default: false
+      traefik_network:
+        description: Traefik network name
+        type: str
+        default: traefik
+        required: true
       traefik_host:
         default: alloy
+      traefik_domain:
+        description: Base domain (e.g., example.com)
+        type: str
+        default: home.arpa
+        required: true
+  traefik_tls:
+    vars:
+      traefik_tls_enabled:
+        description: Enable HTTPS/TLS
+        type: bool
+        default: true
+      traefik_tls_certresolver:
+        description: Traefik certificate resolver name
+        type: str
+        default: cloudflare
+        required: true

+ 65 - 0
library/compose/whoami/template.yaml

@@ -28,7 +28,72 @@ spec:
     vars:
       service_name:
         default: whoami
+      restart_policy:
+        description: Container restart policy
+        type: enum
+        options:
+          - unless-stopped
+          - always
+          - on-failure
+          - 'no'
+        default: unless-stopped
+        required: true
   traefik:
     vars:
       traefik_host:
         default: whoami
+      traefik_network:
+        description: Traefik network name
+        type: str
+        default: traefik
+        required: true
+      traefik_domain:
+        description: Base domain (e.g., example.com)
+        type: str
+        default: home.arpa
+        required: true
+  traefik_tls:
+    vars:
+      traefik_tls_enabled:
+        description: Enable HTTPS/TLS
+        type: bool
+        default: true
+      traefik_tls_certresolver:
+        description: Traefik certificate resolver name
+        type: str
+        default: cloudflare
+        required: true
+  resources:
+    vars:
+      resources_enabled:
+        description: Enable resource limits
+        type: bool
+        default: false
+  swarm:
+    vars:
+      swarm_enabled:
+        description: Enable Docker Swarm mode
+        type: bool
+        default: false
+      swarm_placement_mode:
+        description: Swarm placement mode
+        type: enum
+        options:
+          - replicated
+          - global
+        default: replicated
+        required: true
+      swarm_replicas:
+        description: Number of replicas
+        type: int
+        default: 1
+        needs:
+          - swarm_placement_mode=replicated
+        required: true
+      swarm_placement_host:
+        description: Target hostname for placement constraint
+        type: str
+        default: ''
+        needs:
+          - swarm_placement_mode=replicated
+        extra: Constrains service to run on specific node by hostname