Update default_schema with our updated schema definition

This commit updates the default_schema based on recent changes
to the document definition that Deckhand is supposed to validate.
This commit is contained in:
Felipe Monteiro 2017-07-12 16:52:02 +01:00
parent 81a87c5444
commit ac557f70f4
4 changed files with 80 additions and 56 deletions

View File

@ -15,19 +15,29 @@
substitution_schema = {
'type': 'object',
'properties': {
'dest': {'type': 'string'},
'dest': {
'type': 'object',
'properties': {
'path': {'type': 'string'},
'replacePattern': {'type': 'string'}
},
'additionalProperties': False,
# 'replacePattern' is not required.
'required': ['path']
},
'src': {
'type': 'object',
'properties': {
'apiVersion': {
'type': 'string',
'choices': ['deckhand/v1']
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
},
'kind': {'type': 'string'},
'name': {'type': 'string'}
'name': {'type': 'string'},
'path': {'type': 'string'}
},
'additionalProperties': False,
'required': ['apiVersion', 'kind', 'name']
'required': ['apiVersion', 'kind', 'name', 'path']
}
},
'additionalProperties': False,
@ -37,31 +47,58 @@ substitution_schema = {
schema = {
'type': 'object',
'properties': {
'apiVersion': {
'schemaVersion': {
'type': 'string',
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
},
'kind': {
'type': 'string',
'pattern': '^([A-Za-z]+)$'
},
'kind': {'type': 'string'},
'metadata': {
'type': 'object',
'properties': {
'metadataVersion': {
'type': 'string',
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
},
'name': {'type': 'string'},
'storage': {'type': 'string'},
'labels': {
'type': 'object',
'properties': {
'component': {'type': 'string'},
'hostname': {'type': 'string'}
},
'additionalProperties': False,
'required': ['component', 'hostname']
},
'layerDefinition': {
'type': 'object',
'properties': {
'layer': {'enum': ['global', 'region', 'local']},
'abstract': {'type': 'boolean'},
'childSelector': {
'type': 'object',
'properties': {
'label': {'type': 'string'}
},
'additionalProperties': False,
'required': ['label']
}
},
'additionalProperties': False,
'required': ['layer', 'abstract', 'childSelector']
},
'substitutions': {
'type': 'array',
'items': substitution_schema
}
},
'additionalProperties': False,
'required': ['name', 'storage', 'substitutions']
'required': ['metadataVersion', 'name', 'labels',
'layerDefinition', 'substitutions']
},
'data': {
'type': 'object'
}
},
'additionalProperties': False,
'required': ['apiVersion', 'kind', 'metadata', 'data']
'required': ['schemaVersion', 'kind', 'metadata', 'data']
}

View File

@ -61,33 +61,7 @@ class SecretSubstitution(object):
if v['version'] == self.schema_version][0].schema
def validate_data(self):
"""Pre-validate that the YAML file is correctly formatted.
The YAML file must adhere to the following bare minimum format:
.. code-block:: yaml
---
apiVersion: service/v1
kind: ConsumerOfCertificateData
metadata:
substitutions:
- dest: .tls_endpoint.certificate
src:
apiVersion: deckhand/v1
kind: Certificate
name: some-certificate-asdf-1234
# Forward-reference to specific section under "data" below.
- dest: .tls_endpoint.certificateKey
src:
apiVersion: deckhand/v1
kind: CertificateKey
name: some-certificate-key-asdf-1234
data:
tls_endpoint:
certificate: null # Data to be substituted.
certificateKey: null # Data to be substituted.
"""
"""Pre-validate that the YAML file is correctly formatted."""
self._validate_with_schema()
# Validate that each "dest" field exists in the YAML data.
@ -96,7 +70,7 @@ class SecretSubstitution(object):
sub_data = self.data['data']
for dest in destinations:
result, missing_attr = self._multi_getattr(dest, sub_data)
result, missing_attr = self._multi_getattr(dest['path'], sub_data)
if not result:
raise errors.InvalidFormat(
'The attribute "%s" included in the "dest" field "%s" is '
@ -109,7 +83,7 @@ class SecretSubstitution(object):
# Validate that a schema with "apiVersion" version number exists, then
# use that schema to validate the YAML data.
try:
schema_version = self.data['apiVersion'].split('/')[-1]
schema_version = self.data['schemaVersion'].split('/')[-1]
data_schema_version = self.SchemaVersion(schema_version)
except (AttributeError, IndexError, KeyError) as e:
raise errors.InvalidFormat(

View File

@ -85,8 +85,8 @@ class TestSecretSubtitution(testtools.TestCase):
invalid_data = [
(self._corrupt_data('data'), 'data'),
(self._corrupt_data('metadata'), 'metadata'),
(self._corrupt_data('metadata.metadataVersion'), 'metadataVersion'),
(self._corrupt_data('metadata.name'), 'name'),
(self._corrupt_data('metadata.storage'), 'storage'),
(self._corrupt_data('metadata.substitutions'), 'substitutions'),
(self._corrupt_data('metadata.substitutions.0.dest'), 'dest'),
(self._corrupt_data('metadata.substitutions.0.src'), 'src')
@ -103,11 +103,12 @@ class TestSecretSubtitution(testtools.TestCase):
invalid_data = []
data = copy.deepcopy(self.data)
data['metadata']['substitutions'][0]['dest'] = 'foo'
data['metadata']['substitutions'][0]['dest'] = {'path': 'foo'}
invalid_data.append(self._format_data(data))
data = copy.deepcopy(self.data)
data['metadata']['substitutions'][0]['dest'] = 'tls_endpoint.bar'
data['metadata']['substitutions'][0]['dest'] = {
'path': 'tls_endpoint.bar'}
invalid_data.append(self._format_data(data))
def _test(invalid_entry, field, dest):
@ -117,6 +118,6 @@ class TestSecretSubtitution(testtools.TestCase):
secret_substitution.SecretSubstitution(invalid_entry)
# Verify that invalid body dest reference is invalid.
_test(invalid_data[0], "foo", "foo")
_test(invalid_data[0], "foo", {'path': 'foo'})
# Verify that nested invalid body dest reference is invalid.
_test(invalid_data[1], "bar", "tls_endpoint.bar")
_test(invalid_data[1], "bar", {'path': 'tls_endpoint.bar'})

View File

@ -1,23 +1,35 @@
# Sample YAML file for testing forward replacement.
---
apiVersion: service/v1
kind: ConsumerOfCertificateData
schemaVersion: promenade/v1
kind: SomeConfigType
metadata:
name: asdf-1234
storage: cleartext
metadataVersion: deckhand/v1
name: a-unique-config-name-12345
labels:
component: apiserver
hostname: server0
layerDefinition:
layer: global
abstract: True
childSelector:
label: value
substitutions:
- dest: .tls_endpoint.certificate
- dest:
path: .tls_endpoint.certificate
replacePattern: 'test.pattern'
src:
apiVersion: deckhand/v1
kind: Certificate
name: some-certificate-asdf-1234
- dest: .tls_endpoint.certificateKey
path: .cert
- dest:
path: .tls_endpoint.key
src:
apiVersion: deckhand/v1
kind: CertificateKey
name: some-certificate-key-asdf-1234
name: some-certificate-asdf-1234
path: .key
data:
tls_endpoint:
uri: http://localhost:443
certificate: null
certificateKey: null
certificate: '.cert'
key: deckhand/v1:some-certificate-asdf-1234