+ :param neutron: the neutron client
+ :param keystone: the neutron client
+ :param server: the VMInst domain object
+ :param volume: the Volume domain object
+ :param project_name: the associated project name
+ :param timeout: denotes the amount of time to block to determine if the
+ has been properly attached.
+ :return: updated VmInst object
+ """
+ nova.volumes.create_server_volume(server.id, volume.id)
+
+ start_time = time.time()
+ while time.time() < start_time + timeout:
+ vm = get_server_object_by_id(
+ nova, neutron, keystone, server.id, project_name)
+ for vol_dict in vm.volume_ids:
+ if volume.id == vol_dict['id']:
+ return vm
+ time.sleep(POLL_INTERVAL)
+
+ raise NovaException(
+ 'Attach failed on volume - {} and server - {}'.format(
+ volume.id, server.id))
+
+
+def detach_volume(nova, neutron, keystone, server, volume, project_name,
+ timeout=120):
+ """
+ Detaches a volume to a server. When the timeout parameter is used, a VmInst
+ object with the proper volume updates is returned unless it has not been
+ updated in the allotted amount of time then an Exception will be raised.
+ :param nova: the nova client
+ :param neutron: the neutron client
+ :param keystone: the keystone client
+ :param server: the VMInst domain object
+ :param volume: the Volume domain object
+ :param project_name: the associated project name
+ :param timeout: denotes the amount of time to block to determine if the
+ has been properly detached.
+ :return: updated VmInst object
+ """
+ nova.volumes.delete_server_volume(server.id, volume.id)
+
+ start_time = time.time()
+ while time.time() < start_time + timeout:
+ vm = get_server_object_by_id(
+ nova, neutron, keystone, server.id, project_name)
+ if len(vm.volume_ids) == 0:
+ return vm
+ else:
+ ids = list()
+ for vol_dict in vm.volume_ids:
+ ids.append(vol_dict['id'])
+ if volume.id not in ids:
+ return vm
+ time.sleep(POLL_INTERVAL)
+
+ raise NovaException(
+ 'Detach failed on volume - {} server - {}'.format(
+ volume.id, server.id))
+
+
+class RebootType(enum.Enum):
+ """
+ A rule's direction
+ """
+ soft = 'SOFT'
+ hard = 'HARD'
+
+
+class NovaException(Exception):
+ """
+ Exception when calls to the Keystone client cannot be served properly
+ """
+
+
+class ServerNotFoundError(Exception):
+ """
+ Exception when operations to a VM/Server is requested and the OpenStack
+ Server instance cannot be located