4 # Copyright 2017 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
19 gi
.require_version('RwcalYang', '1.0')
20 from gi
.repository
import RwcalYang
21 import neutronclient
.common
.exceptions
as NeutronException
24 class NetworkUtils(object):
26 Utility class for network operations
28 def __init__(self
, driver
):
32 driver: object of OpenstackDriver()
41 def _parse_cp(self
, cp_info
):
43 Parse the port_info dictionary returned by neutronclient
45 cp_info: A dictionary object representing port attributes
48 Protobuf GI oject of type RwcalYang.VirtualLinkInfoParams_ConnectionPoints()
50 cp
= RwcalYang
.VirtualLinkInfoParams_ConnectionPoints()
51 if 'name' in cp_info
and cp_info
['name']:
52 cp
.name
= cp_info
['name']
54 if 'id' in cp_info
and cp_info
['id']:
55 cp
.connection_point_id
= cp_info
['id']
57 if ('fixed_ips' in cp_info
) and (len(cp_info
['fixed_ips']) >= 1):
58 if 'ip_address' in cp_info
['fixed_ips'][0]:
59 cp
.ip_address
= cp_info
['fixed_ips'][0]['ip_address']
61 if 'mac_address' in cp_info
and cp_info
['mac_address']:
62 cp
.mac_addr
= cp_info
['mac_address']
64 if cp_info
['status'] == 'ACTIVE':
69 if 'network_id' in cp_info
and cp_info
['network_id']:
70 cp
.virtual_link_id
= cp_info
['network_id']
72 if 'device_id' in cp_info
and cp_info
['device_id']:
73 cp
.vdu_id
= cp_info
['device_id']
76 def parse_cloud_virtual_link_info(self
, vlink_info
, port_list
, subnet
):
78 Parse vlink_info dictionary (return by python-client) and put values in GI object for Virtual Link
81 vlink_info : A dictionary object return by neutronclient library listing network attributes
84 Protobuf GI Object of type RwcalYang.VirtualLinkInfoParams()
86 link
= RwcalYang
.VirtualLinkInfoParams()
87 link
.name
= vlink_info
['name']
88 if 'status' in vlink_info
and vlink_info
['status'] == 'ACTIVE':
91 link
.state
= 'inactive'
93 link
.virtual_link_id
= vlink_info
['id']
94 for port
in port_list
:
95 if ('device_owner' in port
) and (port
['device_owner'] == 'compute:None'):
96 link
.connection_points
.append(self
._parse
_cp
(port
))
98 if subnet
is not None:
99 link
.subnet
= subnet
['cidr']
101 if ('provider:network_type' in vlink_info
) and (vlink_info
['provider:network_type'] != None):
102 link
.provider_network
.overlay_type
= vlink_info
['provider:network_type'].upper()
103 if ('provider:segmentation_id' in vlink_info
) and (vlink_info
['provider:segmentation_id']):
104 link
.provider_network
.segmentation_id
= vlink_info
['provider:segmentation_id']
105 if ('provider:physical_network' in vlink_info
) and (vlink_info
['provider:physical_network']):
106 link
.provider_network
.physical_network
= vlink_info
['provider:physical_network'].upper()
110 def setup_vdu_networking(self
, vdu_params
):
112 This function validates the networking/connectivity setup.
115 vdu_params: object of RwcalYang.VDUInitParams()
118 A list of port_ids and network_ids for VDU
124 for cp
in vdu_params
.connection_points
:
125 if cp
.virtual_link_id
== self
.driver
._mgmt
_network
_id
:
126 ### Remove mgmt_network_id from net_ids
128 port_args
.append(self
._create
_cp
_args
(cp
))
131 network_ids
.append(self
.driver
._mgmt
_network
_id
)
133 ### Create ports and collect port ids
135 port_ids
= self
.driver
.neutron_multi_port_create(port_args
)
139 return port_ids
, network_ids
142 def _create_cp_args(self
, cp
):
144 Creates a request dictionary for port create call
146 cp: Object of RwcalYang.VDUInitParams_ConnectionPoints()
148 dict() of request params
151 args
['name'] = cp
.name
152 args
['network_id'] = cp
.virtual_link_id
153 args
['admin_state_up'] = True
155 if cp
.type_yang
== 'VIRTIO' or cp
.type_yang
== 'E1000':
156 args
['binding:vnic_type'] = 'normal'
157 elif cp
.type_yang
== 'SR_IOV':
158 args
['binding:vnic_type'] = 'direct'
160 raise NotImplementedError("Port Type: %s not supported" %(cp
.type_yang
))
163 if cp
.static_ip_address
:
164 args
["fixed_ips"] = [{"ip_address" : cp
.static_ip_address
}]
165 except Exception as e
:
168 if 'port_security_enabled' in cp
:
169 args
['port_security_enabled'] = cp
.port_security_enabled
171 if cp
.has_field('security_group'):
172 if self
.driver
._neutron
_security
_groups
:
173 gid
= self
.driver
._neutron
_security
_groups
[0]['id']
174 args
['security_groups'] = [ gid
]
177 def make_virtual_link_args(self
, link_params
):
179 Function to create kwargs required for neutron_network_create API
182 link_params: Protobuf GI object RwcalYang.VirtualLinkReqParams()
185 A kwargs dictionary for network operation
188 kwargs
['name'] = link_params
.name
189 kwargs
['admin_state_up'] = True
190 kwargs
['external_router'] = False
191 kwargs
['shared'] = False
193 if link_params
.has_field('provider_network'):
194 if link_params
.provider_network
.has_field('physical_network'):
195 kwargs
['physical_network'] = link_params
.provider_network
.physical_network
196 if link_params
.provider_network
.has_field('overlay_type'):
197 kwargs
['network_type'] = link_params
.provider_network
.overlay_type
.lower()
198 if link_params
.provider_network
.has_field('segmentation_id'):
199 kwargs
['segmentation_id'] = link_params
.provider_network
.segmentation_id
203 def make_subnet_args(self
, link_params
, network_id
):
205 Function to create kwargs required for neutron_subnet_create API
208 link_params: Protobuf GI object RwcalYang.VirtualLinkReqParams()
211 A kwargs dictionary for subnet operation
213 kwargs
= {'network_id' : network_id
,
214 'dhcp_params': {'enable_dhcp': True},
215 'gateway_ip' : None,}
217 if link_params
.ip_profile_params
.has_field('ip_version'):
218 kwargs
['ip_version'] = 6 if link_params
.ip_profile_params
.ip_version
== 'ipv6' else 4
220 kwargs
['ip_version'] = 4
222 if link_params
.ip_profile_params
.has_field('subnet_address'):
223 kwargs
['cidr'] = link_params
.ip_profile_params
.subnet_address
224 elif link_params
.ip_profile_params
.has_field('subnet_prefix_pool'):
225 name
= link_params
.ip_profile_params
.subnet_prefix_pool
226 pools
= [ p
['id'] for p
in self
.driver
._neutron
_subnet
_prefix
_pool
if p
['name'] == name
]
228 self
.log
.error("Could not find subnet pool with name :%s to be used for network: %s",
229 link_params
.ip_profile_params
.subnet_prefix_pool
,
231 raise NeutronException
.NotFound("SubnetPool with name %s not found"%(link_params
.ip_profile_params
.subnet_prefix_pool
))
233 kwargs
['subnetpool_id'] = pools
[0]
235 elif link_params
.has_field('subnet'):
236 kwargs
['cidr'] = link_params
.subnet
238 raise NeutronException
.NeutronException("No IP Prefix or Pool name specified")
240 if link_params
.ip_profile_params
.has_field('dhcp_params'):
241 if link_params
.ip_profile_params
.dhcp_params
.has_field('enabled'):
242 kwargs
['dhcp_params']['enable_dhcp'] = link_params
.ip_profile_params
.dhcp_params
.enabled
243 if link_params
.ip_profile_params
.dhcp_params
.has_field('start_address'):
244 kwargs
['dhcp_params']['start_address'] = link_params
.ip_profile_params
.dhcp_params
.start_address
245 if link_params
.ip_profile_params
.dhcp_params
.has_field('count'):
246 kwargs
['dhcp_params']['count'] = link_params
.ip_profile_params
.dhcp_params
.count
248 if link_params
.ip_profile_params
.has_field('dns_server'):
249 kwargs
['dns_server'] = []
250 for server
in link_params
.ip_profile_params
.dns_server
:
251 kwargs
['dns_server'].append(server
.address
)
253 if link_params
.ip_profile_params
.has_field('gateway_address'):
254 kwargs
['gateway_ip'] = link_params
.ip_profile_params
.gateway_address