Пример #1
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()
        if not context.is_admin:
            return utils.format_nova_error(
                403,
                _("Policy doesn't allow os_compute_api:os-aggregates:"
                  "index to be performed."))
        if 'aggregate' not in kw:
            return utils.format_nova_error(400, _('aggregate is not set'))

        host_aggregate = kw['aggregate']
        name = host_aggregate['name'].strip()
        avail_zone = host_aggregate.get('availability_zone')
        if avail_zone:
            avail_zone = avail_zone.strip()

        try:
            with context.session.begin():
                aggregate = az_ag.create_ag_az(context,
                                               ag_name=name,
                                               az_name=avail_zone)
        except db_exc.DBDuplicateEntry:
            return utils.format_nova_error(
                409,
                _('Aggregate %s already exists.') % name)
        except Exception:
            return utils.format_nova_error(500, _('Fail to create aggregate'))

        return {'aggregate': aggregate}
Пример #2
0
 def post(self, **kw):
     context = t_context.extract_context_from_environ()
     if not context.is_admin:
         return utils.format_nova_error(
             403,
             _("Policy doesn't allow os_compute_api:os-aggregates:"
               "index to be performed."))
     try:
         with context.session.begin():
             core.get_resource(context, models.Aggregate, self.aggregate_id)
     except t_exc.ResourceNotFound:
         return utils.format_nova_error(
             404,
             _('Aggregate %s could not be found.') % self.aggregate_id)
     if 'add_host' in kw or 'remove_host' in kw:
         return utils.format_nova_error(
             400, _('Add and remove host action not supported'))
     # TODO(zhiyuan) handle aggregate metadata updating
     try:
         aggregate = az_ag.get_one_ag(context, self.aggregate_id)
         return {'aggregate': aggregate}
     except Exception:
         return utils.format_nova_error(
             500,
             _('Aggregate operation on %s failed') % self.aggregate_id)
Пример #3
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'server' not in kw:
            return utils.format_nova_error(400, _('server is not set'))

        az = kw['server'].get('availability_zone', '')

        pod, b_az = az_ag.get_pod_by_az_tenant(context, az, self.project_id)
        if not pod:
            return utils.format_nova_error(
                500, _('Pod not configured or scheduling failure'))

        t_server_dict = kw['server']
        self._process_metadata_quota(context, t_server_dict)
        self._process_injected_file_quota(context, t_server_dict)

        server_body = self._get_create_server_body(kw['server'], b_az)

        security_groups = []
        if 'security_groups' not in kw['server']:
            security_groups = ['default']
        else:
            for sg in kw['server']['security_groups']:
                if 'name' not in sg:
                    return utils.format_nova_error(
                        400, _('Invalid input for field/attribute'))
                security_groups.append(sg['name'])

        server_body['networks'] = []
        if 'networks' in kw['server']:
            for net_info in kw['server']['networks']:
                if 'uuid' in net_info:
                    nic = {'net-id': net_info['uuid']}
                    server_body['networks'].append(nic)
                elif 'port' in net_info:
                    nic = {'port-id': net_info['port']}
                    server_body['networks'].append(nic)

        client = self._get_client(pod['pod_name'])
        server = client.create_servers(context,
                                       name=server_body['name'],
                                       image=server_body['imageRef'],
                                       flavor=server_body['flavorRef'],
                                       nics=server_body['networks'],
                                       security_groups=security_groups)

        with context.session.begin():
            core.create_resource(
                context, models.ResourceRouting, {
                    'top_id': server['id'],
                    'bottom_id': server['id'],
                    'pod_id': pod['pod_id'],
                    'project_id': self.project_id,
                    'resource_type': constants.RT_SERVER
                })
        pecan.response.status = 202
        return {'server': server}
Пример #4
0
 def get_one(self, _id):
     context = t_context.extract_context_from_environ()
     try:
         with context.session.begin():
             aggregate = az_ag.get_one_ag(context, _id)
             return {'aggregate': aggregate}
     except t_exc.ResourceNotFound:
         return utils.format_nova_error(
             404,
             _('Aggregate %s could not be found.') % _id)
     except Exception:
         return utils.format_nova_error(500,
                                        _('Fail to get aggregate %s') % _id)
Пример #5
0
 def delete(self, _id):
     context = t_context.extract_context_from_environ()
     try:
         with context.session.begin():
             az_ag.delete_ag(context, _id)
             pecan.response.status = 200
     except t_exc.ResourceNotFound:
         return utils.format_nova_error(
             404,
             _('Aggregate %s could not be found.') % _id)
     except Exception:
         return utils.format_nova_error(
             500,
             _('Fail to delete aggregate %s') % _id)
