Templates

Templates provide a mechanism to define reusable node-rules definitions. They allow you to centralize commonly used constraints and apply them consistently across multiple nodes.

Templates are defined as subsections or section lists of the reserved section vr_template at the document root. The name of each subsection is the identifier used by use_template in node-rules definitions.

[vr_template.interface]
type: "section"

[.address]
type: "text"
default: "localhost"

[.protocol]
type: "text"
default: "https"

[.port]
type: "integer"
default: 443

[server.interface]
use_template: "interface"

[client.interface]
use_template: "interface"

[.port]
default: 9000

In this example, the same template is applied to both server.interface and client.interface, while the client overrides the default port.

Rules for Templates

  1. Templates in Root: Templates must be defined as subsections or section lists under vr_template at the document root.

    [vr_template.interface]
    type: "integer"
    
    *[vr_template.service]*
    type: "integer"
    minimum: 1
    maximum: 65534
    
    *[vr_template.service]*
    type: "text"
    in_list: "http", "https", "smtp"
    
  2. Root Restriction: The name vr_template must only appear at the document root and must define a section with regular names.

    [server.vr_template.interface]  # ERROR: "vr_template" must be in the document root
    type: "integer"
    
  3. Template Identifier: The name of a subsection or section list under vr_template is the identifier used to reference the template via use_template.

    [vr_template.port]  # Defines the template "port"
    type: "integer"
    minimum: 1
    maximum: 65534
    
    [server.port]
    use_template: "port"  # References the template "port"
    
  4. Same Structure as Node-Rules: A template is defined exactly like a regular node-rules definition. All rules that apply to node-rules definitions also apply to templates.

    [vr_template.port]
    type: "integer"
    minimum: 1
    maximum: 65534
    
  5. Direct Type Definition Only: A template must define its own type and must not reference another template using use_template.

    Templates cannot be composed or chained.

    [vr_template.port]
    type: "integer"
    minimum: 1
    maximum: 65534
    
    [vr_template.client_port]
    use_template: "port"   # ERROR: Templates must not reference other templates.
    minimum: 1024
    
  6. Copy Semantics: When a template is applied using use_template, its contents are copied into the node-rules definition at the usage location.

    From that point on, the node-rules definition behaves exactly as if the copied rules had been written inline.

    [vr_template.port]
    type: "integer"
    minimum: 1
    maximum: 65534
    
    [server.port]
    use_template: "port"  # Contains a copy of the "port" template.
    
  7. Overrides Allowed: Constraints defined at the usage location overwrite constraints copied from the template.

    This allows templates to define sensible defaults while still permitting context-specific adjustments.

    [vr_template.port]
    type: "integer"
    minimum: 1
    maximum: 65534
    
    [server.port]
    use_template: "port"
    minimum: 1024  # Overrides the "minimum" from the template.
    
  8. Alternatives Cannot Be Overwritten: Constraints defined as alternatives (using section lists) must not be overwritten at the usage location.

    This restriction ensures that the structure and intent of alternative-based templates remain intact.

    *[vr_template.service]*
    type: "integer"
    minimum: 1
    
    *[vr_template.service]*
    type: "text"
    minimum: 1
    
    [server.port]
    use_template: "service"
    minimum: 1024   # ERROR: Alternatives from a template must not be overwritten.