Пример #1
0
    def get(self, request):
        """Get a list of nova services.

        Will return HTTP 501 status code if the service_list extension is
        not supported.
        """
        if api.base.is_service_enabled(request, 'compute') \
           and api.nova.extension_supported('Services', request):
            result = api.nova.service_list(request)
            return {'items': [u.to_dict() for u in result]}
        else:
            raise rest_utils.AjaxError(501, '')
Пример #2
0
    def post(self, request):
        form = UploadObjectForm(request.DATA, request.FILES)
        if not form.is_valid():
            raise rest_utils.AjaxError(500, 'Invalid request')

        data = form.clean()
        meta = create_image_metadata(request.DATA)
        meta['data'] = data['data']

        image = api.glance.image_create(request, **meta)
        return rest_utils.CreatedResponse('/api/glance/images/%s' % image.name,
                                          image.to_dict())
Пример #3
0
def handle_visibility(visibility, meta):
    mapping_to_v1 = {'public': True, 'private': False, 'shared': False}
    # note: presence of 'visibility' previously checked for in general call
    try:
        is_public = mapping_to_v1[visibility]
        if api.glance.VERSIONS.active >= 2:
            meta['visibility'] = visibility
        else:
            meta['is_public'] = is_public
    except KeyError as e:
        raise rest_utils.AjaxError(400,
                                   'invalid visibility option: %s' % e.args[0])
Пример #4
0
def handle_visibility(visibility, meta):
    # The following expects a 'visibility' parameter to be passed via
    # the AJAX call, then translates this to a Glance API v1 is_public
    # parameter.  In the future, if the 'visibility' param is exposed on the
    # glance API, you can check for version, e.g.:
    #   if float(api.glance.get_version()) < 2.0:
    mapping_to_v1 = {'public': True, 'private': False, 'shared': False}
    # note: presence of 'visibility' previously checked for in general call
    try:
        meta['is_public'] = mapping_to_v1[visibility]
    except KeyError as e:
        raise rest_utils.AjaxError(400,
                                   'invalid visibility option: %s' % e.args[0])
Пример #5
0
    def patch(self, request):
        """Update the values for Cinder specific quotas

        This method returns HTTP 204 (no content) on success.
        """
        if api.cinder.is_volume_service_enabled(request):
            cinder_data = {
                key: request.DATA[key] for key in quotas.CINDER_QUOTA_FIELDS
            }

            api.cinder.default_quota_update(request, **cinder_data)
        else:
            raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
Пример #6
0
    def post(self, request):
        """Create a server.

        Create a server using the parameters supplied in the POST
        application/json object. The required parameters as specified by
        the underlying novaclient are:

        :param name: The new server name.
        :param source_id: The ID of the image to use.
        :param flavor_id: The ID of the flavor to use.
        :param key_name: (optional extension) name of previously created
                      keypair to inject into the instance.
        :param user_data: user data to pass to be exposed by the metadata
                      server this can be a file type object as well or a
                      string.
        :param security_groups: An array of one or more objects with a "name"
            attribute.

        Other parameters are accepted as per the underlying novaclient:
        "block_device_mapping", "block_device_mapping_v2", "nics", "meta",
        "availability_zone", "instance_count", "admin_pass", "disk_config",
        "config_drive", "scheduler_hints", "min_inst_count"

        This returns the new server object on success.
        """
        try:
            args = (
                request,
                request.DATA['name'],
                request.DATA['source_id'],
                request.DATA['flavor_id'],
                request.DATA['key_name'],
                request.DATA['user_data'],
                request.DATA['security_groups'],
            )
        except KeyError as e:
            raise rest_utils.AjaxError(400, 'missing required parameter '
                                            "'%s'" % e.args[0])
        kw = {}
        for name in self._optional_create:
            if name in request.DATA:
                data = request.DATA[name]
                kw[name] = data

        new = api.nova.server_create(*args, **kw)
        return rest_utils.CreatedResponse(
            '/api/nova/servers/%s' % utils_http.urlquote(new.id),
            new.to_dict()
        )
