placement: Add support for resource provider aggregates

This is exposed as methods on the 'ResourceProvider' resource since
these don't make a whole lot of sense as separate resources.

Change-Id: Ief0cad2900573b4a6591ab4042a55714baad085a
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2023-07-11 16:22:50 +01:00
parent 15207b2070
commit ebd4d75418
6 changed files with 152 additions and 8 deletions

View File

@ -14,19 +14,21 @@ Resource Classes
^^^^^^^^^^^^^^^^
.. autoclass:: openstack.placement.v1._proxy.Proxy
:noindex:
:members: create_resource_class, update_resource_class,
delete_resource_class, get_resource_class,
resource_classes
:noindex:
:members: create_resource_class, update_resource_class,
delete_resource_class, get_resource_class,
resource_classes
Resource Providers
^^^^^^^^^^^^^^^^^^
.. autoclass:: openstack.placement.v1._proxy.Proxy
:noindex:
:members: create_resource_provider, update_resource_provider,
delete_resource_provider, get_resource_provider,
find_resource_provider, resource_providers
:noindex:
:members: create_resource_provider, update_resource_provider,
delete_resource_provider, get_resource_provider,
find_resource_provider, resource_providers,
get_resource_provider_aggregates,
set_resource_provider_aggregates
Resource Provider Inventories
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -209,6 +209,50 @@ class Proxy(proxy.Proxy):
"""
return self._list(_resource_provider.ResourceProvider, **query)
# resource provider aggregates
def get_resource_provider_aggregates(self, resource_provider):
"""Get a list of aggregates for a resource provider.
:param resource_provider: The value can be either the ID of a resource
provider or an
:class:`~openstack.placement.v1.resource_provider.ResourceProvider`,
instance.
:returns: An instance of
:class:`~openstack.placement.v1.resource_provider.ResourceProvider`
with the ``aggregates`` attribute populated.
:raises: :class:`~openstack.exceptions.ResourceNotFound` when no
resource provider matching the criteria could be found.
"""
res = self._get_resource(
_resource_provider.ResourceProvider,
resource_provider,
)
return res.fetch_aggregates(self)
def set_resource_provider_aggregates(self, resource_provider, *aggregates):
"""Update aggregates for a resource provider.
:param resource_provider: The value can be either the ID of a resource
provider or an
:class:`~openstack.placement.v1.resource_provider.ResourceProvider`,
instance.
:param aggregates: A list of aggregates. These aggregates will replace
all aggregates currently present.
:returns: An instance of
:class:`~openstack.placement.v1.resource_provider.ResourceProvider`
with the ``aggregates`` attribute populated with the updated value.
:raises: :class:`~openstack.exceptions.ResourceNotFound` when no
resource provider matching the criteria could be found.
"""
res = self._get_resource(
_resource_provider.ResourceProvider,
resource_provider,
)
return res.set_aggregates(self, aggregates=aggregates)
# resource provider inventories
def create_resource_provider_inventory(

View File

@ -10,7 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import exceptions
from openstack import resource
from openstack import utils
class ResourceProvider(resource.Resource):
@ -45,6 +47,8 @@ class ResourceProvider(resource.Resource):
# Properties
#: Aggregates
aggregates = resource.Body('aggregates', type=list, list_type=str)
#: The UUID of a resource provider.
id = resource.Body('uuid', alternate_id=True)
#: A consistent view marker that assists with the management of concurrent
@ -59,3 +63,52 @@ class ResourceProvider(resource.Resource):
parent_provider_id = resource.Body('parent_provider_uuid')
#: Read-only UUID of the top-most provider in this provider tree.
root_provider_id = resource.Body('root_provider_uuid')
def fetch_aggregates(self, session):
"""List aggregates set on the resource provider
:param session: The session to use for making this request
:return: The resource provider with aggregates populated
"""
url = utils.urljoin(self.base_path, self.id, 'aggregates')
microversion = self._get_microversion(session, action='fetch')
response = session.get(url, microversion=microversion)
exceptions.raise_from_response(response)
data = response.json()
updates = {'aggregates': data['aggregates']}
if utils.supports_microversion(session, '1.19'):
updates['generation'] = data['resource_provider_generation']
self._body.attributes.update(updates)
return self
def set_aggregates(self, session, aggregates=None):
"""Replaces aggregates on the resource provider
:param session: The session to use for making this request
:param list aggregates: List of aggregates
:return: The resource provider with updated aggregates populated
"""
url = utils.urljoin(self.base_path, self.id, 'aggregates')
microversion = self._get_microversion(session, action='commit')
body = {
'aggregates': aggregates or [],
}
if utils.supports_microversion(session, '1.19'):
body['resource_provider_generation'] = self.generation
response = session.put(url, json=body, microversion=microversion)
exceptions.raise_from_response(response)
data = response.json()
updates = {'aggregates': data['aggregates']}
if 'resource_provider_generation' in data:
updates['resource_provider_generation'] = data[
'resource_provider_generation'
]
self._body.attributes.update(updates)
return self

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from openstack.placement.v1 import resource_provider as _resource_provider
from openstack.tests.functional import base
@ -93,3 +95,25 @@ class TestResourceProvider(base.BaseFunctionalTest):
new_resource_provider_name,
resource_provider.name,
)
def test_resource_provider_aggregates(self):
aggregates = [uuid.uuid4().hex, uuid.uuid4().hex]
# update the resource provider aggregates
resource_provider = (
self.operator_cloud.placement.set_resource_provider_aggregates(
self.resource_provider,
*aggregates,
)
)
self.assertCountEqual(aggregates, resource_provider.aggregates)
# retrieve details of resource provider aggregates
resource_provider = (
self.operator_cloud.placement.get_resource_provider_aggregates(
self.resource_provider,
)
)
self.assertCountEqual(aggregates, resource_provider.aggregates)

View File

@ -90,6 +90,23 @@ class TestPlacementResourceProvider(TestPlacementProxy):
resource_provider.ResourceProvider,
)
def test_resource_provider_set_aggregates(self):
self._verify(
'openstack.placement.v1.resource_provider.ResourceProvider.set_aggregates',
self.proxy.set_resource_provider_aggregates,
method_args=['value', 'a', 'b'],
expected_args=[self.proxy],
expected_kwargs={'aggregates': ('a', 'b')},
)
def test_resource_provider_get_aggregates(self):
self._verify(
'openstack.placement.v1.resource_provider.ResourceProvider.fetch_aggregates',
self.proxy.get_resource_provider_aggregates,
method_args=['value'],
expected_args=[self.proxy],
)
class TestPlacementResourceProviderInventory(TestPlacementProxy):
def test_resource_provider_inventory_create(self):

View File

@ -0,0 +1,4 @@
---
features:
- |
Add support for aggregates to the ``ResourceProvider`` Placement resource.