Use Resource class from common code
Replace own implementation of 'Resource' class with same one from common apiclient code. Partially implements: blueprint use-common-code Change-Id: I87ac06931a23721fc8cc2d58b5a9473618073f32
This commit is contained in:
parent
ec10415dc4
commit
1cc313e5cf
@ -23,10 +23,7 @@ import contextlib
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from manilaclient import exceptions
|
from manilaclient import exceptions
|
||||||
from manilaclient.openstack.common import strutils
|
|
||||||
from manilaclient import utils
|
from manilaclient import utils
|
||||||
|
|
||||||
|
|
||||||
@ -202,91 +199,3 @@ class ManagerWithFind(Manager):
|
|||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class Resource(object):
|
|
||||||
"""Resource as instance of an object.
|
|
||||||
|
|
||||||
A resource represents a particular instance of an object (share,
|
|
||||||
snapshot, etc). This is pretty much just a bag for attributes.
|
|
||||||
|
|
||||||
:param manager: Manager object
|
|
||||||
:param info: dictionary representing resource attributes
|
|
||||||
:param loaded: prevent lazy-loading if set to True
|
|
||||||
"""
|
|
||||||
HUMAN_ID = False
|
|
||||||
|
|
||||||
def __init__(self, manager, info, loaded=False):
|
|
||||||
self.manager = manager
|
|
||||||
self._info = info
|
|
||||||
self._add_details(info)
|
|
||||||
self._loaded = loaded
|
|
||||||
|
|
||||||
# NOTE(sirp): ensure `id` is already present because if it isn't we'll
|
|
||||||
# enter an infinite loop of __getattr__ -> get -> __init__ ->
|
|
||||||
# __getattr__ -> ...
|
|
||||||
if 'id' in self.__dict__ and len(str(self.id)) == 36:
|
|
||||||
self.manager.write_to_completion_cache('uuid', self.id)
|
|
||||||
|
|
||||||
human_id = self.human_id
|
|
||||||
if human_id:
|
|
||||||
self.manager.write_to_completion_cache('human_id', human_id)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def human_id(self):
|
|
||||||
"""Returns human-friendly ID if possible.
|
|
||||||
|
|
||||||
Subclasses may override this provide a pretty ID which can
|
|
||||||
be used for bash completion.
|
|
||||||
"""
|
|
||||||
if 'name' in self.__dict__ and self.HUMAN_ID:
|
|
||||||
return strutils.to_slug(self.name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _add_details(self, info):
|
|
||||||
for (k, v) in six.iteritems(info):
|
|
||||||
try:
|
|
||||||
setattr(self, k, v)
|
|
||||||
except AttributeError:
|
|
||||||
# In this case we already defined the attribute on the class
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __getattr__(self, k):
|
|
||||||
if k not in self.__dict__:
|
|
||||||
# NOTE(bcwaldon): disallow lazy-loading if already loaded once
|
|
||||||
if not self.is_loaded():
|
|
||||||
self.get()
|
|
||||||
return self.__getattr__(k)
|
|
||||||
|
|
||||||
raise AttributeError(k)
|
|
||||||
else:
|
|
||||||
return self.__dict__[k]
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
reprkeys = sorted(k for k in self.__dict__ if k[0] != '_' and
|
|
||||||
k != 'manager')
|
|
||||||
info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
|
|
||||||
return "<%s %s>" % (self.__class__.__name__, info)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
# set_loaded() first ... so if we have to bail, we know we tried.
|
|
||||||
self.set_loaded(True)
|
|
||||||
if not hasattr(self.manager, 'get'):
|
|
||||||
return
|
|
||||||
|
|
||||||
new = self.manager.get(self.id)
|
|
||||||
if new:
|
|
||||||
self._add_details(new._info)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if not isinstance(other, self.__class__):
|
|
||||||
return False
|
|
||||||
if hasattr(self, 'id') and hasattr(other, 'id'):
|
|
||||||
return self.id == other.id
|
|
||||||
return self._info == other._info
|
|
||||||
|
|
||||||
def is_loaded(self):
|
|
||||||
return self._loaded
|
|
||||||
|
|
||||||
def set_loaded(self, val):
|
|
||||||
self._loaded = val
|
|
||||||
|
@ -14,10 +14,11 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
from manilaclient import utils
|
from manilaclient import utils
|
||||||
|
|
||||||
|
|
||||||
class ListExtResource(base.Resource):
|
class ListExtResource(common_base.Resource):
|
||||||
@property
|
@property
|
||||||
def summary(self):
|
def summary(self):
|
||||||
descr = self.description.strip()
|
descr = self.description.strip()
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class Limits(base.Resource):
|
class Limits(common_base.Resource):
|
||||||
"""A collection of RateLimit and AbsoluteLimit objects."""
|
"""A collection of RateLimit and AbsoluteLimit objects."""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class QuotaClassSet(base.Resource):
|
class QuotaClassSet(common_base.Resource):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class QuotaSet(base.Resource):
|
class QuotaSet(common_base.Resource):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
"""Needed by base.Resource to self-refresh and be indexed."""
|
"""Needed by Resource to self-refresh and be indexed."""
|
||||||
return self.tenant_id
|
return self.tenant_id
|
||||||
|
|
||||||
def update(self, *args, **kwargs):
|
def update(self, *args, **kwargs):
|
||||||
|
@ -20,6 +20,7 @@ except ImportError:
|
|||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
from manilaclient import exceptions
|
from manilaclient import exceptions
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
RESOURCES_PATH = '/security-services'
|
RESOURCES_PATH = '/security-services'
|
||||||
RESOURCE_PATH = "/security-services/%s"
|
RESOURCE_PATH = "/security-services/%s"
|
||||||
@ -27,7 +28,7 @@ RESOURCE_NAME = 'security_service'
|
|||||||
RESOURCES_NAME = 'security_services'
|
RESOURCES_NAME = 'security_services'
|
||||||
|
|
||||||
|
|
||||||
class SecurityService(base.Resource):
|
class SecurityService(common_base.Resource):
|
||||||
"""Security service for Manila shares."""
|
"""Security service for Manila shares."""
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<SecurityService: %s>" % self.id
|
return "<SecurityService: %s>" % self.id
|
||||||
|
@ -20,12 +20,13 @@ except ImportError:
|
|||||||
from urllib.parse import urlencode # noqa
|
from urllib.parse import urlencode # noqa
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
RESOURCES_PATH = '/os-services'
|
RESOURCES_PATH = '/os-services'
|
||||||
RESOURCES_NAME = 'services'
|
RESOURCES_NAME = 'services'
|
||||||
|
|
||||||
|
|
||||||
class Service(base.Resource):
|
class Service(common_base.Resource):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Service: %s>" % self.id
|
return "<Service: %s>" % self.id
|
||||||
|
@ -28,7 +28,7 @@ RESOURCE_NAME = 'share_network'
|
|||||||
RESOURCES_NAME = 'share_networks'
|
RESOURCES_NAME = 'share_networks'
|
||||||
|
|
||||||
|
|
||||||
class ShareNetwork(base.Resource):
|
class ShareNetwork(common_base.Resource):
|
||||||
"""Network info for Manila shares."""
|
"""Network info for Manila shares."""
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<ShareNetwork: %s>" % self.id
|
return "<ShareNetwork: %s>" % self.id
|
||||||
|
@ -20,6 +20,7 @@ except ImportError:
|
|||||||
from urllib.parse import urlencode # noqa
|
from urllib.parse import urlencode # noqa
|
||||||
|
|
||||||
from manilaclient import base
|
from manilaclient import base
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
RESOURCES_PATH = '/share-servers'
|
RESOURCES_PATH = '/share-servers'
|
||||||
RESOURCE_PATH = '/share-servers/%s'
|
RESOURCE_PATH = '/share-servers/%s'
|
||||||
@ -27,7 +28,7 @@ RESOURCES_NAME = 'share_servers'
|
|||||||
RESOURCE_NAME = 'share_server'
|
RESOURCE_NAME = 'share_server'
|
||||||
|
|
||||||
|
|
||||||
class ShareServer(base.Resource):
|
class ShareServer(common_base.Resource):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<ShareServer: %s>" % self.id
|
return "<ShareServer: %s>" % self.id
|
||||||
|
@ -23,7 +23,7 @@ from manilaclient import base
|
|||||||
from manilaclient.openstack.common.apiclient import base as common_base
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class ShareSnapshot(base.Resource):
|
class ShareSnapshot(common_base.Resource):
|
||||||
"""Represent a snapshot of a share."""
|
"""Represent a snapshot of a share."""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -26,7 +26,7 @@ from manilaclient import exceptions
|
|||||||
from manilaclient.openstack.common.apiclient import base as common_base
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class Share(base.Resource):
|
class Share(common_base.Resource):
|
||||||
"""A share is an extra block level storage to the OpenStack instances."""
|
"""A share is an extra block level storage to the OpenStack instances."""
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Share: %s>" % self.id
|
return "<Share: %s>" % self.id
|
||||||
|
@ -22,7 +22,7 @@ from manilaclient import base
|
|||||||
from manilaclient.openstack.common.apiclient import base as common_base
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
|
|
||||||
|
|
||||||
class VolumeType(base.Resource):
|
class VolumeType(common_base.Resource):
|
||||||
"""A Volume Type is the type of volume to be created."""
|
"""A Volume Type is the type of volume to be created."""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from manilaclient import base
|
|
||||||
from manilaclient import exceptions
|
from manilaclient import exceptions
|
||||||
|
from manilaclient.openstack.common.apiclient import base as common_base
|
||||||
from manilaclient.v1 import shares
|
from manilaclient.v1 import shares
|
||||||
from tests import utils
|
from tests import utils
|
||||||
from tests.v1 import fakes
|
from tests.v1 import fakes
|
||||||
@ -23,23 +23,23 @@ cs = fakes.FakeClient()
|
|||||||
class BaseTest(utils.TestCase):
|
class BaseTest(utils.TestCase):
|
||||||
|
|
||||||
def test_resource_repr(self):
|
def test_resource_repr(self):
|
||||||
r = base.Resource(None, dict(foo="bar", baz="spam"))
|
r = common_base.Resource(None, dict(foo="bar", baz="spam"))
|
||||||
self.assertEqual(repr(r), "<Resource baz=spam, foo=bar>")
|
self.assertEqual(repr(r), "<Resource baz=spam, foo=bar>")
|
||||||
|
|
||||||
def test_eq(self):
|
def test_eq(self):
|
||||||
# Two resources of the same type with the same id: equal
|
# Two resources of the same type with the same id: equal
|
||||||
r1 = base.Resource(None, {'id': 1, 'name': 'hi'})
|
r1 = common_base.Resource(None, {'id': 1, 'name': 'hi'})
|
||||||
r2 = base.Resource(None, {'id': 1, 'name': 'hello'})
|
r2 = common_base.Resource(None, {'id': 1, 'name': 'hello'})
|
||||||
self.assertEqual(r1, r2)
|
self.assertEqual(r1, r2)
|
||||||
|
|
||||||
# Two resoruces of different types: never equal
|
# Two resoruces of different types: never equal
|
||||||
r1 = base.Resource(None, {'id': 1})
|
r1 = common_base.Resource(None, {'id': 1})
|
||||||
r2 = shares.Share(None, {'id': 1})
|
r2 = shares.Share(None, {'id': 1})
|
||||||
self.assertNotEqual(r1, r2)
|
self.assertNotEqual(r1, r2)
|
||||||
|
|
||||||
# Two resources with no ID: equal if their info is equal
|
# Two resources with no ID: equal if their info is equal
|
||||||
r1 = base.Resource(None, {'name': 'joe', 'age': 12})
|
r1 = common_base.Resource(None, {'name': 'joe', 'age': 12})
|
||||||
r2 = base.Resource(None, {'name': 'joe', 'age': 12})
|
r2 = common_base.Resource(None, {'name': 'joe', 'age': 12})
|
||||||
self.assertEqual(r1, r2)
|
self.assertEqual(r1, r2)
|
||||||
|
|
||||||
def test_findall_invalid_attribute(self):
|
def test_findall_invalid_attribute(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user