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 parameter = param.get("get_param")
166 "Unexpected parameter format for {} {} property {}: {}. "
167 "Please consult the heat guidelines documentation for details."
168 ).format(resource_type, rid, properties, param)
170 # getting parameter if the get_param uses list, and getting official
171 # HEAT parameter type
172 parameter_type = parameter_type_to_heat_type(parameter)
173 if parameter_type == "comma_delimited_list":
174 parameter = parameter[0]
175 elif parameter_type != "string":
178 if exemptions_allowed and parameter in get_aap_exemptions(resource):
181 # if parameter type is not in regx dict, then it is not supported
183 regx_dict = regx[resource_intext].get(parameter_type)
186 "{} {} {} parameter {} defined as type {} "
187 "which is required by platform data model for proper "
188 "assignment and inventory."
189 ).format(resource_type, rid, properties, parameter, parameter_type)
190 if exemptions_allowed:
191 msg = "WARNING: {} {}".format(msg, AAP_EXEMPT_CAVEAT)
194 msg = validate_parameter_format(
195 regx, parameter_type, resource_intext, parameter, rid, exemptions_allowed
200 # checking that parameter includes correct vm_type/network_role
201 parameter_checks = regx.get("parameter_to_resource_comparisons", [])
202 for check in parameter_checks:
203 msg = mismatch_resource_and_parameter_attribute(
204 check, port_match, parameter, rid
212 def validate_parameter_format(
213 regx, parameter_type, resource_intext, parameter, rid, exemptions_allowed
215 """Checks if a parameter format matches the expected format
216 from input format dictionary"""
218 regexp = regx[resource_intext][parameter_type]["machine"]
219 readable_format = regx[resource_intext][parameter_type]["readable"]
220 match = regexp.match(parameter)
223 "{} property parameter {} does not follow {} "
224 "format {} which is required by platform data model for proper "
225 "assignment and inventory."
226 ).format(rid, parameter, resource_intext, readable_format)
227 if exemptions_allowed:
228 msg = "WARNING: {} {}".format(msg, AAP_EXEMPT_CAVEAT)
233 def mismatch_resource_and_parameter_attribute(check, resource_re_match, parameter, rid):
234 """Compares vm_type or network_role from resource
235 is the same as found in parameter"""
236 resource_match = resource_re_match.group(check)
239 and not parameter.startswith(resource_match)
240 and parameter.find("_{}_".format(resource_match)) == -1
242 return ("{0} {1} does not match parameter {2} {1}").format(
243 rid, check, parameter
247 def get_list_of_ports_attached_to_nova_server(nova_server):
248 networks_list = nova_server.get("properties", {}).get("networks")
252 for network in networks_list:
253 network_prop = network.get("port")
255 pid = network_prop.get("get_param")
257 pid = network_prop.get("get_resource")