Пример #1
0
    def test_is_supported_max_version(self):
        req = fakes.HTTPRequest.blank('/fake', version='2.5')

        self.assertFalse(api_version_request.is_supported(
            req, max_version='2.4'))
        self.assertTrue(api_version_request.is_supported(
            req, max_version='2.5'))
        self.assertTrue(api_version_request.is_supported(
            req, max_version='2.6'))
Пример #2
0
    def show(self, request, instance, extend_address=True):
        """Detailed view of a single instance."""
        server = {
            "server": {
                "id":
                instance["uuid"],
                "name":
                instance["display_name"],
                "status":
                self._get_vm_status(instance),
                "tenant_id":
                instance.get("project_id") or "",
                "user_id":
                instance.get("user_id") or "",
                "metadata":
                self._get_metadata(instance),
                "hostId":
                self._get_host_id(instance) or "",
                # TODO(alex_xu): '_get_image' return {} when there image_ref
                # isn't existed in V3 API, we revert it back to return "" in
                # V2.1.
                "image":
                self._get_image(request, instance),
                "flavor":
                self._get_flavor(request, instance),
                "created":
                utils.isotime(instance["created_at"]),
                "updated":
                utils.isotime(instance["updated_at"]),
                "addresses":
                self._get_addresses(request, instance, extend_address),
                "links":
                self._get_links(request, instance["uuid"],
                                self._collection_name),
            },
        }
        if server["server"]["status"] in self._fault_statuses:
            _inst_fault = self._get_fault(request, instance)
            if _inst_fault:
                server['server']['fault'] = _inst_fault

        if server["server"]["status"] in self._progress_statuses:
            server["server"]["progress"] = instance.get("progress", 0)

        if api_version_request.is_supported(request, min_version="2.9"):
            server["server"]["locked"] = (True
                                          if instance["locked_by"] else False)

        if api_version_request.is_supported(request, min_version="2.19"):
            server["server"]["description"] = instance.get(
                "display_description")

        return server
Пример #3
0
 def _format_server_group(self, context, group, req):
     # the id field has its value as the uuid of the server group
     # There is no 'uuid' key in server_group seen by clients.
     # In addition, clients see policies as a ["policy-name"] list;
     # and they see members as a ["server-id"] list.
     server_group = {}
     server_group['id'] = group.uuid
     server_group['name'] = group.name
     server_group['policies'] = group.policies or []
     # NOTE(danms): This has been exposed to the user, but never used.
     # Since we can't remove it, just make sure it's always empty.
     server_group['metadata'] = {}
     members = []
     if group.members:
         # Display the instances that are not deleted.
         filters = {'uuid': group.members, 'deleted': False}
         instances = objects.InstanceList.get_by_filters(context,
                                                         filters=filters)
         members = [instance.uuid for instance in instances]
     server_group['members'] = members
     # Add project id information to the response data for
     # API version v2.13
     if api_version_request.is_supported(req, min_version="2.13"):
         server_group['project_id'] = group.project_id
         server_group['user_id'] = group.user_id
     return server_group
