def _parse_vdu_boot_config_data(self, vm_info): """ Parses VDU supplemental boot data Arguments: vm_info : A dictionary returned by novaclient library listing VM attributes Returns: List of RwcalYang.YangData_RwProject_Project_VnfResources_VduInfoList_SupplementalBootData() """ supplemental_boot_data = None node_id = None if 'config_drive' in vm_info: supplemental_boot_data = RwcalYang.YangData_RwProject_Project_VnfResources_VduInfoList_SupplementalBootData() supplemental_boot_data.boot_data_drive = vm_info['config_drive'] # Look for any metadata if 'metadata' not in vm_info: return node_id, supplemental_boot_data if supplemental_boot_data is None: supplemental_boot_data = RwcalYang.YangData_RwProject_Project_VnfResources_VduInfoList_SupplementalBootData() for key, value in vm_info['metadata'].items(): if key == 'rift_node_id': node_id = value else: try: # rift only cm = supplemental_boot_data.custom_meta_data.add() cm.name = key cm.value = str(value) except Exception as e: pass return node_id, supplemental_boot_data
def test_modify_vdu_add_remove_connection_point(self): vdu, vdu_id = self.create_vdu(self.image, 0) link, link_id = self.create_virtual_link(0) get_vdu = self.cal.do_get_vdu(self.account, vdu_id, no_rwstatus=True) assert len(get_vdu.connection_points) == 0 modify_vdu = RwcalYang.VDUModifyParams() modify_vdu.vdu_id = vdu_id cp = modify_vdu.connection_points_add.add() cp.virtual_link_id = link_id cp.name = "link_1" self.cal.do_modify_vdu(self.account, modify_vdu, no_rwstatus=True) get_vdu = self.cal.do_get_vdu(self.account, vdu_id, no_rwstatus=True) assert len(get_vdu.connection_points) == 1 modify_vdu = RwcalYang.VDUModifyParams() modify_vdu.vdu_id = vdu_id cp = modify_vdu.connection_points_remove.add() cp.connection_point_id = get_vdu.connection_points[0].connection_point_id self.cal.do_modify_vdu(self.account, modify_vdu, no_rwstatus=True) get_vdu = self.cal.do_get_vdu(self.account, vdu_id, no_rwstatus=True) assert len(get_vdu.connection_points) == 0 self.cal.do_delete_vdu(self.account, vdu_id, no_rwstatus=True) self.cal.do_delete_virtual_link(self.account, link_id, no_rwstatus=True)
def start(self): """Tasklet entry point""" self.log.setLevel(logging.DEBUG) super().start() cal = self.get_cal_interface() account = RwcalYang.YangData_RwProject_Project_CloudAccounts_CloudAccountList(account_type="cloudsim") self.app = CalProxyApp(self.log, self.loop, cal, account) self._dts = rift.tasklets.DTS( self.tasklet_info, RwcalYang.get_schema(), self.loop, self.on_dts_state_change ) io_loop = rift.tasklets.tornado.TaskletAsyncIOLoop(asyncio_loop=self.loop) self.server = tornado.httpserver.HTTPServer( self.app, io_loop=io_loop, ) self.log.info("Starting Cal Proxy Http Server on port %s", RwCalProxyTasklet.HTTP_PORT) self.server.listen(RwCalProxyTasklet.HTTP_PORT)
def do_get_vdu_list(self, account): vnf_resources = RwcalYang.VNFResources() for r in self.resources[account.name].vdus.values(): vdu = RwcalYang.VDUInfoParams() vdu.copy_from(r) vnf_resources.vdu_info_list.append(vdu) logger.debug("Returning list of vdu-info of size: %d", len(vnf_resources.vdu_info_list)) return vnf_resources
def do_get_virtual_link_list(self, account): vnf_resources = RwcalYang.VNFResources() for r in self.resources[account.name].vlinks.values(): vlink = RwcalYang.VirtualLinkInfoParams() vlink.copy_from(r) vnf_resources.virtual_link_info_list.append(vlink) logger.debug("Returning list of virtual-link-info of size: %d", len(vnf_resources.virtual_link_info_list)) return vnf_resources
def do_get_vdu_list(self, account): vnf_resources = RwcalYang.YangData_RwProject_Project_VnfResources() for r in self.resources[account.name].vdus.values(): vdu = RwcalYang.YangData_RwProject_Project_VnfResources_VduInfoList( ) vdu.copy_from(r) vnf_resources.vdu_info_list.append(vdu) logger.debug("Returning list of vdu-info of size: %d", len(vnf_resources.vdu_info_list)) return vnf_resources
def do_get_flavor_list(self, account): """ Return a list of flavors """ vim_resources = RwcalYang.VimResources() for flavor in self.cal.flavors.values(): f = RwcalYang.FlavorInfoItem() f.copy_from(flavor) vim_resources.flavorinfo_list.append(f) logger.debug("Returning list of flavor-info of size: %d", len(vim_resources.flavorinfo_list)) return vim_resources
def do_get_flavor_list(self, account): """ Return a list of flavors """ vim_resources = RwcalYang.YangData_RwProject_Project_VimResources() for flavor in self.resources[account.name].flavors.values(): f = RwcalYang.YangData_RwProject_Project_VimResources_FlavorinfoList( ) f.copy_from(flavor) vim_resources.flavorinfo_list.append(f) logger.debug("Returning list of flavor-info of size: %d", len(vim_resources.flavorinfo_list)) return vim_resources
def do_get_image_list(self, account): """ Return a list of the names of all available images. """ boxed_image_list = RwcalYang.VimResources() for image in self.resources[account.name].images.values(): image_entry = RwcalYang.ImageInfoItem() image_entry.id = image.id image_entry.name = image.name if image.has_field('checksum'): image_entry.checksum = image.checksum boxed_image_list.imageinfo_list.append(image_entry) return boxed_image_list
def do_get_network_list(self, account): """Returns a list of network objects""" resources = RwcalYang.VimResources() for network in self.cal.get_network_list(): resources.networkinfo_list.append(rwcal_copy_object(network)) return resources
def do_validate_cloud_creds(self, account): """ Validates the cloud account credentials for the specified account. Performs an access to the resources using Keystone API. If creds are not valid, returns an error code & reason string Arguments: account - a cloud account to validate Returns: Validation Code and Details String """ status = RwcalYang.YangData_Rwcal_ConnectionStatus() try: drv = self._use_driver(account) drv.validate_account_creds() except Exception as e: msg = "RwcalOpenstackPlugin: Exception: %s" % (str(e)) self.log.error(msg) status.status = "failure" status.details = msg else: status.status = "success" status.details = "Connection was successful" return status
def do_get_virtual_link_list(self, account): """Get information about all the virtual links Arguments: account - a cloud account Returns: A list of objects of type RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList """ vnf_resources = RwcalYang.YangData_RwProject_Project_VnfResources() drv = self._use_driver(account) try: networks = drv.neutron_network_list() for network in networks: port_list = drv.neutron_port_list( **{'network_id': network['id']}) if 'subnets' in network and network['subnets']: subnet = drv.neutron_subnet_get(network['subnets'][0]) else: subnet = None virtual_link = drv.utils.network.parse_cloud_virtual_link_info( network, port_list, subnet) vnf_resources.virtual_link_info_list.append(virtual_link) except Exception as e: self.log.exception( "Exception %s occured during virtual-link-list-get", str(e)) raise return vnf_resources
def do_get_network_list(self, account): response = RwcalYang.YangData_RwProject_Project_VimResources() with self._use_driver(account) as drv: networks = drv.get_network_list() for network in networks: response.networkinfo_list.append(self._fill_network_info(network)) return response
def do_get_image_list(self, account): """Returns a list of images""" resources = RwcalYang.VimResources() for image in self.cal.get_image_list(): resources.imageinfo_list.append(rwcal_copy_object(image)) return resources
def do_modify_vdu(self, account, vdu_modify): vdu = self.resources[account.name].vdus[vdu_modify.vdu_id] for c in vdu_modify.connection_points_add: p = vdu.connection_points.add() p.connection_point_id = self.get_uuid(c.name) p.name = c.name p.vdu_id = vdu.vdu_id p.state = 'active' p.ip_address = socket.inet_ntoa( struct.pack('>I', random.randint(1, 0xffffffff))) p.virtual_link_id = c.virtual_link_id # Need to add this connection_point to virtual link vlink = self.resources[account.name].vlinks[c.virtual_link_id] aa = RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList_ConnectionPoints( ) aa.connection_point_id = p.connection_point_id aa.name = p.name aa.virtual_link_id = vlink.virtual_link_id aa.state = 'active' aa.ip_address = p.ip_address aa.vdu_id = p.vdu_id vlink.connection_points.append(aa) for c in vdu_modify.connection_points_remove: for d in vdu.connection_points: if c.connection_point_id == d.connection_point_id: vdu.connection_points.remove(d) break for k, vlink in self.resources[account.name].vlinks.items(): for z in vlink.connection_points: if z.connection_point_id == c.connection_point_id: vlink.connection_points.remove(z) break logger.debug('modified vdu: {}'.format(vdu_modify.vdu_id))
def select_vdu_flavor(self, vdu_params): """ This function attempts to find a pre-existing flavor matching required parameters for VDU instantiation. If no such flavor is found, a new one is created. Arguments: vdu_params: Protobuf GI object RwcalYang.YangData_RwProject_Project_VduInitParams() Returns: flavor_id(string): Flavor id for VDU instantiation """ flavor_id = self.search_vdu_flavor(vdu_params) if flavor_id is not None: self.log.info("Found flavor with id: %s matching requirements for VDU: %s", flavor_id, vdu_params.name) return flavor_id flavor = RwcalYang.YangData_RwProject_Project_VimResources_FlavorinfoList() flavor.name = str(uuid.uuid4()) epa_dict = { k: v for k, v in vdu_params.as_dict().items() if k in ComputeUtils.epa_types } flavor.from_dict(epa_dict) flavor_id = self.driver.nova_flavor_create(name = flavor.name, ram = flavor.vm_flavor.memory_mb, vcpus = flavor.vm_flavor.vcpu_count, disk = flavor.vm_flavor.storage_gb, epa_specs = self.driver.utils.flavor.get_extra_specs(flavor)) return flavor_id
def start(self): """Tasklet entry point""" self.log.setLevel(logging.DEBUG) super().start() cal = self.get_cal_interface() account = RwcalYang.CloudAccount(account_type="cloudsim") self.app = CalProxyApp(self.log, self.loop, cal, account) self._dts = rift.tasklets.DTS( self.tasklet_info, RwcalYang.get_schema(), self.loop, self.on_dts_state_change ) io_loop = rift.tasklets.tornado.TaskletAsyncIOLoop(asyncio_loop=self.loop) self.server = tornado.httpserver.HTTPServer( self.app, io_loop=io_loop, ) self.log.info("Starting Cal Proxy Http Server on port %s", RwCalProxyTasklet.HTTP_PORT) self.server.listen(RwCalProxyTasklet.HTTP_PORT)
def create_image(self, location): img = RwcalYang.ImageInfoItem() img.name = basename(location) img.location = location img.disk_format = "qcow2" img.container_format = "bare" logger.info("Uploading image : %s" % img.name) rc, img_id = self._cal.create_image(self._acct, img) assert rc == RwStatus.SUCCESS rs = None rc = None image = None for i in range(100): rc, rs = self._cal.get_image(self._acct, img_id) assert rc == RwStatus.SUCCESS logger.info("Image (image_id: %s) reached status : %s" % (img_id, rs.state)) if rs.state == 'active': image = rs break else: time.sleep(2) # Sleep for a second if image is None: logger.error("Failed to upload openstack image: %s", img) sys.exit(1) self._image_id = img_id logger.info("Uploading image.......[Done]")
def do_validate_cloud_creds(self, account): """ Validates the cloud account credentials for the specified account. If creds are not valid, returns an error code & reason string Arguments: account - a cloud account to validate Returns: Validation Code and Details String """ status = RwcalYang.YangData_Rwcal_ConnectionStatus() url = 'http://{}:{}/openvim/'.format(account.openvim.host, account.openvim.port) try: r = requests.get(url, timeout=3) r.raise_for_status() except requests.exceptions.HTTPError as e: self.log.error( "OpenvimConnectorPlugin: Openvim account credential validation failed. Exception: %s", str(e)) status.status = "failure" status.details = "Invalid Credentials: %s" % str(e) except Exception as e: self.log.error( "OpenvimConnectorPlugin: Openvim connection failed. Exception: %s", str(e)) status.status = "failure" status.details = "Connection Failed (Invlaid URL): %s" % str(e) else: self.log.debug("Openvim Successfully connected") status.status = "success" status.details = "Connection was successful" return status
def create_network(self, name): logger.info("Creating network with name: %s" % name) network = RwcalYang.NetworkInfoItem() network.network_name = name network.subnet = openstack_info['subnets'][ openstack_info['subnet_index']] if openstack_info['subnet_index'] == len(openstack_info['subnets']): openstack_info['subnet_index'] = 0 else: openstack_info['subnet_index'] += 1 if openstack_info['physical_network']: network.provider_network.physical_network = openstack_info[ 'physical_network'] if openstack_info['network_type']: network.provider_network.overlay_type = openstack_info[ 'network_type'] if openstack_info['segmentation_id']: network.provider_network.segmentation_id = openstack_info[ 'segmentation_id'] openstack_info['segmentation_id'] += 1 rc, net_id = self._cal.create_network(self._acct, network) assert rc == RwStatus.SUCCESS logger.info("Successfully created network with id: %s" % net_id) return net_id
def create_virtual_link_info(network_info, port_list): """Create a GI object for VirtualLinkInfoParams Converts Network and Port information dictionary object returned by container manager into Protobuf Gi Object Arguments: network_info - Network information from container cal port_list - A list of port information from container cal subnet: Subnet information from openstack Returns: Protobuf Gi object for VirtualLinkInfoParams """ link = RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList( ) link.name = network_info.network_name link.state = 'active' link.virtual_link_id = network_info.network_id for port in port_list: c_point = link.connection_points.add() CloudSimPlugin.fill_connection_point_info(c_point, port) link.subnet = network_info.subnet return link
def _fill_virtual_link_info(self, drv, network_info): link = RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList( ) link.name = network_info['name'] link.virtual_link_id = network_info['id'] if network_info['admin_state_up']: link.state = 'active' else: link.state = 'inactive' link.virtual_link_id = network_info['id'] if ('provider:physical' in network_info) and (network_info['provider:physical']): link.provider_network.physical_network = network_info[ 'provider:physical'] if ('provider:vlan' in network_info) and (network_info['provider:vlan']): link.provider_network.segmentation_id = network_info[ 'provider:vlan'] link.provider_network.overlay_type = 'VLAN' if 'ports' in network_info: for port in network_info['ports']: if 'port_id' in port: port_id = port['port_id'] port = drv.get_port(port_id) c_point = link.connection_points.add() RwcalOpenmanoVimConnector._fill_connection_point_info( c_point, port) return link
def fill_vdu_info(vm_info, port_list): """create a gi object for vduinfoparams converts vm information dictionary object returned by openstack driver into protobuf gi object arguments: vm_info - vm information from openstack mgmt_network - management network port_list - a list of port information from container cal returns: protobuf gi object for vduinfoparams """ vdu = RwcalYang.VDUInfoParams() vdu.name = vm_info.vm_name vdu.vdu_id = vm_info.vm_id vdu.management_ip = vm_info.management_ip vdu.public_ip = vm_info.management_ip vdu.node_id = vm_info.user_tags.node_id vdu.image_id = vm_info.image_id vdu.state = 'active' # fill the port information for port in port_list: c_point = vdu.connection_points.add() CloudSimPlugin.fill_connection_point_info(c_point, port) vdu.vm_flavor.vcpu_count = 1 vdu.vm_flavor.memory_mb = 8 * 1024 # 8GB vdu.vm_flavor.storage_gb = 10 return vdu
def do_create_vdu(self, account, vdu_init): vdu_id = self.get_uuid( "%s_%s" % (vdu_init.name, len(self.resources[account.name].vdus))) vdu = RwcalYang.YangData_RwProject_Project_VnfResources_VduInfoList() vdu.vdu_id = vdu_id vdu.name = vdu_init.name vdu.node_id = vdu_init.node_id vdu.image_id = vdu_init.image_id if vdu_init.has_field('flavor_id'): vdu.flavor_id = vdu_init.flavor_id if vdu_init.has_field('vm_flavor'): xx = vdu.vm_flavor.new() xx.from_pbuf(vdu_init.vm_flavor.to_pbuf()) vdu.vm_flavor = xx if vdu_init.has_field('guest_epa'): xx = vdu.guest_epa.new() xx.from_pbuf(vdu_init.guest_epa.to_pbuf()) vdu.guest_epa = xx if vdu_init.has_field('vswitch_epa'): xx = vdu.vswitch_epa.new() xx.from_pbuf(vdu_init.vswitch_epa.to_pbuf()) vdu.vswitch_epa = xx if vdu_init.has_field('hypervisor_epa'): xx = vdu.hypervisor_epa.new() xx.from_pbuf(vdu_init.hypervisor_epa.to_pbuf()) vdu.hypervisor_epa = xx if vdu_init.has_field('host_epa'): xx = vdu.host_epa.new() xx.from_pbuf(vdu_init.host_epa.to_pbuf()) vdu.host_epa = xx vdu.state = 'active' vdu.management_ip = socket.inet_ntoa( struct.pack('>I', random.randint(1, 0xffffffff))) vdu.public_ip = vdu.management_ip for c in vdu_init.connection_points: p = vdu.connection_points.add() p.connection_point_id = self.get_uuid(c.name) p.name = c.name p.vdu_id = vdu_id p.state = 'active' p.ip_address = socket.inet_ntoa( struct.pack('>I', random.randint(1, 0xffffffff))) p.virtual_link_id = c.virtual_link_id # Need to add this connection_point to virtual link vlink = self.resources[account.name].vlinks[c.virtual_link_id] v = vlink.connection_points.add() for field in p.fields: if p.has_field(field): setattr(v, field, getattr(p, field)) self.resources[account.name].vdus[vdu_id] = vdu logger.debug('Created vdu: {}'.format(vdu_id)) return vdu_id
def __init__(self): self._containers = {} self._ports = {} self._bridges = {} self._port_to_container = {} self._port_to_bridge = {} self._container_to_ports = collections.defaultdict(list) self._bridge_to_ports = collections.defaultdict(list) # Create the management network self.mgmt_network = RwcalYang.NetworkInfoItem() self.mgmt_network.network_name = MGMT_NETWORK_NAME network = MGMT_NETWORK_INTERFACE_IP.network self.mgmt_network.subnet = str(network) # Create/Start the default virtd network for NAT-based # connectivity inside containers (http://wiki.libvirt.org/page/Networking) if "default" not in net.virsh_list_network_names(): logger.debug("default virtd network not found. Creating.") net.virsh_define_default() # The default virsh profile create a virbr0 interface # with a 192.168.122.1 ip address. Also sets up iptables # for NAT access. net.virsh_start("default") # Create the IP pool mgmt_network_hosts = network.hosts() # Remove the management interface ip from the pool self._mgmt_ip_pool = list(mgmt_network_hosts) self._mgmt_ip_pool.remove(MGMT_NETWORK_INTERFACE_IP.ip)
def create_vm(self, image, index): """Returns a VM Arguments: image - the image used to create the VM index - an index used to label the VM Returns: A VM object """ vm = RwcalYang.VMInfoItem() vm.vm_name = 'rift-s{}'.format(index + 1) vm.image_id = image.id vm.user_tags.node_id = str(uuid.uuid4()) user_data_template_str = open( os.path.join( os.environ['RIFT_INSTALL'], 'etc/userdata-template', )).read() # Get the interface ip address of the mgmt network # This is where the salt master is accessible on mgmt_interface_ip = "192.168.122.1" # Create salt-stack userdata vm.cloud_init.userdata = user_data_template_str.format( master_ip=mgmt_interface_ip, lxcname=vm.user_tags.node_id, ) rc, vm.vm_id = self.cal.create_vm(self.account, vm) return vm
def _parse_virtual_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.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList_VirtualConnectionPoints() """ cp = RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList_VirtualConnectionPoints() if 'id' in cp_info and cp_info['id']: cp.connection_point_id = cp_info['id'] if 'name' in cp_info and cp_info['name']: cp.name = cp_info['name'] 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_address = cp_info['mac_address'] return cp
def _fill_flavor_info(flavor_info): flavor = RwcalYang.YangData_RwProject_Project_VimResources_FlavorinfoList( ) flavor.name = flavor_info['name'] flavor.id = flavor_info['id'] RwcalOpenmanoVimConnector._fill_epa_attributes(flavor, flavor_info) return flavor
def prepare_virtual_link(self, link_params, network_id): """ Function to create additional resources in the network during network-creation process. It involves following steps - Create subnets - Create any virtual ports in network Arguments: link_params: Protobuf GI object RwcalYang.YangData_RwProject_Project_VirtualLinkReqParams() network_id: string Returns: None """ ### Create subnet kwargs = self.make_subnet_args(link_params, network_id) self.driver.neutron_subnet_create(**kwargs) ### Create Virtual connection point if link_params.has_field('virtual_cps'): port_args = list() for vcp in link_params.virtual_cps: cp = RwcalYang.YangData_RwProject_Project_VduInitParams_ConnectionPoints() cp.from_dict({k:v for k,v in vcp.as_dict().items() if k in ['name','security_group', 'port_security_enabled', 'static_ip_address', 'type_yang']}) cp.virtual_link_id = network_id port_args.append(self._create_cp_args(cp.as_dict())) if port_args: ### Create ports self.driver.neutron_multi_port_create(port_args) return
def do_get_port_list(self, account): """Returns a list of ports""" resources = RwcalYang.VimResources() for port in self.datastore.cal_manager.get_port_list(): resources.portinfo_list.append(rwcal_copy_object(port)) return resources
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.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList() """ link = RwcalYang.YangData_RwProject_Project_VnfResources_VirtualLinkInfoList() 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'] in ['compute:nova', 'compute:None']): link.connection_points.append(self._parse_cp(port)) if ('device_owner' in port) and (port['device_owner'] == ''): link.virtual_connection_points.append(self._parse_virtual_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 start(self): super(ContainerManager, self).start() self.log.info("Starting ContainerManager") self.log.setLevel(logging.DEBUG) ResourceProvisioning.log_hdl = self.log_hdl self.log.debug("Registering with dts") self._dts = rift.tasklets.DTS( self.tasklet_info, RwcalYang.get_schema(), self.loop, self.on_dts_state_change ) self.log.debug("Created DTS Api GI Object: %s", self._dts)