Enforce black code format via pre-commit hook
[vvp/validation-scripts.git] / ice_validator / tests / test_contrail_instance_ip_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 import os
40 import re
41
42 import pytest
43
44 from tests.structures import ContrailV2InstanceIpProcessor, Heat
45 from tests.helpers import validates, get_base_template_from_yaml_files, get_param
46 from tests.utils.incrementals import get_incremental_modules
47 from tests.utils.ports import check_parameter_format
48
49 RE_EXTERNAL_PARAM_IIP = re.compile(  # match pattern
50     r"(?P<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
51 )
52
53 RE_EXTERNAL_PARAM_IIPS = re.compile(  # match pattern
54     r"(?P<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ips$"
55 )
56
57 RE_INTERNAL_PARAM_IIP = re.compile(  # match pattern
58     r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
59 )
60
61 RE_INTERNAL_PARAM_IIPS = re.compile(  # match pattern
62     r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_v6)?_ips$"
63 )
64
65 iip_regx_dict = {
66     "external": {
67         "string": {
68             "readable": "{vm-type}_{network-role}_ip_{ip-index} or {vm-type}_{network-role}_v6_ip_{ip-index}",
69             "machine": RE_EXTERNAL_PARAM_IIP,
70         },
71         "comma_delimited_list": {
72             "readable": "{vm-type}_{network-role}_ips or {vm-type}_{network-role}_v6_ips",
73             "machine": RE_EXTERNAL_PARAM_IIPS,
74         },
75     },
76     "internal": {
77         "string": {
78             "readable": "{vm-type}_int_{network-role}_ip_{ip-index} or {vm-type}_int_{network-role}_v6_ip_{ip-index}",
79             "machine": RE_INTERNAL_PARAM_IIP,
80         },
81         "comma_delimited_list": {
82             "readable": "{vm-type}_int_{network-role}_ips or {vm-type}_int_{network-role}_v6_ips",
83             "machine": RE_INTERNAL_PARAM_IIPS,
84         },
85     },
86     "parameter_to_resource_comparisons": ["vm_type", "network_role"],
87 }
88
89
90 RE_EXTERNAL_PARAM_SID = re.compile(  # match pattern
91     r"(?P<network_role>.+?)(_v6)?_subnet_id$"
92 )
93
94 RE_INTERNAL_PARAM_SID = re.compile(  # match pattern
95     r"int_(?P<network_role>.+?)(_v6)?_subnet_id$"
96 )
97
98 sid_regx_dict = {
99     "external": {
100         "string": {
101             "readable": "{network-role}_subnet_id or {network-role}_v6_subnet_id",
102             "machine": RE_EXTERNAL_PARAM_SID,
103         }
104     },
105     "internal": {
106         "string": {
107             "readable": "int_{network-role}_subnet_id or int_{network-role}_v6_subnet_id",
108             "machine": RE_INTERNAL_PARAM_SID,
109         }
110     },
111     "parameter_to_resource_comparisons": ["network_role"],
112 }
113
114
115 @validates("R-100000", "R-100010", "R-100030", "R-100050", "R-100070")
116 def test_contrail_external_instance_ip_address_parameter(yaml_file):
117     check_parameter_format(
118         yaml_file,
119         iip_regx_dict,
120         "external",
121         ContrailV2InstanceIpProcessor,
122         "instance_ip_address",
123     )
124
125
126 @validates("R-100000", "R-100090", "R-100110", "R-100130", "R-100150")
127 def test_contrail_internal_instance_ip_address_parameter(yaml_file):
128     check_parameter_format(
129         yaml_file,
130         iip_regx_dict,
131         "internal",
132         ContrailV2InstanceIpProcessor,
133         "instance_ip_address",
134     )
135
136
137 @validates("R-100190", "R-100200", "R-100220")
138 def test_contrail_external_instance_subnet_id_parameter(yaml_file):
139     check_parameter_format(
140         yaml_file,
141         sid_regx_dict,
142         "external",
143         ContrailV2InstanceIpProcessor,
144         "subnet_uuid",
145     )
146
147
148 @validates("R-100190", "R-100240", "R-100260")
149 def test_contrail_internal_instance_subnet_id_parameter(yaml_file):
150     check_parameter_format(
151         yaml_file,
152         sid_regx_dict,
153         "internal",
154         ContrailV2InstanceIpProcessor,
155         "subnet_uuid",
156     )
157
158
159 @validates("R-100240", "R-100260")
160 def test_contrail_incremental_module_internal_subnet_usage(yaml_files):
161     base_path = get_base_template_from_yaml_files(yaml_files)
162     if not base_path:
163         pytest.skip("No base module detected to check")
164     base_outputs = Heat(filepath=base_path).outputs
165     incremental_modules = get_incremental_modules(yaml_files)
166     errors = []
167     for module in incremental_modules:
168         heat = Heat(filepath=module)
169         ips = heat.get_resource_by_type(ContrailV2InstanceIpProcessor.resource_type)
170         internal_ips = ((r_id, props) for r_id, props in ips.items() if "_int_" in r_id)
171         for r_id, ip in internal_ips:
172             subnet_uuid = (ip.get("properties") or {}).get("subnet_uuid")
173             subnet_param = get_param(subnet_uuid)
174             if not subnet_param:
175                 continue
176             if subnet_param not in base_outputs:
177                 errors.append(
178                     (
179                         "Resource ({}) is designated as an internal IP, but its "
180                         "subnet_uuid parameter ({}) does not refer to subnet in "
181                         "this template nor is it defined in the output section "
182                         "of the base module ({})"
183                     ).format(r_id, subnet_param, os.path.basename(base_path))
184                 )
185     assert not errors, ". ".join(errors)