Exemplo n.º 1
0
def get_total_usages(req):
    """GET the sum of usages for a project or a project/user.

    On success return a 200 and an application/json body representing the
    sum/total of usages.
    Return 404 Not Found if the wanted microversion does not match.
    """
    context = req.environ['placement.context']

    schema = GET_USAGES_SCHEMA_1_9

    util.validate_query_params(req, schema)

    project_id = req.GET.get('project_id')
    user_id = req.GET.get('user_id')

    usages = rp_obj.UsageList.get_all_by_project_user(context,
                                                      project_id,
                                                      user_id=user_id)

    response = req.response
    usages_dict = {
        'usages':
        {resource.resource_class: resource.usage
         for resource in usages}
    }
    response.body = encodeutils.to_utf8(jsonutils.dumps(usages_dict))
    req.response.content_type = 'application/json'
    return req.response
Exemplo n.º 2
0
def get_total_usages(req):
    """GET the sum of usages for a project or a project/user.

    On success return a 200 and an application/json body representing the
    sum/total of usages.
    Return 404 Not Found if the wanted microversion does not match.
    """
    context = req.environ['placement.context']
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]

    util.validate_query_params(req, schema.GET_USAGES_SCHEMA_1_9)

    project_id = req.GET.get('project_id')
    user_id = req.GET.get('user_id')

    usages = rp_obj.UsageList.get_all_by_project_user(context, project_id,
                                                      user_id=user_id)

    response = req.response
    usages_dict = {'usages': {resource.resource_class: resource.usage
                   for resource in usages}}
    response.body = encodeutils.to_utf8(jsonutils.dumps(usages_dict))
    req.response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        req.response.cache_control = 'no-cache'
        # While it would be possible to generate a last-modified time
        # based on the collection of allocations that result in a usage
        # value (with some spelunking in the SQL) that doesn't align with
        # the question that is being asked in a request for usages: What
        # is the usage, now? So the last-modified time is set to utcnow.
        req.response.last_modified = timeutils.utcnow(with_timezone=True)
    return req.response
Exemplo n.º 3
0
def list_traits(req):
    context = req.environ['placement.context']
    context.can(policies.TRAITS_LIST)
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]
    filters = {}

    util.validate_query_params(req, schema.LIST_TRAIT_SCHEMA)

    if 'name' in req.GET:
        filters = _normalize_traits_qs_param(req.GET['name'])
    if 'associated' in req.GET:
        if req.GET['associated'].lower() not in ['true', 'false']:
            raise webob.exc.HTTPBadRequest(
                _('The query parameter "associated" only accepts '
                  '"true" or "false"'))
        filters['associated'] = (
            True if req.GET['associated'].lower() == 'true' else False)

    traits = rp_obj.TraitList.get_all(context, filters)
    req.response.status = 200
    output, last_modified = _serialize_traits(traits, want_version)
    if want_version.matches((1, 15)):
        req.response.last_modified = last_modified
        req.response.cache_control = 'no-cache'
    req.response.body = encodeutils.to_utf8(jsonutils.dumps(output))
    req.response.content_type = 'application/json'
    return req.response
Exemplo n.º 4
0
def list_allocation_candidates(req):
    """GET a JSON object with a list of allocation requests and a JSON object
    of provider summary objects

    On success return a 200 and an application/json body representing
    a collection of allocation requests and provider summaries
    """
    context = req.environ['placement.context']
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]
    schema = _GET_SCHEMA_1_10
    util.validate_query_params(req, schema)

    requests = util.parse_qs_request_groups(req.GET)

    try:
        cands = rp_obj.AllocationCandidates.get_by_requests(context, requests)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})

    response = req.response
    trx_cands = _transform_allocation_candidates(cands, want_version)
    json_data = jsonutils.dumps(trx_cands)
    response.body = encodeutils.to_utf8(json_data)
    response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        response.cache_control = 'no-cache'
        response.last_modified = timeutils.utcnow(with_timezone=True)
    return response
Exemplo n.º 5
0
def list_allocation_candidates(req):
    """GET a JSON object with a list of allocation requests and a JSON object
    of provider summary objects

    On success return a 200 and an application/json body representing
    a collection of allocation requests and provider summaries
    """
    context = req.environ['placement.context']
    schema = _GET_SCHEMA_1_10
    util.validate_query_params(req, schema)

    resources = util.normalize_resources_qs_param(req.GET['resources'])
    filters = {
        'resources': resources,
    }

    try:
        cands = rp_obj.AllocationCandidates.get_by_filters(context, filters)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})

    response = req.response
    trx_cands = _transform_allocation_candidates(cands)
    json_data = jsonutils.dumps(trx_cands)
    response.body = encodeutils.to_utf8(json_data)
    response.content_type = 'application/json'
    return response
