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": ("allowed_address_pairs", "ip_address"),
95 "network_type": "external",
96 "kwargs": {"exclude_parameter": re.compile(r"^(.+?)_int_(.+?)$")},
99 "property": ("allowed_address_pairs", "ip_address"),
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(
239 yaml_file, resource_type, spec, all_resources, nested_resources=True
242 results = {item["param"] for item in results}
243 for param in Heat(yaml_file).parameters:
244 # AZs often are manipulated and passed into nested templates making
245 # them difficult to detect by looking for the assignment. We'll
246 # just extract them from the parameters if they are there to be safe
247 if re.match(r"availability_zone_\d+", param):
252 def get_template_parameters(
253 yaml_file, resource_type, spec, all_resources=False, nested_resources=False
257 heat = Heat(yaml_file)
259 resources = heat.resources if not nested_resources else heat.get_all_resources()
261 resources = heat.get_resource_by_type(
262 resource_type, all_resources=nested_resources
264 for rid, resource_props in resources.items():
265 for param in prop_iterator(resource_props, *spec.get("property")):
266 if param and get_param(param) and param_helper(spec, get_param(param), rid):
267 # this is first getting the param
268 # then checking if its actually using get_param
269 # then checking a custom helper function (mostly for internal vs external networks)
270 parameters.append({"resource": rid, "param": get_param(param)})
274 def env_violation(yaml_file, parameter, persistent):
275 # Returns True IF there's a violation, False if everything looks good.
277 filepath, filename = os.path.split(yaml_file)
278 environment_pair = get_environment_pair(yaml_file)
279 if not environment_pair: # this is a nested file perhaps?
280 environment_pair = find_environment_file(
282 ) # we want to check parent env
283 if not environment_pair:
284 pytest.skip("unable to determine environment file for nested yaml file")
286 env_yaml = environment_pair.get("eyml")
287 parameters = env_yaml.get("parameters", {})
289 if parameters: # env file can be just parameters:
290 for param, value in parameters.items():
291 if re.match(parameter, param):
295 # confusing return. This function is looking for a violation.
296 return not persistent == in_env
299 def param_helper(spec, param, rid):
300 # helper function that has some predefined additional
301 # checkers, mainly to figure out if internal/external network
303 for k, v in spec.get("kwargs").items():
304 if k == "exclude_resource" and re.match(v, rid):
307 elif k == "exclude_parameter" and re.match(v, param):
314 @validates("R-91125")
315 def test_nova_server_image_parameter_exists_in_environment_file(yaml_file):
316 run_test_parameter(yaml_file, "OS::Nova::Server", "image")
319 @validates("R-69431")
320 def test_nova_server_flavor_parameter_exists_in_environment_file(yaml_file):
321 run_test_parameter(yaml_file, "OS::Nova::Server", "flavor")
324 @categories("environment_file")
325 @validates("R-22838", "R-99812")
326 def test_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file):
327 run_test_parameter(yaml_file, "ALL", "name")
330 @categories("environment_file")
331 @validates("R-59568")
332 def test_nova_server_az_parameter_doesnt_exist_in_environment_file(yaml_file):
333 run_test_parameter(yaml_file, "OS::Nova::Server", "availability_zone")
336 @categories("environment_file")
337 @validates("R-20856")
338 def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(yaml_file):
339 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vnf_id")
342 @categories("environment_file")
343 @validates("R-72871")
344 def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(yaml_file):
345 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_id")
348 @categories("environment_file")
349 @validates("R-37039")
350 def test_nova_server_vf_module_index_parameter_doesnt_exist_in_environment_file(
353 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_index")
356 @categories("environment_file")
357 @validates("R-36542")
358 def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(yaml_file):
359 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vnf_name")
362 @categories("environment_file")
363 @validates("R-80374")
364 def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file(
367 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "vf_module_name")
370 @categories("environment_file")
371 @validates("R-02691")
372 def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file(
375 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "workload_context")
378 @categories("environment_file")
379 @validates("R-13194")
380 def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file(
383 run_test_parameter(yaml_file, "PLATFORM PROVIDED", "environment_context")
386 @categories("environment_file")
387 @validates("R-29872")
388 def test_neutron_port_network_parameter_doesnt_exist_in_environment_file(yaml_file):
389 run_test_parameter(yaml_file, "OS::Neutron::Port", "network")
392 @categories("environment_file")
393 @validates("R-39841", "R-87123", "R-62590", "R-98905", "R-93030", "R-62590")
394 def test_neutron_port_external_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file(
402 network_type="external",
406 @validates("R-28795", "R-97201", "R-93496", "R-90206", "R-98569", "R-93496")
407 def test_neutron_port_internal_fixedips_ipaddress_parameter_exists_in_environment_file(
415 network_type="internal",
419 @categories("environment_file")
420 @validates("R-83677", "R-80829", "R-69634", "R-22288")
421 def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file(
425 yaml_file, "OS::Neutron::Port", "fixed_ips", "subnet", network_type="internal"
429 @categories("environment_file")
430 @validates("R-83412", "R-83418")
431 def test_neutron_port_external_aap_ip_parameter_doesnt_exist_in_environment_file(
437 "allowed_address_pairs",
439 network_type="external",
443 @categories("environment_file")
444 @validates("R-92193")
445 def test_network_fqdn_parameter_doesnt_exist_in_environment_file(yaml_file):
446 run_test_parameter(yaml_file, "PLATFORM PROVIDED", r"^(.+?)_net_fqdn$")
449 @categories("environment_file")
450 @validates("R-76682")
451 def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(yaml_file):
454 "OS::ContrailV2::InterfaceRouteTable",
455 "interface_route_table_routes",
456 "interface_route_table_routes_route",
460 @validates("R-50011")
461 def test_heat_rg_count_parameter_exists_in_environment_file(yaml_file):
462 run_test_parameter(yaml_file, "OS::Heat::ResourceGroup", "count")
465 @categories("environment_file")
466 @validates("R-100020", "R-100040", "R-100060", "R-100080", "R-100170")
467 def test_contrail_external_instance_ip_does_not_exist_in_environment_file(yaml_file):
470 "OS::ContrailV2::InstanceIp",
471 "instance_ip_address",
472 network_type="external",
476 @validates("R-100100", "R-100120", "R-100140", "R-100160", "R-100180")
477 def test_contrail_internal_instance_ip_does_exist_in_environment_file(yaml_file):
480 "OS::ContrailV2::InstanceIp",
481 "instance_ip_address",
482 network_type="internal",
486 @categories("environment_file")
487 @validates("R-100210", "R-100230", "R-100250", "R-100270")
488 def test_contrail_subnet_uuid_does_not_exist_in_environment_file(yaml_file):
489 run_test_parameter(yaml_file, "OS::ContrailV2::InstanceIp", "subnet_uuid")
492 @categories("environment_file")
493 @validates("R-100320", "R-100340")
494 def test_contrail_vmi_aap_does_not_exist_in_environment_file(yaml_file):
497 "OS::ContrailV2::VirtualMachineInterface",
498 "virtual_machine_interface_allowed_address_pairs",
499 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair",
500 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip",
501 "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix",