self.image_settings = image_settings
self.keypair_settings = keypair_settings
- # TODO - get rid of FIP list and only use the dict(). Need to fix
- # populating this object when already exists
- self.__floating_ips = list()
self.__floating_ip_dict = dict()
# Instantiated in self.create()
def create(self, cleanup=False, block=False):
"""
Creates a VM instance
- :param cleanup: When true, only perform lookups for OpenStack objects.
+ :param cleanup: When true, this object is initialized only via queries,
+ else objects will be created when the queries return
+ None. The name of this parameter should be changed to
+ something like 'readonly' as the same goes with all of
+ the other creator classes.
:param block: Thread will block until instance has either become
active, error, or timeout waiting.
Additionally, when True, floating IPs will not be applied
VM with the same name already exists
within the project
"""
- servers = nova_utils.get_servers_by_name(self.__nova,
- self.instance_settings.name)
- for server in servers:
+ server = nova_utils.get_server(
+ self.__nova, vm_inst_settings=self.instance_settings)
+ if server:
if server.name == self.instance_settings.name:
self.__vm = server
logger.info(
'Found existing machine with name - %s',
self.instance_settings.name)
- fips = neutron_utils.get_floating_ips(self.__neutron)
- for fip in fips:
- 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
+
+ fips = neutron_utils.get_floating_ips(self.__neutron,
+ self.__ports)
+ for port_id, fip in fips:
+ settings = self.instance_settings.floating_ip_settings
+ for fip_setting in settings:
+ if port_id == fip_setting.port_id:
+ self.__floating_ip_dict[fip_setting.name] = fip
+ else:
+ port = neutron_utils.get_port_by_id(
+ self.__neutron, port_id)
+ if port and port.name == fip_setting.port_name:
+ self.__floating_ip_dict[fip_setting.name] = fip
def __create_vm(self, block=False):
"""
ext_gateway = self.__ext_gateway_by_router(
floating_ip_setting.router_name)
if ext_gateway:
- subnet = neutron_utils.get_subnet_by_name(
- self.__neutron, floating_ip_setting.subnet_name)
+ subnet = neutron_utils.get_subnet(
+ self.__neutron,
+ subnet_name=floating_ip_setting.subnet_name)
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
logger.info(
:param router_name: The name of the router to lookup
:return: the external network name or None
"""
- router = neutron_utils.get_router_by_name(self.__neutron, router_name)
+ router = neutron_utils.get_router(
+ self.__neutron, router_name=router_name)
if router and router.external_gateway_info:
network = neutron_utils.get_network_by_id(
self.__neutron,
"""
# Cleanup floating IPs
- for floating_ip in self.__floating_ips:
+ for name, floating_ip in self.__floating_ip_dict.items():
try:
logger.info('Deleting Floating IP - ' + floating_ip.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()
self.__floating_ip_dict = dict()
# Cleanup ports
for name, port in self.__ports:
- logger.info('Deleting Port - ' + name)
+ logger.info('Deleting Port with ID - %S ' + port.id)
try:
neutron_utils.delete_port(self.__neutron, port)
except PortNotFoundClient as e:
ports = list()
for port_setting in port_settings:
- port = neutron_utils.get_port_by_name(self.__neutron,
- port_setting.name)
+ port = neutron_utils.get_port(
+ self.__neutron, port_settings=port_setting)
+ if not port:
+ network = neutron_utils.get_network(
+ self.__neutron, network_name=port_setting.network_name)
+ net_ports = neutron_utils.get_ports(self.__neutron, network)
+ for net_port in net_ports:
+ if port_setting.mac_address == net_port.mac_address:
+ port = net_port
+ break
if port:
- ports.append((port_setting.name, {'port': port}))
+ ports.append((port_setting.name, port))
elif not cleanup:
# Exception will be raised when port with same name already
# exists
if subnet:
# Take IP of subnet if there is one configured on which to place
# the floating IP
- for fixed_ip in port.fixed_ips:
- if fixed_ip['subnet_id'] == subnet['subnet']['id']:
+ for fixed_ip in port.ips:
+ if fixed_ip['subnet_id'] == subnet.id:
ip = fixed_ip['ip_address']
break
else:
Returns the latest version of this server object from OpenStack
:return: Server object
"""
- return self.__vm
+ return nova_utils.get_server_object_by_id(self.__nova, self.__vm.id)
def get_console_output(self):
"""
port = self.get_port_by_name(port_name)
if port:
if subnet_name:
- subnet = neutron_utils.get_subnet_by_name(self.__neutron,
- subnet_name)
+ subnet = neutron_utils.get_subnet(
+ self.__neutron, subnet_name=subnet_name)
if not subnet:
logger.warning('Cannot retrieve port IP as subnet could '
'not be located with name - %s',
more than one configured port
:return: the value returned by ansible_utils.apply_ansible_playbook()
"""
- if len(self.__ports) > 1 and len(self.__floating_ips) > 0:
+ if len(self.__ports) > 1 and len(self.__floating_ip_dict) > 0:
if self.vm_active(block=True) and self.vm_ssh_active(block=True):
for key, port in self.__ports:
port_index = self.__ports.index((key, port))
fip = self.__floating_ip_dict.get(floating_ip_setting.name)
if fip:
return fip
- elif len(self.__floating_ips) > 0:
- return self.__floating_ips[0]
+ elif len(self.__floating_ip_dict) > 0:
+ for key, fip in self.__floating_ip_dict.items():
+ return fip
def __config_nic(self, nic_name, port, ip):
"""
def vm_active(self, block=False, poll_interval=POLL_INTERVAL):
"""
- Returns true when the VM status returns the value of
- expected_status_code
+ Returns true when the VM status returns the value of the constant
+ STATUS_ACTIVE
:param block: When true, thread will block until active or timeout
value in seconds has been exceeded (False)
:param poll_interval: The polling interval in seconds
:return: T/F
"""
if not self.__vm:
- return False
+ if expected_status_code == STATUS_DELETED:
+ return True
+ else:
+ return False
status = nova_utils.get_server_status(self.__nova, self.__vm)
if not status:
Returns True when can create a SSH session else False
:return: T/F
"""
- if len(self.__floating_ips) > 0:
+ if len(self.__floating_ip_dict) > 0:
ssh = self.ssh_client()
if ssh:
+ ssh.close()
return True
return False
fip = None
if fip_name and self.__floating_ip_dict.get(fip_name):
return self.__floating_ip_dict.get(fip_name)
- if not fip and len(self.__floating_ips) > 0:
- return self.__floating_ips[0]
- return None
+ if not fip:
+ return self.__get_first_provisioning_floating_ip()
def ssh_client(self, fip_name=None):
"""
fip = self.get_floating_ip(fip_name)
if fip:
return ansible_utils.ssh_client(
- self.__floating_ips[0].ip, self.get_image_user(),
+ self.__get_first_provisioning_floating_ip().ip,
+ self.get_image_user(),
self.keypair_settings.private_filepath,
proxy_settings=self.__os_creds.proxy_settings)
else:
"""
Constructor
:param name: the name of the VM
- :param flavor: the VM's flavor
+ :param flavor: the VM's flavor name
:param port_settings: the port configuration settings (required)
:param security_group_names: a set of names of the security groups to
add to the VM
"""
self.name = kwargs.get('name')
self.port_name = kwargs.get('port_name')
+ self.port_id = kwargs.get('port_id')
self.router_name = kwargs.get('router_name')
self.subnet_name = kwargs.get('subnet_name')
if kwargs.get('provisioning') is not None:
else:
self.provisioning = True
- if not self.name or not self.port_name or not self.router_name:
+ # if not self.name or not self.port_name or not self.router_name:
+ if not self.name or not self.router_name:
+ raise FloatingIpSettingsError(
+ 'The attributes name, port_name and router_name are required')
+
+ if not self.port_name and not self.port_id:
raise FloatingIpSettingsError(
- 'The attributes name, port_name and router_name are required '
- 'for FloatingIPSettings')
+ 'The attributes port_name or port_id are required')
class VmInstanceSettingsError(Exception):