example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …
            
example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …
            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 | 
example/
├── classes
│   ├── distribution
│   │   ├── opensuse
│   │   │   ├── leap
│   │   │   │   ├── 15.1.yml
│   │   │   ├── leap.yml
│   │   │   └── tumbleweed.yml
│   │   └── opensuse.yml
│   └── …
└── nodes
    ├── laptop.yml
    └── …
            The name of a node is derived from its filename only.
| Path | Name | 
|---|---|
| nodes/hosts/example.com.yml | example.com | 
---
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:
    - 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.
---
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.
---
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.
---
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.
---
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.
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.
                            # 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
                            # classA
                            parameters:
                                "a scalar": "Hello World"
                        
                    
                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "a scalar": 1
                        
                    Scalars are overwritten. The Result is:
                parameters:
                    "a scalar": 1
                
            
                            # classA
                            parameters:
                            "a list":
                                - A
                        
                    
                            # NodeA
                            classes:
                                - classA
                            parameters:
                                "a list":
                                    - B
                        
                    Lists are appended.
                parameters:
                    "a list":
                        - A
                        - B
                
            
                            # 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
                
            
                            # 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
                
            
                                # 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