Browse Source

Revert "Lift too strict restrictions on cross-deps role name"

This reverts commit 4a6e3f93de.

Change-Id: Ib3fc11af6ffbc780ab8e7170f7f5cff676f45cf8
Simon Pasquier 3 years ago
parent
commit
5f7b49d1cb

+ 0
- 4
fuel_plugin_builder/errors.py View File

@@ -33,10 +33,6 @@ class ValidationError(FuelPluginException):
33 33
     pass
34 34
 
35 35
 
36
-class TaskFieldError(ValidationError):
37
-    pass
38
-
39
-
40 36
 class FileIsEmpty(ValidationError):
41 37
     def __init__(self, file_path):
42 38
         super(FileIsEmpty, self).__init__(

+ 2
- 3
fuel_plugin_builder/tests/test_base_validator.py View File

@@ -13,7 +13,7 @@
13 13
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 14
 #    License for the specific language governing permissions and limitations
15 15
 #    under the License.
16
-import jsonschema
16
+
17 17
 import mock
18 18
 
19 19
 from fuel_plugin_builder import errors
@@ -37,7 +37,6 @@ class TestBaseValidator(BaseTestCase):
37 37
         self.validator = NewValidator(self.plugin_path)
38 38
         self.data = {'data': 'data1'}
39 39
         self.schema = self.make_schema(['data'], {'data': {'type': 'string'}})
40
-        self.format_checker = jsonschema.FormatChecker
41 40
 
42 41
     @classmethod
43 42
     def make_schema(cls, required, properties):
@@ -55,7 +54,7 @@ class TestBaseValidator(BaseTestCase):
55 54
             'file_path')
56 55
         schema_mock.validate.assert_called_once_with(
57 56
             self.data,
58
-            self.schema, format_checker=self.format_checker)
57
+            self.schema)
59 58
 
60 59
     def test_validate_schema_raises_error(self):
61 60
         schema = self.make_schema(['key'], {'key': {'type': 'string'}})

+ 9
- 78
fuel_plugin_builder/tests/test_validator_v4.py View File

@@ -290,7 +290,7 @@ class TestValidatorV4(TestValidatorV3):
290 290
         mock_data = [{
291 291
             'id': 'plugin_task',
292 292
             'type': 'puppet',
293
-            'groups': ['controller'],
293
+            'group': ['controller'],
294 294
             'reexecute_on': ['bla']}]
295 295
         err_msg = "File '/tmp/plugin_path/deployment_tasks.yaml', " \
296 296
                   "'bla' is not one of"
@@ -333,8 +333,7 @@ class TestValidatorV4(TestValidatorV3):
333 333
         ]
334 334
 
335 335
         err_msg = "File '/tmp/plugin_path/deployment_tasks.yaml', " \
336
-                  "'(role|groups|roles)' is " \
337
-                  "a required property, value path '0'"
336
+                  "'role' is a required property, value path '0'"
338 337
         for task in deployment_tasks_data:
