import os
import subprocess
import uuid
+import tempfile
+import yaml
import rift.rwcal.openstack as openstack_drv
import rw_status
import rift.cal.rwcal_status as rwcal_status
import rwlogger
import neutronclient.common.exceptions as NeutronException
+import keystoneclient.exceptions as KeystoneExceptions
+import tornado
+import gi
+
+gi.require_version('RwSdn', '1.0')
from gi.repository import (
GObject,
RwTypes,
RwcalYang)
-PREPARE_VM_CMD = "prepare_vm.py --auth_url {auth_url} --username {username} --password {password} --tenant_name {tenant_name} --mgmt_network {mgmt_network} --server_id {server_id} --port_metadata"
+PREPARE_VM_CMD = "prepare_vm.py --auth_url {auth_url} --username {username} --password {password} --tenant_name {tenant_name} --region {region} --user_domain {user_domain} --project_domain {project_domain} --mgmt_network {mgmt_network} --server_id {server_id} --port_metadata "
rwstatus_exception_map = { IndexError: RwTypes.RwStatus.NOTFOUND,
KeyError: RwTypes.RwStatus.NOTFOUND,
self._rwlog_handler = None
RwcalOpenstackPlugin.instance_num += 1
-
@contextlib.contextmanager
def _use_driver(self, account):
if self._rwlog_handler is None:
with rwlogger.rwlog_root_handler(self._rwlog_handler):
try:
- drv = self._driver_class(username = account.openstack.key,
- password = account.openstack.secret,
- auth_url = account.openstack.auth_url,
- tenant_name = account.openstack.tenant,
- mgmt_network = account.openstack.mgmt_network,
- cert_validate = account.openstack.cert_validate )
+ drv = self._driver_class(username = account.openstack.key,
+ password = account.openstack.secret,
+ auth_url = account.openstack.auth_url,
+ tenant_name = account.openstack.tenant,
+ mgmt_network = account.openstack.mgmt_network,
+ cert_validate = account.openstack.cert_validate,
+ user_domain_name = account.openstack.user_domain,
+ project_domain_name = account.openstack.project_domain,
+ region = account.openstack.region)
+ except (KeystoneExceptions.Unauthorized, KeystoneExceptions.AuthorizationFailure,
+ NeutronException.NotFound) as e:
+ raise
except Exception as e:
self.log.error("RwcalOpenstackPlugin: OpenstackDriver init failed. Exception: %s" %(str(e)))
raise
Validation Code and Details String
"""
status = RwcalYang.CloudConnectionStatus()
-
try:
with self._use_driver(account) as drv:
drv.validate_account_creds()
+ except KeystoneExceptions.Unauthorized as e:
+ self.log.error("Invalid credentials given for VIM account %s" %account.name)
+ status.status = "failure"
+ status.details = "Invalid Credentials: %s" % str(e)
+
+ except KeystoneExceptions.AuthorizationFailure as e:
+ self.log.error("Bad authentication URL given for VIM account %s. Given auth url: %s" % (
+ account.name, account.openstack.auth_url))
+ status.status = "failure"
+ status.details = "Invalid auth url: %s" % str(e)
+
+ except NeutronException.NotFound as e:
+ self.log.error("Given management network %s could not be found for VIM account %s" % (
+ account.openstack.mgmt_network, account.name))
+ status.status = "failure"
+ status.details = "mgmt network does not exist: %s" % str(e)
+
except openstack_drv.ValidationError as e:
self.log.error("RwcalOpenstackPlugin: OpenstackDriver credential validation failed. Exception: %s", str(e))
status.status = "failure"
image = drv.glance_image_get(image_id)
return RwcalOpenstackPlugin._fill_image_info(image)
+ # This is being deprecated. Please do not use for new SW development
@rwstatus(ret_on_failure=[""])
def do_create_vm(self, account, vminfo):
"""Create a new virtual machine.
kwargs = {}
kwargs['name'] = vminfo.vm_name
kwargs['flavor_id'] = vminfo.flavor_id
- kwargs['image_id'] = vminfo.image_id
+ if vminfo.has_field('image_id'):
+ kwargs['image_id'] = vminfo.image_id
with self._use_driver(account) as drv:
### If floating_ip is required and we don't have one, better fail before any further allocation
+ pool_name = None
+ floating_ip = False
if vminfo.has_field('allocate_public_address') and vminfo.allocate_public_address:
if account.openstack.has_field('floating_ip_pool'):
pool_name = account.openstack.floating_ip_pool
- else:
- pool_name = None
- floating_ip = self._allocate_floating_ip(drv, pool_name)
- else:
- floating_ip = None
+ floating_ip = True
if vminfo.has_field('cloud_init') and vminfo.cloud_init.has_field('userdata'):
kwargs['userdata'] = vminfo.cloud_init.userdata
if guest_epa.numa_node_policy.has_field('node'):
for node in guest_epa.numa_node_policy.node:
if node.has_field('vcpu') and node.vcpu:
- epa_specs['hw:numa_cpus.'+str(node.id)] = ','.join([str(j) for j in node.vcpu])
+ epa_specs['hw:numa_cpus.'+str(node.id)] = ','.join([str(j.id) for j in node.vcpu])
if node.memory_mb:
epa_specs['hw:numa_mem.'+str(node.id)] = str(node.memory_mb)
cpu_features = []
espec_cpu_features = []
for feature in host_epa.cpu_feature:
- cpu_features.append(feature)
+ cpu_features.append(feature.feature)
espec_cpu_features = espec_utils.host.mano_to_extra_spec_cpu_features(cpu_features)
if espec_cpu_features is not None:
epa_specs['capabilities:cpu_info:features'] = espec_cpu_features
numa_node = getattr(flavor,'guest_epa').numa_node_policy.node.add()
numa_node.id = int(node_id)
- numa_node.vcpu = [ int(x) for x in flavor_info['extra_specs'][attr].split(',') ]
+ for x in flavor_info['extra_specs'][attr].split(','):
+ numa_node_vcpu = numa_node.vcpu.add()
+ numa_node_vcpu.id = int(x)
elif attr.startswith('hw:numa_mem.'):
node_id = attr.split('.')[1]
if ('fixed_ips' in port_info) and (len(port_info['fixed_ips']) >= 1):
if 'ip_address' in port_info['fixed_ips'][0]:
c_point.ip_address = port_info['fixed_ips'][0]['ip_address']
+ if 'mac_address' in port_info :
+ c_point.mac_addr = port_info['mac_address']
if port_info['status'] == 'ACTIVE':
c_point.state = 'active'
else:
return link
@staticmethod
- def _fill_vdu_info(vm_info, flavor_info, mgmt_network, port_list, server_group):
+ def _fill_vdu_info(drv, vm_info, flavor_info, mgmt_network, port_list, server_group, volume_list = None):
"""Create a GI object for VDUInfoParams
Converts VM information dictionary object returned by openstack
vdu.public_ip = interface['addr']
# Look for any metadata
- for key, value in vm_info['metadata'].items():
- if key == 'node_id':
- vdu.node_id = value
+# for key, value in vm_info['metadata'].items():
+# if key == 'node_id':
+# vdu.node_id = value
+# else:
+# custommetadata = vdu.supplemental_boot_data.custom_meta_data.add()
+# custommetadata.name = key
+# custommetadata.value = str(value)
+
+ # Look for config_drive
+ if ('config_drive' in vm_info):
+ vdu.supplemental_boot_data.boot_data_drive = vm_info['config_drive']
if ('image' in vm_info) and ('id' in vm_info['image']):
vdu.image_id = vm_info['image']['id']
if ('flavor' in vm_info) and ('id' in vm_info['flavor']):
if flavor_info is not None:
RwcalOpenstackPlugin._fill_epa_attributes(vdu, flavor_info)
+
+ # Fill the volume information
+ if volume_list is not None:
+ for os_volume in volume_list:
+ volr = vdu.volumes.add()
+ try:
+ " Device name is of format /dev/vda"
+ vol_name = (os_volume['device']).split('/')[2]
+ except:
+ continue
+ volr.name = vol_name
+ volr.volume_id = os_volume['volumeId']
+ try:
+ vol_details = drv.cinder_volume_get(volr.volume_id)
+ except:
+ continue
+ if vol_details is None:
+ continue
+ for key, value in vol_details.metadata.items():
+ volmd = volr.custom_meta_data.add()
+ volmd.name = key
+ volmd.value = value
+
return vdu
@rwcalstatus(ret_on_failure=[""])
else:
raise NotImplementedError("Port Type: %s not supported" %(c_point.type_yang))
+ # By default port gets created with post_security enaled as True
+ if 'port_security_enabled' in c_point:
+ kwargs['port_security_enabled'] = c_point.port_security_enabled
+
with self._use_driver(account) as drv:
if c_point.has_field('security_group'):
group = drv.neutron_security_group_by_name(c_point.security_group)
raise OpenstackCALOperationFailure("Create-flavor operation failed for cloud account: %s" %(account.name))
return flavor_id
+ def _create_vm(self, account, vduinfo, pci_assignement=None, server_group=None, port_list=None, network_list=None, imageinfo_list=None):
+ """Create a new virtual machine.
+
+ Arguments:
+ account - a cloud account
+ vminfo - information that defines the type of VM to create
+
+ Returns:
+ The image id
+ """
+ kwargs = {}
+ kwargs['name'] = vduinfo.name
+ kwargs['flavor_id'] = vduinfo.flavor_id
+ if vduinfo.has_field('image_id'):
+ kwargs['image_id'] = vduinfo.image_id
+ else:
+ kwargs['image_id'] = ""
+
+ with self._use_driver(account) as drv:
+ ### If floating_ip is required and we don't have one, better fail before any further allocation
+ floating_ip = False
+ pool_name = None
+ if vduinfo.has_field('allocate_public_address') and vduinfo.allocate_public_address:
+ if account.openstack.has_field('floating_ip_pool'):
+ pool_name = account.openstack.floating_ip_pool
+ floating_ip = True
+
+ if vduinfo.has_field('vdu_init') and vduinfo.vdu_init.has_field('userdata'):
+ kwargs['userdata'] = vduinfo.vdu_init.userdata
+ else:
+ kwargs['userdata'] = ''
+
+ if account.openstack.security_groups:
+ kwargs['security_groups'] = account.openstack.security_groups
+
+ kwargs['port_list'] = port_list
+ kwargs['network_list'] = network_list
+
+ metadata = {}
+ files = {}
+ config_drive = False
+ # Add all metadata related fields
+ if vduinfo.has_field('node_id'):
+ metadata['node_id'] = vduinfo.node_id
+ if pci_assignement is not None:
+ metadata['pci_assignement'] = pci_assignement
+ if vduinfo.has_field('supplemental_boot_data'):
+ if vduinfo.supplemental_boot_data.has_field('custom_meta_data'):
+ for custom_meta_item in vduinfo.supplemental_boot_data.custom_meta_data:
+ if custom_meta_item.data_type == "STRING":
+ metadata[custom_meta_item.name] = custom_meta_item.value
+ elif custom_meta_item.data_type == "JSON":
+ metadata[custom_meta_item.name] = tornado.escape.json_decode(custom_meta_item.value)
+ else:
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Unsupported data-type {} for custom-meta-data name {} ".format(custom_meta_item.data_type, custom_meta_item.name))
+ if vduinfo.supplemental_boot_data.has_field('config_file'):
+ for custom_config_file in vduinfo.supplemental_boot_data.config_file:
+ files[custom_config_file.dest] = custom_config_file.source
+
+ if vduinfo.supplemental_boot_data.has_field('boot_data_drive'):
+ if vduinfo.supplemental_boot_data.boot_data_drive is True:
+ config_drive = True
+
+ kwargs['metadata'] = metadata
+ kwargs['files'] = files
+ kwargs['config_drive'] = config_drive
+
+ if vduinfo.has_field('availability_zone') and vduinfo.availability_zone.has_field('name'):
+ kwargs['availability_zone'] = vduinfo.availability_zone
+ else:
+ kwargs['availability_zone'] = None
+
+ if server_group is not None:
+ kwargs['scheduler_hints'] = {'group': server_group}
+ else:
+ kwargs['scheduler_hints'] = None
+
+ kwargs['block_device_mapping_v2'] = None
+ vol_metadata = False
+ if vduinfo.has_field('volumes') :
+ kwargs['block_device_mapping_v2'] = []
+ with self._use_driver(account) as drv:
+ # Only support image->volume
+ for volume in vduinfo.volumes:
+ block_map = dict()
+ block_map['boot_index'] = volume.boot_priority
+ if "image" in volume:
+ # Support image->volume
+ # Match retrived image info with volume based image name and checksum
+ if volume.image is not None:
+ matching_images = [img for img in imageinfo_list if img['name'] == volume.image]
+ if volume.image_checksum is not None:
+ matching_images = [img for img in matching_images if img['checksum'] == volume.image_checksum]
+ img_id = matching_images[0]['id']
+ if img_id is None:
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Volume image not found for name {} checksum {}".format(volume.name, volume.checksum))
+ block_map['uuid'] = img_id
+ block_map['source_type'] = "image"
+ else:
+ block_map['source_type'] = "blank"
+
+ block_map['device_name'] = volume.name
+ block_map['destination_type'] = "volume"
+ block_map['volume_size'] = volume.size
+ block_map['delete_on_termination'] = True
+ if volume.has_field('device_type') and volume.device_type == 'cdrom':
+ block_map['device_type'] = 'cdrom'
+ if volume.has_field('device_bus') and volume.device_bus == 'ide':
+ block_map['disk_bus'] = 'ide'
+ kwargs['block_device_mapping_v2'].append(block_map)
+
+
+ with self._use_driver(account) as drv:
+ vm_id = drv.nova_server_create(**kwargs)
+ if floating_ip:
+ self.prepare_vdu_on_boot(account, vm_id, floating_ip, pool_name, vduinfo.volumes)
+
+ return vm_id
+
+ def get_openstack_image_info(self, account, image_name, image_checksum=None):
+ self.log.debug("Looking up image id for image name %s and checksum %s on cloud account: %s",
+ image_name, image_checksum, account.name
+ )
+
+ image_list = []
+ with self._use_driver(account) as drv:
+ image_list = drv.glance_image_list()
+ matching_images = [img for img in image_list if img['name'] == image_name]
+
+ # If the image checksum was filled in then further filter the images by the checksum
+ if image_checksum is not None:
+ matching_images = [img for img in matching_images if img['checksum'] == image_checksum]
+ else:
+ self.log.warning("Image checksum not provided. Lookup using image name (%s) only.",
+ image_name)
+
+ if len(matching_images) == 0:
+ raise ResMgrCALOperationFailure("Could not find image name {} (using checksum: {}) for cloud account: {}".format(
+ image_name, image_checksum, account.name
+ ))
+
+ elif len(matching_images) > 1:
+ unique_checksums = {i.checksum for i in matching_images}
+ if len(unique_checksums) > 1:
+ msg = ("Too many images with different checksums matched "
+ "image name of %s for cloud account: %s" % (image_name, account.name))
+ raise ResMgrCALOperationFailure(msg)
+
+ return matching_images[0]
+
@rwcalstatus(ret_on_failure=[""])
def do_create_vdu(self, account, vdu_init):
"""Create a new virtual deployment unit
The vdu_id
"""
### First create required number of ports aka connection points
+ # Add the mgmt_ntwk by default.
+ mgmt_network_id = None
with self._use_driver(account) as drv:
- ### If floating_ip is required and we don't have one, better fail before any further allocation
- if vdu_init.has_field('allocate_public_address') and vdu_init.allocate_public_address:
- if account.openstack.has_field('floating_ip_pool'):
- pool_name = account.openstack.floating_ip_pool
- else:
- pool_name = None
- floating_ip = self._allocate_floating_ip(drv, pool_name)
- else:
- floating_ip = None
+ mgmt_network_id = drv._mgmt_network_id
port_list = []
network_list = []
+ imageinfo_list = []
+ is_explicit_mgmt_defined = False
for c_point in vdu_init.connection_points:
+ # if the user has specified explicit mgmt_network connection point
+ # then remove the mgmt_network from the VM list
+ if c_point.virtual_link_id == mgmt_network_id:
+ is_explicit_mgmt_defined = True
if c_point.virtual_link_id in network_list:
assert False, "Only one port per network supported. Refer: http://specs.openstack.org/openstack/nova-specs/specs/juno/implemented/nfv-multiple-if-1-net.html"
else:
if not vdu_init.has_field('flavor_id'):
vdu_init.flavor_id = self._select_resource_flavor(account,vdu_init)
- ### Check VDU Virtual Interface type and make sure VM with property exists
- if vdu_init.connection_points is not None:
- ### All virtual interfaces need to be of the same type for Openstack Accounts
- if not all(cp.type_yang == vdu_init.connection_points[0].type_yang for cp in vdu_init.connection_points):
- ### We have a mix of E1000 & VIRTIO virtual interface types in the VDU, abort instantiation.
- assert False, "Only one type of Virtual Intefaces supported for Openstack accounts. Found a mix of VIRTIO & E1000."
+ ### Obtain all images for volumes and perform validations
+ if vdu_init.has_field('volumes'):
+ for volume in vdu_init.volumes:
+ if "image" in volume:
+ image_checksum = volume.image_checksum if volume.has_field("image_checksum") else None
+ image_info = self.get_openstack_image_info(account, volume.image, image_checksum)
+ imageinfo_list.append(image_info)
+ elif vdu_init.has_field('image_id'):
+ with self._use_driver(account) as drv:
+ image_info = drv.glance_image_get(vdu_init.image_id)
+ imageinfo_list.append(image_info)
- with self._use_driver(account) as drv:
- img_info = drv.glance_image_get(vdu_init.image_id)
+ if not imageinfo_list:
+ err_str = ("VDU has no image information")
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
- virt_intf_type = vdu_init.connection_points[0].type_yang
- if virt_intf_type == 'E1000':
- if 'hw_vif_model' in img_info and img_info.hw_vif_model == 'e1000':
- self.log.debug("VDU has Virtual Interface E1000, found matching image with property hw_vif_model=e1000")
+ ### Check VDU Virtual Interface type and make sure VM with property exists
+ if vdu_init.connection_points:
+ ### All virtual interfaces need to be of the same type for Openstack Accounts
+ if not (all(cp.type_yang == 'E1000' for cp in vdu_init.connection_points) or all(cp.type_yang != 'E1000' for cp in vdu_init.connection_points)):
+ ### We have a mix of E1000 & VIRTIO/SR_IPOV virtual interface types in the VDU, abort instantiation.
+ assert False, "Only one type of Virtual Intefaces supported for Openstack accounts. Found a mix of VIRTIO/SR_IOV & E1000."
+
+ ## It is not clear if all the images need to checked for HW properties. In the absence of model info describing each im age's properties,
+ ### we shall assume that all images need to have similar properties
+ for img_info in imageinfo_list:
+
+ virt_intf_type = vdu_init.connection_points[0].type_yang
+ if virt_intf_type == 'E1000':
+ if 'hw_vif_model' in img_info and img_info.hw_vif_model == 'e1000':
+ self.log.debug("VDU has Virtual Interface E1000, found matching image with property hw_vif_model=e1000")
+ else:
+ err_str = ("VDU has Virtual Interface E1000, but image '%s' does not have property hw_vif_model=e1000" % img_info.name)
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+ elif virt_intf_type == 'VIRTIO' or virt_intf_type == 'SR_IOV':
+ if 'hw_vif_model' in img_info:
+ err_str = ("VDU has Virtual Interface %s, but image '%s' has hw_vif_model mismatch" % virt_intf_type,img_info.name)
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+ else:
+ self.log.debug("VDU has Virtual Interface %s, found matching image" % virt_intf_type)
else:
- err_str = ("VDU has Virtual Interface E1000, but image '%s' does not have property hw_vif_model=e1000" % img_info.name)
- self.log.error(err_str)
- raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
- elif virt_intf_type == 'VIRTIO':
- if 'hw_vif_model' in img_info:
- err_str = ("VDU has Virtual Interface VIRTIO, but image '%s' has hw_vif_model mismatch" % img_info.name)
+ err_str = ("VDU Virtual Interface '%s' not supported yet" % virt_intf_type)
self.log.error(err_str)
- raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
- else:
- self.log.debug("VDU has Virtual Interface VIRTIO, found matching image")
- else:
- err_str = ("VDU Virtual Interface '%s' not supported yet" % virt_intf_type)
- self.log.error(err_str)
- raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
with self._use_driver(account) as drv:
### Now Create VM
- vm = RwcalYang.VMInfoItem()
- vm.vm_name = vdu_init.name
- vm.flavor_id = vdu_init.flavor_id
- vm.image_id = vdu_init.image_id
- vm_network = vm.network_list.add()
- vm_network.network_id = drv._mgmt_network_id
- if vdu_init.has_field('vdu_init') and vdu_init.vdu_init.has_field('userdata'):
- vm.cloud_init.userdata = vdu_init.vdu_init.userdata
-
- if vdu_init.has_field('node_id'):
- vm.user_tags.node_id = vdu_init.node_id;
-
- if vdu_init.has_field('availability_zone') and vdu_init.availability_zone.has_field('name'):
- vm.availability_zone = vdu_init.availability_zone.name
-
+ vm_network_list = []
+ if not is_explicit_mgmt_defined:
+ vm_network_list.append(drv._mgmt_network_id)
+
+ if vdu_init.has_field('volumes'):
+ # Only combination supported: Image->Volume
+ for volume in vdu_init.volumes:
+ if "volume" in volume:
+ err_str = ("VDU Volume source not supported yet")
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+ if not volume.has_field('device_type'):
+ err_str = ("VDU Volume destination type not defined")
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+ if volume.device_type not in ['disk', 'cdrom'] :
+ err_str = ("VDU Volume destination type '%s' not supported" % volume.device_type)
+ self.log.error(err_str)
+ raise OpenstackCALOperationFailure("Create-vdu operation failed. Error- %s" % err_str)
+
+
+ server_group = None
if vdu_init.has_field('server_group'):
- ### Get list of server group in openstack for name->id mapping
- openstack_group_list = drv.nova_server_group_list()
- group_id = [ i['id'] for i in openstack_group_list if i['name'] == vdu_init.server_group.name]
- if len(group_id) != 1:
- raise OpenstackServerGroupError("VM placement failed. Server Group %s not found in openstack. Available groups" %(vdu_init.server_group.name, [i['name'] for i in openstack_group_list]))
- vm.server_group = group_id[0]
-
- for port_id in port_list:
- port = vm.port_list.add()
- port.port_id = port_id
+ ### Get list of server group in openstack for name->id mapping
+ openstack_group_list = drv.nova_server_group_list()
+ group_id = [ i['id'] for i in openstack_group_list if i['name'] == vdu_init.server_group.name]
+ if len(group_id) != 1:
+ raise OpenstackServerGroupError("VM placement failed. Server Group %s not found in openstack. Available groups" %(vdu_init.server_group.name, [i['name'] for i in openstack_group_list]))
+ server_group = group_id[0]
pci_assignement = self.prepare_vpci_metadata(drv, vdu_init)
if pci_assignement != '':
vm.user_tags.pci_assignement = pci_assignement
- vm_id = self.do_create_vm(account, vm, no_rwstatus=True)
- self.prepare_vdu_on_boot(account, vm_id, floating_ip)
+ vm_id = self._create_vm(account, vdu_init, pci_assignement=pci_assignement, server_group=server_group, port_list=port_list, network_list=vm_network_list, imageinfo_list = imageinfo_list)
return vm_id
def prepare_vpci_metadata(self, drv, vdu_init):
- def prepare_vdu_on_boot(self, account, server_id, floating_ip):
- cmd = PREPARE_VM_CMD.format(auth_url = account.openstack.auth_url,
- username = account.openstack.key,
- password = account.openstack.secret,
- tenant_name = account.openstack.tenant,
- mgmt_network = account.openstack.mgmt_network,
- server_id = server_id)
-
- if floating_ip is not None:
- cmd += (" --floating_ip "+ floating_ip.ip)
+ def prepare_vdu_on_boot(self, account, server_id, floating_ip, pool_name, volumes=None):
+ cmd = PREPARE_VM_CMD.format(auth_url = account.openstack.auth_url,
+ username = account.openstack.key,
+ password = account.openstack.secret,
+ tenant_name = account.openstack.tenant,
+ region = account.openstack.region,
+ user_domain = account.openstack.user_domain,
+ project_domain = account.openstack.project_domain,
+ mgmt_network = account.openstack.mgmt_network,
+ server_id = server_id)
+ if floating_ip:
+ cmd += " --floating_ip"
+ if pool_name:
+ cmd += (" --pool_name " + pool_name)
+
+ vol_metadata = False
+ if volumes is not None:
+ for volume in volumes:
+ if volume.has_field('custom_meta_data'):
+ vol_metadata = True
+ break
+
+ if vol_metadata is True:
+ tmp_file = None
+ with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
+ vol_list = list()
+ for volume in volumes:
+ vol_dict = volume.as_dict()
+ vol_list.append(vol_dict)
+
+ yaml.dump(vol_list, tmp_file)
+ cmd += (" --vol_metadata {}").format(tmp_file.name)
exec_path = 'python3 ' + os.path.dirname(openstack_drv.__file__)
exec_cmd = exec_path+'/'+cmd
Object of type RwcalYang.VDUInfoParams
"""
with self._use_driver(account) as drv:
-
- ### Get list of ports excluding the one for management network
- port_list = [p for p in drv.neutron_port_list(**{'device_id': vdu_id}) if p['network_id'] != drv.get_mgmt_network_id()]
+ port_list = drv.neutron_port_list(**{'device_id': vdu_id})
vm = drv.nova_server_get(vdu_id)
openstack_group_list = drv.nova_server_group_list()
server_group = [ i['name'] for i in openstack_group_list if vm['id'] in i['members']]
- vdu_info = RwcalOpenstackPlugin._fill_vdu_info(vm,
+ openstack_srv_volume_list = drv.nova_volume_list(vm['id'])
+ vdu_info = RwcalOpenstackPlugin._fill_vdu_info(drv, vm,
flavor_info,
account.openstack.mgmt_network,
port_list,
- server_group)
+ server_group,
+ volume_list = openstack_srv_volume_list)
if vdu_info.state == 'active':
try:
console_info = drv.nova_server_console(vdu_info.vdu_id)
with self._use_driver(account) as drv:
vms = drv.nova_server_list()
for vm in vms:
- ### Get list of ports excluding one for management network
- port_list = [p for p in drv.neutron_port_list(**{'device_id': vm['id']}) if p['network_id'] != drv.get_mgmt_network_id()]
+ port_list = drv.neutron_port_list(**{'device_id': vm['id']})
flavor_info = None
openstack_group_list = drv.nova_server_group_list()
server_group = [ i['name'] for i in openstack_group_list if vm['id'] in i['members']]
- vdu = RwcalOpenstackPlugin._fill_vdu_info(vm,
+ openstack_srv_volume_list = drv.nova_volume_list(vm['id'])
+ vdu = RwcalOpenstackPlugin._fill_vdu_info(drv, vm,
flavor_info,
account.openstack.mgmt_network,
port_list,
- server_group)
+ server_group,
+ volume_list = openstack_srv_volume_list)
if vdu.state == 'active':
try:
console_info = drv.nova_server_console(vdu.vdu_id)