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 from tests.structures import Heat
40 from tests.helpers import parameter_type_to_heat_type, prop_iterator
41 from . import nested_dict
45 "If this VNF is not able to adhere to this requirement, please consult the Heat "
46 "Orchestration Template guidelines for more information. If you are knowingly "
47 "violating this requirement after reading the guidelines, then add the parameter "
48 "to the aap_exempt list under this resources metadata to suppress this warning."
52 def get_aap_exemptions(resource_props):
54 Gets the list of parameters that the Heat author has exempted from following
55 the naming conventions associated with AAP.
57 :param resource_props: dict of properties under the resource ID
58 :return: list of all parameters to exempt or an empty list
60 metadata = resource_props.get("metadata") or {}
61 return metadata.get("aap_exempt") or []
64 def check_parameter_format(
65 yaml_file, regx, intext, resource_processor, *properties, exemptions_allowed=False
68 yaml_file: input file to check
69 regx: dictionary containing the regex to use to validate parameter
70 intext: internal or external
71 resource_processor: resource type specific helper, defined in structures.py
72 properties: arg list of property that is being checked
73 exemptions_allowed: If True, then parameters in the aap_exempt list are allowed to
77 invalid_parameters = []
78 heat = Heat(filepath=yaml_file)
79 resource_type = resource_processor.resource_type
80 resources = heat.get_resource_by_type(resource_type)
81 for rid, resource in resources.items():
82 resource_intext, port_match = resource_processor.get_rid_match_tuple(rid)
84 continue # port resource ID not formatted correctely
87 resource_intext != intext
88 ): # skipping if type (internal/external) doesn't match
90 for param in prop_iterator(resource, *properties):
93 and isinstance(param, dict)
94 and "get_resource" not in param
95 and "get_attr" not in param
97 template_parameters = []
98 if "str_replace" in param:
100 template_parameters.extend(
102 for k, v in nested_dict.get(
103 param, "str_replace", "params", default={}
107 template_parameters.append(param)
109 invalid_template_parameters = []
110 for template_parameter in template_parameters:
111 # Looping through each parameter to check
112 # the only case where there can be more than 1 is
113 # if using str_replace
114 msg = validate_port_parameter(
127 # if we found a valid parameter then
128 # reset invalide_template_parameters
129 # and break out of loop
130 invalid_template_parameters = []
133 # haven't found a valid parameter yet
134 invalid_template_parameters.append(msg)
136 invalid_parameters.extend(x for x in invalid_template_parameters)
138 assert not invalid_parameters, "%s" % "\n".join(invalid_parameters)
141 def validate_port_parameter(
153 Performs 4 validations
155 1) param actually uses get_param
156 2) parameter_type + network_type (internal/external) is a valid combination
157 3) parameter format matches expected format from input dictionary
158 4) the vm_type or network role from resource matches parameter
160 If the parameter is present in the resource metadata
161 and exemptions are allowed, then the validation will be skipped.
163 if isinstance(param, dict) and "get_param" in param:
164 parameter = param.get("get_param")
167 "Unexpected parameter format for {} {} property {}: {}. "
168 "Please consult the heat guidelines documentation for details."
169 ).format(resource_type, rid, properties, param)
171 # getting parameter if the get_param uses list, and getting official
172 # HEAT parameter type
173 parameter_type = parameter_type_to_heat_type(parameter)
174 if parameter_type == "comma_delimited_list":
175 parameter = parameter[0]
176 elif parameter_type != "string":
179 if exemptions_allowed and parameter in get_aap_exemptions(resource):
182 # if parameter type is not in regx dict, then it is not supported
184 regx_dict = regx[resource_intext].get(parameter_type)
187 "{} {} {} parameter {} defined as type {} "
188 "which is required by platform data model for proper "
189 "assignment and inventory."
190 ).format(resource_type, rid, properties, parameter, parameter_type)
191 if exemptions_allowed:
192 msg = "WARNING: {} {}".format(msg, AAP_EXEMPT_CAVEAT)
195 msg = validate_parameter_format(
196 regx, parameter_type, resource_intext, parameter, rid, exemptions_allowed
201 # checking that parameter includes correct vm_type/network_role
202 parameter_checks = regx.get("parameter_to_resource_comparisons", [])
203 for check in parameter_checks:
204 msg = mismatch_resource_and_parameter_attribute(
205 check, port_match, parameter, rid
213 def validate_parameter_format(
214 regx, parameter_type, resource_intext, parameter, rid, exemptions_allowed
216 """Checks if a parameter format matches the expected format
217 from input format dictionary"""
219 regexp = regx[resource_intext][parameter_type]["machine"]
220 readable_format = regx[resource_intext][parameter_type]["readable"]
221 match = regexp.match(parameter)
224 "{} property parameter {} does not follow {} "
225 "format {} which is required by platform data model for proper "
226 "assignment and inventory."
227 ).format(rid, parameter, resource_intext, readable_format)
228 if exemptions_allowed:
229 msg = "WARNING: {} {}".format(msg, AAP_EXEMPT_CAVEAT)
234 def mismatch_resource_and_parameter_attribute(check, resource_re_match, parameter, rid):
235 """Compares vm_type or network_role from resource
236 is the same as found in parameter"""
237 resource_match = resource_re_match.group(check)
240 and not parameter.startswith(resource_match)
241 and parameter.find("_{}_".format(resource_match)) == -1
243 return ("{0} {1} does not match parameter {2} {1}").format(
244 rid, check, parameter
248 def get_list_of_ports_attached_to_nova_server(nova_server):
249 networks_list = nova_server.get("properties", {}).get("networks")
253 for network in networks_list:
254 network_prop = network.get("port")
256 pid = network_prop.get("get_param")
258 pid = network_prop.get("get_resource")