deckhand/doc/source/users/layering.rst
Felipe Monteiro a8660a7e53 docs: Reorganize documentation structure
This patch set reorganizes Deckhand's documentation structure
for better organization into 3 distinct categories:

* developer's guide
* operator's guide
* user's guide

This means that the RTD navigation menu on the left-hand side
will have fewer links (see list above) making navigation much
easier. This is similar to how Armada organizes its documentation
too.

This patch set also updates README section with a better
overview and trims some fat from it (remove testing
documentation as it doesn't really belong there -- there
is a dedicated page for that already).

Finally, this patch set changes the exceptions page to
render as a basic list of autoexception classes because
the current tabularized view is not rendering correctly
on RTD [0].

[0] https://airship-deckhand.readthedocs.io/en/latest/exceptions.html
Change-Id: I162383bf8e3bbd5004603c979ac7b0d760a210c4
2018-09-26 20:29:02 -04:00

5.7 KiB

Document Layering

Introduction

Layering provides a restricted data inheritance model intended to help reduce duplication in configuration. Documents with different schema's are never layered together (see the substitution section if you need to combine data from multiple types of documents).

Layering is controlled in two places:

  1. The LayeringPolicy control document (described below), which defines the valid layers and their order of precedence.
  2. In the metadata.layeringDefinition section of normal (metadata.schema=metadata/Document/v1) documents.

When rendering a particular document, you resolve the chain of parents upward through the layers, and begin working back down each layer rendering at each document in the chain.

When rendering each layer, the parent document is used as the starting point, so the entire contents of the parent are brought forward. Then the list of actions will be applied in order. Supported actions are:

  • merge - "deep" merge child data at the specified path into the existing data
  • replace - overwrite existing data with child data at the specified path
  • delete - remove the existing data at the specified path

After actions are applied for a given layer, substitutions are applied (see the Substitution section for details).

Parent Selection

Selection of document parents is controlled by the parentSelector field and works as follows:

  • A given document, C, that specifies a parentSelector, will have exactly one parent, P. If comparing layering with inheritance, layering, then, does not allow multi-inheritance.
  • Both C and P must have the same schema.
  • Both C and P should have different metadata.name values except in the case of replacement.
  • Document P will be the highest-precedence document whose metadata.labels are a superset of document C's parentSelector. Where:
    • Highest precedence means that P belongs to the lowest layer defined in the layerOrder list from the LayeringPolicy which is at least one level higher than the layer for C. For example, if C has layer site, then its parent P must at least have layer type or above in the following layerOrder:

      ---
      ...
      layerOrder:
        - global # Highest layer
        - type
        - site   # Lowest layer
    • Superset means that P at least has all the labels in its metadata.labels that child C references via its parentSelector. In other words, parent P can have more labels than C uses to reference it, but C must at least have one matching label in its parentSelector with P.

  • Deckhand will select P if it belongs to the highest-precedence layer. For example, if C belongs to layer site, P belongs to layer type, and G belongs to layer global, then Deckhand will use P as the parent for C. If P is non-existent, then G will be selected instead.

For example, consider the following sample documents:

---
schema: deckhand/LayeringPolicy/v1
metadata:
  schema: metadata/Control/v1
  name: layering-policy
data:
  layerOrder:
    - global
    - region
    - site
---
schema: example/Kind/v1
metadata:
  schema: metadata/Document/v1
  name: global-1234
  labels:
    key1: value1
  layeringDefinition:
    abstract: true
    layer: global
data:
  a:
    x: 1
    y: 2
---
schema: example/Kind/v1
metadata:
  schema: metadata/Document/v1
  name: region-1234
  labels:
    key1: value1
  layeringDefinition:
    abstract: true
    layer: region
    parentSelector:
      key1: value1
    actions:
      - method: replace
        path: .a
data:
  a:
    z: 3
---
schema: example/Kind/v1
metadata:
  schema: metadata/Document/v1
  name: site-1234
  layeringDefinition:
    layer: site
    parentSelector:
      key1: value1
    actions:
      - method: merge
        path: .
data:
  b: 4

When rendering, the parent chosen for site-1234 will be region-1234, since it is the highest precedence document that matches the label selector defined by parentSelector, and the parent chosen for region-1234 will be global-1234 for the same reason. The rendered result for site-1234 would be:

---
schema: example/Kind/v1
metadata:
  name: site-1234
data:
  a:
    z: 3
  b: 4

If region-1234 were later removed, then the parent chosen for site-1234 would become global-1234, and the rendered result would become:

---
schema: example/Kind/v1
metadata:
  name: site-1234
data:
  a:
    x: 1
    y: 2
  b: 4