Пример #7
0
    def post(self, request):
        """Perform some action on the collection of users.

        The POST data should be an application/json object with two
        parameters: "action" and "data".

        action = "delete"
            This action deletes multiple users in one call, using the list of
            ids (strings) passed in as data.

            This action returns HTTP 204 (no content) on success.

        action = "create"
            This action creates a user using the parameters supplied in
            "data". The base parameters are name (string), email (string,
            optional), password (string, optional), project_id (string,
            optional), enabled (boolean, defaults to true). The user will be
            created in the default domain.

            This action returns the new user object on success.

            This action returns HTTP 204 (no content) on success.
        """
        action = request.DATA['action']
        data = request.DATA['data']

        if action == 'delete':
            for user_id in data:
                if user_id != request.user.id:
                    api.keystone.user_delete(request, user_id)
        elif action == 'create':
            # not sure why email is forced to None, but other code does it
            domain = api.keystone.get_default_domain(request)
            new_user = api.keystone.user_create(
                request,
                name=data['name'],
                email=data.get('email') or None,
                password=data.get('password'),
                project=data.get('project_id'),
                enabled=True,
                domain=domain.id
            )
            return rest_utils.CreatedResponse(
                '/api/keystone/users/%s' % new_user.id,
                new_user.to_dict()
            )
        else:
            raise rest_utils.AjaxError(400, 'invalid action')
Пример #8
0
    def _verify_arguments(self, security_groups):
        try:
            args = (
                self.request,
                self.request.DATA['name'],
                self.request.DATA['source_id'],
                self.request.DATA['flavor'],
                self.request.DATA['key_name'],
                None,
                security_groups,
            )

        except KeyError as e:
            raise rest_utils.AjaxError(400, 'missing required parameter '
                                            "'%s'" % e.args[0])

        return args
Пример #9
0
    def get(self, request):
        if api.base.is_service_enabled(request, 'network'):
            quota_set = api.neutron.tenant_quota_get(
                request, request.user.tenant_id)

            result = [{
                'display_name': quotas.QUOTA_NAMES.get(
                    quota.name,
                    quota.name.replace('_', ' ').title()
                ) + '',
                'name': quota.name,
                'limit': quota.limit
            } for quota in quota_set]

            return {'items': result}
        else:
            raise rest_utils.AjaxError(501, _('Service Neutron is disabled.'))
Пример #10
0
    def post(self, request):
        """Perform some action on the collection of roles.

        The POST data should be an application/json object with two
        parameters: "action" and "data".

        action = "delete"
            This action deletes multiple roles in one call, using the list of
            ids (strings) passed in as data.

            This method returns HTTP 204 (no content) on success.

        action = "create"
            This action creates a role using the "name" (string) parameter
            supplied in the "data" object.

            This method returns the new role object on success.

        action = "grant"
            This action adds a role to a user using the parameters
            "user_id" (string), "project_id" (string) and "role_id" (string).

            This method returns HTTP 204 (no content) on success.
        """
        action = request.DATA['action']
        data = request.DATA['data']

        if action == 'delete':
            for role_id in data:
                api.keystone.role_delete(request, role_id)
        elif action == 'create':
            new_role = api.keystone.role_create(request, data['name'])
            return rest_utils.CreatedResponse(
                '/api/keystone/roles/%s' % new_role.id,
                new_role.to_dict()
            )
        elif action == 'grant':
            api.keystone.add_tenant_user_role(
                request,
                data['project_id'],
                data['user_id'],
                data['role_id']
            )
        else:
            raise rest_utils.AjaxError(400, 'invalid (unrecognised) action')
