2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
8 # Unless otherwise specified, all software contained herein is licensed
9 # under the Apache License, Version 2.0 (the "License");
10 # you may not use this software except in compliance with the License.
11 # You may obtain a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
23 # Unless otherwise specified, all documentation contained herein is licensed
24 # under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25 # you may not use this documentation except in compliance with the License.
26 # You may obtain a copy of the License at
28 # https://creativecommons.org/licenses/by/4.0/
30 # Unless required by applicable law or agreed to in writing, documentation
31 # distributed under the License is distributed on an "AS IS" BASIS,
32 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 # See the License for the specific language governing permissions and
34 # limitations under the License.
36 # ============LICENSE_END============================================
38 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
41 """ environment file structure
46 from .helpers import validates, get_environment_pair
51 # pylint: disable=invalid-name
54 def check_parameter_exists(pattern, parameters):
58 for param in parameters:
59 if pattern.search(param):
65 def check_param_in_env_file(environment_pair, param, DESIRED):
67 if not environment_pair:
68 pytest.skip("No heat/env pair could be identified")
70 env_file = environment_pair.get("eyml")
72 pattern = re.compile(r'^{}$'.format(param))
74 if "parameters" not in env_file:
75 pytest.skip("No parameters specified in the environment file")
77 return check_parameter_exists(pattern,
78 env_file.get("parameters", {})
83 This function supports this structure, deviations
84 may or may not work without enhancement
89 prop0: { get_param: parameter_0 }
90 prop1: # this is a list of dicts
91 - nested_prop_0: { get_param: parameter_1 }
92 - nested_prop_1: { get_param: [parameter_2, {index}] }
93 prop2: # this is a dict of dicts
94 nested_prop_0: { get_param: parameter_1 }
98 def check_resource_parameter(environment_pair,
102 resource_type_inverse=False,
104 exclude_resource=''):
106 if not environment_pair:
107 pytest.skip("No heat/env pair could be identified")
109 env_file = environment_pair.get("eyml")
110 template_file = environment_pair.get("yyml")
112 if "parameters" not in env_file:
113 pytest.skip("No parameters specified in the environment file")
115 invalid_parameters = []
118 for resource, resource_prop in template_file.get("resources", {}).items():
120 if exclude_resource and re.match(exclude_resource, resource):
123 if resource_prop.get("type") == resource_type or \
124 (resource_prop.get("type") != resource_type
125 and resource_type_inverse):
129 if not resource_prop.get("properties"):
132 resource_parameter = resource_prop.get("properties").get(prop)
134 if not resource_parameter:
137 if isinstance(resource_parameter, list) and nested_prop:
138 for param in resource_parameter:
140 nested_param = param.get(nested_prop)
144 pattern = nested_param.get("get_param")
149 if isinstance(pattern, list):
152 elif isinstance(resource_parameter, dict):
154 if nested_prop and nested_prop in resource_parameter:
155 resource_parameter = resource_parameter.get(nested_prop)
157 pattern = resource_parameter.get("get_param")
165 if check_param_in_env_file(environment_pair, pattern, DESIRED):
166 invalid_parameters.append(pattern)
168 return set(invalid_parameters)
171 @validates('R-91125')
172 def test_nova_server_image_parameter_exists_in_environment_file(heat_template):
174 if pytest.config.getoption("validation_profile") == "heat_only":
175 pytest.skip("skipping test because validation profile is heat only")
177 environment_pair = get_environment_pair(heat_template)
181 resource_type = "OS::Nova::Server"
183 invalid_parameters = check_resource_parameter(environment_pair,
188 assert not invalid_parameters, ("OS::Nova::Server {} parameters not"
189 " found in {} environment file {}"
191 environment_pair.get("name"),
195 @validates('R-69431')
196 def test_nova_server_flavor_parameter_exists_in_environment_file(heat_template):
198 if pytest.config.getoption("validation_profile") == "heat_only":
199 pytest.skip("skipping test because validation profile is heat only")
201 environment_pair = get_environment_pair(heat_template)
205 resource_type = "OS::Nova::Server"
207 invalid_parameters = check_resource_parameter(environment_pair,
212 assert not invalid_parameters, ("OS::Nova::Server {} parameters not"
213 " found in {} environment file {}"
215 environment_pair.get("name"),
219 @validates('R-22838')
220 def test_nova_server_name_parameter_doesnt_exist_in_environment_file(heat_template):
222 if pytest.config.getoption("validation_profile") == "heat_only":
223 pytest.skip("skipping test because validation profile is heat only")
225 environment_pair = get_environment_pair(heat_template)
229 resource_type = "OS::Nova::Server"
231 invalid_parameters = check_resource_parameter(environment_pair,
236 assert not invalid_parameters, ("OS::Nova::Server {} parameters"
237 " found in {} environment file {}"
239 environment_pair.get("name"),
243 @validates('R-59568')
244 def test_nova_server_az_parameter_doesnt_exist_in_environment_file(heat_template):
246 if pytest.config.getoption("validation_profile") == "heat_only":
247 pytest.skip("skipping test because validation profile is heat only")
249 environment_pair = get_environment_pair(heat_template)
251 prop = "availability_zone"
253 resource_type = "OS::Nova::Server"
255 invalid_parameters = check_resource_parameter(environment_pair,
260 assert not invalid_parameters, ("OS::Nova::Server {} parameters"
261 " found in {} environment file {}"
263 environment_pair.get("name"),
267 @validates('R-20856')
268 def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(heat_template):
270 if pytest.config.getoption("validation_profile") == "heat_only":
271 pytest.skip("skipping test because validation profile is heat only")
273 environment_pair = get_environment_pair(heat_template)
278 invalid_parameters = check_param_in_env_file(environment_pair,
282 assert not invalid_parameters, ("{} parameters"
283 " found in {} environment file {}"
285 environment_pair.get("name"),
289 @validates('R-72871')
290 def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(heat_template):
292 if pytest.config.getoption("validation_profile") == "heat_only":
293 pytest.skip("skipping test because validation profile is heat only")
295 environment_pair = get_environment_pair(heat_template)
297 prop = "vf_module_id"
300 invalid_parameters = check_param_in_env_file(environment_pair,
304 assert not invalid_parameters, ("{} parameters"
305 " found in {} environment file {}"
307 environment_pair.get("name"),
311 @validates('R-36542')
312 def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(heat_template):
314 if pytest.config.getoption("validation_profile") == "heat_only":
315 pytest.skip("skipping test because validation profile is heat only")
317 environment_pair = get_environment_pair(heat_template)
322 invalid_parameters = check_param_in_env_file(environment_pair,
326 assert not invalid_parameters, ("{} parameters"
327 " found in {} environment file {}"
329 environment_pair.get("name"),
333 @validates('R-80374')
334 def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file(heat_template):
336 if pytest.config.getoption("validation_profile") == "heat_only":
337 pytest.skip("skipping test because validation profile is heat only")
339 environment_pair = get_environment_pair(heat_template)
341 prop = "vf_module_name"
344 invalid_parameters = check_param_in_env_file(environment_pair,
348 assert not invalid_parameters, ("{} parameters"
349 " found in {} environment file {}"
351 environment_pair.get("name"),
355 @validates('R-02691')
356 def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file(heat_template):
358 if pytest.config.getoption("validation_profile") == "heat_only":
359 pytest.skip("skipping test because validation profile is heat only")
361 environment_pair = get_environment_pair(heat_template)
363 prop = "workload_context"
366 invalid_parameters = check_param_in_env_file(environment_pair,
370 assert not invalid_parameters, ("{} parameters"
371 " found in {} environment file {}"
373 environment_pair.get("name"),
377 @validates('R-13194')
378 def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file(heat_template):
380 if pytest.config.getoption("validation_profile") == "heat_only":
381 pytest.skip("skipping test because validation profile is heat only")
383 environment_pair = get_environment_pair(heat_template)
385 prop = "environment_context"
388 invalid_parameters = check_param_in_env_file(environment_pair,
392 assert not invalid_parameters, ("{} parameters"
393 " found in {} environment file {}"
395 environment_pair.get("name"),
399 @validates('R-29872')
400 def test_nova_server_network_parameter_doesnt_exist_in_environment_file(heat_template):
402 if pytest.config.getoption("validation_profile") == "heat_only":
403 pytest.skip("skipping test because validation profile is heat only")
405 environment_pair = get_environment_pair(heat_template)
408 nested_prop = "network"
410 resource_type = "OS::Nova::Server"
412 invalid_parameters = check_resource_parameter(environment_pair,
416 nested_prop=nested_prop)
418 assert not invalid_parameters, ("{} {} parameters"
419 " found in {} environment file {}"
420 .format(resource_type,
422 environment_pair.get("name"),
426 @validates('R-39841',
438 def test_neutron_port_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file(heat_template):
440 if pytest.config.getoption("validation_profile") == "heat_only":
441 pytest.skip("skipping test because validation profile is heat only")
443 environment_pair = get_environment_pair(heat_template)
446 nested_prop = "ip_address"
448 resource_type = "OS::Neutron::Port"
450 invalid_parameters = check_resource_parameter(environment_pair,
454 nested_prop=nested_prop)
456 assert not invalid_parameters, ("{} {} parameters"
457 " found in {} environment file {}"
458 .format(resource_type,
460 environment_pair.get("name"),
464 @validates('R-83677',
468 def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file(heat_template):
470 if pytest.config.getoption("validation_profile") == "heat_only":
471 pytest.skip("skipping test because validation profile is heat only")
473 environment_pair = get_environment_pair(heat_template)
476 nested_prop = "subnet_id"
478 resource_type = "OS::Neutron::Port"
480 invalid_parameters = check_resource_parameter(environment_pair,
484 nested_prop=nested_prop)
486 assert not invalid_parameters, ("{} {} parameters"
487 " found in {} environment file {}"
488 .format(resource_type,
490 environment_pair.get("name"),
494 @validates('R-83412',
496 def test_neutron_port_aap_ip_parameter_doesnt_exist_in_environment_file(heat_template):
498 if pytest.config.getoption("validation_profile") == "heat_only":
499 pytest.skip("skipping test because validation profile is heat only")
501 environment_pair = get_environment_pair(heat_template)
503 prop = "allowed_address_pairs"
504 nested_prop = "ip_address"
506 resource_type = "OS::Neutron::Port"
508 invalid_parameters = check_resource_parameter(environment_pair,
512 nested_prop=nested_prop)
514 assert not invalid_parameters, ("{} {} parameters"
515 " found in {} environment file {}"
516 .format(resource_type,
518 environment_pair.get("name"),
522 @validates('R-99812')
523 def test_non_nova_server_name_parameter_doesnt_exist_in_environment_file(heat_template):
525 if pytest.config.getoption("validation_profile") == "heat_only":
526 pytest.skip("skipping test because validation profile is heat only")
528 environment_pair = get_environment_pair(heat_template)
532 resource_type = "OS::Nova::Server"
534 invalid_parameters = check_resource_parameter(environment_pair,
538 resource_type_inverse=True)
540 assert not invalid_parameters, ("non-{} {} parameters"
541 " found in {} environment file {}"
542 .format(resource_type,
544 environment_pair.get("name"),
548 @validates('R-92193')
549 def test_network_fqdn_parameter_doesnt_exist_in_environment_file(heat_template):
551 if pytest.config.getoption("validation_profile") == "heat_only":
552 pytest.skip("skipping test because validation profile is heat only")
554 environment_pair = get_environment_pair(heat_template)
556 prop = r'^(.+?)_net_fqdn$'
559 invalid_parameters = check_param_in_env_file(environment_pair,
563 assert not invalid_parameters, ("{} parameters"
564 " found in {} environment file {}"
566 environment_pair.get("name"),
570 @validates('R-76682')
571 def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(heat_template):
573 if pytest.config.getoption("validation_profile") == "heat_only":
574 pytest.skip("skipping test because validation profile is heat only")
576 environment_pair = get_environment_pair(heat_template)
578 prop = "interface_route_table_routes"
579 nested_prop = "interface_route_table_routes_route"
581 resource_type = "OS::ContrailV2::InterfaceRouteTable"
583 invalid_parameters = check_resource_parameter(environment_pair,
587 nested_prop=nested_prop)
589 assert not invalid_parameters, ("{} {} parameters"
590 " found in {} environment file {}"
591 .format(resource_type,
593 environment_pair.get("name"),
597 @validates('R-50011')
598 def test_heat_rg_count_parameter_exists_in_environment_file(heat_template):
600 if pytest.config.getoption("validation_profile") == "heat_only":
601 pytest.skip("skipping test because validation profile is heat only")
603 environment_pair = get_environment_pair(heat_template)
607 resource_type = "OS::Heat::ResourceGroup"
608 exclude_resource = re.compile(r'^(.+?)_subint_(.+?)_port_(.+?)_subinterfaces$')
610 invalid_parameters = check_resource_parameter(environment_pair,
614 exclude_resource=exclude_resource)
616 assert not invalid_parameters, ("{} {} parameters not"
617 " found in {} environment file {}"
618 .format(resource_type,
620 environment_pair.get("name"),