[VVP] updating validation scripts in dublin
[vvp/validation-scripts.git] / ice_validator / tests / utils / network_roles.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 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
39 #
40
41 import re
42 import socket
43
44 PARAM_FORMATS = [
45     ["network", "string", "internal", re.compile(r"int_(.+?)_net_id")],
46     ["network", "string", "internal", re.compile(r"int_(.+?)_net_name")],
47     ["network", "string", "external", re.compile(r"(.+?)_net_id")],
48     ["network", "string", "external", re.compile(r"(.+?)_net_name")],
49 ]
50
51 RESOURCE_FORMATS = [
52     re.compile(r"int_(.+?)_network"),  # OS::ContrailV2::VirtualNetwork
53     re.compile(r"int_(.+?)_RVN"),  # OS::ContrailV2::VirtualNetwork
54     re.compile(r"int_(.+?)"),  # OS::Neutron::Net
55 ]
56
57
58 def get_network_role_and_type(resource):
59     """
60     Derive the network role and type (internal vs. external) from an
61     OS::Neutron::Port.
62
63     :param resource: dict of Resource attributes
64     :return: tuple of (network_role, network_type) where network_type is
65              'internal' or 'external'.  Returns (None, None) if resource
66              is not a port or the values cannot be derived.
67     """
68     if not isinstance(resource, dict):
69         return None, None
70     if resource.get("type", "") != "OS::Neutron::Port":
71         return None, None
72
73     network_props = resource.get("properties", {}).get("network", {})
74     is_resource = "get_resource" in network_props
75     if is_resource:
76         network = network_props.get("get_resource", "")
77     else:
78         network = network_props.get("get_param", "")
79
80     if is_resource:  # connecting to an network in the template
81         for format in RESOURCE_FORMATS:
82             m = format.match(network)
83             if m and m.group(1):
84                 return m.group(1), "internal"
85     else:
86         for format in PARAM_FORMATS:
87             m = format[3].match(network)
88             if m and m.group(1):
89                 return m.group(1), format[2]
90     return None, None
91
92
93 def get_network_role_from_port(resource):
94     """
95     Get the network-role from a OS::Neutron::Port resource.  Returns None
96     if resource is not a port or the network-role cannot be derived
97     """
98     return get_network_role_and_type(resource)[0]
99
100
101 def get_network_roles(resources, of_type=""):
102     """
103     Returns the network roles derived from the OS::Neutron::Port resources
104     in the collection of ``resources``.  If ``of_type`` is not specified
105     then all network roles will be returned, or ``external`` or ``internal``
106     can be passed to select only those network roles
107
108     :param resources:   collection of resource attributes (dict)
109     :param of_type:     "internal" or "external"
110     :return:            set of network roles discovered
111     """
112     valid_of_type = ("", "external", "internal")
113     if of_type not in ("", "external", "internal"):
114         raise RuntimeError("of_type must one of " + ", ".join(valid_of_type))
115     network_roles = set()
116     for v in resources.values():
117         nr, nt = get_network_role_and_type(v)
118         if not nr:
119             continue
120         if not of_type:
121             network_roles.add(nr)
122         elif of_type and of_type == nt:
123             network_roles.add(nr)
124     return network_roles
125
126
127 def get_network_type_from_port(resource):
128     """
129     Get the network-type (internal or external) from an OS::Neutron::Port
130     resource.  Returns None if the resource is not a port or the type
131     cannot be derived.
132     """
133     return get_network_role_and_type(resource)[1]
134
135
136 def is_valid_ip_address(ip_address, ip_type="ipv4"):
137     """
138     check if an ip address is valid
139     """
140     if ip_type == "ipv4":
141         return is_valid_ipv4_address(ip_address)
142     elif ip_type == "ipv6":
143         return is_valid_ipv6_address(ip_address)
144     return False
145
146
147 def is_valid_ipv4_address(ip_address):
148     """
149     check if an ip address of the type ipv4
150     is valid
151     """
152     try:
153         socket.inet_pton(socket.AF_INET, ip_address)
154     except AttributeError:
155         try:
156             socket.inet_aton(ip_address)
157         except (OSError, socket.error):
158             return False
159         return ip_address.count(".") == 3
160     except (OSError, socket.error):
161         return False
162     return True
163
164
165 def is_valid_ipv6_address(ip_address):
166     """
167     check if an ip address of the type ipv6
168     is valid
169     """
170     try:
171         socket.inet_pton(socket.AF_INET6, ip_address)
172     except (OSError, socket.error):
173         return False
174     return True
175
176
177 def property_uses_get_resource(resource, property_name):
178     """
179     returns true if a port's network property
180     uses the get_resource function
181     """
182     if not isinstance(resource, dict):
183         return False
184     if "properties" not in resource:
185         return False
186     for k1, v1 in resource["properties"].items():
187         if k1 != property_name:
188             continue
189         if isinstance(v1, dict) and "get_resource" in v1:
190             return True
191     return False