339 338
             self.check_raised_exception(
340 339
                 utils_mock, [task],
@@ -343,89 +342,21 @@ class TestValidatorV4(TestValidatorV3):
343 342
     # This is the section of tests inherited from the v3 validator
344 343
     # where decorators is re-defined for module v4
345 344
 
345
+    @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
346
+    def test_check_deployment_task_role(self, utils_mock, *args):
347
+        super(TestValidatorV4, self).test_check_deployment_task_role(
348
+            utils_mock)
349
+
346 350
     @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
347 351
     @mock.patch('fuel_plugin_builder.validators.base.utils.exists')
348 352
     def test_check_tasks_no_file(self, exists_mock, utils_mock, *args):
349 353
         super(TestValidatorV4, self).test_check_deployment_task_role(
350 354
             exists_mock, utils_mock)
351 355
 
352
-    @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
353
-    def test_check_deployment_task_role(self, utils_mock, *args):
354
-        utils_mock.parse_yaml.return_value = [
355
-            {'id': 'plugin_name', 'type': 'group', 'groups': ['a', 'b']},
356
-            {'id': 'plugin_name', 'type': 'group', 'groups': '*'},
357
-            {'id': 'plugin_name', 'type': 'puppet', 'role': ['a', 'b']},
358
-            {'id': 'plugin_name', 'type': 'puppet', 'role': '*'},
359
-            {'id': 'plugin_name', 'type': 'shell', 'roles': ['a', 'b']},
360
-            {'id': 'plugin_name', 'type': 'shell', 'roles': '*'},
361
-            {'id': 'plugin_name', 'type': 'skipped', 'role': '/test/'},
362
-            {'id': 'plugin_name', 'type': 'stage'},
363
-            {'id': 'plugin_name', 'type': 'reboot', 'groups': 'contrail'},
364
-            {
365
-                'id': 'plugin_name',
366
-                'type': 'copy_files',
367
-                'role': '*',
368
-                'parameters': {
369
-                    'files': [
370
-                        {'src': 'some_source', 'dst': 'some_destination'}]}
371
-            },
372
-            {
373
-                'id': 'plugin_name',
374
-                'type': 'sync',
375
-                'role': 'plugin_name',
376
-                'parameters': {
377
-                    'src': 'some_source', 'dst': 'some_destination'}
378
-            },
379
-            {
380
-                'id': 'plugin_name',
381
-                'type': 'upload_file',
382
-                'role': '/^.*plugin\w+name$/',
383
-                'parameters': {
384
-                    'path': 'some_path', 'data': 'some_data'}
385
-            },
386
-        ]
387
-
388
-        self.validator.check_deployment_tasks()
389
-
390 356
     @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
391 357
     def test_check_deployment_task_role_failed(self, utils_mock, *args):
392
-        mock_data = [{
393
-            'id': 'plugin_name',
394
-            'type': 'group',
395
-            'role': ['plugin_n@me']}]
396
-        err_msg = "field should"
397
-        self.check_raised_exception(
398
-            utils_mock, mock_data,
399
-            err_msg, self.validator.check_deployment_tasks)
400
-
401
-    @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
402
-    def test_check_deployment_task_required_missing(self, utils_mock, *args):
403
-        mock_data = [{
404
-            'id': 'plugin_name',
405
-            'type': 'puppet'}]
406
-        err_msg = "is a required property"
407
-        self.check_raised_exception(
408
-            utils_mock, mock_data,
409
-            err_msg, self.validator.check_deployment_tasks)
410
-
411
-    @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
412
-    def test_check_deployment_task_required_roles_missing_is_ok(
413
-            self, utils_mock, *args):
414
-        utils_mock.parse_yaml.return_value = [{
415
-            'id': 'plugin_name',
416
-            'type': 'stage'}]
417
-        self.validator.check_deployment_tasks()
418
-
419
-    @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
420
-    def test_check_deployment_task_role_regexp_failed(self, utils_mock, *args):
421
-        mock_data = [{
422
-            'id': 'plugin_name',
423
-            'type': 'group',
424
-            'role': '/[0-9]++/'}]
425
-        err_msg = "field should.*multiple repeat"
426
-        self.check_raised_exception(
427
-            utils_mock, mock_data,
428
-            err_msg, self.validator.check_deployment_tasks)
358
+        super(TestValidatorV4, self).test_check_deployment_task_role_failed(
359
+            utils_mock)
429 360
 
430 361
     @mock.patch('fuel_plugin_builder.validators.validator_v4.utils')
431 362
     def test_check_group_type_deployment_task_does_not_contain_manifests(

+ 3
- 7
fuel_plugin_builder/validators/base.py View File

@@ -35,16 +35,15 @@ class BaseValidator(object):
35 35
     def basic_version(self):
36 36
         pass
37 37
 
38
-    def __init__(self, plugin_path, format_checker=jsonschema.FormatChecker):
38
+    def __init__(self, plugin_path):
39 39
         self.plugin_path = plugin_path
40
-        self.format_checker = format_checker
41 40
 
42 41
     def validate_schema(self, data, schema, file_path, value_path=None):
43 42
         logger.debug(
44 43
             'Start schema validation for %s file, %s', file_path, schema)
44
+
45 45
         try:
46
-            jsonschema.validate(data, schema,
47
-                                format_checker=self.format_checker)
46
+            jsonschema.validate(data, schema)
48 47
         except jsonschema.exceptions.ValidationError as exc:
49 48
             raise errors.ValidationError(
50 49
                 self._make_error_message(exc, file_path, value_path))
@@ -105,7 +104,6 @@ class BaseValidator(object):
105 104
     @abc.abstractmethod
106 105
     def validate(self):
107 106
         """Performs validation
108
-
109 107
         """
110 108
 
111 109
     def check_schemas(self):
@@ -171,11 +169,9 @@ class BaseValidator(object):
171 169
 
172 170
     def check_compatibility(self):
173 171
         """Json schema doesn't have any conditions, so we have
174
-
175 172
         to make sure here, that this validation schema can be used
176 173
         for described fuel releases
177 174
         """
178
-
179 175
         meta = utils.parse_yaml(self.meta_path)
180 176
         for fuel_release in meta['fuel_version']:
181 177
             if StrictVersion(fuel_release) < StrictVersion(self.basic_version):

+ 0
- 53
fuel_plugin_builder/validators/formatchecker.py View File

@@ -1,53 +0,0 @@
1
-# -*- coding: utf-8 -*-
2
-
3
-#    Copyright 2016 Mirantis, Inc.
4
-#
5
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
-#    not use this file except in compliance with the License. You may obtain
7
-#    a copy of the License at
8
-#
9
-#         http://www.apache.org/licenses/LICENSE-2.0
10
-#
11
-#    Unless required by applicable law or agreed to in writing, software
12
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
-#    License for the specific language governing permissions and limitations
15
-#    under the License.
16
-
17
-import re
18
-from sre_constants import error as sre_error
19
-
20
-import jsonschema
21
-import six
22
-
23
-from fuel_plugin_builder import errors
24
-
25
-
26
-class FormatChecker(jsonschema.FormatChecker):
27
-
28
-    def __init__(self, role_patterns=(), *args, **kwargs):
29
-        super(FormatChecker, self).__init__()
30
-
31
-        @self.checks('fuel_task_role_format')
32
-        def _validate_role(instance):
33
-            sre_msg = None
34
-            if isinstance(instance, six.string_types):
35
-                if instance.startswith('/') and instance.endswith('/'):
36
-                    try:
37
-                        if re.compile(instance[1:-1]):
38
-                            return True
39
-                    except sre_error as e:
40
-                        sre_msg = str(e)
41
-                else:
42
-                    for role_pattern in role_patterns:
43
-                        if re.match(role_pattern, instance):
44
-                            return True
45
-                err_msg = "Role field should be either a valid " \
46
-                          "regexp enclosed by " \
47
-                          "slashes or a string of '{0}' or an " \
48
-                          "array of those. " \
49
-                          "Got '{1}' instead.".format(", ".join(role_patterns),
50
-                                                      instance)
51
-                if sre_msg:
52
-                    err_msg += "SRE error: \"{0}\"".format(sre_msg)
53
-                raise errors.TaskFieldError(err_msg)

+ 13
- 35
fuel_plugin_builder/validators/schemas/v4.py View File

@@ -27,23 +27,16 @@ COMPATIBLE_COMPONENT_NAME_PATTERN = \
27 27
     '^({0}):([0-9a-z_-]+:)*([0-9a-z_-]+|(\*)?)$'.format(COMPONENTS_TYPES_STR)
28 28
 
29 29
 
30
-TASK_NAME_PATTERN = TASK_ROLE_PATTERN = '^[0-9a-zA-Z_-]+$|^\*$'
30
+TASK_NAME_PATTERN = TASK_ROLE_PATTERN = '^[0-9a-zA-Z_-]+$'
31 31
 NETWORK_ROLE_PATTERN = '^[0-9a-z_-]+$'
32 32
 FILE_PERMISSIONS_PATTERN = '^[0-7]{4}$'
33 33
 TASK_VERSION_PATTERN = '^\d+.\d+.\d+$'
34 34
 STAGE_PATTERN = '^(post_deployment|pre_deployment)' \
35 35
                 '(/[-+]?([0-9]*\.[0-9]+|[0-9]+))?$'
36 36
 
37
-DEFAULT_TASK_ROLE_GROUP_ASSIGNMENT = ('roles', 'groups', 'role')
38
-TASK_OBLIGATORY_FIELDS = ['id', 'type']
39
-
40 37
 
41 38
 class SchemaV4(SchemaV3):
42 39
 
43
-    def __init__(self):
44
-        super(SchemaV4, self).__init__()
45
-        self.role_pattern = TASK_ROLE_PATTERN
46
-
47 40
     @property
48 41
     def _task_relation(self):
49 42
         return {
@@ -65,13 +58,13 @@ class SchemaV4(SchemaV3):
65 58
             'oneOf': [
66 59
                 {
67 60
                     'type': 'string',
68
-                    'format': 'fuel_task_role_format'
61
+                    'enum': ['*', 'master', 'self']
69 62
                 },
70 63
                 {
71 64
                     'type': 'array',
72 65
                     'items': {
73 66
                         'type': 'string',
74
-                        'format': 'fuel_task_role_format'
67
+                        'pattern': TASK_ROLE_PATTERN
75 68
                     }
76 69
                 }
77 70
             ]
@@ -102,9 +95,7 @@ class SchemaV4(SchemaV3):
102 95
             }
103 96
         }
104 97
 
105
-    def _gen_task_schema(self, task_types, required=None,
106
-                         parameters=None,
107
-                         required_any=DEFAULT_TASK_ROLE_GROUP_ASSIGNMENT):
98
+    def _gen_task_schema(self, task_types, required=None, parameters=None):
108 99
         """Generate deployment task schema using prototype.
109 100
 
110 101
         :param task_types: task types
@@ -128,21 +119,11 @@ class SchemaV4(SchemaV3):
128 119
         }
129 120
         parameters.setdefault("properties", {})
130 121
         parameters["properties"].setdefault("strategy", self._task_strategy)
131
-        task_specific_req_fields = list(set(TASK_OBLIGATORY_FIELDS +
132
-                                            (required or [])))
133
-        required_fields = []
134
-
135
-        # Some tasks are ephemeral, so we can leave it as is without target
136
-        # groups|role|roles, others must have at least one such field
137
-        if required_any:
138
-            for group_name_alias in DEFAULT_TASK_ROLE_GROUP_ASSIGNMENT:
139
-                required_fields.append({"required": task_specific_req_fields
140
-                                        + [group_name_alias]})
141
-        else:
142
-            required_fields.append({"required": task_specific_req_fields})
122
+
143 123
         return {
144 124
             '$schema': 'http://json-schema.org/draft-04/schema#',
145 125
             'type': 'object',
126
+            'required': list(set(['id', 'type'] + (required or []))),
146 127
             'properties': {
147 128
                 'type': {'enum': task_types},
148 129
                 'id': {
@@ -151,8 +132,6 @@ class SchemaV4(SchemaV3):
151 132
                 'version': {
152 133
                     'type': 'string', "pattern": TASK_VERSION_PATTERN},
153 134
                 'role': self._task_role,
154
-                'groups': self._task_role,
155
-                'roles': self._task_role,
156 135
                 'required_for': self.task_group,
157 136
                 'requires': self.task_group,
158 137
                 'cross-depends': {
@@ -169,8 +148,7 @@ class SchemaV4(SchemaV3):
169 148
                         'pattern': TASK_ROLE_PATTERN}},
170 149
                 'reexecute_on': self._task_reexecute,
171 150
                 'parameters': parameters or {},
172
-            },
173
-            'anyOf': required_fields
151
+            }
174 152
         }
175 153
 
176 154
     @property
@@ -202,7 +180,7 @@ class SchemaV4(SchemaV3):
202 180
     def copy_files_task(self):
203 181
         return self._gen_task_schema(
204 182
             "copy_files",
205
-            ['parameters'],
183
+            ['role', 'parameters'],
206 184
             {
207 185
                 'type': 'object',
208 186
                 'required': ['files'],
@@ -225,7 +203,7 @@ class SchemaV4(SchemaV3):
225 203
 
226 204
     @property
227 205
     def group_task(self):
228
-        return self._gen_task_schema("group", [])
206
+        return self._gen_task_schema("group", ['role'])
229 207
 
230 208
     @property
231 209
     def puppet_task(self):
@@ -264,7 +242,7 @@ class SchemaV4(SchemaV3):
264 242
     def shell_task(self):
265 243
         return self._gen_task_schema(
266 244
             "shell",
267
-            [],
245
+            ['role'],
268 246
             {
269 247
                 'type': 'object',
270 248
                 'required': ['cmd'],
@@ -287,13 +265,13 @@ class SchemaV4(SchemaV3):
287 265
 
288 266
     @property
289 267
     def stage_task(self):
290
-        return self._gen_task_schema("stage", required_any=())
268
+        return self._gen_task_schema("stage")
291 269
 
292 270
     @property
293 271
     def sync_task(self):
294 272
         return self._gen_task_schema(
295 273
             "sync",
296
-            ['parameters'],
274
+            ['role', 'parameters'],
297 275
             {
298 276
                 'type': 'object',
299 277
                 'required': ['src', 'dst'],
@@ -309,7 +287,7 @@ class SchemaV4(SchemaV3):
309 287
     def upload_file_task(self):
310 288
         return self._gen_task_schema(
311 289
             "upload_file",
312
-            ['parameters'],
290
+            ['role', 'parameters'],
313 291
             {
314 292
                 'type': 'object',
315 293
                 'required': ['path', 'data'],

+ 1
- 4
fuel_plugin_builder/validators/validator_v4.py View File

@@ -19,11 +19,9 @@ from os.path import join as join_path
19 19
 
20 20
 from fuel_plugin_builder import errors
21 21
 from fuel_plugin_builder import utils
22
-from fuel_plugin_builder.validators.formatchecker import FormatChecker
23 22
 from fuel_plugin_builder.validators.schemas import SchemaV4
24 23
 from fuel_plugin_builder.validators import ValidatorV3
25 24
 
26
-
27 25
 logger = logging.getLogger(__name__)
28 26
 
29 27
 
@@ -32,8 +30,7 @@ class ValidatorV4(ValidatorV3):
32 30
     schema = SchemaV4()
33 31
 
34 32
     def __init__(self, *args, **kwargs):
35
-        super(ValidatorV4, self).__init__(format_checker=FormatChecker(
36
-            role_patterns=[self.schema.role_pattern]), *args, **kwargs)
33
+        super(ValidatorV4, self).__init__(*args, **kwargs)
37 34
         self.components_path = join_path(self.plugin_path, 'components.yaml')
38 35
 
39 36
     @property

Loading…
Cancel
Save