senlin/senlin/drivers/os/nova_v2.py

330 lines
12 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack import exceptions as sdk_exc
from oslo_config import cfg
from oslo_log import log
from senlin.common import consts
from senlin.drivers import base
from senlin.drivers import sdk
LOG = log.getLogger(__name__)
class NovaClient(base.DriverBase):
"""Nova V2 driver."""
def __init__(self, params):
super(NovaClient, self).__init__(params)
self.conn = sdk.create_connection(params)
self.session = self.conn.session
@sdk.translate_exception
def flavor_find(self, name_or_id, ignore_missing=False):
return self.conn.compute.find_flavor(name_or_id, ignore_missing)
@sdk.translate_exception
def keypair_create(self, **attrs):
return self.conn.compute.create_keypair(**attrs)
@sdk.translate_exception
def keypair_delete(self, name_or_id, ignore_missing=False):
return self.conn.compute.delete_keypair(name_or_id, ignore_missing)
@sdk.translate_exception
def keypair_find(self, name_or_id, ignore_missing=False):
return self.conn.compute.find_keypair(name_or_id, ignore_missing)
@sdk.translate_exception
def server_create(self, **attrs):
server_obj = self.conn.compute.create_server(**attrs)
return server_obj
@sdk.translate_exception
def server_get(self, server):
return self.conn.compute.get_server(server)
@sdk.translate_exception
def server_update(self, server, **attrs):
return self.conn.compute.update_server(server, **attrs)
@sdk.translate_exception
def server_delete(self, server, ignore_missing=True):
return self.conn.compute.delete_server(server,
ignore_missing=ignore_missing)
@sdk.translate_exception
def server_force_delete(self, server, ignore_missing=True):
return self.conn.compute.delete_server(server,
ignore_missing=ignore_missing,
force=True)
@sdk.translate_exception
def server_rebuild(self, server, image, name=None, admin_password=None,
**attrs):
return self.conn.compute.rebuild_server(server, name, admin_password,
image=image, **attrs)
@sdk.translate_exception
def server_resize(self, server, flavor):
return self.conn.compute.resize_server(server, flavor)
@sdk.translate_exception
def server_resize_confirm(self, server):
return self.conn.compute.confirm_server_resize(server)
@sdk.translate_exception
def server_resize_revert(self, server):
return self.conn.compute.revert_server_resize(server)
@sdk.translate_exception
def server_reboot(self, server, reboot_type):
return self.conn.compute.reboot_server(server, reboot_type)
@sdk.translate_exception
def server_change_password(self, server, new_password):
return self.conn.compute.change_server_password(server, new_password)
@sdk.translate_exception
def server_pause(self, server):
return self.conn.compute.pause_server(server)
@sdk.translate_exception
def server_unpause(self, server):
return self.conn.compute.unpause_server(server)
@sdk.translate_exception
def server_suspend(self, server):
return self.conn.compute.suspend_server(server)
@sdk.translate_exception
def server_resume(self, server):
return self.conn.compute.resume_server(server)
@sdk.translate_exception
def server_lock(self, server):
return self.conn.compute.lock_server(server)
@sdk.translate_exception
def server_unlock(self, server):
return self.conn.compute.unlock_server(server)
@sdk.translate_exception
def server_start(self, server):
return self.conn.compute.start_server(server)
@sdk.translate_exception
def server_stop(self, server):
return self.conn.compute.stop_server(server)
@sdk.translate_exception
def server_rescue(self, server, admin_pass=None, image_ref=None):
return self.conn.compute.rescue_server(server, admin_pass=admin_pass,
image_ref=image_ref)
@sdk.translate_exception
def server_unrescue(self, server):
return self.conn.compute.unrescue_server(server)
@sdk.translate_exception
def server_migrate(self, server):
return self.conn.compute.migrate_server(server)
@sdk.translate_exception
def server_evacuate(self, server, host=None, admin_pass=None, force=None):
return self.conn.compute.evacuate_server(
server, host=host, admin_pass=admin_pass, force=force)
@sdk.translate_exception
def server_create_image(self, server, name, metadata=None):
return self.conn.compute.create_server_image(server, name, metadata)
@sdk.translate_exception
def wait_for_server(self, server, status=consts.VS_ACTIVE,
failures=None,
interval=2, timeout=None):
"""Wait for server creation complete"""
if failures is None:
failures = [consts.VS_ERROR]
if timeout is None:
timeout = cfg.CONF.default_nova_timeout
server_obj = self.conn.compute.find_server(server, False)
self.conn.compute.wait_for_server(server_obj, status=status,
failures=failures,
interval=interval,
wait=timeout)
return
@sdk.translate_exception
def wait_for_server_delete(self, server, timeout=None):
"""Wait for server deleting complete"""
if timeout is None:
timeout = cfg.CONF.default_nova_timeout
server_obj = self.conn.compute.find_server(server, True)
if server_obj:
self.conn.compute.wait_for_delete(server_obj, wait=timeout)
return
@sdk.translate_exception
def server_interface_create(self, server, **attrs):
return self.conn.compute.create_server_interface(server, **attrs)
@sdk.translate_exception
def server_interface_list(self, server, **query):
return self.conn.compute.server_interfaces(server, **query)
@sdk.translate_exception
def server_interface_delete(self, interface, server, ignore_missing=True):
return self.conn.compute.delete_server_interface(interface, server,
ignore_missing)
@sdk.translate_exception
def server_metadata_get(self, server):
res = self.conn.compute.get_server_metadata(server)
return res.metadata
def _ignore_forbidden_call(self, func, *args, **kwargs):
try:
return func(*args, **kwargs)
except sdk_exc.HttpException as exc:
if exc.status_code != 403:
raise
@sdk.translate_exception
def server_metadata_update(self, server, metadata):
# Clean all existing metadata first
res = self.conn.compute.get_server_metadata(server)
if res.metadata:
for key in res.metadata:
self._ignore_forbidden_call(
self.conn.compute.delete_server_metadata, server, [key])
if metadata:
for key, value in metadata.items():
self._ignore_forbidden_call(
self.conn.compute.set_server_metadata,
server, **{key: value})
@sdk.translate_exception
def server_metadata_delete(self, server, keys):
self.conn.compute.delete_server_metadata(server, keys)
@sdk.translate_exception
def availability_zone_list(self, **query):
return self.conn.compute.availability_zones(**query)
def validate_azs(self, azs):
"""check whether availability zones provided are valid.
:param azs: A list of availability zone names for checking.
:returns: A list of zones that are found available on Nova.
"""
known = self.availability_zone_list()
names = [az.name for az in known if az.state['available']]
found = []
for az in azs:
if az in names:
found.append(az)
else:
LOG.warning("Availability zone '%s' is not available.",
az)
return found
@sdk.translate_exception
def server_group_create(self, **attrs):
return self.conn.compute.create_server_group(**attrs)
@sdk.translate_exception
def server_group_delete(self, server_group, ignore_missing=True):
return self.conn.compute.delete_server_group(
server_group, ignore_missing=ignore_missing)
@sdk.translate_exception
def server_group_find(self, name_or_id, ignore_missing=True):
return self.conn.compute.find_server_group(
name_or_id, ignore_missing=ignore_missing)
@sdk.translate_exception
def hypervisor_list(self, **query):
return self.conn.compute.hypervisors(**query)
@sdk.translate_exception
def hypervisor_get(self, hypervisor):
return self.conn.compute.get_hypervisor(hypervisor)
@sdk.translate_exception
def hypervisor_find(self, name_or_id, ignore_missing=False):
# try finding hypervisor by id
try:
return self.conn.compute.get_hypervisor(name_or_id)
except sdk_exc.HttpException:
# ignore http exception and instead get list and check by name
pass
# if the hypervisor could not be found using id, search list using name
results = self.conn.compute.hypervisors(
hypervisor_hostname_pattern=name_or_id)
result = None
for maybe_result in results:
name_value = maybe_result.name
if name_value == name_or_id:
# Only allow one resource to be found. If we already
# found a match, raise an exception to show it.
if result is None:
result = maybe_result
else:
msg = "More than one hypervisor exists with the name '%s'."
msg = (msg % name_or_id)
raise sdk_exc.DuplicateResource(msg)
if result is not None:
return result
if ignore_missing:
return None
raise sdk_exc.ResourceNotFound(
"No hypervisor found for %s" % (name_or_id))
@sdk.translate_exception
def service_list(self):
return self.conn.compute.services()
@sdk.translate_exception
def service_force_down(self, service):
return self.conn.compute.force_service_down(service, service.host,
service.binary)
@sdk.translate_exception
def create_volume_attachment(self, server, **attr):
return self.conn.compute.create_volume_attachment(server, **attr)
@sdk.translate_exception
def delete_volume_attachment(self, volume_id, server, ignore_missing=True):
return self.conn.compute.delete_volume_attachment(
volume_id, server, ignore_missing=ignore_missing
)
@sdk.translate_exception
def server_floatingip_associate(self, server, address):
return self.conn.compute.add_floating_ip_to_server(server, address)
@sdk.translate_exception
def server_floatingip_disassociate(self, server, address):
return self.conn.compute.remove_floating_ip_from_server(server,
address)