Exemplo n.º 6
0
def list_resource_providers(req):
    """GET a list of resource providers.

    On success return a 200 and an application/json body representing
    a collection of resource providers.
    """
    context = req.environ['placement.context']
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]

    schema = GET_RPS_SCHEMA_1_0
    if want_version.matches((1, 14)):
        schema = GET_RPS_SCHEMA_1_14
    elif want_version.matches((1, 4)):
        schema = GET_RPS_SCHEMA_1_4
    elif want_version.matches((1, 3)):
        schema = GET_RPS_SCHEMA_1_3

    util.validate_query_params(req, schema)

    filters = {}
    for attr in ['uuid', 'name', 'member_of', 'in_tree']:
        if attr in req.GET:
            value = req.GET[attr]
            # special case member_of to always make its value a
            # list, either by accepting the single value, or if it
            # starts with 'in:' splitting on ','.
            # NOTE(cdent): This will all change when we start using
            # JSONSchema validation of query params.
            if attr == 'member_of':
                if value.startswith('in:'):
                    value = value[3:].split(',')
                else:
                    value = [value]
                # Make sure the values are actually UUIDs.
                for aggr_uuid in value:
                    if not uuidutils.is_uuid_like(aggr_uuid):
                        raise webob.exc.HTTPBadRequest(
                            _('Invalid uuid value: %(uuid)s') %
                            {'uuid': aggr_uuid})
            filters[attr] = value
    if 'resources' in req.GET:
        resources = util.normalize_resources_qs_param(req.GET['resources'])
        filters['resources'] = resources
    try:
        resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
            context, filters)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})

    response = req.response
    output, last_modified = _serialize_providers(
        req.environ, resource_providers, want_version)
    response.body = encodeutils.to_utf8(jsonutils.dumps(output))
    response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        response.last_modified = last_modified
        response.cache_control = 'no-cache'
    return response
Exemplo n.º 7
0
def list_traits(req):
    context = req.environ['placement.context']
    context.can(policies.TRAITS_LIST)
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]
    filters = {}

    util.validate_query_params(req, schema.LIST_TRAIT_SCHEMA)

    if 'name' in req.GET:
        filters = _normalize_traits_qs_param(req.GET['name'])
    if 'associated' in req.GET:
        if req.GET['associated'].lower() not in ['true', 'false']:
            raise webob.exc.HTTPBadRequest(
                _('The query parameter "associated" only accepts '
                  '"true" or "false"'))
        filters['associated'] = (
            True if req.GET['associated'].lower() == 'true' else False)

    traits = rp_obj.TraitList.get_all(context, filters)
    req.response.status = 200
    output, last_modified = _serialize_traits(traits, want_version)
    if want_version.matches((1, 15)):
        req.response.last_modified = last_modified
        req.response.cache_control = 'no-cache'
    req.response.body = encodeutils.to_utf8(jsonutils.dumps(output))
    req.response.content_type = 'application/json'
    return req.response
def list_allocation_candidates(req):
    """GET a JSON object with a list of allocation requests and a JSON object
    of provider summary objects

    On success return a 200 and an application/json body representing
    a collection of allocation requests and provider summaries
    """
    context = req.environ['placement.context']
    schema = _GET_SCHEMA_1_10
    util.validate_query_params(req, schema)

    resources = util.normalize_resources_qs_param(req.GET['resources'])
    filters = {
        'resources': resources,
    }

    try:
        cands = rp_obj.AllocationCandidates.get_by_filters(context, filters)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})

    response = req.response
    trx_cands = _transform_allocation_candidates(cands)
    json_data = jsonutils.dumps(trx_cands)
    response.body = encodeutils.to_utf8(json_data)
    response.content_type = 'application/json'
    return response