Пример #11
0
    def get(self, request):
        """Provides a list with the user's servers

        Example GET:
        http://localhost/api/extension/servers
        """
        try:
            instances, _more = server_list(
                request,
                search_opts=rest_utils.parse_filters_kwargs(request)[0])
        except Exception as e:
            raise rest_utils.AjaxError(400, 'Unable to retrieve instances. '
                                            "'%s'" % e.args[0])

        all_servers = [u.to_dict() for u in instances]

        return {
            'items': all_servers
        }
Пример #12
0
    def post(self, request, container, object_name):
        """Create or replace an object or pseudo-folder

        :param request:
        :param container:
        :param object_name:

        If the object_name (ie. POST path) ends in a '/' then a folder is
        created, rather than an object. Any file content passed along with
        the request will be ignored in that case.

        POST parameter:

        :param file: the file data for the upload.

        :return:
        """
        form = UploadObjectForm(request.POST, request.FILES)
        if not form.is_valid():
            raise rest_utils.AjaxError(500, 'Invalid request')

        data = form.clean()

        if object_name[-1] == '/':
            try:
                result = api.swift.swift_create_pseudo_folder(
                    request,
                    container,
                    object_name
                )
            except exceptions.AlreadyExists as e:
                return rest_utils.JSONResponse(str(e), 409)
        else:
            result = api.swift.swift_upload_object(
                request,
                container,
                object_name,
                data['file']
            )

        return rest_utils.CreatedResponse(
            u'/api/swift/containers/%s/object/%s' % (container, result.name)
        )
Пример #13
0
    def patch(self, request, project_id):
        """Update a single project quota data.

        The PATCH data should be an application/json object with the
        attributes to set to new quota values.

        This method returns HTTP 204 (no content) on success.
        """
        disabled_quotas = quotas.get_disabled_quotas(request)

        if api.base.is_service_enabled(request, 'compute'):
            nova_data = {
                key: request.DATA[key] for key in quotas.NOVA_QUOTA_FIELDS
                if key not in disabled_quotas
            }

            api.nova.tenant_quota_update(request, project_id, **nova_data)
        else:
            raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
Пример #14
0
    def delete(self, request):
        """Delete a list of servers.


        Example GET:
        http://localhost/api/nova/servers
        """
        try:
            args = (
                request,
                request.DATA['instances_ids'],
            )
        except KeyError as e:
            raise rest_utils.AjaxError(
                400, 'missing required parameter '
                "'%s'" % e.args[0])
        for id in request.DATA['instances_ids']:
            api.nova.reset_state(request, id, 'active')
            api.nova.server_delete(request, id)
Пример #15
0
 def get(self, request):
     """Get a list of cinder services.
     Will return HTTP 501 status code if the service_list extension is
     not supported.
     """
     if api.base.is_service_enabled(request, 'volume') and \
        api.cinder.extension_supported(request, 'Services'):
         result = api.cinder.service_list(request)
         return {'items': [{
             'binary': u.binary,
             'host': u.host,
             'zone': u.zone,
             'updated_at': u.updated_at,
             'status': u.status,
             'state': u.state,
             'id': idx + 1
         } for idx, u in enumerate(result)]}
     else:
         raise rest_utils.AjaxError(501, '')
Пример #16
0
    def post(self, request):
        """Create a project (tenant).

        Create a project using parameters supplied in the POST
        application/json object. The "name" (string) parameter is required,
        others are optional: "description" (string), "domain_id" (string) and
        "enabled" (boolean, defaults to true). Additional, undefined
        parameters may also be provided, but you'll have to look deep into
        keystone to figure out what they might be.

        This method returns the new project object on success.
        """
        kwargs = _tenant_kwargs_from_DATA(request.DATA)
        if not kwargs['name']:
            raise rest_utils.AjaxError(400, '"name" is required')
        new_project = api.keystone.tenant_create(request, **kwargs)
        return rest_utils.CreatedResponse(
            '/api/keystone/projects/%s' % new_project.id,
            new_project.to_dict())