Пример #4
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["compute.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except exception.ComputeHostNotFound:
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14') and
                CONF.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
Пример #5
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["compute.context"]
        authorize(context)

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except exception.ComputeHostNotFound:
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14')
                and CONF.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
Пример #6
0
    def update(self, req, id, body):
        """Perform service update"""
        if api_version_request.is_supported(req, min_version='2.11'):
            actions = self.actions.copy()
            actions["force-down"] = self._forced_down
        else:
            actions = self.actions

        return self._perform_action(req, id, body, actions)
Пример #7
0
    def update(self, req, id, body):
        """Perform service update"""
        if api_version_request.is_supported(req, min_version='2.11'):
            actions = self.actions.copy()
            actions["force-down"] = self._forced_down
        else:
            actions = self.actions

        return self._perform_action(req, id, body, actions)
Пример #8
0
    def index(self, req):
        """Return a list of all running services. Filter by host & service
        name
        """
        if api_version_request.is_supported(req, min_version='2.11'):
            _services = self._get_services_list(req, ['forced_down'])
        else:
            _services = self._get_services_list(req)

        return {'services': _services}
Пример #9
0
    def index(self, req):
        """Return all migrations in progress."""
        context = req.environ['compute.context']
        authorize(context, "index")
        migrations = self.compute_api.get_migrations(context, req.GET)

        if api_version_request.is_supported(req, min_version='2.23'):
            return {'migrations': self._output(req, migrations, True)}

        return {'migrations': self._output(req, migrations)}
Пример #10
0
    def index(self, req):
        """Return all migrations in progress."""
        context = req.environ['compute.context']
        authorize(context, "index")
        migrations = self.compute_api.get_migrations(context, req.GET)

        if api_version_request.is_supported(req, min_version='2.23'):
            return {'migrations': self._output(req, migrations, True)}

        return {'migrations': self._output(req, migrations)}
Пример #11
0
    def index(self, req):
        """Return a list of all running services. Filter by host & service
        name
        """
        if api_version_request.is_supported(req, min_version='2.11'):
            _services = self._get_services_list(req, ['forced_down'])
        else:
            _services = self._get_services_list(req)

        return {'services': _services}
Пример #12
0
    def show(self, request, instance, extend_address=True):
        """Detailed view of a single instance."""
        server = {
            "server": {
                "id": instance["uuid"],
                "name": instance["display_name"],
                "status": self._get_vm_status(instance),
                "tenant_id": instance.get("project_id") or "",
                "user_id": instance.get("user_id") or "",
                "metadata": self._get_metadata(instance),
                "hostId": self._get_host_id(instance) or "",
                # TODO(alex_xu): '_get_image' return {} when there image_ref
                # isn't existed in V3 API, we revert it back to return "" in
                # V2.1.
                "image": self._get_image(request, instance),
                "flavor": self._get_flavor(request, instance),
                "created": utils.isotime(instance["created_at"]),
                "updated": utils.isotime(instance["updated_at"]),
                "addresses": self._get_addresses(request, instance,
                                                 extend_address),
                "links": self._get_links(request,
                                         instance["uuid"],
                                         self._collection_name),
            },
        }
        if server["server"]["status"] in self._fault_statuses:
            _inst_fault = self._get_fault(request, instance)
            if _inst_fault:
                server['server']['fault'] = _inst_fault

        if server["server"]["status"] in self._progress_statuses:
            server["server"]["progress"] = instance.get("progress", 0)

        if api_version_request.is_supported(request, min_version="2.9"):
            server["server"]["locked"] = (True if instance["locked_by"]
                                          else False)

        if api_version_request.is_supported(request, min_version="2.19"):
            server["server"]["description"] = instance.get(
                                                "display_description")

        return server
Пример #13
0
def _check_request_version(req, min_version, method, server_id, server_state):
    if not api_version_request.is_supported(req, min_version=min_version):
        exc_inv = exception.InstanceInvalidState(
                attr='vm_state',
                instance_uuid=server_id,
                state=server_state,
                method=method)
        common.raise_http_conflict_for_instance_invalid_state(
                exc_inv,
                method,
                server_id)
Пример #14
0
def _translate_vif_summary_view(req, vif):
    """Maps keys for VIF summary view."""
    d = {}
    d['id'] = vif.uuid
    d['mac_address'] = vif.address
    if api_version_request.is_supported(req, min_version='2.12'):
        d['net_id'] = vif.net_uuid
    # NOTE(gmann): This is for v2.1 compatible mode where response should be
    # same as v2 one.
    if req.is_legacy_v2():
        d['OS-EXT-VIF-NET:net_id'] = vif.net_uuid
    return d
Пример #15
0
def _translate_vif_summary_view(req, vif):
    """Maps keys for VIF summary view."""
    d = {}
    d['id'] = vif.uuid
    d['mac_address'] = vif.address
    if api_version_request.is_supported(req, min_version='2.12'):
        d['net_id'] = vif.net_uuid
    # NOTE(gmann): This is for v2.1 compatible mode where response should be
    # same as v2 one.
    if req.is_legacy_v2():
        d['OS-EXT-VIF-NET:net_id'] = vif.net_uuid
    return d
Пример #16
0
 def _extend_server(self, context, server, req, bdms):
     volumes_attached = []
     for bdm in bdms:
         if bdm.get('volume_id'):
             volume_attached = {'id': bdm['volume_id']}
             if api_version_request.is_supported(req, min_version='2.3'):
                 volume_attached['delete_on_termination'] = (
                     bdm['delete_on_termination'])
             volumes_attached.append(volume_attached)
     # NOTE(mriedem): The os-extended-volumes prefix should not be used for
     # new attributes after v2.1. They are only in v2.1 for backward compat
     # with v2.0.
     key = "%s:volumes_attached" % ExtendedVolumes.alias
     server[key] = volumes_attached
Пример #17
0
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["compute.context"]
        authorize(context, action='migrate_live')

        host = body["os-migrateLive"]["host"]
        block_migration = body["os-migrateLive"]["block_migration"]

        if api_version_request.is_supported(req, min_version='2.25'):
            if block_migration == 'auto':
                block_migration = None
            else:
                block_migration = strutils.bool_from_string(block_migration,
                                                            strict=True)
            disk_over_commit = None
        else:
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]

            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)

        try:
            instance = common.get_instance(self.compute_api, context, id)
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError,
                exception.LiveMigrationWithOldNovaNotSafe,
                exception.LiveMigrationWithOldNovaNotSupported) as ex:
            raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
