2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2019 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============================================
39 """ environment file structure
45 from tests.helpers import (
50 find_environment_file,
53 from tests.structures import Heat
54 from tests.utils.nested_files import file_is_a_nested_template
57 # Whats persistent mean? It means it goes in env.
58 # When adding an additional case, note the ","
59 # at the end of a property to make it a tuple.
60 ENV_PARAMETER_SPEC = {
61 "PLATFORM PROVIDED": [
62 {"property": ("vnf_id",), "persistent": False, "kwargs": {}},
63 {"property": ("vnf_name",), "persistent": False, "kwargs": {}},
64 {"property": ("vf_module_id",), "persistent": False, "kwargs": {}},
65 {"property": ("vf_module_index",), "persistent": False, "kwargs": {}},
66 {"property": ("vf_module_name",), "persistent": False, "kwargs": {}},
67 {"property": ("workload_context",), "persistent": False, "kwargs": {}},
68 {"property": ("environment_context",), "persistent": False, "kwargs": {}},
69 {"property": (r"^(.+?)_net_fqdn$",), "persistent": False, "kwargs": {}},
71 "ALL": [{"property": ("name",), "persistent": False, "kwargs": {}}],
73 {"property": ("image",), "persistent": True, "kwargs": {}},
74 {"property": ("flavor",), "persistent": True, "kwargs": {}},
75 {"property": ("availability_zone",), "persistent": False, "kwargs": {}},
77 "OS::Neutron::Port": [
78 {"property": ("network",), "persistent": False, "kwargs": {}},
80 "property": ("fixed_ips", "ip_address"),
82 "network_type": "external",
83 "kwargs": {"exclude_parameter": re.compile(r"^(.+?)_int_(.+?)$")},
86 "property": ("fixed_ips", "ip_address"),
88 "network_type": "internal",
89 "kwargs": {"exclude_parameter": re.compile(r"^((?!_int_).)*$")},
91 {"property": ("fixed_ips", "subnet"), "persistent": False, "kwargs": {}},
93 "property": ("fixed_ips", "allowed_address_pairs"),
95 "network_type": "external",
96 "kwargs": {"exclude_parameter": re.compile(r"^(.+?)_int_(.+?)$")},
99 "property": ("fixed_ips", "allowed_address_pairs"),
101 "network_type": "internal",
102 "kwargs": {"exclude_parameter": re.compile(r"^((?!_int_).)*$")},
105 "OS::ContrailV2::InterfaceRouteTable": [
108 "interface_route_table_routes",
109 "interface_route_table_routes_route",
115 "OS::Heat::ResourceGroup": [
117 "property": ("count",),
120 "exclude_resource": re.compile(
121 r"^(.+?)_subint_(.+?)_port_(.+?)_subinterfaces$"
126 "OS::ContrailV2::InstanceIp": [
128 "property": ("instance_ip_address",),
130 "network_type": "external",
131 "kwargs": {"exclude_resource": re.compile(r"^.*_int_.*$")},
134 "property": ("instance_ip_address",),
136 "network_type": "internal",
137 "kwargs": {"exclude_resource": re.compile(r"(?!.*_int_.*)")},
140 "property": ("subnet_uuid",),
142 "network_type": "internal",
143 "kwargs": {"exclude_resource": re.compile(r"(?!.*_int_.*)")},
146 "OS::ContrailV2::VirtualMachineInterface": [
149 "virtual_machine_interface_allowed_address_pairs",
150 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair",
151 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip",
152 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix",
155 "network_type": "external",
156 "kwargs": {"exclude_resource": re.compile(r"(?!.*_int_.*)")},
162 def run_test_parameter(yaml_file, resource_type, *prop, **kwargs):
163 template_parameters = []
164 invalid_parameters = []
166 parameter_spec = ENV_PARAMETER_SPEC.get(
168 ) # matching spec dict on resource type
169 for spec in parameter_spec:
170 # iterating through spec dict and trying to match on property
171 if spec.get("property") == prop:
178 ): # now matching on additional kwargs passed in from test (i.e. network_type)
179 if not spec.get(k) or spec.get(k) != v:
183 if resource_type == "PLATFORM PROVIDED":
184 if file_is_a_nested_template(yaml_file):
186 "Not checking nested files for PLATFORM PROVIDED params"
188 template_parameters.append(
189 {"resource": "", "param": param_spec.get("property")[0]}
192 all_resources = False
193 if resource_type == "ALL":
195 template_parameters = get_template_parameters(
199 all_resources=all_resources,
200 ) # found the correct spec, proceeding w/ test
203 for parameter in template_parameters:
204 param = parameter.get("param")
205 persistence = param_spec.get("persistent")
207 if env_violation(yaml_file, param, spec.get("persistent")):
208 human_text = "must" if persistence else "must not"
209 human_text2 = "was not" if persistence else "was"
211 invalid_parameters.append(
212 "{} parameter {} {} be enumerated in an environment file, but "
213 "parameter {} for {} {} found.".format(
214 resource_type, prop, human_text, param, yaml_file, human_text2
218 assert not invalid_parameters, "\n".join(invalid_parameters)
221 def get_preload_excluded_parameters(yaml_file, persistent_only=False, env_spec=None):
223 Returns set of all parameters that should not be included in the preload's
224 vnf parameters/tag-values section.
226 if persistent_only only parameters that are marked as persistent will
229 env_spec = env_spec or ENV_PARAMETER_SPEC
231 for resource_type, specs in env_spec.items():
232 # apply to all resources if not in the format of an OpenStack resource
233 all_resources = "::" not in resource_type
235 if persistent_only and not spec.get("persistent"):
238 get_template_parameters(yaml_file, resource_type, spec, all_resources)
240 return {item["param"] for item in results}
243 def get_template_parameters(yaml_file, resource_type, spec, all_resources=False):
246 heat = Heat(yaml_file)
248 resources = heat.resources
250 resources = heat.get_resource_by_type(resource_type)
252 for rid, resource_props in resources.items():
253 for param in prop_iterator(resource_props, *spec.get("property")):
254 if param and get_param(param) and param_helper(spec, get_param(param), rid):
255 # this is first getting the param
256 # then checking if its actually using get_param
257 # then checking a custom helper function (mostly for internal vs external networks)
258 parameters.append({"resource": rid, "param": get_param(param)})
263 def env_violation(yaml_file, parameter, persistent):
264 # Returns True IF there's a violation, False if everything looks good.
266 filepath, filename = os.path.split(yaml_file)
267 environment_pair = get_environment_pair(yaml_file)
268 if not environment_pair: # this is a nested file perhaps?
269 environment_pair = find_environment_file(
271 ) # we want to check parent env
272 if not environment_pair:
273 pytest.skip("unable to determine environment file for nested yaml file")
275 env_yaml = environment_pair.get("eyml")
276 parameters = env_yaml.get("parameters", {})
278 if parameters: # env file can be just parameters:
279 for param, value in parameters.items():
280 if re.match(parameter, param):
284 # confusing return. This function is looking for a violation.
285 return not persistent == in_env
288 def param_helper(spec, param, rid):
289 # helper function that has some predefined additional
290 # checkers, mainly to figure out if internal/external network
292 for k, v in spec.get("kwargs").items():
293 if k == "exclude_resource" and re.match(v, rid):
296 elif k == "exclude_parameter" and re.match(v, param):
303 @validates("R-91125")
304 def test_nova_server_image_parameter_exists_in_environment_file(yaml_file):
305 run_test_parameter(yaml_file, "OS::Nova::Server", "image")
308 @validates("R-69431")
309 def test_nova_server_flavor_parameter_exists_in_environment_file(yaml_file):
310 run_test_parameter(yaml_file, "OS::Nova::Server", "flavor")
313 @categories("environment_file")
314 @validates("R-22838", "R-99812")
315 def test_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file):
316 run_test_parameter(yaml_file, "ALL", "name")
319 @categories("environment_file")
320 @validates("R-59568")
321 def test_nova_server_az_parameter_doesnt_exist_in_environment_file(yaml_file):
322 run_test_parameter(yaml_file, "OS::Nova::Server", "availability_zone")
325 @categories("environment_file")
326 @validates("R-20856")
327 def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(yaml_file):
328 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vnf_id")
331 @categories("environment_file")
332 @validates("R-72871")
333 def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(yaml_file):
334 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_id")
337 @categories("environment_file")
338 @validates("R-37039")
339 def test_nova_server_vf_module_index_parameter_doesnt_exist_in_environment_file(
342 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_index")
345 @categories("environment_file")
346 @validates("R-36542")
347 def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(yaml_file):
348 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vnf_name")
351 @categories("environment_file")
352 @validates("R-80374")
353 def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file(
356 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_name")
359 @categories("environment_file")
360 @validates("R-02691")
361 def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file(
364 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "workload_context")
367 @categories("environment_file")
368 @validates("R-13194")
369 def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file(
372 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "environment_context")
375 @categories("environment_file")
376 @validates("R-29872")
377 def test_neutron_port_network_parameter_doesnt_exist_in_environment_file(yaml_file):
378 run_test_parameter(yaml_file, "OS::Neutron::Port", "network")
381 @categories("environment_file")
382 @validates("R-39841", "R-87123", "R-62590", "R-98905", "R-93030", "R-62590")
383 def test_neutron_port_external_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file(
391 network_type="external",
395 @validates("R-28795", "R-97201", "R-93496", "R-90206", "R-98569", "R-93496")
396 def test_neutron_port_internal_fixedips_ipaddress_parameter_exists_in_environment_file(
404 network_type="internal",
408 @categories("environment_file")
409 @validates("R-83677", "R-80829", "R-69634", "R-22288")
410 def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file(
414 yaml_file, "OS::Neutron::Port", "fixed_ips", "subnet", network_type="internal"
418 @categories("environment_file")
419 @validates("R-83412", "R-83418")
420 def test_neutron_port_external_aap_ip_parameter_doesnt_exist_in_environment_file(
426 "allowed_address_pairs",
428 network_type="external",
432 @categories("environment_file")
433 @validates("R-92193")
434 def test_network_fqdn_parameter_doesnt_exist_in_environment_file(yaml_file):
435 run_test_parameter(yaml_file, "PLATFORM PROVIDED", r"^(.+?)_net_fqdn$")
438 @categories("environment_file")
439 @validates("R-76682")
440 def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(yaml_file):
443 "OS::ContrailV2::InterfaceRouteTable",
444 "interface_route_table_routes",
445 "interface_route_table_routes_route",
449 @validates("R-50011")
450 def test_heat_rg_count_parameter_exists_in_environment_file(yaml_file):
451 run_test_parameter(yaml_file, "OS::Heat::ResourceGroup", "count")
454 @categories("environment_file")
455 @validates("R-100020", "R-100040", "R-100060", "R-100080", "R-100170")
456 def test_contrail_external_instance_ip_does_not_exist_in_environment_file(yaml_file):
459 "OS::ContrailV2::InstanceIp",
460 "instance_ip_address",
461 network_type="external",
465 @validates("R-100100", "R-100120", "R-100140", "R-100160", "R-100180")
466 def test_contrail_internal_instance_ip_does_exist_in_environment_file(yaml_file):
469 "OS::ContrailV2::InstanceIp",
470 "instance_ip_address",
471 network_type="internal",
475 @categories("environment_file")
476 @validates("R-100210", "R-100230", "R-100250", "R-100270")
477 def test_contrail_subnet_uuid_does_not_exist_in_environment_file(yaml_file):
478 run_test_parameter(yaml_file, "OS::ContrailV2::InstanceIp", "subnet_uuid")
481 @categories("environment_file")
482 @validates("R-100320", "R-100340")
483 def test_contrail_vmi_aap_does_not_exist_in_environment_file(yaml_file):
486 "OS::ContrailV2::VirtualMachineInterface",
487 "virtual_machine_interface_allowed_address_pairs",
488 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair",
489 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip",
490 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix",