logger.info(
'Found existing machine with name - %s',
self.instance_settings.name)
- fips = self.__nova.floating_ips.list()
+ fips = neutron_utils.get_floating_ips(self.__neutron)
for fip in fips:
- if fip.instance_id == server.id:
- self.__floating_ips.append(fip)
- # TODO - Determine a means to associate to the FIP
- # configuration and add to FIP map
+ for subnet_name, ips in server.networks.items():
+ if fip.ip in ips:
+ self.__floating_ips.append(fip)
+ # TODO - Determine a means to associate to the FIP
+ # configuration and add to FIP map
def __create_vm(self, block=False):
"""
active, error, or timeout waiting. Floating IPs will be
assigned after active when block=True
"""
- nics = []
- for key, port in self.__ports:
- kv = dict()
- kv['port-id'] = port['port']['id']
- nics.append(kv)
-
- logger.info('Creating VM with name - ' + self.instance_settings.name)
- keypair_name = None
- if self.keypair_settings:
- keypair_name = self.keypair_settings.name
-
- flavor = nova_utils.get_flavor_by_name(self.__nova,
- self.instance_settings.flavor)
- if not flavor:
- raise Exception(
- 'Flavor not found with name - %s',
- self.instance_settings.flavor)
-
- image = glance_utils.get_image(
- glance_utils.glance_client(self.__os_creds),
- self.image_settings.name)
- if image:
- self.__vm = self.__nova.servers.create(
- name=self.instance_settings.name,
- flavor=flavor,
- image=image,
- nics=nics,
- key_name=keypair_name,
- security_groups=self.instance_settings.security_group_names,
- userdata=self.instance_settings.userdata,
- availability_zone=self.instance_settings.availability_zone)
-
- else:
- raise Exception(
- 'Cannot create instance, image cannot be located with name %s',
- self.image_settings.name)
-
- logger.info(
- 'Created instance with name - %s', self.instance_settings.name)
+ glance = glance_utils.glance_client(self.__os_creds)
+ self.__vm = nova_utils.create_server(
+ self.__nova, self.__neutron, glance, self.instance_settings,
+ self.image_settings, self.keypair_settings)
+ logger.info('Created instance with name - %s',
+ self.instance_settings.name)
if block:
if not self.vm_active(block=True):
- raise Exception(
+ raise VmInstanceCreationError(
'Fatal error, VM did not become ACTIVE within the alloted '
'time')
- # TODO - the call above should add security groups. The return object
- # shows they exist but the association had never been made by
- # OpenStack. This call is here to ensure they have been added
+ # Create server should do this but found it needed to occur here
for sec_grp_name in self.instance_settings.security_group_names:
if self.vm_active(block=True):
nova_utils.add_security_group(self.__nova, self.__vm,
sec_grp_name)
else:
- raise Exception(
+ raise VmInstanceCreationError(
'Cannot applying security group with name ' +
sec_grp_name +
' to VM that did not activate with name - ' +
port = port_dict.get(floating_ip_setting.port_name)
if not port:
- raise Exception(
+ raise VmInstanceCreationError(
'Cannot find port object with name - ' +
floating_ip_setting.port_name)
if ext_gateway:
subnet = neutron_utils.get_subnet_by_name(
self.__neutron, floating_ip_setting.subnet_name)
- floating_ip = nova_utils.create_floating_ip(self.__nova,
- ext_gateway)
+ floating_ip = neutron_utils.create_floating_ip(
+ self.__neutron, ext_gateway)
self.__floating_ips.append(floating_ip)
self.__floating_ip_dict[floating_ip_setting.name] = floating_ip
floating_ip_setting.router_name)
self.__add_floating_ip(floating_ip, port, subnet)
else:
- raise Exception('Unable to add floating IP to port,'
- ' cannot locate router with an external '
- 'gateway ')
+ raise VmInstanceCreationError(
+ 'Unable to add floating IP to port, cannot locate router '
+ 'with an external gateway ')
def __ext_gateway_by_router(self, router_name):
"""
:return: the external network name or None
"""
router = neutron_utils.get_router_by_name(self.__neutron, router_name)
- if router and router['router'].get('external_gateway_info'):
+ if router and router.external_gateway_info:
network = neutron_utils.get_network_by_id(
self.__neutron,
- router['router']['external_gateway_info']['network_id'])
+ router.external_gateway_info['network_id'])
if network:
- return network['network']['name']
+ return network.name
return None
def clean(self):
for floating_ip in self.__floating_ips:
try:
logger.info('Deleting Floating IP - ' + floating_ip.ip)
- nova_utils.delete_floating_ip(self.__nova, floating_ip)
+ neutron_utils.delete_floating_ip(self.__neutron, floating_ip)
except Exception as e:
logger.error('Error deleting Floating IP - ' + str(e))
self.__floating_ips = list()
ports = list()
for port_setting in port_settings:
- # First check to see if network already has this port
- # TODO/FIXME - this could potentially cause problems if another
- # port with the same name exists
- # VM has the same network/port name pair
- found = False
-
- # TODO/FIXME - should we not be iterating on ports for the specific
- # network in question as unique port names
- # seem to only be important by network
- existing_ports = self.__neutron.list_ports()['ports']
- for existing_port in existing_ports:
- if existing_port['name'] == port_setting.name:
- ports.append((port_setting.name, {'port': existing_port}))
- found = True
- break
-
- if not found and not cleanup:
- ports.append((port_setting.name,
- neutron_utils.create_port(self.__neutron,
- self.__os_creds,
- port_setting)))
+ port = neutron_utils.get_port_by_name(self.__neutron,
+ port_setting.name)
+ if port:
+ ports.append((port_setting.name, {'port': port}))
+ elif not cleanup:
+ # Exception will be raised when port with same name already
+ # exists
+ ports.append(
+ (port_setting.name, neutron_utils.create_port(
+ self.__neutron, self.__os_creds, port_setting)))
return ports
if subnet:
# Take IP of subnet if there is one configured on which to place
# the floating IP
- for fixed_ip in port['port']['fixed_ips']:
+ for fixed_ip in port.fixed_ips:
if fixed_ip['subnet_id'] == subnet['subnet']['id']:
ip = fixed_ip['ip_address']
break
else:
# Simply take the first
- ip = port['port']['fixed_ips'][0]['ip_address']
+ ip = port.ips[0]['ip_address']
if ip:
count = timeout / poll_interval
while count > 0:
logger.debug('Attempting to add floating IP to instance')
try:
- self.__vm.add_floating_ip(floating_ip, ip)
+ nova_utils.add_floating_ip_to_server(
+ self.__nova, self.__vm, floating_ip, ip)
logger.info(
'Added floating IP %s to port IP %s on instance %s',
floating_ip.ip, ip, self.instance_settings.name)
count -= 1
pass
else:
- raise Exception(
+ raise VmInstanceCreationError(
'Unable find IP address on which to place the floating IP')
logger.error('Timeout attempting to add the floating IP to instance.')
- raise Exception('Timeout while attempting add floating IP to instance')
+ raise VmInstanceCreationError(
+ 'Timeout while attempting add floating IP to instance')
def get_os_creds(self):
"""
Returns the latest version of this server object from OpenStack
:return: Server object
"""
- return nova_utils.get_latest_server_object(self.__nova, self.__vm)
+ return self.__vm
+
+ def get_console_output(self):
+ """
+ Returns the vm console object for parsing logs
+ :return: the console output object
+ """
+ return nova_utils.get_server_console_output(self.__nova, self.__vm)
def get_port_ip(self, port_name, subnet_name=None):
"""
"""
port = self.get_port_by_name(port_name)
if port:
- port_dict = port['port']
if subnet_name:
subnet = neutron_utils.get_subnet_by_name(self.__neutron,
subnet_name)
'not be located with name - %s',
subnet_name)
return None
- for fixed_ip in port_dict['fixed_ips']:
- if fixed_ip['subnet_id'] == subnet['subnet']['id']:
+ for fixed_ip in port.ips:
+ if fixed_ip['subnet_id'] == subnet.id:
return fixed_ip['ip_address']
else:
- fixed_ips = port_dict['fixed_ips']
- if fixed_ips and len(fixed_ips) > 0:
- return fixed_ips[0]['ip_address']
+ if port.ips and len(port.ips) > 0:
+ return port.ips[0]['ip_address']
return None
def get_port_mac(self, port_name):
"""
port = self.get_port_by_name(port_name)
if port:
- port_dict = port['port']
- return port_dict['mac_address']
+ return port.mac_address
return None
def get_port_by_name(self, port_name):
logger.warning('Cannot find port with name - ' + port_name)
return None
+ def get_vm_info(self):
+ """
+ Returns a dictionary of a VMs info as returned by OpenStack
+ :return: a dict()
+ """
+ return nova_utils.get_server_info(self.__nova, self.__vm)
+
def config_nics(self):
"""
Responsible for configuring NICs on RPM systems where the instance has
more than one configured port
- :return: None
+ :return: the value returned by ansible_utils.apply_ansible_playbook()
"""
if len(self.__ports) > 1 and len(self.__floating_ips) > 0:
if self.vm_active(block=True) and self.vm_ssh_active(block=True):
port_index = self.__ports.index((key, port))
if port_index > 0:
nic_name = 'eth' + repr(port_index)
- self.__config_nic(
+ retval = self.__config_nic(
nic_name, port,
self.__get_first_provisioning_floating_ip().ip)
logger.info('Configured NIC - %s on VM - %s',
nic_name, self.instance_settings.name)
+ return retval
def __get_first_provisioning_floating_ip(self):
"""
elif len(self.__floating_ips) > 0:
return self.__floating_ips[0]
- def __config_nic(self, nic_name, port, floating_ip):
+ def __config_nic(self, nic_name, port, ip):
"""
Although ports/NICs can contain multiple IPs, this code currently only
supports the first.
:param nic_name: Name of the interface
:param port: The port information containing the expected IP values.
- :param floating_ip: The floating IP on which to apply the playbook.
+ :param ip: The IP on which to apply the playbook.
:return: the return value from ansible
"""
- ip = port['port']['fixed_ips'][0]['ip_address']
+ port_ip = port.ips[0]['ip_address']
variables = {
- 'floating_ip': floating_ip,
+ 'floating_ip': ip,
'nic_name': nic_name,
- 'nic_ip': ip
+ 'nic_ip': port_ip
}
if self.image_settings.nic_config_pb_loc and self.keypair_settings:
if not self.__vm:
return False
- instance = self.__nova.servers.get(self.__vm.id)
- if not instance:
+ status = nova_utils.get_server_status(self.__nova, self.__vm)
+ if not status:
logger.warning('Cannot find instance with id - ' + self.__vm.id)
return False
- if instance.status == 'ERROR':
- raise Exception('Instance had an error during deployment')
+ if status == 'ERROR':
+ raise VmInstanceCreationError(
+ 'Instance had an error during deployment')
logger.debug(
'Instance status [%s] is - %s', self.instance_settings.name,
- instance.status)
- return instance.status == expected_status_code
+ status)
+ return status == expected_status_code
def vm_ssh_active(self, block=False, poll_interval=POLL_INTERVAL):
"""
def add_security_group(self, security_group):
"""
Adds a security group to this VM. Call will block until VM is active.
- :param security_group: the OpenStack security group object
+ :param security_group: the SNAPS SecurityGroup domain object
:return True if successful else False
"""
self.vm_active(block=True)
try:
nova_utils.add_security_group(self.__nova, self.get_vm_inst(),
- security_group['security_group'][
- 'name'])
+ security_group.name)
return True
except NotFound as e:
logger.warning('Security group not added - ' + str(e))
if kwargs.get('security_group_names'):
if isinstance(kwargs['security_group_names'], list):
- self.security_group_names = kwargs['security_group_names']
+ self.security_group_names = kwargs['security_group_names']
elif isinstance(kwargs['security_group_names'], set):
self.security_group_names = kwargs['security_group_names']
elif isinstance(kwargs['security_group_names'], str):
self.security_group_names = [kwargs['security_group_names']]
else:
- raise Exception(
+ raise VmInstanceSettingsError(
'Invalid data type for security_group_names attribute')
else:
self.security_group_names = set()
self.availability_zone = None
if not self.name or not self.flavor:
- raise Exception(
+ raise VmInstanceSettingsError(
'Instance configuration requires the attributes: name, flavor')
if len(self.port_settings) == 0:
- raise Exception(
+ raise VmInstanceSettingsError(
'Instance configuration requires port settings (aka. NICS)')
self.provisioning = True
if not self.name or not self.port_name or not self.router_name:
- raise Exception(
+ raise FloatingIpSettingsError(
'The attributes name, port_name and router_name are required '
'for FloatingIPSettings')
+
+
+class VmInstanceSettingsError(Exception):
+ """
+ Exception to be thrown when an VM instance settings are incorrect
+ """
+
+
+class FloatingIpSettingsError(Exception):
+ """
+ Exception to be thrown when an VM instance settings are incorrect
+ """
+
+
+class VmInstanceCreationError(Exception):
+ """
+ Exception to be thrown when an VM instance cannot be created
+ """