-#
+#
# Copyright 2016 RIFT.IO Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
import rift.cal.rwcal_status as rwcal_status
import rwlogger
import neutronclient.common.exceptions as NeutronException
+import keystoneclient.exceptions as KeystoneExceptions
from gi.repository import (
GObject,
tenant_name = account.openstack.tenant,
mgmt_network = account.openstack.mgmt_network,
cert_validate = account.openstack.cert_validate )
+ 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"
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]
except Exception as e:
self.log.error("Encountered exceptions during network creation. Exception: %s", str(e))
raise
-
+
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:
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'] = subnet_pool['id']
elif link_params.has_field('subnet'):
kwargs['cidr'] = link_params.subnet
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)
+ 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
-
+
drv.neutron_subnet_create(**kwargs)
-
+
return network_id
kwargs['network_id'] = c_point.virtual_link_id
kwargs['admin_state_up'] = True
- if c_point.type_yang == 'VIRTIO':
+ if c_point.type_yang == 'VIRTIO' or c_point.type_yang == 'E1000':
kwargs['port_type'] = 'normal'
elif c_point.type_yang == 'SR_IOV':
kwargs['port_type'] = 'direct'
else:
- raise NotImplementedError("Port Type: %s not supported" %(c_point.port_type))
+ raise NotImplementedError("Port Type: %s not supported" %(c_point.type_yang))
with self._use_driver(account) as drv:
if c_point.has_field('security_group'):
elif available.has_field('pcie_device'):
self.log.debug("Rejecting available flavor because pcie_device not required but available")
return False
-
-
+
+
if required.has_field('mempage_size'):
self.log.debug("Matching mempage_size")
if available.has_field('mempage_size') == False:
elif available.has_field('mempage_size'):
self.log.debug("Rejecting available flavor because mempage_size not required but available")
return False
-
+
if required.has_field('cpu_pinning_policy'):
self.log.debug("Matching cpu_pinning_policy")
if required.cpu_pinning_policy != 'ANY':
elif available.has_field('cpu_pinning_policy'):
self.log.debug("Rejecting available flavor because cpu_pinning_policy not required but available")
return False
-
+
if required.has_field('cpu_thread_pinning_policy'):
self.log.debug("Matching cpu_thread_pinning_policy")
if available.has_field('cpu_thread_pinning_policy') == False:
elif available.has_field('trusted_execution'):
self.log.debug("Rejecting available flavor because trusted_execution not required but available")
return False
-
+
if required.has_field('numa_node_policy'):
self.log.debug("Matching numa_node_policy")
if available.has_field('numa_node_policy') == False:
elif available.numa_node_policy.has_field('node_cnt'):
self.log.debug("Rejecting available flavor because numa node count not required but available")
return False
-
+
if required.numa_node_policy.has_field('mem_policy'):
self.log.debug("Matching numa_node_policy mem_policy")
if available.numa_node_policy.has_field('mem_policy') == False:
elif available.has_field('cpu_model'):
self.log.debug("Rejecting available flavor because cpu_model not required but available")
return False
-
+
if required.has_field('cpu_arch'):
self.log.debug("Matching CPU architecture")
if available.has_field('cpu_arch') == False:
elif available.has_field('cpu_arch'):
self.log.debug("Rejecting available flavor because cpu_arch not required but available")
return False
-
+
if required.has_field('cpu_vendor'):
self.log.debug("Matching CPU vendor")
if available.has_field('cpu_vendor') == False:
elif available.has_field('cpu_socket_count'):
self.log.debug("Rejecting available flavor because cpu_socket_count not required but available")
return False
-
+
if required.has_field('cpu_core_count'):
self.log.debug("Matching CPU core count")
if available.has_field('cpu_core_count') == False:
elif available.has_field('cpu_core_count'):
self.log.debug("Rejecting available flavor because cpu_core_count not required but available")
return False
-
+
if required.has_field('cpu_core_thread_count'):
self.log.debug("Matching CPU core thread count")
if available.has_field('cpu_core_thread_count') == False:
elif available.has_field('cpu_core_thread_count'):
self.log.debug("Rejecting available flavor because cpu_core_thread_count not required but available")
return False
-
+
if required.has_field('cpu_feature'):
self.log.debug("Matching CPU feature list")
if available.has_field('cpu_feature') == False:
elif available.has_field('cpu_feature'):
self.log.debug("Rejecting available flavor because cpu_feature not required but available")
return False
- self.log.info("Successful match for Host EPA attributes")
+ self.log.info("Successful match for Host EPA attributes")
return True
def _match_placement_group_inputs(self, required, available):
self.log.info("Matching Host aggregate attributes")
-
+
if not required and not available:
# Host aggregate not required and not available => success
self.log.info("Successful match for Host Aggregate attributes")
# - Host aggregate not required but available
self.log.debug("Rejecting available flavor because host Aggregate mismatch. Required: %s, Available: %s ", required, available)
return False
-
+
def match_epa_params(self, resource_info, request_params):
result = self._match_vm_flavor(getattr(request_params, 'vm_flavor'),
getattr(resource_info, 'vm_flavor'))
if result == False:
self.log.debug("Host Aggregate mismatched")
return False
-
+
return True
def _select_resource_flavor(self, account, vdu_init):
- """
+ """
Select a existing flavor if it matches the request or create new flavor
"""
flavor = RwcalYang.FlavorInfoItem()
epa_types = ['vm_flavor', 'guest_epa', 'host_epa', 'host_aggregate', 'hypervisor_epa', 'vswitch_epa']
epa_dict = {k: v for k, v in vdu_init.as_dict().items() if k in epa_types}
flavor.from_dict(epa_dict)
-
+
rc, response = self.do_get_flavor_list(account)
if rc != RwTypes.RwStatus.SUCCESS:
self.log.error("Get-flavor-info-list operation failed for cloud account: %s",
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."
+
+ with self._use_driver(account) as drv:
+ img_info = drv.glance_image_get(vdu_init.image_id)
+
+ 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':
+ 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)
+ 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)
+
with self._use_driver(account) as drv:
### Now Create VM
vm = RwcalYang.VMInfoItem()