Exemplo n.º 9
0
def list_allocation_candidates(req):
    """GET a JSON object with a list of allocation requests and a JSON object
    of provider summary objects

    On success return a 200 and an application/json body representing
    a collection of allocation requests and provider summaries
    """
    context = req.environ['placement.context']
    context.can(policies.LIST)
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]
    get_schema = schema.GET_SCHEMA_1_10
    if want_version.matches((1, 25)):
        get_schema = schema.GET_SCHEMA_1_25
    elif want_version.matches((1, 21)):
        get_schema = schema.GET_SCHEMA_1_21
    elif want_version.matches((1, 17)):
        get_schema = schema.GET_SCHEMA_1_17
    elif want_version.matches((1, 16)):
        get_schema = schema.GET_SCHEMA_1_16
    util.validate_query_params(req, get_schema)

    requests = util.parse_qs_request_groups(req)
    limit = req.GET.getall('limit')
    # JSONschema has already confirmed that limit has the form
    # of an integer.
    if limit:
        limit = int(limit[0])

    group_policy = req.GET.getall('group_policy') or None
    # Schema ensures we get either "none" or "isolate"
    if group_policy:
        group_policy = group_policy[0]
    else:
        # group_policy is required if more than one numbered request group was
        # specified.
        if len([rg for rg in requests.values() if rg.use_same_provider]) > 1:
            raise webob.exc.HTTPBadRequest(
                _('The "group_policy" parameter is required when specifying '
                  'more than one "resources{N}" parameter.'))

    try:
        cands = rp_obj.AllocationCandidates.get_by_requests(
            context, requests, limit=limit, group_policy=group_policy)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})
    except exception.TraitNotFound as exc:
        raise webob.exc.HTTPBadRequest(six.text_type(exc))

    response = req.response
    trx_cands = _transform_allocation_candidates(cands, requests, want_version)
    json_data = jsonutils.dumps(trx_cands)
    response.body = encodeutils.to_utf8(json_data)
    response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        response.cache_control = 'no-cache'
        response.last_modified = timeutils.utcnow(with_timezone=True)
    return response
Exemplo n.º 10
0
def list_resource_providers(req):
    """GET a list of resource providers.

    On success return a 200 and an application/json body representing
    a collection of resource providers.
    """
    context = req.environ['placement.context']
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]

    schema = GET_RPS_SCHEMA_1_0
    if want_version == (1, 3):
        schema = GET_RPS_SCHEMA_1_3
    if want_version >= (1, 4):
        schema = GET_RPS_SCHEMA_1_4

    util.validate_query_params(req, schema)

    filters = {}
    for attr in ['uuid', 'name', 'member_of']:
        if attr in req.GET:
            value = req.GET[attr]
            # special case member_of to always make its value a
            # list, either by accepting the single value, or if it
            # starts with 'in:' splitting on ','.
            # NOTE(cdent): This will all change when we start using
            # JSONSchema validation of query params.
            if attr == 'member_of':
                if value.startswith('in:'):
                    value = value[3:].split(',')
                else:
                    value = [value]
                # Make sure the values are actually UUIDs.
                for aggr_uuid in value:
                    if not uuidutils.is_uuid_like(aggr_uuid):
                        raise webob.exc.HTTPBadRequest(
                            _('Invalid uuid value: %(uuid)s') %
                            {'uuid': aggr_uuid})
            filters[attr] = value
    if 'resources' in req.GET:
        resources = util.normalize_resources_qs_param(req.GET['resources'])
        filters['resources'] = resources
    try:
        resource_providers = objects.ResourceProviderList.get_all_by_filters(
            context, filters)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})

    response = req.response
    response.body = encodeutils.to_utf8(
        jsonutils.dumps(_serialize_providers(req.environ, resource_providers)))
    response.content_type = 'application/json'
    return response
Exemplo n.º 11
0
def list_allocation_candidates(req):
    """GET a JSON object with a list of allocation requests and a JSON object
    of provider summary objects

    On success return a 200 and an application/json body representing
    a collection of allocation requests and provider summaries
    """
    context = req.environ['placement.context']
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]
    get_schema = schema.GET_SCHEMA_1_10
    if want_version.matches((1, 21)):
        get_schema = schema.GET_SCHEMA_1_21
    elif want_version.matches((1, 17)):
        get_schema = schema.GET_SCHEMA_1_17
    elif want_version.matches((1, 16)):
        get_schema = schema.GET_SCHEMA_1_16
    util.validate_query_params(req, get_schema)

    # Control whether we handle forbidden traits.
    allow_forbidden = want_version.matches((1, 22))

    requests = util.parse_qs_request_groups(
        req.GET, allow_forbidden=allow_forbidden)
    limit = req.GET.getall('limit')
    # JSONschema has already confirmed that limit has the form
    # of an integer.
    if limit:
        limit = int(limit[0])

    try:
        cands = rp_obj.AllocationCandidates.get_by_requests(context, requests,
                                                            limit)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})
    except exception.TraitNotFound as exc:
        raise webob.exc.HTTPBadRequest(six.text_type(exc))

    response = req.response
    trx_cands = _transform_allocation_candidates(cands, want_version)
    json_data = jsonutils.dumps(trx_cands)
    response.body = encodeutils.to_utf8(json_data)
    response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        response.cache_control = 'no-cache'
        response.last_modified = timeutils.utcnow(with_timezone=True)
    return response
