Repository


example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …

Classes


example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …

Class Naming

The name of a class is derived from its filesystem path. Slashes become dots.

Path Name
classes/distribution/opensuse.yml distribution.opensuse
classes/domain/michael-jansen.biz.yml domain.michael-jansen.biz

Nodes


example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …

Node Naming

The name of a node is derived from its filename only.

Path Name
nodes/hosts/example.com.yml example.com

Node


---
classes:
    - distribution.opensuse
applications:
    - digikam
    - development-c++
environment: "private"
parameters:
    accounts:
        mjansen:
            fullname: Michael Jansen
            root: yes

A node can specify the following attributes

  • classes to inherit from.
  • applications to apply to the node.
  • environment this node belongs to.
  • parameters to apply to this node.

Node / Classes


---
classes:
    - distribution.opensuse
applications:
    - digikam
    - development-c++
environment: "private"
parameters:
    accounts:
        mjansen:
            fullname: Michael Jansen
            root: yes

classes are a concept to extract common node configuration into base classes for configuration reuse.

inheritance is well defined.

interpolation can be used to delegate configuration to nodes or child classes.

Node / Applications


---
classes:
    - distribution.opensuse
applications:
    - digikam
    - development-c++
environment: "private"
parameters:
    accounts:
        mjansen:
            fullname: Michael Jansen
            root: yes

applications is a set of behaviours to apply to the node.

Node / Environment


---
classes:
    - distribution.opensuse
applications:
    - digikam
    - development-c++
environment: "private"
parameters:
    accounts:
        mjansen:
            fullname: Michael Jansen
            root: yes

environment is the name of the environment this node belongs to.

Node / Parameters


---
classes:
    - distribution.opensuse
applications:
    - digikam
    - development-c++
environment: "private"
parameters:
    accounts:
        mjansen:
            fullname: Michael Jansen
            root: yes

parameters is a freeform field you can use to specify whatever you want.

Class


---
classes:
- distribution.opensuse.tumbleweed
- pc.laptop
applications:
- kde
- libre-office
environment: private
parameters:
  motd: Have a nice day

classes can have the exact same attributes as nodes.

classes represent abstract concepts you can apply to nodes by inheritance.

classes can be used to query the repository for all nodes inheriting them.

Inheritance

Nodes and classes can inherit from classes. The configuration of the child will be merged into the configuration of the base class following a clear set of rules leading to reproducible and predictable results.

First the inheritance chain is determined.

Then the configuration is merged left to right following the inheritance chain.

On the resulting configuration interpolation is applied.

Inheritance Chain


                            # classA
                            classes:
                        

                            # classB
                            classes:
                                - classA
                        

                            # classC
                            classes:
                                - classB
                                - classA
                        

                            # nodeA
                            classes:
                                - classC
                                - classA
                        

The inheritance chain is determined by following the base classes depth first top to bottom.

classA -> classB -> classA -> classC -> classA -> nodeA

If a class appears more than once in the chain all but the first appearance are removed.

classA -> classB -> classC -> nodeA

Merging / Scalars


                            # classA
                            parameters:
                                "a scalar": "Hello World"
                        

                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "a scalar": 1
                        

Scalars are overwritten. The Result is:


                parameters:
                    "a scalar": 1
                

Merging / Lists


                            # classA
                            parameters:
                            "a list":
                                - A
                        

                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "a list":
                                    - B
                        

Lists are appended.


                parameters:
                    "a list":
                        - A
                        - B
                

Merging / Maps


                            # classA
                            parameters:
                            "a map":
                                a: 1
                                b: 2
                        

                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "a map":
                                    b: 3
                                    c: 4
                        

Maps are merged. We make NO GUARANTEES about the order in maps.


                parameters:
                    "a map":
                        b: 3
                        c: 4
                        a: 1
                

Merging / Overwriting


                            # classA
                            parameters:
                                "a map":
                                    a: 1
                                "a list":
                                    - A
                        

                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "~a list":
                                    - B
                                "~a map":
                                    b: 2
                        

It is also possible to overwrite lists and maps instead of merging. Just prefix the attribute name with a tilde.


                parameters:
                    "a list":
                        - B
                    "a map":
                        b: 2
                

Interpolation


                                # domain.example.com
                                parameters:
                                  host:
                                    domain: example.com
                                    fqdn: >
                                      $(host:name).(host:domain)
                            

                                # host
                                classes:
                                  - domain.example.com
                                parameters:
                                  host:
                                    name: host
                            

Interpolation is done AFTER merging the configuration. Thats why the domain.example.com class can reference a parameter set by the node.


                    parameters:
                        host:
                           domain: example.com
                           fqdn: host.example.com
                           host: host