Merge "Revamp Deckhand documentation"
This commit is contained in:
commit
8541266e14
77
README.rst
77
README.rst
@ -1,7 +1,25 @@
|
||||
========
|
||||
Deckhand
|
||||
========
|
||||
A foundational python REST YAML processing engine providing data and secrets
|
||||
management to other platform services.
|
||||
|
||||
Deckhand is a document-based configuration storage service built with
|
||||
auditability and validation in mind.
|
||||
|
||||
Core Responsibilities
|
||||
=====================
|
||||
|
||||
* layering - helps reduce duplication in configuration while maintaining
|
||||
auditability across many sites
|
||||
* substitution - provides separation between secret data and other
|
||||
configuration data, while allowing a simple interface for clients
|
||||
* revision history - improves auditability and enables services to provide
|
||||
functional validation of a well-defined collection of documents that are
|
||||
meant to operate together
|
||||
* validation - allows services to implement and register different kinds of
|
||||
validations and report errors
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
To generate a configuration file automatically::
|
||||
|
||||
@ -36,3 +54,58 @@ To run locally in a development environment::
|
||||
$ sudo pip install .
|
||||
$ sudo python setup.py install
|
||||
$ uwsgi --http :9000 -w deckhand.cmd --callable deckhand_callable --enable-threads -L
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Automated Testing
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
To run unit tests using sqlite, execute:
|
||||
|
||||
::
|
||||
|
||||
$ tox -epy27
|
||||
$ tox -epy35
|
||||
|
||||
against a py27- or py35-backed environment, respectively. To run individual
|
||||
unit tests, run:
|
||||
|
||||
::
|
||||
|
||||
$ tox -e py27 -- deckhand.tests.unit.db.test_revisions
|
||||
|
||||
for example.
|
||||
|
||||
To run unit tests using postgresql, execute:
|
||||
|
||||
::
|
||||
|
||||
$ tox -epy27-postgresql
|
||||
$ tox -epy35-postgresql
|
||||
|
||||
To run functional tests:
|
||||
|
||||
::
|
||||
|
||||
$ tox -e functional
|
||||
|
||||
You can also run a subset of tests via a regex:
|
||||
|
||||
::
|
||||
|
||||
$ tox -e functional -- gabbi.suitemaker.test_gabbi_document-crud-success-multi-bucket
|
||||
|
||||
Manual Testing
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Document creation can be tested locally using (from root deckhand directory):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ curl -i -X PUT localhost:9000/api/v1.0/bucket/{bucket_name}/documents \
|
||||
-H "Content-Type: application/x-yaml" \
|
||||
--data-binary "@deckhand/tests/unit/resources/sample_document.yaml"
|
||||
|
||||
# revision_id copy/pasted from previous response.
|
||||
$ curl -i -X GET localhost:9000/api/v1.0/revisions/1
|
||||
|
@ -1,167 +0,0 @@
|
||||
Control
|
||||
=======
|
||||
|
||||
This is the external-facing API service to operate on and query
|
||||
Deckhand-managed data.
|
||||
|
||||
v1.0 Endpoints
|
||||
--------------
|
||||
|
||||
POST `/documents`
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Accepts a multi-document YAML body and creates a new revision which adds
|
||||
those documents. Updates are detected based on exact match to an existing
|
||||
document of `schema` + `metadata.name`. Documents are "deleted" by including
|
||||
documents with the tombstone metadata schema, such as:
|
||||
|
||||
```yaml
|
||||
---
|
||||
schema: any-namespace/AnyKind/v1
|
||||
metadata:
|
||||
schema: metadata/Tombstone/v1
|
||||
name: name-to-delete
|
||||
...
|
||||
```
|
||||
|
||||
This endpoint is the only way to add, update, and delete documents. This
|
||||
triggers Deckhand's internal schema validations for all documents.
|
||||
|
||||
If no changes are detected, a new revision should not be created. This allows
|
||||
services to periodically re-register their schemas without creating
|
||||
unnecessary revisions.
|
||||
|
||||
Sample response:
|
||||
|
||||
```yaml
|
||||
---
|
||||
created_at: '2017-07-31T14:46:46.119853'
|
||||
data:
|
||||
path:
|
||||
to:
|
||||
merge:
|
||||
into:
|
||||
ignored: {data: here}
|
||||
parent: {foo: bar}
|
||||
substitution: {target: null}
|
||||
deleted: false
|
||||
deleted_at: null
|
||||
id: f99630d9-a89c-4aad-9aaa-7c44462047c1
|
||||
metadata:
|
||||
labels: {genesis: enabled, master: enabled}
|
||||
layeringDefinition:
|
||||
abstract: false
|
||||
actions:
|
||||
- {method: merge, path: .path.to.merge.into.parent}
|
||||
- {method: delete, path: .path.to.delete}
|
||||
layer: region
|
||||
parentSelector: {required_key_a: required_label_a, required_key_b: required_label_b}
|
||||
name: unique-name-given-schema
|
||||
schema: metadata/Document/v1
|
||||
storagePolicy: cleartext
|
||||
substitutions:
|
||||
- dest: {path: .substitution.target}
|
||||
src: {name: name-of-source-document, path: .source.path, schema: another-service/SourceType/v1}
|
||||
name: unique-name-given-schema
|
||||
revision_id: 0206088a-c9e9-48e1-8725-c9bdac15d6b7
|
||||
schema: some-service/ResourceType/v1
|
||||
updated_at: '2017-07-31T14:46:46.119858'
|
||||
```
|
||||
|
||||
GET `/revisions`
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Lists existing revisions and reports basic details including a summary of
|
||||
validation status for each `deckhand/ValidationPolicy` that is part of that
|
||||
revision.
|
||||
|
||||
Sample response:
|
||||
|
||||
```yaml
|
||||
---
|
||||
count: 7
|
||||
next: https://deckhand/api/v1.0/revisions?limit=2&offset=2
|
||||
prev: null
|
||||
results:
|
||||
- id: 0
|
||||
url: https://deckhand/api/v1.0/revisions/0
|
||||
createdAt: 2017-07-14T21:23Z
|
||||
validationPolicies:
|
||||
site-deploy-validation:
|
||||
status: failed
|
||||
- id: 1
|
||||
url: https://deckhand/api/v1.0/revisions/1
|
||||
createdAt: 2017-07-16T01:15Z
|
||||
validationPolicies:
|
||||
site-deploy-validation:
|
||||
status: succeeded
|
||||
...
|
||||
```
|
||||
|
||||
GET `/revisions/{revision_id}/documents`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Returns a multi-document YAML response containing all the documents matching
|
||||
the filters specified via query string parameters. Returned documents will be
|
||||
as originally posted with no substitutions or layering applied.
|
||||
|
||||
Supported query string parameters:
|
||||
|
||||
* `schema` - string, optional - The top-level `schema` field to select. This
|
||||
may be partially specified by section, e.g., `schema=promenade` would select all
|
||||
`kind` and `version` schemas owned by promenade, or `schema=promenade/Node`
|
||||
which would select all versions of `promenade/Node` documents. One may not
|
||||
partially specify the namespace or kind, so `schema=promenade/No` would not
|
||||
select `promenade/Node/v1` documents, and `schema=prom` would not select
|
||||
`promenade` documents.
|
||||
* `metadata.name` - string, optional
|
||||
* `metadata.layeringDefinition.abstract` - string, optional - Valid values are
|
||||
the "true" and "false".
|
||||
* `metadata.layeringDefinition.layer` - string, optional - Only return documents from
|
||||
the specified layer.
|
||||
* `metadata.label` - string, optional, repeatable - Uses the format
|
||||
`metadata.label=key=value`. Repeating this parameter indicates all
|
||||
requested labels must apply (AND not OR).
|
||||
|
||||
Sample response:
|
||||
|
||||
```yaml
|
||||
created_at: '2017-07-31T14:36:00.352701'
|
||||
data: {foo: bar}
|
||||
deleted: false
|
||||
deleted_at: null
|
||||
id: ffba233a-326b-4eed-9b21-079ebd2a53f0
|
||||
metadata:
|
||||
labels: {genesis: enabled, master: enabled}
|
||||
layeringDefinition:
|
||||
abstract: false
|
||||
actions:
|
||||
- {method: merge, path: .path.to.merge.into.parent}
|
||||
- {method: delete, path: .path.to.delete}
|
||||
layer: region
|
||||
parentSelector: {required_key_a: required_label_a, required_key_b: required_label_b}
|
||||
name: foo-name-given-schema
|
||||
schema: metadata/Document/v1
|
||||
storagePolicy: cleartext
|
||||
substitutions:
|
||||
- dest: {path: .substitution.target}
|
||||
src: {name: name-of-source-document, path: .source.path, schema: another-service/SourceType/v1}
|
||||
name: foo-name-given-schema
|
||||
revision_id: d3428d6a-d8c4-4a5b-8006-aba974cc36a2
|
||||
schema: some-service/ResourceType/v1
|
||||
updated_at: '2017-07-31T14:36:00.352705'
|
||||
```
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Document creation can be tested locally using (from root deckhand directory):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ curl -i -X PUT localhost:9000/api/v1.0/bucket/{bucket_name}/documents \
|
||||
-H "Content-Type: application/x-yaml" \
|
||||
--data-binary "@deckhand/tests/unit/resources/sample_document.yaml"
|
||||
|
||||
# revision_id copy/pasted from previous response.
|
||||
$ curl -i -X GET localhost:9000/api/v1.0/revisions/1
|
1137
doc/design.md
1137
doc/design.md
File diff suppressed because it is too large
Load Diff
499
doc/source/api_ref.rst
Normal file
499
doc/source/api_ref.rst
Normal file
@ -0,0 +1,499 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _api-ref:
|
||||
|
||||
Deckhand API Documentation
|
||||
==========================
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
This API will only support YAML as a serialization format. Since the IETF
|
||||
does not provide an official media type for YAML, this API will use
|
||||
``application/x-yaml``.
|
||||
|
||||
This is a description of the ``v1.0`` API. Documented paths are considered
|
||||
relative to ``/api/v1.0``.
|
||||
|
||||
PUT ``/bucket/{bucket_name}/documents``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Accepts a multi-document YAML body and creates a new revision that updates the
|
||||
contents of the ``bucket_name`` bucket. Documents from the specified bucket that
|
||||
exist in previous revisions, but are absent from the request are removed from
|
||||
that revision (though still accessible via older revisions).
|
||||
|
||||
Documents in other buckets are not changed and will be included in queries for
|
||||
documents of the newly created revision.
|
||||
|
||||
Updates are detected based on exact match to an existing document of ``schema`` +
|
||||
``metadata.name``. It is an error that responds with ``409 Conflict`` to attempt
|
||||
to PUT a document with the same ``schema`` + ``metadata.name`` as an existing
|
||||
document from a different bucket in the most-recent revision.
|
||||
|
||||
This endpoint is the only way to add, update, and delete documents. This
|
||||
triggers Deckhand's internal schema validations for all documents.
|
||||
|
||||
If no changes are detected, a new revision should not be created. This allows
|
||||
services to periodically re-register their schemas without creating
|
||||
unnecessary revisions.
|
||||
|
||||
GET ``/revisions/{revision_id}/documents``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Returns a multi-document YAML response containing all the documents matching
|
||||
the filters specified via query string parameters. Returned documents will be
|
||||
as originally added with no substitutions or layering applied.
|
||||
|
||||
Supported query string parameters:
|
||||
|
||||
* ``schema`` - string, optional - The top-level ``schema`` field to select. This
|
||||
may be partially specified by section, e.g., ``schema=promenade`` would select all
|
||||
``kind`` and ``version`` schemas owned by promenade, or ``schema=promenade/Node``
|
||||
which would select all versions of ``promenade/Node`` documents. One may not
|
||||
partially specify the namespace or kind, so ``schema=promenade/No`` would not
|
||||
select ``promenade/Node/v1`` documents, and ``schema=prom`` would not select
|
||||
``promenade`` documents.
|
||||
* ``metadata.name`` - string, optional
|
||||
* ``metadata.layeringDefinition.abstract`` - string, optional - Valid values are
|
||||
the "true" and "false".
|
||||
* ``metadata.layeringDefinition.layer`` - string, optional - Only return documents from
|
||||
the specified layer.
|
||||
* ``metadata.label`` - string, optional, repeatable - Uses the format
|
||||
``metadata.label=key=value``. Repeating this parameter indicates all
|
||||
requested labels must apply (AND not OR).
|
||||
* ``sort`` - string, optional, repeatable - Defines the sort order for returning
|
||||
results. Default is by creation date. Repeating this parameter indicates use
|
||||
of multi-column sort with the most significant sorting column applied first.
|
||||
* ``status.bucket`` - string, optional, repeatable - Used to select documents
|
||||
only from a particular bucket. Repeating this parameter indicates documents
|
||||
from any of the specified buckets should be returned.
|
||||
|
||||
GET ``/revisions/{revision_id}/rendered-documents``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Returns a multi-document YAML of fully layered and substituted documents. No
|
||||
abstract documents will be returned. This is the primary endpoint that
|
||||
consumers will interact with for their configuration.
|
||||
|
||||
Valid query parameters are the same as for
|
||||
``/revisions/{revision_id}/documents``, minus the paremters in
|
||||
``metadata.layeringDetinition``, which are not supported.
|
||||
|
||||
GET ``/revisions``
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Lists existing revisions and reports basic details including a summary of
|
||||
validation status for each ``deckhand/ValidationPolicy`` that is part of that
|
||||
revision.
|
||||
|
||||
Supported query string parameters:
|
||||
|
||||
* ``tag`` - string, optional, repeatable - Used to select revisions that have
|
||||
been tagged with particular tags.
|
||||
|
||||
Sample response:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
count: 7
|
||||
next: https://deckhand/api/v1.0/revisions?limit=2&offset=2
|
||||
prev: null
|
||||
results:
|
||||
- id: 1
|
||||
url: https://deckhand/api/v1.0/revisions/1
|
||||
createdAt: 2017-07-14T21:23Z
|
||||
buckets: [mop]
|
||||
tags: [a, b, c]
|
||||
validationPolicies:
|
||||
site-deploy-validation:
|
||||
status: failure
|
||||
- id: 2
|
||||
url: https://deckhand/api/v1.0/revisions/2
|
||||
createdAt: 2017-07-16T01:15Z
|
||||
buckets: [flop, mop]
|
||||
tags: [b]
|
||||
validationPolicies:
|
||||
site-deploy-validation:
|
||||
status: success
|
||||
|
||||
DELETE ``/revisions``
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Permanently delete all documents.
|
||||
|
||||
.. warning::
|
||||
|
||||
This removes all revisions and resets the data store.
|
||||
|
||||
GET ``/revisions/{{revision_id}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Get a detailed description of a particular revision. The status of each
|
||||
``ValidationPolicy`` belonging to the revision is also included. Valid values
|
||||
for the status of each validation policy are:
|
||||
|
||||
* ``success`` - All validations associated with the policy are ``success``.
|
||||
* ``failure`` - Any validation associated with the policy has status ``failure``,
|
||||
``expired`` or ``missing``.
|
||||
|
||||
Sample response:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
id: 1
|
||||
url: https://deckhand/api/v1.0/revisions/1
|
||||
createdAt: 2017-07-14T021:23Z
|
||||
buckets: [mop]
|
||||
tags:
|
||||
a:
|
||||
name: a
|
||||
url: https://deckhand/api/v1.0/revisions/1/tags/a
|
||||
validationPolicies:
|
||||
site-deploy-validation:
|
||||
url: https://deckhand/api/v1.0/revisions/1/documents?schema=deckhand/ValidationPolicy/v1&name=site-deploy-validation
|
||||
status: failure
|
||||
validations:
|
||||
- name: deckhand-schema-validation
|
||||
url: https://deckhand/api/v1.0/revisions/1/validations/deckhand-schema-validation/0
|
||||
status: success
|
||||
- name: drydock-site-validation
|
||||
status: missing
|
||||
- name: promenade-site-validation
|
||||
url: https://deckhand/api/v1.0/revisions/1/validations/promenade-site-validation/0
|
||||
status: expired
|
||||
- name: armada-deployability-validation
|
||||
url: https://deckhand/api/v1.0/revisions/1/validations/armada-deployability-validation/0
|
||||
status: failure
|
||||
|
||||
Validation status is always for the most recent entry for a given validation.
|
||||
A status of ``missing`` indicates that no entries have been created. A status
|
||||
of ``expired`` indicates that the validation had succeeded, but the
|
||||
``expiresAfter`` limit specified in the ``ValidationPolicy`` has been exceeded.
|
||||
|
||||
GET ``/revisions/{{revision_id}}/diff/{{comparison_revision_id}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This endpoint provides a basic comparison of revisions in terms of how the
|
||||
buckets involved have changed. Only buckets with existing documents in either
|
||||
of the two revisions in question will be reported; buckets with documents that
|
||||
are only present in revisions between the two being compared are omitted from
|
||||
this report. That is, buckets with documents that were accidentally created
|
||||
(and then deleted to rectify the mistake) that are not directly present in
|
||||
the two revisions being compared are omitted.
|
||||
|
||||
The response will contain a status of ``created``, ``deleted``, ``modified``, or
|
||||
``unmodified`` for each bucket.
|
||||
|
||||
The ordering of the two revision ids is not important.
|
||||
|
||||
For the purposes of diffing, the ``revision_id`` "0" is treated as a revision
|
||||
with no documents, so queries comparing revision "0" to any other revision will
|
||||
report "created" for each bucket in the compared revision.
|
||||
|
||||
Diffing a revision against itself will respond with the each of the buckets in
|
||||
the revision as ``unmodified``.
|
||||
|
||||
Diffing revision "0" against itself results in an empty dictionary as the response.
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
|
||||
A response for a typical case, ``GET /api/v1.0/revisions/6/diff/3`` (or
|
||||
equivalently ``GET /api/v1.0/revisions/3/diff/6``).
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
bucket_a: created
|
||||
bucket_b: deleted
|
||||
bucket_c: modified
|
||||
bucket_d: unmodified
|
||||
|
||||
A response for diffing against an empty revision, ``GET /api/v1.0/revisions/0/diff/6``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
bucket_a: created
|
||||
bucket_c: created
|
||||
bucket_d: created
|
||||
|
||||
A response for diffing a revision against itself, ``GET /api/v1.0/revisions/6/diff/6``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
bucket_a: unmodified
|
||||
bucket_c: unmodified
|
||||
bucket_d: unmodified
|
||||
|
||||
Diffing two revisions that contain the same documents, ``GET /api/v1.0/revisions/8/diff/11``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
bucket_e: unmodified
|
||||
bucket_f: unmodified
|
||||
bucket_d: unmodified
|
||||
|
||||
Diffing revision zero with itself, ``GET /api/v1.0/revisions/0/diff/0``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
{}
|
||||
|
||||
POST ``/revisions/{{revision_id}}/validations/{{name}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add the results of a validation for a particular revision.
|
||||
|
||||
An example ``POST`` request body indicating validation success:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
status: success
|
||||
validator:
|
||||
name: promenade
|
||||
version: 1.1.2
|
||||
|
||||
An example ``POST`` request indicating validation failure:
|
||||
|
||||
::
|
||||
|
||||
POST /api/v1.0/revisions/3/validations/promenade-site-validation
|
||||
Content-Type: application/x-yaml
|
||||
|
||||
---
|
||||
status: failure
|
||||
errors:
|
||||
- documents:
|
||||
- schema: promenade/Node/v1
|
||||
name: node-document-name
|
||||
- schema: promenade/Masters/v1
|
||||
name: kubernetes-masters
|
||||
message: Node has master role, but not included in cluster masters list.
|
||||
validator:
|
||||
name: promenade
|
||||
version: 1.1.2
|
||||
|
||||
GET ``/revisions/{{revision_id}}/validations``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Gets the list of validations which have been reported for this revision.
|
||||
|
||||
Sample response:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
count: 2
|
||||
next: null
|
||||
prev: null
|
||||
results:
|
||||
- name: deckhand-schema-validation
|
||||
url: https://deckhand/api/v1.0/revisions/4/validations/deckhand-schema-validation
|
||||
status: success
|
||||
- name: promenade-site-validation
|
||||
url: https://deckhand/api/v1.0/revisions/4/validations/promenade-site-validation
|
||||
status: failure
|
||||
|
||||
GET ``/revisions/{{revision_id}}/validations/{{name}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Gets the list of validation entry summaries that have been posted.
|
||||
|
||||
Sample response:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
count: 1
|
||||
next: null
|
||||
prev: null
|
||||
results:
|
||||
- id: 0
|
||||
url: https://deckhand/api/v1.0/revisions/4/validations/promenade-site-validation/0/entries/0
|
||||
status: failure
|
||||
|
||||
GET ``/revisions/{{revision_id}}/validations/{{name}}/entries/{{entry_id}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Gets the full details of a particular validation entry, including all posted
|
||||
error details.
|
||||
|
||||
Sample response:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
name: promenade-site-validation
|
||||
url: https://deckhand/api/v1.0/revisions/4/validations/promenade-site-validation/entries/0
|
||||
status: failure
|
||||
createdAt: 2017-07-16T02:03Z
|
||||
expiresAfter: null
|
||||
expiresAt: null
|
||||
errors:
|
||||
- documents:
|
||||
- schema: promenade/Node/v1
|
||||
name: node-document-name
|
||||
- schema: promenade/Masters/v1
|
||||
name: kubernetes-masters
|
||||
message: Node has master role, but not included in cluster masters list.
|
||||
|
||||
POST ``/revisions/{{revision_id}}/tags/{{tag}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Associate the revision with a collection of metadata, if provided, by way of
|
||||
a tag. The tag itself can be used to label the revision.
|
||||
|
||||
Sample request with body:
|
||||
|
||||
::
|
||||
|
||||
POST ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foobar``
|
||||
Content-Type: application/x-yaml
|
||||
|
||||
---
|
||||
thing: bar
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 201 Created
|
||||
Location: https://deckhand/api/v1.0/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foobar
|
||||
|
||||
---
|
||||
tag: foobar
|
||||
data:
|
||||
thing: bar
|
||||
|
||||
Sample request without body:
|
||||
|
||||
::
|
||||
|
||||
POST ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foobar``
|
||||
Content-Type: application/x-yaml
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 201 Created
|
||||
Location: https://deckhand/api/v1.0/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foobar
|
||||
|
||||
---
|
||||
tag: foobar
|
||||
data: {}
|
||||
|
||||
GET ``/revisions/{{revision_id}}/tags``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
List the tags associated with a revision.
|
||||
|
||||
Sample request with body:
|
||||
|
||||
::
|
||||
|
||||
GET ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags``
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
---
|
||||
- tag: foo
|
||||
data:
|
||||
thing: bar
|
||||
- tag: baz
|
||||
data:
|
||||
thing: qux
|
||||
|
||||
GET ``/revisions/{{revision_id}}/tags/{{tag}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Show tag details for tag associated with a revision.
|
||||
|
||||
Sample request with body:
|
||||
|
||||
::
|
||||
|
||||
GET ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foo``
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
---
|
||||
tag: foo
|
||||
data:
|
||||
thing: bar
|
||||
|
||||
DELETE ``/revisions/{{revision_id}}/tags/{{tag}}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Delete tag associated with a revision.
|
||||
|
||||
Sample request with body:
|
||||
|
||||
::
|
||||
|
||||
GET ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags/foo``
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 204 No Content
|
||||
|
||||
DELETE ``/revisions/{{revision_id}}/tags``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Delete all tags associated with a revision.
|
||||
|
||||
Sample request with body:
|
||||
|
||||
::
|
||||
|
||||
GET ``/revisions/0615b731-7f3e-478d-8ba8-a223eab4757e/tags``
|
||||
|
||||
Sample response:
|
||||
|
||||
::
|
||||
|
||||
Content-Type: application/x-yaml
|
||||
HTTP/1.1 204 No Content
|
||||
|
||||
POST ``/rollback/{target_revision_id}``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Creates a new revision that contains exactly the same set of documents as the
|
||||
revision specified by ``target_revision_id``.
|
32
doc/source/buckets.rst
Normal file
32
doc/source/buckets.rst
Normal file
@ -0,0 +1,32 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _bucket:
|
||||
|
||||
Buckets
|
||||
=======
|
||||
|
||||
Collections of documents, called buckets, are managed together. All documents
|
||||
belong to a bucket and all documents that are part of a bucket must be fully
|
||||
specified together.
|
||||
|
||||
To create or update a new document in, e.g. bucket ``mop``, one must PUT the
|
||||
entire set of documents already in ``mop`` along with the new or modified
|
||||
document. Any documents not included in that PUT will be automatically
|
||||
deleted in the created revision.
|
||||
|
||||
This feature allows the separation of concerns when delivering different
|
||||
categories of documents, while making the delivered payload more declarative.
|
177
doc/source/document_types.rst
Normal file
177
doc/source/document_types.rst
Normal file
@ -0,0 +1,177 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _document-types:
|
||||
|
||||
Document Types
|
||||
==============
|
||||
|
||||
Control Documents
|
||||
-----------------
|
||||
|
||||
Control documents (documents which have ``metadata.schema=metadata/Control/v1``),
|
||||
are special, and are used to control the behavior of Deckhand at runtime. Only
|
||||
the following types of control documents are allowed.
|
||||
|
||||
DataSchema
|
||||
^^^^^^^^^^
|
||||
|
||||
``DataSchema`` documents are used by various services to register new schemas
|
||||
that Deckhand can use for validation. No ``DataSchema`` documents with names
|
||||
beginning with ``deckhand/`` or ``metadata/`` are allowed. Tme ``metadata.name``
|
||||
field of each ``DataSchema`` document specifies the top level ``schema`` that it
|
||||
is used to validate.
|
||||
|
||||
The contents of its ``data`` key are expected to be the json schema definition
|
||||
for the target document type from the target's top level ``data`` key down.
|
||||
|
||||
.. TODO: give valid, tiny schema as example
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/DataSchema/v1 # This specifies the official JSON schema meta-schema.
|
||||
metadata:
|
||||
schema: metadata/Control/v1
|
||||
name: promenade/Node/v1 # Specifies the documents to be used for validation.
|
||||
labels:
|
||||
application: promenade
|
||||
data: # Valid JSON Schema is expected here.
|
||||
$schema: http://blah
|
||||
...
|
||||
|
||||
LayeringPolicy
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Only one ``LayeringPolicy`` document can exist within the system at any time.
|
||||
It is an error to attempt to insert a new ``LayeringPolicy`` document if it has
|
||||
a different ``metadata.name`` than the existing document. If the names match,
|
||||
it is treated as an update to the existing document.
|
||||
|
||||
This document defines the strict order in which documents are merged together
|
||||
from their component parts. It should result in a validation error if a
|
||||
document refers to a layer not specified in the ``LayeringPolicy``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/LayeringPolicy/v1
|
||||
metadata:
|
||||
schema: metadata/Control/v1
|
||||
name: layering-policy
|
||||
data:
|
||||
layerOrder:
|
||||
- global
|
||||
- site-type
|
||||
- region
|
||||
- site
|
||||
- force
|
||||
...
|
||||
|
||||
ValidationPolicy
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Unlike ``LayeringPolicy``, many ``ValidationPolicy`` documents are allowed. This
|
||||
allows services to check whether a particular revision (described below) of
|
||||
documents meets a configurable set of validations without having to know up
|
||||
front the complete list of validations.
|
||||
|
||||
Each validation ``name`` specified here is a reference to data that is postable
|
||||
by other services. Names beginning with ``deckhand`` are reserved for internal
|
||||
use. See the Validation section below for more details.
|
||||
|
||||
Since validations may indicate interactions with external and changing
|
||||
circumstances, an optional ``expiresAfter`` key may be specified for each
|
||||
validation as an ISO8601 duration. If no ``expiresAfter`` is specified, a
|
||||
successful validation does not expire. Note that expirations are specific to
|
||||
the combination of ``ValidationPolicy`` and validation, not to each validation
|
||||
by itself.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/ValidationPolicy/v1
|
||||
metadata:
|
||||
schema: metadata/Control/v1
|
||||
name: site-deploy-ready
|
||||
data:
|
||||
validations:
|
||||
- name: deckhand-schema-validation
|
||||
- name: drydock-site-validation
|
||||
expiresAfter: P1W
|
||||
- name: promenade-site-validation
|
||||
expiresAfter: P1W
|
||||
- name: armada-deployability-validation
|
||||
...
|
||||
|
||||
Provided Utility Document Kinds
|
||||
-------------------------------
|
||||
|
||||
These are documents that use the ``Document`` metadata schema, but live in the
|
||||
``deckhand`` namespace.
|
||||
|
||||
Certificate
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/Certificate/v1
|
||||
metadata:
|
||||
schema: metadata/Document/v1
|
||||
name: application-api
|
||||
storagePolicy: cleartext
|
||||
data: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDYDCCAkigAwIBAgIUKG41PW4VtiphzASAMY4/3hL8OtAwDQYJKoZIhvcNAQEL
|
||||
...snip...
|
||||
P3WT9CfFARnsw2nKjnglQcwKkKLYip0WY2wh3FE7nrQZP6xKNaSRlh6p2pCGwwwH
|
||||
HkvVwA==
|
||||
-----END CERTIFICATE-----
|
||||
...
|
||||
|
||||
CertificateKey
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/CertificateKey/v1
|
||||
metadata:
|
||||
schema: metadata/Document/v1
|
||||
name: application-api
|
||||
storagePolicy: encrypted
|
||||
data: |-
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAx+m1+ao7uTVEs+I/Sie9YsXL0B9mOXFlzEdHX8P8x4nx78/T
|
||||
...snip...
|
||||
Zf3ykIG8l71pIs4TGsPlnyeO6LzCWP5WRSh+BHnyXXjzx/uxMOpQ/6I=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
...
|
||||
|
||||
Passphrase
|
||||
^^^^^^^^^^
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/Passphrase/v1
|
||||
metadata:
|
||||
schema: metadata/Document/v1
|
||||
name: application-admin-password
|
||||
storagePolicy: encrypted
|
||||
data: some-password
|
||||
...
|
164
doc/source/documents.rst
Normal file
164
doc/source/documents.rst
Normal file
@ -0,0 +1,164 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Documents
|
||||
=========
|
||||
|
||||
All configuration data is stored entirely as structured documents, for which
|
||||
schemas must be registered. Documents satisfy the following use cases:
|
||||
|
||||
* layering - helps reduce duplication in configuration while maintaining
|
||||
auditability across many sites
|
||||
* substitution - provides separation between secret data and other
|
||||
configuration data, while allowing a simple interface for clients
|
||||
* revision history - improves auditability and enables services to provide
|
||||
functional validation of a well-defined collection of documents that are
|
||||
meant to operate together
|
||||
* validation - allows services to implement and register different kinds of
|
||||
validations and report errors
|
||||
|
||||
Detailed documentation for :ref:`layering`, :ref:`substitution`,
|
||||
:ref:`revision-history` and :ref:`validation` should be reviewed for a more
|
||||
thorough understanding of each concept.
|
||||
|
||||
Document Format
|
||||
---------------
|
||||
|
||||
The document format is modeled loosely after Kubernetes practices. The top
|
||||
level of each document is a dictionary with 3 keys: ``schema``, ``metadata``,
|
||||
and ``data``.
|
||||
|
||||
* ``schema`` - Defines the name of the JSON schema to be used for validation.
|
||||
Must have the form: ``<namespace>/<kind>/<version>``, where the meaning of
|
||||
each component is:
|
||||
* ``namespace`` - Identifies the owner of this type of document. The
|
||||
values `deckhand` and `metadata` are reserved for internal use.
|
||||
* ``kind`` - Identifies a type of configuration resource in the namespace.
|
||||
* ``version`` - Describe the version of this resource, e.g. "v1".
|
||||
* ``metadata`` - Defines details that Deckhand will inspect and understand.
|
||||
There are multiple schemas for this section as discussed below. All the
|
||||
various types of metadata include a `name` field which must be unique for
|
||||
each document `schema`.
|
||||
* ``data`` - Data to be validated by the schema described by the ``schema``
|
||||
field. Deckhand only interacts with content here as instructed to do so by
|
||||
the ``metadata`` section. The form of this section is considered to be
|
||||
completely owned by the ``namespace`` in the ``schema``.
|
||||
|
||||
Below is a fictitious example of a complete document, which illustrates all the
|
||||
valid fields in the ``metadata`` section:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: some-service/ResourceType/v1
|
||||
metadata:
|
||||
schema: metadata/Document/v1
|
||||
name: unique-name-given-schema
|
||||
storagePolicy: cleartext
|
||||
labels:
|
||||
genesis: enabled
|
||||
master: enabled
|
||||
layeringDefinition:
|
||||
abstract: true
|
||||
layer: region
|
||||
parentSelector:
|
||||
required_key_a: required_label_a
|
||||
required_key_b: required_label_b
|
||||
actions:
|
||||
- method: merge
|
||||
path: .path.to.merge.into.parent
|
||||
- method: delete
|
||||
path: .path.to.delete
|
||||
substitutions:
|
||||
- dest:
|
||||
path: .substitution.target
|
||||
src:
|
||||
schema: another-service/SourceType/v1
|
||||
name: name-of-source-document
|
||||
path: .source.path
|
||||
data:
|
||||
path:
|
||||
to:
|
||||
merge:
|
||||
into:
|
||||
parent:
|
||||
foo: bar
|
||||
ignored:
|
||||
data: here
|
||||
substitution:
|
||||
target: null
|
||||
|
||||
Document Metadata
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are 2 supported kinds of document metadata. Documents with `Document`
|
||||
metadata are the most common, and are used for normal configuration data.
|
||||
Documents with `Control` metadata are used to customize the behavior of
|
||||
Deckhand.
|
||||
|
||||
schema: metadata/Document/v1
|
||||
""""""""""""""""""""""""""""
|
||||
|
||||
This type of metadata allows the following metadata hierarchy:
|
||||
|
||||
* ``name`` - string, required - Unique within a revision for a given ``schema``.
|
||||
* ``storagePolicy`` - string, required - Either ``cleartext`` or ``encrypted``. If
|
||||
``encyrpted`` is specified, then the ``data`` section of the document will be
|
||||
stored in an secure backend (likely via OpenStack Barbican). ``metadata`` and
|
||||
``schema`` fields are always stored in cleartext.
|
||||
* ``layeringDefinition`` - dict, required - Specifies layering details. See the
|
||||
Layering section below for details.
|
||||
|
||||
* ``abstract`` - boolean, required - An abstract document is not expected to
|
||||
pass schema validation after layering and substitution are applied.
|
||||
Non-abstract (concrete) documents are.
|
||||
* ``layer`` - string, required - References a layer in the ``LayeringPolicy``
|
||||
control document.
|
||||
* ``parentSelector`` - labels, optional - Used to construct document chains for
|
||||
executing merges.
|
||||
* ``actions`` - list, optional - A sequence of actions to apply this documents
|
||||
data during the merge process.
|
||||
* ``method`` - string, required - How to layer this content.
|
||||
* ``path`` - string, required - What content in this document to layer onto
|
||||
parent content.
|
||||
|
||||
* ``substitutions`` - list, optional - A sequence of substitutions to apply. See
|
||||
the Substitutions section for additional details.
|
||||
|
||||
* ``dest`` - dict, required - A description of the inserted content destination.
|
||||
|
||||
* ``path`` - string, required - The JSON path where the data will be placed
|
||||
into the ``data`` section of this document.
|
||||
* ``pattern`` - string, optional - A regex to search for in the string
|
||||
specified at ``path`` in this document and replace with the source data
|
||||
|
||||
* ``src`` - dict, required - A description of the inserted content source.
|
||||
|
||||
* ``schema`` - string, required - The ``schema`` of the source document.
|
||||
* ``name`` - string, required - The ``metadata.name`` of the source document.
|
||||
* ``path`` - string, required - The JSON path from which to extract data in
|
||||
the source document relative to its ``data`` section.
|
||||
|
||||
|
||||
schema: metadata/Control/v1
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
This schema is the same as the ``Document`` schema, except it omits the
|
||||
``storagePolicy``, ``layeringDefinition``, and ``substitutions`` keys, as these
|
||||
actions are not supported on ``Control`` documents.
|
||||
|
||||
The complete list of valid ``Control`` document kinds is specified below along
|
||||
with descriptions of each document kind.
|
@ -1,18 +1,18 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
====================================
|
||||
Welcome to Deckhand's documentation!
|
||||
@ -38,7 +38,14 @@ User's Guide
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
policy-enforcement
|
||||
documents
|
||||
document_types
|
||||
buckets
|
||||
validation
|
||||
substitution
|
||||
layering
|
||||
revision_history
|
||||
api_ref
|
||||
|
||||
Developer's Guide
|
||||
=================
|
||||
@ -47,6 +54,7 @@ Developer's Guide
|
||||
:maxdepth: 2
|
||||
|
||||
HACKING
|
||||
policy-enforcement
|
||||
testing
|
||||
|
||||
Glossary
|
||||
|
151
doc/source/layering.rst
Normal file
151
doc/source/layering.rst
Normal file
@ -0,0 +1,151 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _layering:
|
||||
|
||||
Document Layering
|
||||
=================
|
||||
|
||||
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 :ref:`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).
|
||||
|
||||
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``. Document ``P`` will be the highest
|
||||
precedence (i.e. part of the lowest layer defined in the ``layerOrder`` list
|
||||
from the ``LayeringPolicy``) document that has the labels indicated by the
|
||||
``parentSelector`` (and possibly additional labels) from the set of all
|
||||
documents of the same ``schema`` as ``C`` that are in layers above the layer ``C``
|
||||
is in. For example, consider the following sample documents:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
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:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
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:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: example/Kind/v1
|
||||
metadata:
|
||||
name: site-1234
|
||||
data:
|
||||
a:
|
||||
x: 1
|
||||
y: 2
|
||||
b: 4
|
||||
|
||||
.. TODO: Add figures for this example, with region present, have site point
|
||||
.. with dotted line at global and indicate in caption (or something) that it's
|
||||
.. selected for but ignored, because there's a higher-precedence layer to select
|
@ -1,17 +1,17 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Rest API Policy Enforcement
|
||||
|
57
doc/source/revision_history.rst
Normal file
57
doc/source/revision_history.rst
Normal file
@ -0,0 +1,57 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _revision-history:
|
||||
|
||||
Revision History
|
||||
================
|
||||
|
||||
Revision History
|
||||
----------------
|
||||
|
||||
Documents will be ingested in batches which will be given a revision index.
|
||||
This provides a common language for describing complex validations on sets of
|
||||
documents.
|
||||
|
||||
Revisions can be thought of as commits in a linear git history, thus looking
|
||||
at a revision includes all content from previous revisions.
|
||||
|
||||
Revision Diffing
|
||||
----------------
|
||||
|
||||
By maintaining a linear history of all the documents in each revision, Deckhand
|
||||
is able to diff different revisions together to report what has changed
|
||||
across revisions, allowing external services to determine whether the Deckhand
|
||||
configuration undergone any changes since the service last queried the Deckhand
|
||||
API.
|
||||
|
||||
The revision difference is calculated by comparing the `overall` difference
|
||||
across all the documents in the buckets associated with the two revisions that
|
||||
are diffed. For example, if a bucket shared between two revisions contains two
|
||||
documents, and between the first revision and the second revision, if only
|
||||
one of those two documents has been modified, the bucket itself is tagged
|
||||
as ``modified``. For more information about revision diffing, please reference
|
||||
the :ref:`api-ref`.
|
||||
|
||||
Revision Rollback
|
||||
-----------------
|
||||
|
||||
As all the changes to documents are maintained via revisions, it is possible to
|
||||
rollback the latest revision in Deckhand to a prior revision. This behavior can
|
||||
be loosely compared to a ``git rebase`` in which it is possible to squash the
|
||||
latest revision in order to go back to the previous revision. This behavior is
|
||||
useful for undoing accidental changes and returning to a stable internal
|
||||
configuration.
|
140
doc/source/substitution.rst
Normal file
140
doc/source/substitution.rst
Normal file
@ -0,0 +1,140 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _substitution:
|
||||
|
||||
Secret Substitution
|
||||
===================
|
||||
|
||||
Substitution is primarily designed as a mechanism for inserting secrets into
|
||||
configuration documents, but works for unencrypted source documents as well.
|
||||
Substitution is applied at each layer after all merge actions occur. Further,
|
||||
substitution is only applied to the ``data`` section of a document.
|
||||
|
||||
Concrete (non-abstract) documents can be used as a source of substitution
|
||||
into other documents. This substitution is layer-independent, so given the 3
|
||||
layer example above, which includes ``global``, ``region`` and ``site`` layers,
|
||||
a document in the ``region`` layer could insert data from a document in the
|
||||
``site`` layer.
|
||||
|
||||
Here is a sample set of documents demonstrating substitution:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: deckhand/Certificate/v1
|
||||
metadata:
|
||||
name: example-cert
|
||||
storagePolicy: cleartext
|
||||
layeringDefinition:
|
||||
layer: site
|
||||
data: |
|
||||
CERTIFICATE DATA
|
||||
---
|
||||
schema: deckhand/CertificateKey/v1
|
||||
metadata:
|
||||
name: example-key
|
||||
storagePolicy: encrypted
|
||||
layeringDefinition:
|
||||
layer: site
|
||||
data: |
|
||||
KEY DATA
|
||||
---
|
||||
schema: deckhand/Passphrase/v1
|
||||
metadata:
|
||||
name: example-password
|
||||
storagePolicy: encrypted
|
||||
layeringDefinition:
|
||||
layer: site
|
||||
data: my-secret-password
|
||||
---
|
||||
schema: armada/Chart/v1
|
||||
metadata:
|
||||
name: example-chart-01
|
||||
storagePolicy: cleartext
|
||||
layeringDefinition:
|
||||
layer: region
|
||||
substitutions:
|
||||
- dest:
|
||||
path: .chart.values.tls.certificate
|
||||
src:
|
||||
schema: deckhand/Certificate/v1
|
||||
name: example-cert
|
||||
path: .
|
||||
- dest:
|
||||
path: .chart.values.tls.key
|
||||
src:
|
||||
schema: deckhand/CertificateKey/v1
|
||||
name: example-key
|
||||
path: .
|
||||
- dest:
|
||||
path: .chart.values.some_url
|
||||
pattern: INSERT_[A-Z]+_HERE
|
||||
src:
|
||||
schema: deckhand/Passphrase/v1
|
||||
name: example-password
|
||||
path: .
|
||||
data:
|
||||
chart:
|
||||
details:
|
||||
data: here
|
||||
values:
|
||||
some_url: http://admin:INSERT_PASSWORD_HERE@service-name:8080/v1
|
||||
...
|
||||
|
||||
The rendered document will look like:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
schema: armada/Chart/v1
|
||||
metadata:
|
||||
name: example-chart-01
|
||||
storagePolicy: cleartext
|
||||
layeringDefinition:
|
||||
layer: region
|
||||
substitutions:
|
||||
- dest:
|
||||
path: .chart.values.tls.certificate
|
||||
src:
|
||||
schema: deckhand/Certificate/v1
|
||||
name: example-cert
|
||||
path: .
|
||||
- dest:
|
||||
path: .chart.values.tls.key
|
||||
src:
|
||||
schema: deckhand/CertificateKey/v1
|
||||
name: example-key
|
||||
path: .
|
||||
- dest:
|
||||
path: .chart.values.some_url
|
||||
pattern: INSERT_[A-Z]+_HERE
|
||||
src:
|
||||
schema: deckhand/Passphrase/v1
|
||||
name: example-password
|
||||
path: .
|
||||
data:
|
||||
chart:
|
||||
details:
|
||||
data: here
|
||||
values:
|
||||
some_url: http://admin:my-secret-password@service-name:8080/v1
|
||||
tls:
|
||||
certificate: |
|
||||
CERTIFICATE DATA
|
||||
key: |
|
||||
KEY DATA
|
||||
...
|
@ -1,17 +1,17 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
=======
|
||||
Testing
|
||||
|
61
doc/source/validation.rst
Normal file
61
doc/source/validation.rst
Normal file
@ -0,0 +1,61 @@
|
||||
..
|
||||
Copyright 2017 AT&T Intellectual Property.
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _validation:
|
||||
|
||||
Document Validation
|
||||
===================
|
||||
|
||||
Validations
|
||||
-----------
|
||||
|
||||
The validation system provides a unified approach to complex validations that
|
||||
require coordination of multiple documents and business logic that resides in
|
||||
consumer services.
|
||||
|
||||
Services can report success or failure of named validations for a given
|
||||
revision. Those validations can then be referenced by many ``ValidationPolicy``
|
||||
control documents. The intended purpose use is to allow a simple mapping that
|
||||
enables consuming services to be able to quickly check whether the
|
||||
configuration in Deckhand is in a valid state for performing a specific
|
||||
action.
|
||||
|
||||
Deckhand-Provided Validations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In addition to allowing 3rd party services to report configurable validation
|
||||
statuses, Deckhand provides a few internal validations which are made
|
||||
available immediately upon document ingestion.
|
||||
|
||||
Here is a list of internal validations:
|
||||
|
||||
* ``deckhand-document-schema-validation`` - All concrete documents in the
|
||||
revision successfully pass their JSON schema validations. Will cause
|
||||
this to report an error.
|
||||
* ``deckhand-policy-validation`` - All required policy documents are in-place,
|
||||
and existing documents conform to those policies. E.g. if a 3rd party
|
||||
document specifies a ``layer`` that is not present in the layering policy,
|
||||
that will cause this validation to report an error.
|
||||
|
||||
Externally Provided Validations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As mentioned, other services can report whether named validations that have
|
||||
been registered by those services as success or failure. ``DataSchema`` control
|
||||
documents are used to register a new validation mapping that other services
|
||||
can reference to verify whether a Deckhand bucket is in a valid configuration.
|
||||
For more information, refer to the ``DataSchema`` section in
|
||||
:ref:`document-types`.
|
Loading…
x
Reference in New Issue
Block a user