Exemplo n.º 12
0
def get_total_usages(req):
    """GET the sum of usages for a project or a project/user.

    On success return a 200 and an application/json body representing the
    sum/total of usages.
    Return 404 Not Found if the wanted microversion does not match.
    """
    context = req.environ['placement.context']
    # TODO(mriedem): When we support non-admins to use GET /usages we
    # should pass the project_id (and user_id?) from the query parameters
    # into context.can() for the target.
    context.can(policies.TOTAL_USAGES)
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]

    util.validate_query_params(req, schema.GET_USAGES_SCHEMA_1_9)

    project_id = req.GET.get('project_id')
    user_id = req.GET.get('user_id')

    usages = rp_obj.UsageList.get_all_by_project_user(context, project_id,
                                                      user_id=user_id)

    response = req.response
    usages_dict = {'usages': {resource.resource_class: resource.usage
                   for resource in usages}}
    response.body = encodeutils.to_utf8(jsonutils.dumps(usages_dict))
    req.response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        req.response.cache_control = 'no-cache'
        # While it would be possible to generate a last-modified time
        # based on the collection of allocations that result in a usage
        # value (with some spelunking in the SQL) that doesn't align with
        # the question that is being asked in a request for usages: What
        # is the usage, now? So the last-modified time is set to utcnow.
        req.response.last_modified = timeutils.utcnow(with_timezone=True)
    return req.response
Exemplo n.º 13
0
def list_resource_providers(req):
    """GET a list of resource providers.

    On success return a 200 and an application/json body representing
    a collection of resource providers.
    """
    context = req.environ['placement.context']
    context.can(policies.LIST)
    want_version = req.environ[microversion.MICROVERSION_ENVIRON]

    schema = rp_schema.GET_RPS_SCHEMA_1_0
    if want_version.matches((1, 18)):
        schema = rp_schema.GET_RPS_SCHEMA_1_18
    elif want_version.matches((1, 14)):
        schema = rp_schema.GET_RPS_SCHEMA_1_14
    elif want_version.matches((1, 4)):
        schema = rp_schema.GET_RPS_SCHEMA_1_4
    elif want_version.matches((1, 3)):
        schema = rp_schema.GET_RPS_SCHEMA_1_3

    allow_forbidden = want_version.matches((1, 22))

    util.validate_query_params(req, schema)

    filters = {}
    # special handling of member_of qparam since we allow multiple member_of
    # params at microversion 1.24.
    if 'member_of' in req.GET:
        filters['member_of'] = util.normalize_member_of_qs_params(req)

    qpkeys = ('uuid', 'name', 'in_tree', 'resources', 'required')
    for attr in qpkeys:
        if attr in req.GET:
            value = req.GET[attr]
            if attr == 'resources':
                value = util.normalize_resources_qs_param(value)
            elif attr == 'required':
                value = util.normalize_traits_qs_param(
                    value, allow_forbidden=allow_forbidden)
            filters[attr] = value
    try:
        resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
            context, filters)
    except exception.ResourceClassNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid resource class in resources parameter: %(error)s') %
            {'error': exc})
    except exception.TraitNotFound as exc:
        raise webob.exc.HTTPBadRequest(
            _('Invalid trait(s) in "required" parameter: %(error)s') %
            {'error': exc})

    response = req.response
    output, last_modified = _serialize_providers(
        req.environ, resource_providers, want_version)
    response.body = encodeutils.to_utf8(jsonutils.dumps(output))
    response.content_type = 'application/json'
    if want_version.matches((1, 15)):
        response.last_modified = last_modified
        response.cache_control = 'no-cache'
    return response