Пример #17
0
    def create_instance(self, request, suffix=""):
        # Instances need to be created one by one, because each instance
        # needs to have it's own GBP port
        kw = {'instance_count': 1}

        # Mandatory creation arguments and port creation
        try:
            instance_name = request.DATA['name'] + suffix

            if "group_policy_targets" in request.DATA and (
                    request.DATA["group_policy_targets"]):
                meta_data, nics = self.create_ports(request, instance_name)

                kw['meta'] = meta_data
                kw['nics'] = nics
            else:
                if 'nics' in request.DATA:
                    kw['nics'] = request.DATA['nics']
                if 'meta' in request.DATA:
                    kw['meta'] = request.DATA['meta']

            args = (
                request,
                instance_name,
                request.DATA['source_id'],
                request.DATA['flavor_id'],
                request.DATA['key_name'],
                request.DATA['user_data'],
                request.DATA['security_groups'],
            )

        except KeyError as e:
            raise rest_utils.AjaxError(
                400, 'Missing required parameter '
                "'%s'" % e.args[0])

        # Optional creation arguments
        for name in self.optional_arguments:
            if name in request.DATA:
                kw[name] = request.DATA[name]

        return api.nova.server_create(*args, **kw)
Пример #18
0
    def post(self, request):
        try:
            args = (request, request.DATA['selected_range'],
                    request.DATA['instance_count'])
        except KeyError as e:
            raise rest_utils.AjaxError(
                400, 'missing required parameter'
                "'%s'" % e.args[0])

        selected_range = request.DATA['selected_range']
        instance_count = request.DATA['instance_count']

        unassigned_ips = set([
            addr.ip for addr in api.network.tenant_floating_ip_list(request)
            if addr.instance_id is None
        ])

        allocated_ips = set(
            [addr.ip for addr in api.network.tenant_floating_ip_list(request)])

        already_associated = list(allocated_ips - unassigned_ips)

        already_associated_set = IPSet(already_associated)

        already_associated_ranges = list(
            already_associated_set.iter_ipranges())

        ranges_set = IPSet(
            IPRange(selected_range['start'], selected_range['end']))

        for associated_range in already_associated_ranges:
            print(associated_range)
            ranges_set.remove(associated_range)

        available_ips = []

        for ip in ranges_set:
            if len(available_ips) < instance_count:
                available_ips.append(ip)
            else:
                break
        return {"available_ips": available_ips}
Пример #19
0
    def patch(self, request, project_id):
        """Update a single project quota data.

        The PATCH data should be an application/json object with the
        attributes to set to new quota values.

        This method returns HTTP 204 (no content) on success.
        """
        # Filters cinder quota fields
        disabled_quotas = quotas.get_disabled_quotas(request)

        if api.cinder.is_volume_service_enabled(request):
            cinder_data = {
                key: request.DATA[key] for key in quotas.CINDER_QUOTA_FIELDS
                if key not in disabled_quotas
            }

            api.cinder.tenant_quota_update(request, project_id, **cinder_data)
        else:
            raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
Пример #20
0
    def post(self, request):
        instance_count = request.DATA['instance_count']

        try:
            if instance_count == 1:
                self.create_instance(request)
            elif instance_count > 1:
                for i in range(0, instance_count):
                    self.create_instance(request, "_" + str(i))

        except Exception:
            instance_name = request.DATA['name']

            error = _("Unable to launch member %(count)s with name %(name)s")
            message = error % {'count': instance_count, 'name': instance_name}
            LOG.exception(message)

            raise rest_utils.AjaxError(400, message)

        return rest_utils.CreatedResponse('/api/nova/servers/%s')
Пример #21
0
    def patch(self, request):
        """Update the values for Nova specific quotas

        This method returns HTTP 204 (no content) on success.
        """
        if api.base.is_service_enabled(request, 'compute'):
            disabled_quotas = quotas.get_disabled_quotas(request)

            filtered_quotas = [quota for quota in quotas.NOVA_QUOTA_FIELDS
                               if quota not in disabled_quotas]

            request_data = {
                key: request.DATA.get(key, None) for key in filtered_quotas
            }

            nova_data = {key: value for key, value in request_data.items()
                         if value is not None}

            api.nova.default_quota_update(request, **nova_data)
        else:
            raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
