388
class Resource(object):
388
class Resource(base.Resource):
389
389
"""Base class for OpenStack resources (tenant, user, etc.).
391
391
This is pretty much just a bag for attributes.
397
def __init__(self, manager, info, loaded=False):
398
"""Populate and bind to a manager.
400
:param manager: Manager object
401
:param info: dictionary representing resource attributes
402
:param loaded: prevent lazy-loading if set to True
404
self.manager = manager
406
self._add_details(info)
407
self._loaded = loaded
411
"""Human-readable ID which can be used for bash completion.
413
if self.NAME_ATTR in self.__dict__ and self.HUMAN_ID:
414
return strutils.to_slug(getattr(self, self.NAME_ATTR))
417
def _add_details(self, info):
418
for (k, v) in six.iteritems(info):
422
def __getattr__(self, k):
423
if k not in self.__dict__:
424
#NOTE(bcwaldon): disallow lazy-loading if already loaded once
425
if not self.is_loaded():
427
return self.__getattr__(k)
429
raise AttributeError(k)
431
return self.__dict__[k]
434
reprkeys = sorted(k for k in self.__dict__ if k[0] != '_' and
436
info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
437
return "<%s %s>" % (self.__class__.__name__, info)
440
# set_loaded() first ... so if we have to bail, we know we tried.
441
self.set_loaded(True)
442
if not hasattr(self.manager, 'get'):
445
new = self.manager.get(self.id)
447
self._add_details(new._info)
449
394
def delete(self):
450
395
return self.manager.delete(self)
452
def __eq__(self, other):
453
if not isinstance(other, Resource):
454
return NotImplemented
455
# two resources of different types are not equal
456
if not isinstance(other, self.__class__):
458
if hasattr(self, 'id') and hasattr(other, 'id'):
459
return self.id == other.id
460
return self._info == other._info
465
def set_loaded(self, val):