Configuration inheritance

Capabilities

Capability

Support

Comment

Single file template

Supported feature

Template a single file (see simple Inheritance)

Single file template - variables overriding

Supported feature

Single file template - Sharing variables between multiples files

Supported feature

A file or template can import one or more variables.ospp that contains variable that can be used by the templating. See variable file

Single file template - template of template

Supported feature

Single file template - multiples files Inheritance (many templates used by one file)

Not supported feature

To avoid configuration error and conflict this feature will not be supported

Template playbook - Complexe template on multiples files

Supported feature

See templating playbook

Concepts

Templates provide a way to simplify the integration process when a lot of files share a common structure and only a few elements must be changed for each individual item.

They allow individual files to define only a subset of required fields and rely on a more generic template file (or template file chain) to provide other configuration fields. They also allow variables to be defined in templates, with their actual value defined in the individual files referring to the template.

Warning

Templating is categorized into two types: inheritance templating, which is described on this page, and configuration generation templating, further detailed in Templating Generation

Examples

Single file Template (Inheritance)

Usage

Almost any OnSphere configuration file can be templated by defining a file of the same name with the .template extension (for example value.ospp.template), and referencing it.

To reference a template, the templateId field is used. As the ItemId can be used for multiple templates (Value, Owner, …), when the resolution is done, the ItemId will point to the template file with the same name as the original file (value.ospp -> value.ospp.template).

Evaluation rules

Templates can themselves be templated. In that case, the templates must all have the same name (with the extension .template only once, not one per level), and are evaluated from bottom (the file referencing the first template) to top (the template that references no other template). Fields are inherited from top to bottom and are overridden from bottom to top.

Variables

All variables defined in a user of a template override the variables inherited from a template (i.e., they replace the field if it was inherited, or they define it if it was not).

Note

Variables can be used freely for defining references (moduleId, templateId, accessedValues, …).

Overriding

All fields defined in a user of a template override the fields inherited from a template (i.e., they replace the field if it was inherited, or they define it if it was not).

Objects :

Only the fields that are explicitly defined in a user of a template will be overridden, even if they are inner fields of a more complex object. It means that an object must be completely redefined for it to completely override the object inherited from the template.

Arrays :

When overriding the content of an array, new elements are simply added to the array. It means that elements in an array cannot be overridden or removed.

Here is an example :

root/value/callback.ospp

{
    "templateId": "root.template",
    "linkedOutputs": ["root.other-output"]
}

root/template/callback.ospp.template

{
    "linkedOutputs": ["root.output"]
}

The result will be interpreted as if the value.ospp file was defined as :

root/value/callback.ospp

{
    "linkedOutputs": ["root.output", "root.other-output"]
}

Variables files

Variables can be used locally or in an external file named variables.ospp referenced by the variablesFiles entry in any JSON files. They behave like the other variables when inherited. When multiple variable files are present, the variables contained inside the first variableFile of the list take precedence over the ones declared below it.

Note

A variable is defined within the file that incorporates the variablesFiles, and within the variablesFiles, the corresponding value will be sourced from the file that incorporates it.

Variable key access

To access a variable, the variable key must be enclosed inside ${ and } curly braces with dollar sign as prefix. To access objects or array properties, the full JSON path must be used.

For example, with the following variable content:

{
  "variables": {
    "complex": {
        "key": "value",
        "boolean": true,
        "int": 12,
        "decimal": 12.5,
        "array": [
            {"object": { "id": 12, "content": false } },
            {"object": { "id": 15, "content": true } }
        ]
    },
    "array": ["test", -5, {"id": "id-from-object"}]
  }
}

You can access the following content with the keys:

  • ${complex.boolean} to access true value

  • ${complex.array[0].object.id} to access 12 value

  • ${array[2].id} to access "id-from-object" value

Examples

Illustration

Here is an example of a template file that defines a variable name, description and type for a value. The value.ospp file simply references the template and provides the variable content.

  • Red color show a static link for templateId

  • Green color show a dynamic link templateId defined by a variable

Static reference

Red elements show a static link to a template

Dynamic reference

Green elements defined a link configured by a variable defined in the initial value.ospp.

Overriding variables

In orange in the example, we use the internal variables to define the unit of the smooth:

  1. The default variable is defined with the value DAYS in root.modbus.template.

  2. The variable is redefine in value.ospp with value MINUTES.

  3. As value.ospp is the most specific file, the value will be set to MINUTES.

In blue in the example, we use the external variables to define the value of the smooth :

  1. The default variables is defined with the value 20 in root.modbus.template.default.

  2. The variable is redefine in root.basement with 5.

  3. As variables.ospp is the most specific file, the value will be set to 5.

@startuml
skinparam backgroundColor transparent

[*] --> v
state "value.ospp" as v : { \n\
    "name" : "Modbus device basement",\n\
    "type" : "BOOLEAN",\n\
    <color:red>"templateId": "root.modbus.template",</color>\n\
    "templateVariables" : {\n\
        "smooth-unit" : <color:orange>"MINUTES"</color>,\n\
        <color:green>"ref-template" : "root.default.delay"</color>\n\
    },\n\
    <color:red>"variablesFiles" : [</color>\n\
        <color:red>"root.basement"</color>\n\
    <color:red>]</color>\n\
}

v -> t : <color:red>root.modbus.template</color>
state "value.ospp.template" as t  : { \n\
    "templateVariables" : {\n\
        <color:orange>"smooth-unit" : "DAYS"</color>,\n\
    }\n\
    "templateId": <color:green>"${ref-template}"</color>,\n\
        "smooth" : {\n\
            "value" : <color:blue>"${smooth-value}"</color>,\n\
            "unit" : <color:orange>"${smooth-unit}"</color> \n\
        }\n\
    },\n\
    <color:red>"variablesFiles" : [</color>\n\
        <color:red>"root.modbus.template.default"</color>\n\
    <color:red>]</color>\n\
}

v --> var : <color:red>root.basement</color>
state "variables.ospp" as var : { \n\
    "variables" : {\n\
        "smooth-value" : <color:blue>5</color>\n\
    }\n\
}

t --> varDef : <color:red>root.modbus.template.default</color>
state "variables.ospp" as varDef : { \n\
    "variables" : {\n\
        "smooth-value" : <color:blue>20</color>\n\
    }\n\
}

t -> d :  <color:green>from variable ref-template : "root.default.delay"</color>

state "value.ospp.template" as d : { \n\
    "delay": { \n\
        "unit": "DAYS", \n\
        "value": 2 \n\
    } \n\
}

v --> result

result : { \n\
    "name" : "Modbus device basement",\n\
    "type" : "BOOLEAN",\n\
    "smooth" : {\n\
        "value" : <color:blue>5</color>,\n\
        "unit" : <color:orange>"MINUTES</color>" \n\
    },\n\
    "delay": { \n\
        "unit": "DAYS", \n\
        "value": 2 \n\
    }\n\
}

@enduml