Пример #22
0
    def post(self, request):
        """Perform some action on the collection of domains.

        The POST data should be an application/json object with two
        parameters: "action" and "data".

        action = "delete"
            This action deletes multiple domains in one call, using the list of
            ids (strings) passed in as data.

            This method returns HTTP 204 (no content) on success.

        action = "create"
            This action creates a domain using parameters supplied in the
            "data" object. The "name" (string) parameter is required, others
            are optional: "description" (string) and "enabled" (boolean,
            defaults to true).

            This method returns the new domain object on success.
        """
        action = request.DATA['action']
        data = request.DATA['data']

        if action == 'delete':
            for domain_id in data:
                api.keystone.domain_delete(request, domain_id)
        elif action == 'create':
            new_domain = api.keystone.domain_create(
                request,
                data['name'],
                description=data.get('description'),
                enabled=data.get('enabled', True),
            )
            return rest_utils.CreatedResponse(
                '/api/keystone/domains/%s' % new_domain.id,
                new_domain.to_dict()
            )
        else:
            raise rest_utils.AjaxError(400, 'invalid action')
Пример #23
0
def create_image_metadata(data):
    try:
        """Use the given dict of image form data to generate the metadata used for
        creating the image in glance.
        """

        meta = {
            'protected': data.get('protected'),
            'min_disk': data.get('min_disk', 0),
            'min_ram': data.get('min_ram', 0),
            'name': data.get('name'),
            'disk_format': data.get('disk_format'),
            'container_format': data.get('container_format')
        }
        properties = {}

        # 'architecture' will be directly mapped
        # into the .properties by the handle_unknown_properties function.
        # 'kernel' and 'ramdisk' need to get specifically mapped for backwards
        # compatibility.
        props = data.get('properties')
        if props and props.get('description'):
            properties['description'] = props.get('description')
        if data.get('kernel'):
            properties['kernel_id'] = data.get('kernel')
        if data.get('ramdisk'):
            properties['ramdisk_id'] = data.get('ramdisk')
        handle_unknown_properties(data, properties)
        if api.glance.VERSIONS.active >= 2:
            meta.update(properties)
        else:
            meta['properties'] = properties

        handle_visibility(data.get('visibility'), meta)

    except KeyError as e:
        raise rest_utils.AjaxError(400,
                                   'missing required parameter %s' % e.args[0])
    return meta
Пример #24
0
    def post(self, request):
        """Get a list of servers.

        The listing result is an object with property "items". Each item is
        a server.

        Example GET:
        http://localhost/api/nova/recover_servers/
        """
        try:
            args = (request, request.DATA['selectedInstances'])
        except KeyError as e:
            raise rest_utils.AjaxError(
                400, 'missing required parameter'
                "'%s'" % e.args[0])

        for ins in request.DATA['selectedInstances']:
            bdm = {'vda': ins['instance_volume_id'] + ':vol::false'}
            nic = [{
                'net-id': ins['net_id'],
                'v4-fixed-ip': ins['internal_ip']
            }]
            time.sleep(3)
            api.nova.server_create(request,
                                   name=ins['instance_name'],
                                   image='',
                                   flavor=ins['flavor_id'],
                                   key_name=None,
                                   user_data='',
                                   security_groups=[],
                                   block_device_mapping=bdm,
                                   nics=nic,
                                   disk_config="AUTO",
                                   config_drive=False)
            time.sleep(2)
            if ins['floating_ip'] is not None:
                api.nova.addExisitingFloatingIp(request, ins['instance_name'],
                                                ins['floating_ip'])
