3a3bf229748586b777b113c35f0b8b4fecbc5690
[vvp/validation-scripts.git] / ice_validator / tests / test_environment_file_parameters.py
1 # -*- coding: utf8 -*-
2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
7 #
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
12 #
13 #             http://www.apache.org/licenses/LICENSE-2.0
14 #
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.
20 #
21 #
22 #
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
27 #
28 #             https://creativecommons.org/licenses/by/4.0/
29 #
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.
35 #
36 # ============LICENSE_END============================================
37 #
38 #
39 """ environment file structure
40 """
41 import os
42 from .helpers import validates, categories, get_environment_pair, find_environment_file
43 import re
44 import pytest
45 from tests import cached_yaml as yaml
46
47 VERSION = "1.0.0"
48
49 # pylint: disable=invalid-name
50
51
52 def check_parameter_exists(pattern, parameters):
53     if not parameters:
54         return False
55
56     for param in parameters:
57         if pattern.search(param):
58             return True
59
60     return False
61
62
63 def check_param_in_env_file(environment_pair, param, DESIRED, exclude_parameter=None):
64
65     # workaround for internal/external parameters
66     if exclude_parameter and re.match(exclude_parameter, param):
67         return False
68
69     if not environment_pair:
70         pytest.skip("No heat/env pair could be identified")
71
72     env_file = environment_pair.get("eyml")
73
74     pattern = re.compile(r"^{}$".format(param))
75
76     if "parameters" not in env_file:
77         pytest.skip("No parameters specified in the environment file")
78
79     return (
80         check_parameter_exists(pattern, env_file.get("parameters", {})) is not DESIRED
81     )
82
83
84 """
85 This function supports this structure, deviations
86 may or may not work without enhancement
87
88 resource_id:
89     type: <resource_type>
90     properties:
91         prop0: { get_param: parameter_0 }
92         prop1:  # this is a list of dicts
93             - nested_prop_0: { get_param: parameter_1 }
94             - nested_prop_1: { get_param: [parameter_2, {index}] }
95         prop2:  # this is a dict of dicts
96             nested_prop_0: { get_param: parameter_1 }
97         prop3: { get_param: [parameter_3, 0]}
98 """
99
100
101 def check_resource_parameter(
102     environment_pair,
103     prop,
104     DESIRED,
105     resource_type,
106     resource_type_inverse=False,
107     nested_prop="",
108     exclude_resource="",
109     exclude_parameter="",
110 ):
111     if not environment_pair:
112         pytest.skip("No heat/env pair could be identified")
113
114     env_file = environment_pair.get("eyml")
115     template_file = environment_pair.get("yyml")
116
117     if "parameters" not in env_file:
118         pytest.skip("No parameters specified in the environment file")
119
120     invalid_parameters = []
121     if template_file:
122         for resource, resource_prop in template_file.get("resources", {}).items():
123
124             # workaround for subinterface resource groups
125             if exclude_resource and re.match(exclude_resource, resource):
126                 continue
127
128             if (
129                 resource_prop.get("type") == resource_type and not resource_type_inverse
130             ) or (resource_prop.get("type") != resource_type and resource_type_inverse):
131
132                 pattern = False
133
134                 if not resource_prop.get("properties"):
135                     continue
136
137                 resource_parameter = resource_prop.get("properties").get(prop)
138
139                 if not resource_parameter:
140                     continue
141                 if isinstance(resource_parameter, list) and nested_prop:
142                     for param in resource_parameter:
143                         nested_param = param.get(nested_prop)
144                         if not nested_param:
145                             continue
146
147                         if isinstance(nested_param, dict):
148                             pattern = nested_param.get("get_param")
149                         else:
150                             pattern = ""
151
152                         if not pattern:
153                             continue
154
155                         if isinstance(pattern, list):
156                             pattern = pattern[0]
157
158                         if check_param_in_env_file(
159                             environment_pair,
160                             pattern,
161                             DESIRED,
162                             exclude_parameter=exclude_parameter,
163                         ):
164                             invalid_parameters.append(pattern)
165
166                 elif isinstance(resource_parameter, dict):
167                     if nested_prop and nested_prop in resource_parameter:
168                         resource_parameter = resource_parameter.get(nested_prop)
169
170                     pattern = resource_parameter.get("get_param")
171                     if not pattern:
172                         continue
173
174                     if isinstance(pattern, list):
175                         pattern = pattern[0]
176
177                     if check_param_in_env_file(
178                         environment_pair,
179                         pattern,
180                         DESIRED,
181                         exclude_parameter=exclude_parameter,
182                     ):
183                         invalid_parameters.append(pattern)
184                 else:
185                     continue
186
187     return set(invalid_parameters)
188
189
190 def run_check_resource_parameter(
191     yaml_file, prop, DESIRED, resource_type, check_resource=True, **kwargs
192 ):
193
194     filepath, filename = os.path.split(yaml_file)
195     environment_pair = get_environment_pair(yaml_file)
196
197     if not environment_pair:
198         # this is a nested file
199
200         if not check_resource:
201             # dont check env for nested files
202             # This will be tested separately for parent template
203             pytest.skip("This test doesn't apply to nested files")
204
205         environment_pair = find_environment_file(yaml_file)
206         if environment_pair:
207             with open(yaml_file, "r") as f:
208                 yml = yaml.load(f)
209             environment_pair["yyml"] = yml
210         else:
211             pytest.skip("unable to determine environment file for nested yaml file")
212
213     if check_resource:
214         invalid_parameters = check_resource_parameter(
215             environment_pair, prop, DESIRED, resource_type, **kwargs
216         )
217     else:
218         invalid_parameters = check_param_in_env_file(environment_pair, prop, DESIRED)
219
220     if kwargs.get("resource_type_inverse"):
221         resource_type = "non-{}".format(resource_type)
222
223     assert not invalid_parameters, (
224         "{} {} parameters in template {}{}"
225         " found in {} environment file: {}".format(
226             resource_type,
227             prop,
228             filename,
229             " not" if DESIRED else "",
230             environment_pair.get("name"),
231             invalid_parameters,
232         )
233     )
234
235
236 @validates("R-91125")
237 def test_nova_server_image_parameter_exists_in_environment_file(yaml_file):
238     run_check_resource_parameter(yaml_file, "image", True, "OS::Nova::Server")
239
240
241 @validates("R-69431")
242 def test_nova_server_flavor_parameter_exists_in_environment_file(yaml_file):
243     run_check_resource_parameter(yaml_file, "flavor", True, "OS::Nova::Server")
244
245
246 @categories("environment_file")
247 @validates("R-22838")
248 def test_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file):
249     run_check_resource_parameter(yaml_file, "name", False, "OS::Nova::Server")
250
251
252 @categories("environment_file")
253 @validates("R-59568")
254 def test_nova_server_az_parameter_doesnt_exist_in_environment_file(yaml_file):
255     run_check_resource_parameter(
256         yaml_file, "availability_zone", False, "OS::Nova::Server"
257     )
258
259
260 @categories("environment_file")
261 @validates("R-20856")
262 def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(yaml_file):
263     run_check_resource_parameter(yaml_file, "vnf_id", False, "", check_resource=False)
264
265
266 @categories("environment_file")
267 @validates("R-72871")
268 def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(yaml_file):
269     run_check_resource_parameter(
270         yaml_file, "vf_module_id", False, "", check_resource=False
271     )
272
273
274 @categories("environment_file")
275 @validates("R-37039")
276 def test_nova_server_vf_module_index_parameter_doesnt_exist_in_environment_file(
277     yaml_file
278 ):
279     run_check_resource_parameter(
280         yaml_file, "vf_module_index", False, "", check_resource=False
281     )
282
283
284 @categories("environment_file")
285 @validates("R-36542")
286 def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(yaml_file):
287     run_check_resource_parameter(yaml_file, "vnf_name", False, "", check_resource=False)
288
289
290 @categories("environment_file")
291 @validates("R-80374")
292 def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file(
293     yaml_file
294 ):
295     run_check_resource_parameter(
296         yaml_file, "vf_module_name", False, "", check_resource=False
297     )
298
299
300 @categories("environment_file")
301 @validates("R-02691")
302 def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file(
303     yaml_file
304 ):
305     run_check_resource_parameter(
306         yaml_file, "workload_context", False, "", check_resource=False
307     )
308
309
310 @categories("environment_file")
311 @validates("R-13194")
312 def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file(
313     yaml_file
314 ):
315     run_check_resource_parameter(
316         yaml_file, "environment_context", False, "", check_resource=False
317     )
318
319
320 @categories("environment_file")
321 @validates("R-29872")
322 def test_neutron_port_network_parameter_doesnt_exist_in_environment_file(yaml_file):
323     run_check_resource_parameter(yaml_file, "network", False, "OS::Neutron::Port")
324
325
326 @categories("environment_file")
327 @validates("R-39841", "R-87123", "R-62590", "R-98905", "R-93030", "R-62590")
328 def test_neutron_port_external_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file(
329     yaml_file
330 ):
331     run_check_resource_parameter(
332         yaml_file,
333         "fixed_ips",
334         False,
335         "OS::Neutron::Port",
336         nested_prop="ip_address",
337         exclude_parameter=re.compile(r"^(.+?)_int_(.+?)$"),
338     )
339
340
341 @validates("R-28795", "R-97201", "R-93496", "R-90206", "R-98569", "R-93496")
342 def test_neutron_port_internal_fixedips_ipaddress_parameter_exists_in_environment_file(
343     yaml_file
344 ):
345     run_check_resource_parameter(
346         yaml_file,
347         "fixed_ips",
348         True,
349         "OS::Neutron::Port",
350         nested_prop="ip_address",
351         exclude_parameter=re.compile(r"^((?!_int_).)*$"),
352     )
353
354
355 @categories("environment_file")
356 @validates("R-83677", "R-80829", "R-69634", "R-22288")
357 def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file(
358     yaml_file
359 ):
360     run_check_resource_parameter(
361         yaml_file, "fixed_ips", False, "OS::Neutron::Port", nested_prop="subnet"
362     )
363
364
365 @categories("environment_file")
366 @validates("R-83412", "R-83418")
367 def test_neutron_port_aap_ip_parameter_doesnt_exist_in_environment_file(yaml_file):
368     run_check_resource_parameter(
369         yaml_file,
370         "allowed_address_pairs",
371         False,
372         "OS::Neutron::Port",
373         nested_prop="ip_address",
374     )
375
376
377 @categories("environment_file")
378 @validates("R-99812")
379 def test_non_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file):
380     run_check_resource_parameter(
381         yaml_file, "name", False, "OS::Nova::Server", resource_type_inverse=True
382     )
383
384
385 @categories("environment_file")
386 @validates("R-92193")
387 def test_network_fqdn_parameter_doesnt_exist_in_environment_file(yaml_file):
388     run_check_resource_parameter(
389         yaml_file, r"^(.+?)_net_fqdn$", False, "", check_resource=False
390     )
391
392
393 @categories("environment_file")
394 @validates("R-76682")
395 def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(yaml_file):
396     run_check_resource_parameter(
397         yaml_file,
398         "interface_route_table_routes",
399         False,
400         "OS::ContrailV2::InterfaceRouteTable",
401         nested_prop="interface_route_table_routes_route",
402     )
403
404
405 @validates("R-50011")
406 def test_heat_rg_count_parameter_exists_in_environment_file(yaml_file):
407     run_check_resource_parameter(
408         yaml_file,
409         "count",
410         True,
411         "OS::Heat::ResourceGroup",
412         exclude_resource=re.compile(r"^(.+?)_subint_(.+?)_port_(.+?)_subinterfaces$"),
413     )