Add support for the GroupType resource

Introduce the GroupType resource, fill in its
resources, and implement API calls to support the
Cinder v3 API

Task: 41856
Story: 2008619
Task: 42191
Story: 2008621
Change-Id: I32b7d6861ed9b15bb0fac1af4acde50c1f3f847a
This commit is contained in:
Dylan Zapzalka 2021-03-31 17:29:48 -05:00
parent 5f892ab13a
commit 6327052ef0
5 changed files with 241 additions and 0 deletions

View File

@ -14,6 +14,7 @@ from openstack.block_storage import _base_proxy
from openstack.block_storage.v3 import availability_zone
from openstack.block_storage.v3 import backup as _backup
from openstack.block_storage.v3 import capabilities as _capabilities
from openstack.block_storage.v3 import group_type as _group_type
from openstack.block_storage.v3 import limits as _limits
from openstack.block_storage.v3 import resource_filter as _resource_filter
from openstack.block_storage.v3 import snapshot as _snapshot
@ -549,6 +550,101 @@ class Proxy(_base_proxy.BaseBlockStorageProxy):
return self._list(availability_zone.AvailabilityZone)
def get_group_type(self, group_type):
"""Get a specific group type
:param group_type: The value can be the ID of a group type
or a :class:`~openstack.block_storage.v3.group_type.GroupType`
instance.
:returns: One :class:
`~openstack.block_storage.v3.group_type.GroupType` instance.
:raises: :class:`~openstack.exceptions.ResourceNotFound` when no
resource can be found.
"""
return self._get(_group_type.GroupType, group_type)
def find_group_type(self, name_or_id, ignore_missing=True):
"""Find a single group type
:param name_or_id: The name or ID of a group type.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be raised
when the group type does not exist.
:returns: One :class:`~openstack.block_storage.v3.group_type
.GroupType'
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._find(
_group_type.GroupType, name_or_id, ignore_missing=ignore_missing)
def group_types(self, **query):
"""Retrive a generator of group types
:param dict query: Optional query parameters to be sent to limit the
resources being returned:
* sort: Comma-separated list of sort keys and optional sort
directions in the form of <key> [:<direction>]. A valid
direction is asc (ascending) or desc (descending).
* limit: Requests a page size of items. Returns a number of items
up to a limit value. Use the limit parameter to make an
initial limited request and use the ID of the last-seen item
from the response as the marker parameter value in a
subsequent limited request.
* offset: Used in conjunction with limit to return a slice of
items. Is where to start in the list.
* marker: The ID of the last-seen item.
:returns: A generator of group type objects.
"""
return self._list(_group_type.GroupType, **query)
def create_group_type(self, **attrs):
"""Create a group type
:param dict attrs: Keyword arguments which will be used to create
a :class:`~openstack.block_storage.v3.group_type.GroupType'
comprised of the properties on the GroupType class.
:returns: The results of group type creation.
:rtype: :class:`~openstack.block_storage.v3.group_type.GroupTye'.
"""
return self._create(_group_type.GroupType, **attrs)
def delete_group_type(self, group_type, ignore_missing=True):
"""Delete a group type
:param group_type: The value can be the ID of a group type
or a :class:`~openstack.block_storage.v3.group_type.GroupType`
instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be raised when
the zone does not exist.
When set to ``True``, no exception will be set when attempting to
delete a nonexistent zone.
:returns: ''None''
"""
self._delete(
_group_type.GroupType, group_type, ignore_missing=ignore_missing)
def update_group_type(self, group_type, **attrs):
"""Update a group_type
:param group_type: The value can be the ID of a group type or a
:class:`~openstack.block_storage.v3.group_type.GroupType`
instance.
:param dict attrs: The attributes to update on the group type.
:returns: The updated group type.
:rtype: :class:`~openstack.block_storage.v3.group_type.GroupType`
"""
return self._update(
_group_type.GroupType, group_type, **attrs)
def wait_for_status(self, res, status='ACTIVE', failures=None,
interval=2, wait=120):
"""Wait for a resource to be in a particular status.

View File