Пример #18
0
 def show(self, req, resp_obj, id):
     context = req.environ['compute.context']
     authorize_extend = False
     authorize_host_status = False
     if authorize(context):
         authorize_extend = True
     if (api_version_request.is_supported(req, min_version='2.16') and
         soft_authorize(context, action='show:host_status')):
         authorize_host_status = True
     if authorize_extend or authorize_host_status:
         server = resp_obj.obj['server']
         db_instance = req.get_db_instance(server['id'])
         # server['id'] is guaranteed to be in the cache due to
         # the core API adding it in its 'show' method.
         if authorize_extend:
             self._extend_server(context, server, db_instance, req)
         if authorize_host_status:
             self._server_host_status(context, server, db_instance, req)
Пример #19
0
 def show(self, req, resp_obj, id):
     context = req.environ['compute.context']
     authorize_extend = False
     authorize_host_status = False
     if authorize(context):
         authorize_extend = True
     if (api_version_request.is_supported(req, min_version='2.16')
             and soft_authorize(context, action='show:host_status')):
         authorize_host_status = True
     if authorize_extend or authorize_host_status:
         server = resp_obj.obj['server']
         db_instance = req.get_db_instance(server['id'])
         # server['id'] is guaranteed to be in the cache due to
         # the core API adding it in its 'show' method.
         if authorize_extend:
             self._extend_server(context, server, db_instance, req)
         if authorize_host_status:
             self._server_host_status(context, server, db_instance, req)
Пример #20
0
    def _add_tenant_access(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context, action="add_tenant_access")

        vals = body['addTenantAccess']
        tenant = vals['tenant']

        flavor = common.get_flavor(context, id)

        try:
            if api_version_request.is_supported(req, min_version='2.7'):
                if flavor.is_public:
                    exp = _("Can not add access to a public flavor.")
                    raise webob.exc.HTTPConflict(explanation=exp)
            flavor.add_access(tenant)
        except exception.FlavorNotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())
        except exception.FlavorAccessExists as err:
            raise webob.exc.HTTPConflict(explanation=err.format_message())
        except exception.AdminRequired as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        return _marshall_flavor_access(flavor)
Пример #21
0
    def _add_tenant_access(self, req, id, body):
        context = req.environ['compute.context']
        authorize(context, action="add_tenant_access")

        vals = body['addTenantAccess']
        tenant = vals['tenant']

        flavor = common.get_flavor(context, id)

        try:
            if api_version_request.is_supported(req, min_version='2.7'):
                if flavor.is_public:
                    exp = _("Can not add access to a public flavor.")
                    raise webob.exc.HTTPConflict(explanation=exp)
            flavor.add_access(tenant)
        except exception.FlavorNotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())
        except exception.FlavorAccessExists as err:
            raise webob.exc.HTTPConflict(explanation=err.format_message())
        except exception.AdminRequired as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        return _marshall_flavor_access(flavor)