Пример #25
0
    def get(self, request):
        """Get the values for Cinder specific quotas

        Example GET:
        http://localhost/api/cinder/quota-sets/defaults/
        """
        if api.cinder.is_volume_service_enabled(request):
            quota_set = api.cinder.default_quota_get(request,
                                                     request.user.tenant_id)

            result = [{
                'display_name':
                quotas.QUOTA_NAMES.get(quota.name,
                                       quota.name.replace("_", " ").title()) +
                '',
                'name':
                quota.name,
                'limit':
                quota.limit
            } for quota in quota_set]
            return {'items': result}
        else:
            raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
Пример #26
0
    def post(self, request):
        '''Check policy rules.

        Check the group of policy rules supplied in the POST
        application/json object. The policy target, if specified will also be
        passed in to the policy check method as well.

        The action returns an object with one key: "allowed" and the value
        is the result of the policy check, True or False.
        '''

        rules = []
        try:
            rules_in = request.DATA['rules']
            rules = tuple([tuple(rule) for rule in rules_in])
        except Exception:
            raise rest_utils.AjaxError(400, 'unexpected parameter format')

        policy_target = request.DATA.get('target') or {}

        result = policy.check(rules, request, policy_target)

        return {"allowed": result}
Пример #27
0
    def post(self, request):
        """Export an EC2 instance to OpenStack
        :param request: HTTP request
        """
        try:
            args = (request, request.DATA['name'], request.DATA['source_id'],
                    request.DATA['flavor_id'], request.DATA['key_name'],
                    request.DATA['user_data'], request.DATA['security_groups'],
                    request.DATA.get('leave_original_instance'),
                    request.DATA.get('leave_instance_snapshot'))
        except KeyError as e:
            raise rest_utils.AjaxError(
                400, 'missing required parameter '
                "'%s'" % e.args[0])
        kw = {}
        for name in self._optional_create:
            if name in request.DATA:
                kw[name] = request.DATA[name]

        new = taskflow.run_export_instance_tasks(*args, **kw)
        return rest_utils.CreatedResponse(
            '/api/nova/servers/%s' % utils_http.urlquote(new.id),
            new.to_dict())
Пример #28
0
 def post(self, request):
     """Import an EC2 instance from OpenStack
     :param request: HTTP request
     """
     try:
         taskflow.run_import_instance_tasks(
             request,
             source_type=request.DATA.get("source_type", {}).get("type"),
             source_id=request.DATA.get("source_id"),
             flavor=request.DATA.get("flavor_id"),
             key_name=request.DATA.get("key_name"),
             security_groups=request.DATA.get("security_groups"),
             availability_zone=request.DATA.get("availability_zone"),
             instance_count=request.DATA.get("instance_count"),
             leave_original_instance=request.DATA.get(
                 "leave_original_instance"),
             leave_instance_snapshot=request.DATA.get(
                 "leave_instance_snapshot"))
     except KeyError as e:
         raise rest_utils.AjaxError(
             400, "missing required parameter "
             "'%s'" % e.args[0])
     return rest_utils.CreatedResponse("aws/ec2/instances", {})
Пример #29
0
    def post(self, request):
        """Create an EC2 instance
        :param request: HTTP request
        """
        try:
            instance_id = ec2.create_instance(
                request,
                name=request.DATA["name"],
                image_id=request.DATA["source_id"],
                flavor=request.DATA["flavor_id"],
                key_name=request.DATA["key_name"],
                security_groups=request.DATA.get("security_groups"),
                availability_zone=request.DATA.get("availability_zone", None),
                instance_count=request.DATA["instance_count"])
        except KeyError as e:
            raise rest_utils.AjaxError(
                400, "missing required parameter "
                "'%s'" % e.args[0])

        instance = ec2.get_instance(request, instance_id)
        return rest_utils.CreatedResponse(
            "aws/ec2/instances/%s" % utils_http.urlquote(instance_id),
            instance.to_dict())
 def f(self, request):
     raise utils.AjaxError(404, 'b0rk')