Browse Source

Merge "refactor: Move replacement checks into separate module"

changes/22/610722/3
Zuul 8 months ago
parent
commit
eb178e1d7f
2 changed files with 87 additions and 50 deletions
  1. 82
    0
      deckhand/engine/_replacement.py
  2. 5
    50
      deckhand/engine/layering.py

+ 82
- 0
deckhand/engine/_replacement.py View File

@@ -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."""
16
+from deckhand import errors
17
+
18
+
19
+def 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
+
31
+def 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
+
50
+def 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
+
69
+def 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)

+ 5
- 50
deckhand/engine/layering.py View File

@@ -24,6 +24,7 @@ from oslo_utils import excutils
24 24
 from deckhand.common.document import DocumentDict as dd
25 25
 from deckhand.common import utils
26 26
 from deckhand.common.validation_message import ValidationMessage
27
+from deckhand.engine import _replacement as replacement
27 28
 from deckhand.engine import document_validation
28 29
 from deckhand.engine import secrets_manager
29 30
 from deckhand.engine import utils as engine_utils
@@ -59,64 +60,18 @@ class DocumentLayering(object):
59 60
     def _calc_replacements_and_substitutions(
60 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 63
         for document in self._documents_by_index.values():
109 64
             parent_meta = self._parents.get(document.meta)
110 65
             parent = self._documents_by_index.get(parent_meta)
111 66
 
112 67
             if document.is_replacement:
113
-                _check_document_with_replacement_field_has_parent(
68
+                replacement.check_document_with_replacement_field_has_parent(
114 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 71
                     parent, document)
117 72
                 parent.replaced_by = document
118 73
             else:
119
-                _check_non_replacement_and_parent_different_schema_and_name(
74
+                replacement.check_child_and_parent_different_metadata_name(
120 75
                     parent, document)
121 76
 
122 77
         # Since a substitution source only provides the document's
@@ -130,7 +85,7 @@ class DocumentLayering(object):
130 85
             if src_ref.meta in self._documents_by_index:
131 86
                 src_ref = self._documents_by_index[src_ref.meta]
132 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 89
                     src_ref = src_ref.replaced_by
135 90
             substitution_source_map[(src_ref.schema, src_ref.name)] = src_ref
136 91
 

Loading…
Cancel
Save