[VVP] updating OS::Neutron::Port parameter tests
[vvp/validation-scripts.git] / ice_validator / tests / utils / ports.py
1 # -*- coding: utf8 -*-
2 # ============LICENSE_START=======================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2017 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 from .network_roles import get_network_role_and_type
40 from tests.structures import Heat, NeutronPortProcessor
41 from tests.helpers import parameter_type_to_heat_type
42 from . import nested_dict
43
44
45 def check_ip_format(yaml_file, regx, port_type, resource_property, nested_property):
46     """
47     yaml_file: input file to check
48     regx: dictionary containing the regex to use to validate parameter
49     port_type: internal or external
50     resource_property: OS::Neutron::Port property to check for parameter
51     nested_property: resource_property will be a list of dicts, this is the key to index into
52     """
53     invalid_ips = []
54     heat = Heat(filepath=yaml_file)
55     ports = heat.get_resource_by_type("OS::Neutron::Port")
56     heat_parameters = heat.parameters
57
58     for rid, resource in ports.items():
59         network_role, network_type = get_network_role_and_type(resource)
60         if (
61             network_type != port_type
62         ):  # skipping if port type (internal/external) doesn't match
63             continue
64
65         name, port_match = NeutronPortProcessor.get_rid_match_tuple(rid)
66         if not port_match:
67             continue  # port resource ID not formatted correctely
68
69         params = nested_dict.get(resource, "properties", resource_property, default={})
70
71         for param in params:
72             prop = nested_dict.get(param, nested_property)
73             if (
74                 not prop
75                 or not isinstance(prop, dict)
76                 or "get_resource" in prop
77                 or "get_attr" in prop
78                 # or "str_replace" in prop - should str_replace be checked?
79             ):
80                 continue  # lets only check parameters shall we?
81
82             # checking parameter uses get_param
83             parameter = nested_dict.get(prop, "get_param")
84             if not parameter:
85                 msg = (
86                     "Unexpected parameter format for OS::Neutron::Port {} property {}: {}. "
87                     + "Please consult the heat guidelines documentation for details."
88                 ).format(rid, resource_property, prop)
89                 invalid_ips.append(msg)  # should this be a failure?
90                 continue
91
92             # getting parameter if the get_param uses list, and getting official HEAT parameter type
93             parameter_type = parameter_type_to_heat_type(parameter)
94             if parameter_type == "comma_delimited_list":
95                 parameter = parameter[0]
96             elif parameter_type != "string":
97                 continue
98
99             # checking parameter format = type defined in template
100             heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type")
101             if not heat_parameter_type or heat_parameter_type != parameter_type:
102                 msg = (
103                     "OS::Neutron::Port {} parameter {} defined as type {} "
104                     + "is being used as type {} in the heat template"
105                 ).format(
106                     resource_property, parameter, heat_parameter_type, parameter_type
107                 )
108                 invalid_ips.append(msg)
109                 continue
110
111             # if parameter type is not in regx dict, then it is not supported by automation
112             regx_dict = regx[port_type].get(parameter_type)
113             if not regx_dict:
114                 msg = (
115                     "WARNING: OS::Neutron::Port {} parameter {} defined as type {} "
116                     + "is not supported by platform automation. If this VNF is not able "
117                     + "to adhere to this requirement, please consult the Heat Orchestration "
118                     + "Template guidelines for alternative solutions. If already adhering to "
119                     + "an alternative provided by the heat guidelines, please disregard this "
120                     + "message."
121                 ).format(resource_property, parameter, parameter_type)
122                 invalid_ips.append(msg)
123                 continue
124
125             # checking if param adheres to guidelines format
126             regexp = regx[port_type][parameter_type]["machine"]
127             readable_format = regx[port_type][parameter_type]["readable"]
128             match = regexp.match(parameter)
129             if not match:
130                 msg = "{} parameter {} does not follow format {}".format(
131                     resource_property, parameter, readable_format
132                 )
133                 invalid_ips.append(msg)
134                 continue
135
136             # checking that parameter includes correct vm_type/network_role
137             parameter_checks = regx.get("parameter_to_resource_comparisons", [])
138             for check in parameter_checks:
139                 resource_match = port_match.group(check)
140                 if (
141                     resource_match
142                     and not parameter.startswith(resource_match)
143                     and parameter.find("_{}_".format(resource_match)) == -1
144                 ):
145                     msg = (
146                         "OS::Neutron::Port {0} property {1} parameter "
147                         + "{2} {3} does match resource {3} {4}"
148                     ).format(rid, resource_property, parameter, check, resource_match)
149                     invalid_ips.append(msg)
150                     continue
151
152     assert not invalid_ips, "%s" % "\n".join(invalid_ips)
153
154
155 def get_list_of_ports_attached_to_nova_server(nova_server):
156     networks_list = nova_server.get("properties", {}).get("networks")
157
158     port_ids = []
159     if networks_list:
160         for network in networks_list:
161             network_prop = network.get("port")
162             if network_prop:
163                 pid = network_prop.get("get_param")
164                 if not pid:
165                     pid = network_prop.get("get_resource")
166                 port_ids.append(pid)
167
168     return port_ids