Пример #22
0
    def _extend_server(self, context, server, instance, req):
        key = "OS-EXT-SRV-ATTR:hypervisor_hostname"
        server[key] = instance.node

        properties = ['host', 'name']
        if api_version_request.is_supported(req, min_version='2.3'):
            # NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix below
            # and that's OK for microversion 2.3 which is being compatible
            # with v2.0 for the ec2 API split out from Nova. After this,
            # however, new microversoins should not be using the
            # OS-EXT-SRV-ATTR prefix.
            properties += ['reservation_id', 'launch_index',
                           'hostname', 'kernel_id', 'ramdisk_id',
                           'root_device_name', 'user_data']
        for attr in properties:
            if attr == 'name':
                key = "OS-EXT-SRV-ATTR:instance_%s" % attr
            else:
                # NOTE(mriedem): Nothing after microversion 2.3 should use the
                # OS-EXT-SRV-ATTR prefix for the attribute key name.
                key = "OS-EXT-SRV-ATTR:%s" % attr
            server[key] = instance[attr]
Пример #23
0
    def _extend_server(self, context, server, instance, req):
        key = "OS-EXT-SRV-ATTR:hypervisor_hostname"
        server[key] = instance.node

        properties = ['host', 'name']
        if api_version_request.is_supported(req, min_version='2.3'):
            # NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix below
            # and that's OK for microversion 2.3 which is being compatible
            # with v2.0 for the ec2 API split out from Nova. After this,
            # however, new microversoins should not be using the
            # OS-EXT-SRV-ATTR prefix.
            properties += [
                'reservation_id', 'launch_index', 'hostname', 'kernel_id',
                'ramdisk_id', 'root_device_name', 'user_data'
            ]
        for attr in properties:
            if attr == 'name':
                key = "OS-EXT-SRV-ATTR:instance_%s" % attr
            else:
                # NOTE(mriedem): Nothing after microversion 2.3 should use the
                # OS-EXT-SRV-ATTR prefix for the attribute key name.
                key = "OS-EXT-SRV-ATTR:%s" % attr
            server[key] = instance[attr]
Пример #24
0
 def detail(self, req, resp_obj):
     context = req.environ['compute.context']
     authorize_extend = False
     authorize_host_status = False
     if authorize(context):
         authorize_extend = True
     if (api_version_request.is_supported(req, min_version='2.16')
             and soft_authorize(context, action='show:host_status')):
         authorize_host_status = True
     if authorize_extend or authorize_host_status:
         servers = list(resp_obj.obj['servers'])
         if servers:
             instances = req.get_db_instances()
             # Instances is guaranteed to be in the cache due to
             # the core API adding it in its 'detail' method.
             if authorize_host_status:
                 host_statuses = self.compute_api.get_instances_host_statuses(
                     instances.values())
             for server in servers:
                 if authorize_extend:
                     instance = instances[server['id']]
                     self._extend_server(context, server, instance, req)
                 if authorize_host_status:
                     server['host_status'] = host_statuses[server['id']]
Пример #25
0
 def detail(self, req, resp_obj):
     context = req.environ['compute.context']
     authorize_extend = False
     authorize_host_status = False
     if authorize(context):
         authorize_extend = True
     if (api_version_request.is_supported(req, min_version='2.16') and
         soft_authorize(context, action='show:host_status')):
         authorize_host_status = True
     if authorize_extend or authorize_host_status:
         servers = list(resp_obj.obj['servers'])
         if servers:
             instances = req.get_db_instances()
             # Instances is guaranteed to be in the cache due to
             # the core API adding it in its 'detail' method.
             if authorize_host_status:
                 host_statuses = self.compute_api.get_instances_host_statuses(
                                 instances.values())
             for server in servers:
                 if authorize_extend:
                     instance = instances[server['id']]
                     self._extend_server(context, server, instance, req)
                 if authorize_host_status:
                     server['host_status'] = host_statuses[server['id']]
Пример #26
0
 def _get_on_shared_storage(self, req, evacuate_body):
     if api_version_request.is_supported(req, min_version='2.14'):
         return None
     else:
         return strutils.bool_from_string(evacuate_body["onSharedStorage"])
Пример #27
0
 def _get_on_shared_storage(self, req, evacuate_body):
     if api_version_request.is_supported(req, min_version='2.14'):
         return None
     else:
         return strutils.bool_from_string(evacuate_body["onSharedStorage"])