Пример #6
0
 def get_one(self, _id):
     # NOTE(zhiyuan) this function handles two kinds of requests
     # GET /flavors/flavor_id
     # GET /flavors/detail
     context = t_context.extract_context_from_environ()
     if _id == 'detail':
         with context.session.begin():
             flavors = core.query_resource(context, models.InstanceTypes,
                                           [], [])
             for flavor in flavors:
                 flavor['id'] = flavor['flavorid']
                 del flavor['flavorid']
             return {'flavors': flavors}
     else:
         with context.session.begin():
             flavors = core.query_resource(context, models.InstanceTypes,
                                           [{
                                               'key': 'flavorid',
                                               'comparator': 'eq',
                                               'value': _id
                                           }], [])
             if not flavors:
                 return utils.format_nova_error(
                     404,
                     _('Flavor %s could not be found') % _id)
             flavor = flavors[0]
             flavor['id'] = flavor['flavorid']
             del flavor['flavorid']
             return {'flavor': flavor}
Пример #7
0
 def get_one(self, _id):
     context = t_context.extract_context_from_environ()
     if _id == 'detail':
         return self.get_all()
     image = self.client.get_images(context, _id)
     if not image:
         return utils.format_nova_error(404, _('Image not found'))
     return {'image': self._construct_show_image_entry(context, image)}
Пример #8
0
 def _process_metadata_quota(self, context, t_server_dict):
     try:
         ctx = context.elevated()
         metadata = t_server_dict.get('metadata', None)
         self._check_metadata_properties_quota(ctx, metadata)
     except t_exceptions.InvalidMetadata as e1:
         LOG.exception(_LE('Invalid metadata %(exception)s'),
                       {'exception': str(e1)})
         return utils.format_nova_error(400, _('Invalid metadata'))
     except t_exceptions.InvalidMetadataSize as e2:
         LOG.exception(_LE('Invalid metadata size %(exception)s'),
                       {'exception': str(e2)})
         return utils.format_nova_error(400, _('Invalid metadata size'))
     except t_exceptions.MetadataLimitExceeded as e3:
         LOG.exception(_LE('Quota exceeded %(exception)s'),
                       {'exception': str(e3)})
         return utils.format_nova_error(400,
                                        _('Quota exceeded in metadata'))
Пример #9
0
    def get_all(self):
        context = t_context.extract_context_from_environ()

        try:
            with context.session.begin():
                aggregates = az_ag.get_all_ag(context)
        except Exception:
            return utils.format_nova_error(500, _('Fail to list aggregates'))
        return {'aggregates': aggregates}
Пример #10
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()
        if not context.is_admin:
            return utils.format_nova_error(
                403,
                _("Policy doesn't allow os_compute_api:os-flavor-manage "
                  "to be performed."))

        required_fields = ['name', 'ram', 'vcpus', 'disk']
        if 'flavor' not in kw:
            utils.format_nova_error(400, _('flavor is not set'))
        if not utils.validate_required_fields_set(kw['flavor'],
                                                  required_fields):
            utils.format_nova_error(
                400, _('Invalid input for field/attribute flavor.'))

        flavor_dict = {
            'name': kw['flavor']['name'],
            'flavorid': kw['flavor'].get('id'),
            'memory_mb': kw['flavor']['ram'],
            'vcpus': kw['flavor']['vcpus'],
            'root_gb': kw['flavor']['disk'],
            'ephemeral_gb': kw['flavor'].get('OS-FLV-EXT-DATA:ephemeral', 0),
            'swap': kw['flavor'].get('swap', 0),
            'rxtx_factor': kw['flavor'].get('rxtx_factor', 1.0),
            'is_public': kw['flavor'].get('os-flavor-access:is_public', True),
        }

        try:
            with context.session.begin():
                flavor = core.create_resource(context, models.InstanceTypes,
                                              flavor_dict)
        except db_exc.DBDuplicateEntry as e:
            if 'flavorid' in e.columns:
                return utils.format_nova_error(
                    409,
                    _('Flavor with ID %s already '
                      'exists.') % flavor_dict['flavorid'])
            else:
                return utils.format_nova_error(
                    409,
                    _('Flavor with name %s already '
                      'exists.') % flavor_dict['name'])
        except Exception:
            utils.format_nova_error(500, _('Failed to create flavor'))

        flavor['id'] = flavor['flavorid']
        del flavor['flavorid']
        return {'flavor': flavor}
Пример #11
0
 def delete(self, _id):
     context = t_context.extract_context_from_environ()
     try:
         with context.session.begin():
             flavors = core.query_resource(context, models.InstanceTypes,
                                           [{
                                               'key': 'flavorid',
                                               'comparator': 'eq',
                                               'value': _id
                                           }], [])
             if not flavors:
                 return utils.format_nova_error(
                     404,
                     _('Flavor %s could not be found') % _id)
             core.delete_resource(context, models.InstanceTypes,
                                  flavors[0]['id'])
     except Exception:
         return utils.format_nova_error(500, _('Failed to delete flavor'))
     pecan.response.status = 202
     return
