summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-10-29 17:26:37 +0000
committerGerrit Code Review <review@openstack.org>2018-10-29 17:26:37 +0000
commiteb178e1d7f4f7eeed09e60c19b36a3943f2af196 (patch)
treebc10d190c0833c3e7c5152f451a2b39a74038bc5
parent56e606bf4baa52b956f0b93032692cd4943b7341 (diff)
parent24d86ea749abddf754cfbb8ce656e3155f8edcfc (diff)
Merge "refactor: Move replacement checks into separate module"
-rw-r--r--deckhand/engine/_replacement.py82
-rw-r--r--deckhand/engine/layering.py55
2 files changed, 87 insertions, 50 deletions
diff --git a/deckhand/engine/_replacement.py b/deckhand/engine/_replacement.py
new file mode 100644
index 0000000..1ac4755
--- /dev/null
+++ b/deckhand/engine/_replacement.py
@@ -0,0 +1,82 @@
1# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Functions for validation replacement logic."""
16from deckhand import errors
17
18
19def check_document_with_replacement_field_has_parent(
20 parent_meta, parent, document):
21 """Validate that a document with ``metadata.replacement`` has a parent."""
22 if not parent_meta or not parent:
23 error_message = (
24 'Document replacement requires that the document with '
25 '`replacement: true` have a parent.')
26 raise errors.InvalidDocumentReplacement(
27 schema=document.schema, name=document.name,
28 layer=document.layer, reason=error_message)
29
30
31def check_replacement_and_parent_same_schema_and_name(
32 parent, document):
33 """Validate that replacement-child and replacement-parent documents have
34 the same ``schema`` and ``metadata.name`` values which is a hard
35 requirement for replacement.
36
37 """
38 # This checks that a document can only be a replacement for
39 # another document with the same `metadata.name` and `schema`.
40 if not (document.schema == parent.schema and
41 document.name == parent.name):
42 error_message = (
43 'Document replacement requires that both documents '
44 'have the same `schema` and `metadata.name`.')
45 raise errors.InvalidDocumentReplacement(
46 schema=document.schema, name=document.name,
47 layer=document.layer, reason=error_message)
48
49
50def check_child_and_parent_different_metadata_name(
51 parent, document):
52 """Validate that "regular" child and parent documents (without a
53 replacement relationship) have the same ``schema`` but different
54 ``metadata.name``.
55
56 """
57 if (parent and document.schema == parent.schema and
58 document.name == parent.name):
59 error_message = (
60 'Non-replacement documents cannot have the same `schema` '
61 'and `metadata.name` as their parent. Either add '
62 '`replacement: true` to the document or give the document '
63 'a different name.')
64 raise errors.InvalidDocumentReplacement(
65 schema=document.schema, name=document.name,
66 layer=document.layer, reason=error_message)
67
68
69def check_only_one_level_of_replacement(src_ref):
70 """Validate that only one level of replacement exists, meaning that
71 a replacement document cannot itself be replaced by yet another
72 replacement document.
73
74 """
75 # If the document has a replacement, use the replacement as the
76 # substitution source instead.
77 if src_ref.is_replacement:
78 error_message = ('A replacement document cannot itself'
79 ' be replaced by another document.')
80 raise errors.InvalidDocumentReplacement(
81 schema=src_ref.schema, name=src_ref.name,
82 layer=src_ref.layer, reason=error_message)
diff --git a/deckhand/engine/layering.py b/deckhand/engine/layering.py
index aaa3b45..c4c0e58 100644
--- a/deckhand/engine/layering.py
+++ b/deckhand/engine/layering.py
@@ -24,6 +24,7 @@ from oslo_utils import excutils
24from deckhand.common.document import DocumentDict as dd 24from deckhand.common.document import DocumentDict as dd
25from deckhand.common import utils 25from deckhand.common import utils
26from deckhand.common.validation_message import ValidationMessage 26from deckhand.common.validation_message import ValidationMessage
27from deckhand.engine import _replacement as replacement
27from deckhand.engine import document_validation 28from deckhand.engine import document_validation
28from deckhand.engine import secrets_manager 29from deckhand.engine import secrets_manager
29from deckhand.engine import utils as engine_utils 30from deckhand.engine import utils as engine_utils
@@ -59,64 +60,18 @@ class DocumentLayering(object):
59 def _calc_replacements_and_substitutions( 60 def _calc_replacements_and_substitutions(
60 self, substitution_sources): 61 self, substitution_sources):
61 62
62 def _check_document_with_replacement_field_has_parent(
63 parent_meta, parent, document):
64 if not parent_meta or not parent:
65 error_message = (
66 'Document replacement requires that the document with '
67 '`replacement: true` have a parent.')
68 raise errors.InvalidDocumentReplacement(
69 schema=document.schema, name=document.name,
70 layer=document.layer, reason=error_message)
71
72 def _check_replacement_and_parent_same_schema_and_name(
73 parent, document):
74 # This checks that a document can only be a replacement for
75 # another document with the same `metadata.name` and `schema`.
76 if not (document.schema == parent.schema and
77 document.name == parent.name):
78 error_message = (
79 'Document replacement requires that both documents '
80 'have the same `schema` and `metadata.name`.')
81 raise errors.InvalidDocumentReplacement(
82 schema=document.schema, name=document.name,
83 layer=document.layer, reason=error_message)
84
85 def _check_non_replacement_and_parent_different_schema_and_name(
86 parent, document):
87 if (parent and document.schema == parent.schema and
88 document.name == parent.name):
89 error_message = (
90 'Non-replacement documents cannot have the same `schema` '
91 'and `metadata.name` as their parent. Either add '
92 '`replacement: true` to the document or give the document '
93 'a different name.')
94 raise errors.InvalidDocumentReplacement(
95 schema=document.schema, name=document.name,
96 layer=document.layer, reason=error_message)
97
98 def _check_replacement_not_itself_replaced_by_another(src_ref):
99 # If the document has a replacement, use the replacement as the
100 # substitution source instead.
101 if src_ref.is_replacement:
102 error_message = ('A replacement document cannot itself'
103 ' be replaced by another document.')
104 raise errors.InvalidDocumentReplacement(
105 schema=src_ref.schema, name=src_ref.name,
106 layer=src_ref.layer, reason=error_message)
107
108 for document in self._documents_by_index.values(): 63 for document in self._documents_by_index.values():
109 parent_meta = self._parents.get(document.meta) 64 parent_meta = self._parents.get(document.meta)
110 parent = self._documents_by_index.get(parent_meta) 65 parent = self._documents_by_index.get(parent_meta)
111 66
112 if document.is_replacement: 67 if document.is_replacement:
113 _check_document_with_replacement_field_has_parent( 68 replacement.check_document_with_replacement_field_has_parent(
114 parent_meta, parent, document) 69 parent_meta, parent, document)
115 _check_replacement_and_parent_same_schema_and_name( 70 replacement.check_replacement_and_parent_same_schema_and_name(
116 parent, document) 71 parent, document)
117 parent.replaced_by = document 72 parent.replaced_by = document
118 else: 73 else:
119 _check_non_replacement_and_parent_different_schema_and_name( 74 replacement.check_child_and_parent_different_metadata_name(
120 parent, document) 75 parent, document)
121 76
122 # Since a substitution source only provides the document's 77 # Since a substitution source only provides the document's
@@ -130,7 +85,7 @@ class DocumentLayering(object):
130 if src_ref.meta in self._documents_by_index: 85 if src_ref.meta in self._documents_by_index:
131 src_ref = self._documents_by_index[src_ref.meta] 86 src_ref = self._documents_by_index[src_ref.meta]
132 if src_ref.has_replacement: 87 if src_ref.has_replacement:
133 _check_replacement_not_itself_replaced_by_another(src_ref) 88 replacement.check_only_one_level_of_replacement(src_ref)
134 src_ref = src_ref.replaced_by 89 src_ref = src_ref.replaced_by
135 substitution_source_map[(src_ref.schema, src_ref.name)] = src_ref 90 substitution_source_map[(src_ref.schema, src_ref.name)] = src_ref
136 91