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:
parent
81a87c5444
commit
ac557f70f4
@ -15,19 +15,29 @@
|
|||||||
substitution_schema = {
|
substitution_schema = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'dest': {'type': 'string'},
|
'dest': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'path': {'type': 'string'},
|
||||||
|
'replacePattern': {'type': 'string'}
|
||||||
|
},
|
||||||
|
'additionalProperties': False,
|
||||||
|
# 'replacePattern' is not required.
|
||||||
|
'required': ['path']
|
||||||
|
},
|
||||||
'src': {
|
'src': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'apiVersion': {
|
'apiVersion': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'choices': ['deckhand/v1']
|
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
|
||||||
},
|
},
|
||||||
'kind': {'type': 'string'},
|
'kind': {'type': 'string'},
|
||||||
'name': {'type': 'string'}
|
'name': {'type': 'string'},
|
||||||
|
'path': {'type': 'string'}
|
||||||
},
|
},
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'required': ['apiVersion', 'kind', 'name']
|
'required': ['apiVersion', 'kind', 'name', 'path']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
@ -37,31 +47,58 @@ substitution_schema = {
|
|||||||
schema = {
|
schema = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'apiVersion': {
|
'schemaVersion': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
|
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
|
||||||
},
|
},
|
||||||
'kind': {
|
'kind': {'type': 'string'},
|
||||||
'type': 'string',
|
|
||||||
'pattern': '^([A-Za-z]+)$'
|
|
||||||
},
|
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
|
'metadataVersion': {
|
||||||
|
'type': 'string',
|
||||||
|
'pattern': '^([A-Za-z]+\/v[0-9]{1})$'
|
||||||
|
},
|
||||||
'name': {'type': 'string'},
|
'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': {
|
'substitutions': {
|
||||||
'type': 'array',
|
'type': 'array',
|
||||||
'items': substitution_schema
|
'items': substitution_schema
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'required': ['name', 'storage', 'substitutions']
|
'required': ['metadataVersion', 'name', 'labels',
|
||||||
|
'layerDefinition', 'substitutions']
|
||||||
},
|
},
|
||||||
'data': {
|
'data': {
|
||||||
'type': 'object'
|
'type': 'object'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'required': ['apiVersion', 'kind', 'metadata', 'data']
|
'required': ['schemaVersion', 'kind', 'metadata', 'data']
|
||||||
}
|
}
|
||||||
|
@ -61,33 +61,7 @@ class SecretSubstitution(object):
|
|||||||
if v['version'] == self.schema_version][0].schema
|
if v['version'] == self.schema_version][0].schema
|
||||||
|
|
||||||
def validate_data(self):
|
def validate_data(self):
|
||||||
"""Pre-validate that the YAML file is correctly formatted.
|
"""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.
|
|
||||||
"""
|
|
||||||
self._validate_with_schema()
|
self._validate_with_schema()
|
||||||
|
|
||||||
# Validate that each "dest" field exists in the YAML data.
|
# Validate that each "dest" field exists in the YAML data.
|
||||||
@ -96,7 +70,7 @@ class SecretSubstitution(object):
|
|||||||
sub_data = self.data['data']
|
sub_data = self.data['data']
|
||||||
|
|
||||||
for dest in destinations:
|
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:
|
if not result:
|
||||||
raise errors.InvalidFormat(
|
raise errors.InvalidFormat(
|
||||||
'The attribute "%s" included in the "dest" field "%s" is '
|
'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
|
# Validate that a schema with "apiVersion" version number exists, then
|
||||||
# use that schema to validate the YAML data.
|
# use that schema to validate the YAML data.
|
||||||
try:
|
try:
|
||||||
schema_version = self.data['apiVersion'].split('/')[-1]
|
schema_version = self.data['schemaVersion'].split('/')[-1]
|
||||||
data_schema_version = self.SchemaVersion(schema_version)
|
data_schema_version = self.SchemaVersion(schema_version)
|
||||||
except (AttributeError, IndexError, KeyError) as e:
|
except (AttributeError, IndexError, KeyError) as e:
|
||||||
raise errors.InvalidFormat(
|
raise errors.InvalidFormat(
|
||||||
|
@ -85,8 +85,8 @@ class TestSecretSubtitution(testtools.TestCase):
|
|||||||
invalid_data = [
|
invalid_data = [
|
||||||
(self._corrupt_data('data'), 'data'),
|
(self._corrupt_data('data'), 'data'),
|
||||||
(self._corrupt_data('metadata'), 'metadata'),
|
(self._corrupt_data('metadata'), 'metadata'),
|
||||||
|
(self._corrupt_data('metadata.metadataVersion'), 'metadataVersion'),
|
||||||
(self._corrupt_data('metadata.name'), 'name'),
|
(self._corrupt_data('metadata.name'), 'name'),
|
||||||
(self._corrupt_data('metadata.storage'), 'storage'),
|
|
||||||
(self._corrupt_data('metadata.substitutions'), 'substitutions'),
|
(self._corrupt_data('metadata.substitutions'), 'substitutions'),
|
||||||
(self._corrupt_data('metadata.substitutions.0.dest'), 'dest'),
|
(self._corrupt_data('metadata.substitutions.0.dest'), 'dest'),
|
||||||
(self._corrupt_data('metadata.substitutions.0.src'), 'src')
|
(self._corrupt_data('metadata.substitutions.0.src'), 'src')
|
||||||
@ -103,11 +103,12 @@ class TestSecretSubtitution(testtools.TestCase):
|
|||||||
invalid_data = []
|
invalid_data = []
|
||||||
|
|
||||||
data = copy.deepcopy(self.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))
|
invalid_data.append(self._format_data(data))
|
||||||
|
|
||||||
data = copy.deepcopy(self.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))
|
invalid_data.append(self._format_data(data))
|
||||||
|
|
||||||
def _test(invalid_entry, field, dest):
|
def _test(invalid_entry, field, dest):
|
||||||
@ -117,6 +118,6 @@ class TestSecretSubtitution(testtools.TestCase):
|
|||||||
secret_substitution.SecretSubstitution(invalid_entry)
|
secret_substitution.SecretSubstitution(invalid_entry)
|
||||||
|
|
||||||
# Verify that invalid body dest reference is invalid.
|
# 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.
|
# 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'})
|
||||||
|
@ -1,23 +1,35 @@
|
|||||||
# Sample YAML file for testing forward replacement.
|
# Sample YAML file for testing forward replacement.
|
||||||
---
|
---
|
||||||
apiVersion: service/v1
|
schemaVersion: promenade/v1
|
||||||
kind: ConsumerOfCertificateData
|
kind: SomeConfigType
|
||||||
metadata:
|
metadata:
|
||||||
name: asdf-1234
|
metadataVersion: deckhand/v1
|
||||||
storage: cleartext
|
name: a-unique-config-name-12345
|
||||||
|
labels:
|
||||||
|
component: apiserver
|
||||||
|
hostname: server0
|
||||||
|
layerDefinition:
|
||||||
|
layer: global
|
||||||
|
abstract: True
|
||||||
|
childSelector:
|
||||||
|
label: value
|
||||||
substitutions:
|
substitutions:
|
||||||
- dest: .tls_endpoint.certificate
|
- dest:
|
||||||
|
path: .tls_endpoint.certificate
|
||||||
|
replacePattern: 'test.pattern'
|
||||||
src:
|
src:
|
||||||
apiVersion: deckhand/v1
|
apiVersion: deckhand/v1
|
||||||
kind: Certificate
|
kind: Certificate
|
||||||
name: some-certificate-asdf-1234
|
name: some-certificate-asdf-1234
|
||||||
- dest: .tls_endpoint.certificateKey
|
path: .cert
|
||||||
|
- dest:
|
||||||
|
path: .tls_endpoint.key
|
||||||
src:
|
src:
|
||||||
apiVersion: deckhand/v1
|
apiVersion: deckhand/v1
|
||||||
kind: CertificateKey
|
kind: CertificateKey
|
||||||
name: some-certificate-key-asdf-1234
|
name: some-certificate-asdf-1234
|
||||||
|
path: .key
|
||||||
data:
|
data:
|
||||||
tls_endpoint:
|
tls_endpoint:
|
||||||
uri: http://localhost:443
|
certificate: '.cert'
|
||||||
certificate: null
|
key: deckhand/v1:some-certificate-asdf-1234
|
||||||
certificateKey: null
|
|
||||||
|
Loading…
Reference in New Issue
Block a user