@ -0,0 +1,36 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack import resource
class GroupType(resource.Resource):
resource_key = "group_type"
resources_key = "group_types"
base_path = "/group_types"
# capabilities
allow_fetch = True
allow_create = True
allow_delete = True
allow_commit = True
allow_list = True
_max_microversion = "3.11"
#: Properties
#: The group type description.
description = resource.Body("description")
#: Contains the specifications for a group type.
group_specs = resource.Body("group_specs", type=dict)
#: Whether the group type is publicly visible.
is_public = resource.Body("is_public", type=bool)

View File

@ -0,0 +1,39 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage.v3 import group_type as _group_type
from openstack.tests.functional.block_storage.v3 import base
class TestGroupType(base.BaseBlockStorageTest):
def setUp(self):
super(TestGroupType, self).setUp()
self.GROUP_TYPE_NAME = self.getUniqueString()
self.GROUP_TYPE_ID = None
group_type = self.conn.block_storage.create_group_type(
name=self.GROUP_TYPE_NAME)
self.assertIsInstance(group_type, _group_type.GroupType)
self.assertEqual(self.GROUP_TYPE_NAME, group_type.name)
self.GROUP_TYPE_ID = group_type.id
def tearDown(self):
group_type = self.conn.block_storage.delete_group_type(
self.GROUP_TYPE_ID, ignore_missing=False)
self.assertIsNone(group_type)
super(TestGroupType, self).tearDown()
def test_get(self):
group_type = self.conn.block_storage.get_group_type(self.GROUP_TYPE_ID)
self.assertEqual(self.GROUP_TYPE_NAME, group_type.name)

View File

@ -0,0 +1,46 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage.v3 import group_type
from openstack.tests.unit import base
GROUP_TYPE = {
"id": "6685584b-1eac-4da6-b5c3-555430cf68ff",
"name": "grp-type-001",
"description": "group type 001",
"is_public": True,
"group_specs": {
"consistent_group_snapshot_enabled": "<is> False"
}
}
class TestGroupType(base.TestCase):
def test_basic(self):
resource = group_type.GroupType()
self.assertEqual("group_type", resource.resource_key)
self.assertEqual("group_types", resource.resources_key)
self.assertEqual("/group_types", resource.base_path)
self.assertTrue(resource.allow_create)
self.assertTrue(resource.allow_fetch)
self.assertTrue(resource.allow_delete)
self.assertTrue(resource.allow_commit)
self.assertTrue(resource.allow_list)
def test_make_resource(self):
resource = group_type.GroupType(**GROUP_TYPE)
self.assertEqual(GROUP_TYPE["id"], resource.id)
self.assertEqual(GROUP_TYPE["name"], resource.name)
self.assertEqual(GROUP_TYPE["description"], resource.description)
self.assertEqual(GROUP_TYPE["is_public"], resource.is_public)
self.assertEqual(GROUP_TYPE["group_specs"], resource.group_specs)

View File

@ -14,6 +14,7 @@ from unittest import mock
from openstack.block_storage.v3 import _proxy
from openstack.block_storage.v3 import backup
from openstack.block_storage.v3 import capabilities
from openstack.block_storage.v3 import group_type
from openstack.block_storage.v3 import limits
from openstack.block_storage.v3 import resource_filter
from openstack.block_storage.v3 import snapshot
@ -245,3 +246,26 @@ class TestVolumeProxy(test_proxy_base.TestProxyBase):
def test_resource_filters(self):
self.verify_list(self.proxy.resource_filters,
resource_filter.ResourceFilter)
def test_group_type_get(self):
self.verify_get(self.proxy.get_group_type, group_type.GroupType)
def test_group_type_find(self):
self.verify_find(self.proxy.find_group_type, group_type.GroupType)
def test_group_types(self):
self.verify_list(self.proxy.group_types, group_type.GroupType)
def test_group_type_create(self):
self.verify_create(self.proxy.create_group_type, group_type.GroupType)
def test_group_type_delete(self):
self.verify_delete(
self.proxy.delete_group_type, group_type.GroupType, False)
def test_group_type_delete_ignore(self):
self.verify_delete(
self.proxy.delete_group_type, group_type.GroupType, True)
def test_group_type_update(self):
self.verify_update(self.proxy.update_group_type, group_type.GroupType)