X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=rwcal%2Fplugins%2Fvala%2Frwcal_openstack%2Frift%2Frwcal%2Fopenstack%2Futils%2Fnetwork.py;fp=rwcal%2Fplugins%2Fvala%2Frwcal_openstack%2Frift%2Frwcal%2Fopenstack%2Futils%2Fnetwork.py;h=b0c58af24ae27c1c0c3ba37e96bc2b47f25dcd6c;hb=eb223959413d75048f484c1978af10d6b551f19c;hp=0000000000000000000000000000000000000000;hpb=c148feb9a12330f67e4093e4848506106961b737;p=osm%2FSO.git diff --git a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/utils/network.py b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/utils/network.py new file mode 100644 index 00000000..b0c58af2 --- /dev/null +++ b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/utils/network.py @@ -0,0 +1,249 @@ +#!/usr/bin/python + +# +# Copyright 2017 RIFT.IO Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import gi +gi.require_version('RwcalYang', '1.0') +from gi.repository import RwcalYang +import neutronclient.common.exceptions as NeutronException + + +class NetworkUtils(object): + """ + Utility class for network operations + """ + def __init__(self, driver): + """ + Constructor for class + Arguments: + driver: object of OpenstackDriver() + """ + self._driver = driver + self.log = driver.log + + @property + def driver(self): + return self._driver + + def _parse_cp(self, cp_info): + """ + Parse the port_info dictionary returned by neutronclient + Arguments: + cp_info: A dictionary object representing port attributes + + Returns: + Protobuf GI oject of type RwcalYang.VirtualLinkInfoParams_ConnectionPoints() + """ + cp = RwcalYang.VirtualLinkInfoParams_ConnectionPoints() + if 'name' in cp_info and cp_info['name']: + cp.name = cp_info['name'] + + if 'id' in cp_info and cp_info['id']: + cp.connection_point_id = cp_info['id'] + + if ('fixed_ips' in cp_info) and (len(cp_info['fixed_ips']) >= 1): + if 'ip_address' in cp_info['fixed_ips'][0]: + cp.ip_address = cp_info['fixed_ips'][0]['ip_address'] + + if 'mac_address' in cp_info and cp_info['mac_address']: + cp.mac_addr = cp_info['mac_address'] + + if cp_info['status'] == 'ACTIVE': + cp.state = 'active' + else: + cp.state = 'inactive' + + if 'network_id' in cp_info and cp_info['network_id']: + cp.virtual_link_id = cp_info['network_id'] + + if 'device_id' in cp_info and cp_info['device_id']: + cp.vdu_id = cp_info['device_id'] + return cp + + def parse_cloud_virtual_link_info(self, vlink_info, port_list, subnet): + """ + Parse vlink_info dictionary (return by python-client) and put values in GI object for Virtual Link + + Arguments: + vlink_info : A dictionary object return by neutronclient library listing network attributes + + Returns: + Protobuf GI Object of type RwcalYang.VirtualLinkInfoParams() + """ + link = RwcalYang.VirtualLinkInfoParams() + link.name = vlink_info['name'] + if 'status' in vlink_info and vlink_info['status'] == 'ACTIVE': + link.state = 'active' + else: + link.state = 'inactive' + + link.virtual_link_id = vlink_info['id'] + for port in port_list: + if ('device_owner' in port) and (port['device_owner'] == 'compute:None'): + link.connection_points.append(self._parse_cp(port)) + + if subnet is not None: + link.subnet = subnet['cidr'] + + if ('provider:network_type' in vlink_info) and (vlink_info['provider:network_type'] != None): + link.provider_network.overlay_type = vlink_info['provider:network_type'].upper() + if ('provider:segmentation_id' in vlink_info) and (vlink_info['provider:segmentation_id']): + link.provider_network.segmentation_id = vlink_info['provider:segmentation_id'] + if ('provider:physical_network' in vlink_info) and (vlink_info['provider:physical_network']): + link.provider_network.physical_network = vlink_info['provider:physical_network'].upper() + + return link + + def setup_vdu_networking(self, vdu_params): + """ + This function validates the networking/connectivity setup. + + Arguments: + vdu_params: object of RwcalYang.VDUInitParams() + + Returns: + A list of port_ids and network_ids for VDU + + """ + port_args = list() + network_ids = list() + add_mgmt_net = False + for cp in vdu_params.connection_points: + if cp.virtual_link_id == self.driver._mgmt_network_id: + ### Remove mgmt_network_id from net_ids + add_mgmt_net = True + port_args.append(self._create_cp_args(cp)) + + if not add_mgmt_net: + network_ids.append(self.driver._mgmt_network_id) + + ### Create ports and collect port ids + port_ids = self.driver.neutron_multi_port_create(port_args) + return port_ids, network_ids + + + def _create_cp_args(self, cp): + """ + Creates a request dictionary for port create call + Arguments: + cp: Object of RwcalYang.VDUInitParams_ConnectionPoints() + Returns: + dict() of request params + """ + args = dict() + args['name'] = cp.name + args['network_id'] = cp.virtual_link_id + args['admin_state_up'] = True + + if cp.type_yang == 'VIRTIO' or cp.type_yang == 'E1000': + args['binding:vnic_type'] = 'normal' + elif cp.type_yang == 'SR_IOV': + args['binding:vnic_type'] = 'direct' + else: + raise NotImplementedError("Port Type: %s not supported" %(cp.type_yang)) + + if cp.static_ip_address: + args["fixed_ips"] = [{"ip_address" : cp.static_ip_address}] + + if 'port_security_enabled' in cp: + args['port_security_enabled'] = cp.port_security_enabled + + if cp.has_field('security_group'): + if self.driver._neutron_security_groups: + gid = self.driver._neutron_security_groups[0]['id'] + args['security_groups'] = [ gid ] + return args + + def make_virtual_link_args(self, link_params): + """ + Function to create kwargs required for neutron_network_create API + + Arguments: + link_params: Protobuf GI object RwcalYang.VirtualLinkReqParams() + + Returns: + A kwargs dictionary for network operation + """ + kwargs = dict() + kwargs['name'] = link_params.name + kwargs['admin_state_up'] = True + kwargs['external_router'] = False + kwargs['shared'] = False + + if link_params.has_field('provider_network'): + if link_params.provider_network.has_field('physical_network'): + kwargs['physical_network'] = link_params.provider_network.physical_network + if link_params.provider_network.has_field('overlay_type'): + kwargs['network_type'] = link_params.provider_network.overlay_type.lower() + if link_params.provider_network.has_field('segmentation_id'): + kwargs['segmentation_id'] = link_params.provider_network.segmentation_id + + return kwargs + + def make_subnet_args(self, link_params, network_id): + """ + Function to create kwargs required for neutron_subnet_create API + + Arguments: + link_params: Protobuf GI object RwcalYang.VirtualLinkReqParams() + + Returns: + A kwargs dictionary for subnet operation + """ + kwargs = {'network_id' : network_id, + 'dhcp_params': {'enable_dhcp': True}, + 'gateway_ip' : None,} + + if link_params.ip_profile_params.has_field('ip_version'): + kwargs['ip_version'] = 6 if link_params.ip_profile_params.ip_version == 'ipv6' else 4 + else: + kwargs['ip_version'] = 4 + + if link_params.ip_profile_params.has_field('subnet_address'): + kwargs['cidr'] = link_params.ip_profile_params.subnet_address + elif link_params.ip_profile_params.has_field('subnet_prefix_pool'): + name = link_params.ip_profile_params.subnet_prefix_pool + pools = [ p['id'] for p in self.driver._neutron_subnet_prefix_pool if p['name'] == name ] + if not pools: + self.log.error("Could not find subnet pool with name :%s to be used for network: %s", + link_params.ip_profile_params.subnet_prefix_pool, + link_params.name) + raise NeutronException.NotFound("SubnetPool with name %s not found"%(link_params.ip_profile_params.subnet_prefix_pool)) + + kwargs['subnetpool_id'] = pools[0] + + elif link_params.has_field('subnet'): + kwargs['cidr'] = link_params.subnet + else: + raise NeutronException.NeutronException("No IP Prefix or Pool name specified") + + if link_params.ip_profile_params.has_field('dhcp_params'): + if link_params.ip_profile_params.dhcp_params.has_field('enabled'): + kwargs['dhcp_params']['enable_dhcp'] = link_params.ip_profile_params.dhcp_params.enabled + if link_params.ip_profile_params.dhcp_params.has_field('start_address'): + kwargs['dhcp_params']['start_address'] = link_params.ip_profile_params.dhcp_params.start_address + if link_params.ip_profile_params.dhcp_params.has_field('count'): + kwargs['dhcp_params']['count'] = link_params.ip_profile_params.dhcp_params.count + + if link_params.ip_profile_params.has_field('dns_server'): + kwargs['dns_server'] = [] + for server in link_params.ip_profile_params.dns_server: + kwargs['dns_server'].append(server.address) + + if link_params.ip_profile_params.has_field('gateway_address'): + kwargs['gateway_ip'] = link_params.ip_profile_params.gateway_address + + return kwargs