From 5734d078fc944b035c5873a7c61cafbede8304d3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 6 Jul 2017 09:32:49 +0100 Subject: [PATCH] placement: adds REST API for nested providers Adds a new microversion (1.14) to the placement REST API for supporting nested resource providers. For POST /resource_providers and PUT /resource_providers/{uuid}, a new optional 'parent_provider_uuid' field is added to the request payload. For GET /resource_providers/{uuid} responses, the 'parent_provider_uuid' field and a convenience field called 'root_provider_uuid' are provided. For GET /resource_providers, a new '?in_tree=' parameter is supported. This parameter accepts a UUID of a resource provider. This will cause the resulting list of resource providers to be only the providers within the same "provider tree" as the provider identified by Clients for the placement REST API can specify either 'OpenStack-API-Version: placement 1.14' or 'placement latest' to handle the new 'parent_provider_uuid' attribute and to query for resource providers in a provider tree. Change-Id: I4db74e4dc682bc03df6ec94cd1c3a5f5dc927a7b blueprint: nested-resource-providers APIImpact --- .../placement/handlers/resource_provider.py | 80 ++++++-- nova/api/openstack/placement/microversion.py | 3 + .../placement/rest_api_version_history.rst | 19 ++ .../api/openstack/placement/fixtures.py | 2 + .../placement/gabbits/microversion.yaml | 4 +- .../placement/gabbits/resource-provider.yaml | 175 +++++++++++++++++- .../create-resource_providers-request.json | 3 +- .../source/get-resource_provider.json | 4 +- .../source/get-resource_providers.json | 8 +- placement-api-ref/source/parameters.yaml | 36 ++++ .../source/resource_provider.inc | 6 +- .../source/resource_providers.inc | 6 +- .../update-resource_provider-request.json | 5 +- ...d-resource-providers-552a923a96d7adca.yaml | 13 ++ 14 files changed, 335 insertions(+), 29 deletions(-) create mode 100644 releasenotes/notes/placement-rest-api-nested-resource-providers-552a923a96d7adca.yaml diff --git a/nova/api/openstack/placement/handlers/resource_provider.py b/nova/api/openstack/placement/handlers/resource_provider.py index c504bc94f..81ecce086 100644 --- a/nova/api/openstack/placement/handlers/resource_provider.py +++ b/nova/api/openstack/placement/handlers/resource_provider.py @@ -41,13 +41,30 @@ POST_RESOURCE_PROVIDER_SCHEMA = { }, "required": [ "name" - ], + ], "additionalProperties": False, } # Remove uuid to create the schema for PUTting a resource provider PUT_RESOURCE_PROVIDER_SCHEMA = copy.deepcopy(POST_RESOURCE_PROVIDER_SCHEMA) PUT_RESOURCE_PROVIDER_SCHEMA['properties'].pop('uuid') +# Placement API microversion 1.14 adds an optional parent_provider_uuid field +# to the POST and PUT request schemas +POST_RP_SCHEMA_V1_14 = copy.deepcopy(POST_RESOURCE_PROVIDER_SCHEMA) +POST_RP_SCHEMA_V1_14["properties"]["parent_provider_uuid"] = { + "anyOf": [ + { + "type": "string", + "format": "uuid", + }, + { + "type": "null", + } + ] +} +PUT_RP_SCHEMA_V1_14 = copy.deepcopy(POST_RP_SCHEMA_V1_14) +PUT_RP_SCHEMA_V1_14['properties'].pop('uuid') + # Represents the allowed query string parameters to the GET /resource_providers # API call GET_RPS_SCHEMA_1_0 = { @@ -80,6 +97,17 @@ GET_RPS_SCHEMA_1_4['properties']['resources'] = { "type": "string" } +# Placement API microversion 1.14 adds support for requesting resource +# providers within a tree of providers. The 'in_tree' query string parameter +# should be the UUID of a resource provider. The result of the GET call will +# include only those resource providers in the same "provider tree" as the +# provider with the UUID represented by 'in_tree' +GET_RPS_SCHEMA_1_14 = copy.deepcopy(GET_RPS_SCHEMA_1_4) +GET_RPS_SCHEMA_1_14['properties']['in_tree'] = { + "type": "string", + "format": "uuid", +} + def _serialize_links(environ, resource_provider): url = util.resource_provider_url(environ, resource_provider) @@ -97,20 +125,23 @@ def _serialize_links(environ, resource_provider): return links -def _serialize_provider(environ, resource_provider): +def _serialize_provider(environ, resource_provider, want_version): data = { 'uuid': resource_provider.uuid, 'name': resource_provider.name, 'generation': resource_provider.generation, 'links': _serialize_links(environ, resource_provider) } + if want_version.matches((1, 14)): + data['parent_provider_uuid'] = resource_provider.parent_provider_uuid + data['root_provider_uuid'] = resource_provider.root_provider_uuid return data -def _serialize_providers(environ, resource_providers): +def _serialize_providers(environ, resource_providers, want_version): output = [] for provider in resource_providers: - provider_data = _serialize_provider(environ, provider) + provider_data = _serialize_provider(environ, provider, want_version) output.append(provider_data) return {"resource_providers": output} @@ -124,12 +155,15 @@ def create_resource_provider(req): header pointing to the newly created resource provider. """ context = req.environ['placement.context'] - data = util.extract_json(req.body, POST_RESOURCE_PROVIDER_SCHEMA) + schema = POST_RESOURCE_PROVIDER_SCHEMA + want_version = req.environ[microversion.MICROVERSION_ENVIRON] + if want_version.matches((1, 14)): + schema = POST_RP_SCHEMA_V1_14 + data = util.extract_json(req.body, schema) try: - uuid = data.get('uuid', uuidutils.generate_uuid()) - resource_provider = rp_obj.ResourceProvider( - context, name=data['name'], uuid=uuid) + uuid = data.setdefault('uuid', uuidutils.generate_uuid()) + resource_provider = rp_obj.ResourceProvider(context, **data) resource_provider.create() except db_exc.DBDuplicateEntry as exc: # Whether exc.columns has one or two entries (in the event @@ -192,8 +226,9 @@ def get_resource_provider(req): resource_provider = rp_obj.ResourceProvider.get_by_uuid( context, uuid) + want_version = req.environ[microversion.MICROVERSION_ENVIRON] req.response.body = encodeutils.to_utf8(jsonutils.dumps( - _serialize_provider(req.environ, resource_provider))) + _serialize_provider(req.environ, resource_provider, want_version))) req.response.content_type = 'application/json' return req.response @@ -210,15 +245,17 @@ def list_resource_providers(req): 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): + 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']: + 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 @@ -250,8 +287,8 @@ def list_resource_providers(req): {'error': exc}) response = req.response - response.body = encodeutils.to_utf8( - jsonutils.dumps(_serialize_providers(req.environ, resource_providers))) + response.body = encodeutils.to_utf8(jsonutils.dumps( + _serialize_providers(req.environ, resource_providers, want_version))) response.content_type = 'application/json' return response @@ -271,9 +308,16 @@ def update_resource_provider(req): resource_provider = rp_obj.ResourceProvider.get_by_uuid( context, uuid) - data = util.extract_json(req.body, PUT_RESOURCE_PROVIDER_SCHEMA) + schema = PUT_RESOURCE_PROVIDER_SCHEMA + want_version = req.environ[microversion.MICROVERSION_ENVIRON] + if want_version.matches((1, 14)): + schema = PUT_RP_SCHEMA_V1_14 - resource_provider.name = data['name'] + data = util.extract_json(req.body, schema) + + for field in rp_obj.ResourceProvider.SETTABLE_FIELDS: + if field in data: + setattr(resource_provider, field, data[field]) try: resource_provider.save() @@ -287,7 +331,7 @@ def update_resource_provider(req): {'rp_uuid': uuid, 'error': exc}) req.response.body = encodeutils.to_utf8(jsonutils.dumps( - _serialize_provider(req.environ, resource_provider))) + _serialize_provider(req.environ, resource_provider, want_version))) req.response.status = 200 req.response.content_type = 'application/json' return req.response diff --git a/nova/api/openstack/placement/microversion.py b/nova/api/openstack/placement/microversion.py index 323e68b4d..d4a6a20cf 100644 --- a/nova/api/openstack/placement/microversion.py +++ b/nova/api/openstack/placement/microversion.py @@ -54,6 +54,9 @@ VERSIONS = [ # as GET. The 'allocation_requests' format in GET # /allocation_candidates is updated to be the same as well. '1.13', # Adds POST /allocations to set allocations for multiple consumers + # as GET + '1.14', # Adds parent and root provider UUID on resource provider + # representation and 'in_tree' filter on GET /resource_providers ] diff --git a/nova/api/openstack/placement/rest_api_version_history.rst b/nova/api/openstack/placement/rest_api_version_history.rst index b4a2c1827..5dc510a18 100644 --- a/nova/api/openstack/placement/rest_api_version_history.rst +++ b/nova/api/openstack/placement/rest_api_version_history.rst @@ -178,3 +178,22 @@ with the new `PUT` format. Version 1.13 gives the ability to set or clear allocations for more than one consumer uuid with a request to ``POST /allocations``. + +1.14 Add nested resource providers +---------------------------------- + +The 1.14 version introduces the concept of nested resource providers. The +resource provider resource now contains two new attributes: + +* ``parent_provider_uuid`` indicates the provider's direct parent, or null if + there is no parent. This attribute can be set in the call to ``POST + /resource_providers`` and ``PUT /resource_providers/{uuid}`` if the attribute + has not already been set to a non-NULL value (i.e. we do not support + "reparenting" a provider) +* ``root_provider_uuid`` indicates the UUID of the root resource provider in + the provider's tree. This is a read-only attribute + +A new ``in_tree=`` parameter is now available in the ``GET +/resource-providers`` API call. Supplying a UUID value for the ``in_tree`` +parameter will cause all resource providers within the "provider tree" of the +provider matching ```` to be returned. diff --git a/nova/tests/functional/api/openstack/placement/fixtures.py b/nova/tests/functional/api/openstack/placement/fixtures.py index f419cd4f8..9e9634678 100644 --- a/nova/tests/functional/api/openstack/placement/fixtures.py +++ b/nova/tests/functional/api/openstack/placement/fixtures.py @@ -85,6 +85,8 @@ class APIFixture(fixture.GabbiFixture): os.environ['INSTANCE_UUID'] = uuidutils.generate_uuid() os.environ['MIGRATION_UUID'] = uuidutils.generate_uuid() os.environ['CONSUMER_UUID'] = uuidutils.generate_uuid() + os.environ['PARENT_PROVIDER_UUID'] = uuidutils.generate_uuid() + os.environ['ALT_PARENT_PROVIDER_UUID'] = uuidutils.generate_uuid() def stop_fixture(self): self.api_db_fixture.cleanup() diff --git a/nova/tests/functional/api/openstack/placement/gabbits/microversion.yaml b/nova/tests/functional/api/openstack/placement/gabbits/microversion.yaml index ccbdcbb8c..c2e8b6deb 100644 --- a/nova/tests/functional/api/openstack/placement/gabbits/microversion.yaml +++ b/nova/tests/functional/api/openstack/placement/gabbits/microversion.yaml @@ -39,13 +39,13 @@ tests: response_json_paths: $.errors[0].title: Not Acceptable -- name: latest microversion is 1.13 +- name: latest microversion is 1.14 GET: / request_headers: openstack-api-version: placement latest response_headers: vary: /OpenStack-API-Version/ - openstack-api-version: placement 1.13 + openstack-api-version: placement 1.14 - name: other accept header bad version GET: / diff --git a/nova/tests/functional/api/openstack/placement/gabbits/resource-provider.yaml b/nova/tests/functional/api/openstack/placement/gabbits/resource-provider.yaml index 8c2ac663f..c0c7f53ce 100644 --- a/nova/tests/functional/api/openstack/placement/gabbits/resource-provider.yaml +++ b/nova/tests/functional/api/openstack/placement/gabbits/resource-provider.yaml @@ -6,6 +6,7 @@ defaults: request_headers: x-auth-token: admin accept: application/json + openstack-api-version: placement latest tests: @@ -80,6 +81,7 @@ tests: response_json_paths: $.uuid: $ENVIRON['RP_UUID'] $.name: $ENVIRON['RP_NAME'] + $.parent_provider_uuid: null $.generation: 0 $.links[?rel = "self"].href: /resource_providers/$ENVIRON['RP_UUID'] $.links[?rel = "inventories"].href: /resource_providers/$ENVIRON['RP_UUID']/inventories @@ -107,6 +109,7 @@ tests: $.resource_providers[0].uuid: $ENVIRON['RP_UUID'] $.resource_providers[0].name: $ENVIRON['RP_NAME'] $.resource_providers[0].generation: 0 + $.resource_providers[0].parent_provider_uuid: null $.resource_providers[0].links[?rel = "self"].href: /resource_providers/$ENVIRON['RP_UUID'] $.resource_providers[0].links[?rel = "inventories"].href: /resource_providers/$ENVIRON['RP_UUID']/inventories $.resource_providers[0].links[?rel = "usages"].href: /resource_providers/$ENVIRON['RP_UUID']/usages @@ -174,7 +177,7 @@ tests: $.resource_providers[0].links[?rel = "inventories"].href: /resource_providers/$ENVIRON['RP_UUID']/inventories $.resource_providers[0].links[?rel = "usages"].href: /resource_providers/$ENVIRON['RP_UUID']/usages -- name: update a resource provider +- name: update a resource provider's name PUT: /resource_providers/$RESPONSE['$.resource_providers[0].uuid'] request_headers: content-type: application/json @@ -208,6 +211,174 @@ tests: response_json_paths: $.errors[0].title: Bad Request +# This section of tests validate nested resource provider relationships and +# constraints. We attempt to set the parent provider UUID for the primary +# resource provider to a UUID value of a provider we have not yet created and +# expect a failure. We then create that parent provider record and attempt to +# set the same parent provider UUID without also setting the root provider UUID +# to the same value, with an expected failure. Finally, we set the primary +# provider's root AND parent to the new provider UUID and verify success. + +- name: test POST microversion limits nested providers + POST: /resource_providers + request_headers: + openstack-api-version: placement 1.13 + content-type: application/json + data: + name: child + parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 'JSON does not validate' + +- name: test PUT microversion limits nested providers + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + openstack-api-version: placement 1.13 + content-type: application/json + data: + name: child + parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 'JSON does not validate' + +- name: fail trying to set a root provider UUID + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + data: + root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 'JSON does not validate' + +- name: fail trying to self-parent + POST: /resource_providers + request_headers: + content-type: application/json + data: + name: child + uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID'] + parent_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 'parent provider UUID cannot be same as UUID' + +- name: update a parent provider UUID to non-existing provider + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + data: + name: parent + parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 'parent provider UUID does not exist' + +- name: now create the parent provider + POST: /resource_providers + request_headers: + content-type: application/json + data: + name: parent + uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 201 + +- name: get provider with old microversion no root provider UUID field + GET: /resource_providers/$ENVIRON['PARENT_PROVIDER_UUID'] + request_headers: + openstack-api-version: placement 1.13 + content-type: application/json + response_json_paths: + $.`len`: 4 + name: parent + status: 200 + +- name: get provider has root provider UUID field + GET: /resource_providers/$ENVIRON['PARENT_PROVIDER_UUID'] + request_headers: + content-type: application/json + response_json_paths: + $.`len`: 6 + name: parent + root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + parent_provider_uuid: null + status: 200 + +- name: update a parent + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + data: + name: child + parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 200 + +- name: get provider has new parent and root provider UUID field + GET: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + response_json_paths: + name: child + root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + status: 200 + +- name: fail trying to un-parent + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + data: + name: child + parent_provider_uuid: null + status: 400 + response_strings: + - 'un-parenting a provider is not currently allowed' + +- name: list all resource providers in a tree that does not exist + GET: /resource_providers?in_tree=$ENVIRON['ALT_PARENT_PROVIDER_UUID'] + response_json_paths: + $.resource_providers.`len`: 0 + +- name: list all resource providers in a tree with multiple providers in tree + GET: /resource_providers?in_tree=$ENVIRON['RP_UUID'] + response_json_paths: + $.resource_providers.`len`: 2 + # Verify that we have both the parent and child in the list + $.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + $.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID'] + +- name: create a new parent provider + POST: /resource_providers + request_headers: + content-type: application/json + data: + name: altwparent + uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID'] + status: 201 + response_headers: + location: //resource_providers/[a-f0-9-]+/ + response_forbidden_headers: + - content-type + +- name: list all resource providers in a tree + GET: /resource_providers?in_tree=$ENVIRON['ALT_PARENT_PROVIDER_UUID'] + response_json_paths: + $.resource_providers.`len`: 1 + $.resource_providers[?uuid="$ENVIRON['ALT_PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID'] + +- name: fail trying to re-parent to a different provider + PUT: /resource_providers/$ENVIRON['RP_UUID'] + request_headers: + content-type: application/json + data: + name: child + parent_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID'] + status: 400 + response_strings: + - 're-parenting a provider is not currently allowed' + - name: create a new provider POST: /resource_providers request_headers: @@ -221,7 +392,7 @@ tests: request_headers: content-type: application/json data: - name: new name + name: child status: 409 response_json_paths: $.errors[0].title: Conflict diff --git a/placement-api-ref/source/create-resource_providers-request.json b/placement-api-ref/source/create-resource_providers-request.json index b6613a0a9..4b3dcd871 100644 --- a/placement-api-ref/source/create-resource_providers-request.json +++ b/placement-api-ref/source/create-resource_providers-request.json @@ -1,4 +1,5 @@ { "name": "NFS Share", - "uuid": "7d2590ae-fb85-4080-9306-058b4c915e3f" + "uuid": "7d2590ae-fb85-4080-9306-058b4c915e3f", + "parent_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8" } diff --git a/placement-api-ref/source/get-resource_provider.json b/placement-api-ref/source/get-resource_provider.json index 7f65c1c1f..9a79680eb 100644 --- a/placement-api-ref/source/get-resource_provider.json +++ b/placement-api-ref/source/get-resource_provider.json @@ -27,5 +27,7 @@ } ], "name": "Ceph Storage Pool", - "uuid": "3b4005be-d64b-456f-ba36-0ffd02718868" + "uuid": "3b4005be-d64b-456f-ba36-0ffd02718868", + "parent_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8", + "root_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8" } diff --git a/placement-api-ref/source/get-resource_providers.json b/placement-api-ref/source/get-resource_providers.json index a5a32a946..33509c977 100644 --- a/placement-api-ref/source/get-resource_providers.json +++ b/placement-api-ref/source/get-resource_providers.json @@ -29,7 +29,9 @@ "rel": "allocations" } ], - "name": "vgr.localdomain" + "name": "vgr.localdomain", + "parent_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8", + "root_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8" }, { "generation": 2, @@ -60,7 +62,9 @@ "rel": "allocations" } ], - "name": "pony1" + "name": "pony1", + "parent_provider_uuid": null, + "root_provider_uuid": "d0b381e9-8761-42de-8e6c-bba99a96d5f5" } ] } diff --git a/placement-api-ref/source/parameters.yaml b/placement-api-ref/source/parameters.yaml index b2f49f232..faca44710 100644 --- a/placement-api-ref/source/parameters.yaml +++ b/placement-api-ref/source/parameters.yaml @@ -58,6 +58,14 @@ resource_provider_name_query: required: false description: > The name of a resource provider to filter the list. +resource_provider_tree_query: + type: string + in: query + required: false + description: > + A UUID of a resource provider. The returned resource providers will be in + the same "provider tree" as the specified provider. + min_version: 1.14 resource_provider_uuid_query: <<: *resource_provider_uuid_path in: query @@ -290,6 +298,34 @@ resource_provider_object: required: true description: > A dictionary which contains the UUID of the resource provider. +resource_provider_parent_provider_uuid: + type: string + in: body + required: false + description: > + The UUID of the immediate parent of the resource provider. + min_version: 1.14 +resource_provider_parent_provider_uuid_required: + type: string + in: body + required: true + description: > + The UUID of the immediate parent of the resource provider. + min_version: 1.14 +resource_provider_root_provider_uuid: + type: string + in: body + required: false + description: > + Read-only UUID of the top-most provider in this provider tree. + min_version: 1.14 +resource_provider_root_provider_uuid_required: + type: string + in: body + required: true + description: > + Read-only UUID of the top-most provider in this provider tree. + min_version: 1.14 resource_provider_usages: type: object in: body diff --git a/placement-api-ref/source/resource_provider.inc b/placement-api-ref/source/resource_provider.inc index bc1dcbbd7..21bd87d50 100644 --- a/placement-api-ref/source/resource_provider.inc +++ b/placement-api-ref/source/resource_provider.inc @@ -34,7 +34,8 @@ Response - uuid: resource_provider_uuid - links: resource_provider_links - name: resource_provider_name - + - parent_provider_uuid: resource_provider_parent_provider_uuid_required + - root_provider_uuid: resource_provider_root_provider_uuid_required Response Example ---------------- @@ -63,6 +64,7 @@ Request - uuid: resource_provider_uuid_path - name: resource_provider_name + - parent_provider_uuid: resource_provider_parent_provider_uuid Request example --------------- @@ -79,6 +81,8 @@ Response - uuid: resource_provider_uuid - links: resource_provider_links - name: resource_provider_name + - parent_provider_uuid: resource_provider_parent_provider_uuid_required + - root_provider_uuid: resource_provider_root_provider_uuid_required Response Example ---------------- diff --git a/placement-api-ref/source/resource_providers.inc b/placement-api-ref/source/resource_providers.inc index b0bdc5ff5..cffd98a7a 100644 --- a/placement-api-ref/source/resource_providers.inc +++ b/placement-api-ref/source/resource_providers.inc @@ -28,6 +28,7 @@ of all filters are merged with a boolean `AND`. - uuid: resource_provider_uuid_query - member_of: member_of - resources: resources_query + - in_tree: resource_provider_tree_query Response -------- @@ -39,7 +40,8 @@ Response - uuid: resource_provider_uuid - links: resource_provider_links - name: resource_provider_name - + - parent_provider_uuid: resource_provider_parent_provider_uuid + - root_provider_uuid: resource_provider_root_provider_uuid Response Example ---------------- @@ -69,6 +71,8 @@ Request - name: resource_provider_name - uuid: resource_provider_uuid_opt + - parent_provider_uuid: resource_provider_parent_provider_uuid + - root_provider_uuid: resource_provider_root_provider_uuid Request example --------------- diff --git a/placement-api-ref/source/update-resource_provider-request.json b/placement-api-ref/source/update-resource_provider-request.json index 72673db21..e3df4d590 100644 --- a/placement-api-ref/source/update-resource_provider-request.json +++ b/placement-api-ref/source/update-resource_provider-request.json @@ -1 +1,4 @@ - {"name": "Shared storage"} + { + "name": "Shared storage", + "parent_provider_uuid": "542df8ed-9be2-49b9-b4db-6d3183ff8ec8" + } diff --git a/releasenotes/notes/placement-rest-api-nested-resource-providers-552a923a96d7adca.yaml b/releasenotes/notes/placement-rest-api-nested-resource-providers-552a923a96d7adca.yaml new file mode 100644 index 000000000..548c4c93d --- /dev/null +++ b/releasenotes/notes/placement-rest-api-nested-resource-providers-552a923a96d7adca.yaml @@ -0,0 +1,13 @@ +--- +features: + - New placement REST API microversion 1.14 is added to support nested + resource providers. Users of the placement REST API can now pass a + ``in_tree=`` parameter to the ``GET /resource_providers`` REST API + call. This will trigger the placement service to return all resource + provider records within the "provider tree" of the resource provider with + the supplied UUID value. The resource provider representation now includes + a ``parent_provider_uuid`` value that indicates the UUID of the immediate + parent resource provider, or ``null`` if the provider has no parent. For + convenience, the resource provider resource also contains a + ``root_provider_uuid`` field that is populated with the UUID of the + top-most resource provider in the provider tree.