Пример #12
0
 def _process_injected_file_quota(self, context, t_server_dict):
     try:
         ctx = context.elevated()
         injected_files = t_server_dict.get('injected_files', None)
         self._check_injected_file_quota(ctx, injected_files)
     except (t_exceptions.OnsetFileLimitExceeded,
             t_exceptions.OnsetFilePathLimitExceeded,
             t_exceptions.OnsetFileContentLimitExceeded) as e:
         msg = str(e)
         LOG.exception(_LE('Quota exceeded %(msg)s'), {'msg': msg})
         return utils.format_nova_error(400, _('Quota exceeded %s') % msg)
Пример #13
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        action_handle = None
        action_type = None
        for _type in self.handle_map:
            if _type in kw:
                action_handle = self.handle_map[_type]
                action_type = _type
        if not action_handle:
            return utils.format_nova_error(400,
                                           _('Server action not supported'))

        server_mappings = db_api.get_bottom_mappings_by_top_id(
            context, self.server_id, constants.RT_SERVER)
        if not server_mappings:
            return utils.format_nova_error(
                404,
                _('Server %s could not be found') % self.server_id)

        pod_name = server_mappings[0][0]['pod_name']
        try:
            resp, body = action_handle(context, pod_name, kw)
            pecan.response.status = resp.status_code
            if not body:
                return pecan.response
            else:
                return body
        except Exception as e:
            code = 500
            message = _('Action %(action)s on server %(server_id)s fails') % {
                'action': action_type,
                'server_id': self.server_id
            }
            if hasattr(e, 'code'):
                code = e.code
            ex_message = str(e)
            if ex_message:
                message = ex_message
            LOG.error(message)
            return utils.format_nova_error(code, message)
Пример #14
0
    def get_one(self, _id, **kwargs):
        context = t_context.extract_context_from_environ()

        if _id == 'detail':
            # return {'servers': [self._construct_brief_server_entry(
            #     server) for server in self._get_all(context, kwargs)]}
            return {'servers': self._get_all(context, kwargs)}

        mappings = db_api.get_bottom_mappings_by_top_id(
            context, _id, constants.RT_SERVER)
        if not mappings:
            return utils.format_nova_error(
                404,
                _('Instance %s could not be found.') % _id)
        pod, bottom_id = mappings[0]
        client = self._get_client(pod['pod_name'])
        server = client.get_servers(context, bottom_id)
        if not server:
            return utils.format_nova_error(
                404,
                _('Instance %s could not be found.') % _id)
        else:
            return {'server': server}
Пример #15
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'volumeAttachment' not in kw:
            return utils.format_nova_error(400,
                                           _('volumeAttachment is not set'))
        body = kw['volumeAttachment']
        if 'volumeId' not in body:
            return utils.format_nova_error(
                400, _('Invalid input for field/attribute volumeAttachment'))

        server_mappings = db_api.get_bottom_mappings_by_top_id(
            context, self.server_id, constants.RT_SERVER)
        if not server_mappings:
            return utils.format_nova_error(
                404,
                _('Instance %s could not be '
                  'found.') % self.server_id)
        volume_mappings = db_api.get_bottom_mappings_by_top_id(
            context, body['volumeId'], constants.RT_VOLUME)
        if not volume_mappings:
            return utils.format_nova_error(
                404,
                _('Volume %s could not be found') % body['volumeId'])

        server_pod_name = server_mappings[0][0]['pod_name']
        volume_pod_name = volume_mappings[0][0]['pod_name']
        if server_pod_name != volume_pod_name:
            LOG.error(
                _LE('Server %(server)s is in pod %(server_pod)s and '
                    'volume %(volume)s is in pod %(volume_pod)s, which '
                    'are not the same.'), {
                        'server': self.server_id,
                        'server_pod': server_pod_name,
                        'volume': body['volumeId'],
                        'volume_pod': volume_pod_name
                    })
            return utils.format_nova_error(
                400, _('Server and volume not in the same pod'))

        device = None
        if 'device' in body:
            device = body['device']
            # this regular expression is copied from nova/block_device.py
            match = re.match('(^/dev/x{0,1}[a-z]{0,1}d{0,1})([a-z]+)[0-9]*$',
                             device)
            if not match:
                return utils.format_nova_error(
                    400,
                    _('The supplied device path (%s) is '
                      'invalid.') % device)

        client = self._get_client(server_pod_name)
        volume = client.action_server_volumes(context, 'create_server_volume',
                                              server_mappings[0][1],
                                              volume_mappings[0][1], device)
        return {'volumeAttachment': volume.to_dict()}
Пример #16
0
 def get_one(self, _id):
     context = t_context.extract_context_from_environ()
     network = self.client.get_networks(context, _id)
     if not network:
         return utils.format_nova_error(404, _('Network not found'))
     return {'network': self._construct_network_entry(network)}