Esempio n. 1
0
    def __init__(self):
        self._categories = OrderedDict()
        self._locations = {}

        # Always register OCCI Core types
        self.register(EntityKind)
        self.register(ResourceKind)
        self.register(LinkKind)
Esempio n. 2
0
class Category(object):
    """The OCCI Category type."""
    class CategoryError(Exception):
        pass

    class Invalid(CategoryError):
        pass

    class DoesNotExist(CategoryError):
        pass

    def __init__(self,
                 term,
                 scheme,
                 title=None,
                 related=None,
                 attributes=None,
                 defaults=None):
        self.term = term
        self.scheme = scheme
        self.title = title
        self.related = related
        self.attributes = OrderedDict()
        self.unique_attributes = OrderedDict()
        self.defaults = defaults or OrderedDict()

        # Attribute definitions
        if related:
            self.attributes = related.attributes.copy()
        for attr in attributes or ():
            self.unique_attributes[attr.name] = attr
        self.attributes.update(self.unique_attributes)

        # Attribute defaults

    def __repr__(self):
        return "%s('%s', '%s')" % (self.__class__.__name__, self.term,
                                   self.scheme)

    def __str__(self):
        return self.scheme + self.term

    def __cmp__(self, other):
        return cmp(str(self), str(other))

    def is_related(self, category):
        current = self
        while current:
            if category == current:
                return True
            current = current.related
        return False
Esempio n. 3
0
    def __init__(self):
        self._categories = OrderedDict()
        self._locations = {}

        # Always register OCCI Core types
        self.register(EntityKind)
        self.register(ResourceKind)
        self.register(LinkKind)
Esempio n. 4
0
class Category(object):
    """The OCCI Category type."""

    class CategoryError(Exception):
        pass
    class Invalid(CategoryError):
        pass
    class DoesNotExist(CategoryError):
        pass

    def __init__(self, term, scheme, title=None, related=None, attributes=None, defaults=None):
        self.term = term
        self.scheme = scheme
        self.title = title
        self.related = related
        self.attributes = OrderedDict()
        self.unique_attributes = OrderedDict()
        self.defaults = defaults or OrderedDict()

        # Attribute definitions
        if related:
            self.attributes = related.attributes.copy()
        for attr in attributes or ():
            self.unique_attributes[attr.name] = attr
        self.attributes.update(self.unique_attributes)

        # Attribute defaults

    def __repr__(self):
        return "%s('%s', '%s')" % (self.__class__.__name__, self.term, self.scheme)

    def __str__(self):
        return self.scheme + self.term

    def __cmp__(self, other):
        return cmp(str(self), str(other))

    def is_related(self, category):
        current = self
        while current:
            if category == current:
                return True
            current = current.related
        return False
Esempio n. 5
0
    def __init__(self,
                 term,
                 scheme,
                 title=None,
                 related=None,
                 attributes=None,
                 defaults=None):
        self.term = term
        self.scheme = scheme
        self.title = title
        self.related = related
        self.attributes = OrderedDict()
        self.unique_attributes = OrderedDict()
        self.defaults = defaults or OrderedDict()

        # Attribute definitions
        if related:
            self.attributes = related.attributes.copy()
        for attr in attributes or ():
            self.unique_attributes[attr.name] = attr
        self.attributes.update(self.unique_attributes)
Esempio n. 6
0
    def __init__(self, term, scheme, title=None, related=None, attributes=None, defaults=None):
        self.term = term
        self.scheme = scheme
        self.title = title
        self.related = related
        self.attributes = OrderedDict()
        self.unique_attributes = OrderedDict()
        self.defaults = defaults or OrderedDict()

        # Attribute definitions
        if related:
            self.attributes = related.attributes.copy()
        for attr in attributes or ():
            self.unique_attributes[attr.name] = attr
        self.attributes.update(self.unique_attributes)
Esempio n. 7
0
    def _json_obj(self, obj):
        """Render a `DataObject` into a JSON-friendly dictionary structure.
        """
        json_obj = OrderedDict()
        json_obj['kind'] = None
        json_obj['kinds'] = []
        json_obj['mixins'] = []
        json_obj['categories'] = []
        json_obj['actions'] = []
        json_obj['links'] = []
        json_obj['attributes'] = OrderedDict()

        # Categories
        for category in obj.categories:
            d = OrderedDict()
            d['term'] = category.term
            d['scheme'] = category.scheme

            d['title'] = category.title
            if category.related:
                d['related'] = str(category.related)
            if category.attributes:
                attr_defs = OrderedDict()
                for attr in category.unique_attributes.itervalues():
                    attr_props = OrderedDict()
                    attr_props['mutable'] = attr.mutable
                    attr_props['required'] = attr.required
                    attr_props['type'] = attr.type_name
                    attr_defs[attr.name] = attr_props
                d['attributes'] = attr_defs
            if category.defaults:
                d['defaults'] = category.defaults
            if hasattr(category, 'actions') and category.actions:
                d['actions'] = [str(cat) for cat in category.actions]
            if hasattr(category, 'location') and category.location:
                d['location'] = obj.translator.url_build(category.location,
                                                         path_only=True)

            cat_class = category.__class__.__name__.lower()
            if cat_class == 'kind':
                json_obj['kinds'].append(d)
            elif cat_class == 'mixin':
                json_obj['mixins'].append(d)
            else:
                json_obj['categories'].append(d)

        # Links
        for link in obj.links:
            d = OrderedDict()
            if link.target_title:
                d['title'] = link.target_title
            d['target_uri'] = link.target_location
            d['target_type'] = [str(cat) for cat in link.target_categories]
            if link.link_location:
                d['link_uri'] = link.link_location
            if link.link_categories:
                d['link_type'] = [str(cat) for cat in link.link_categories]
            if link.link_attributes:
                attrs = OrderedDict()
                for name, value in link.link_attributes:
                    attrs[name] = value
                d['attributes'] = attrs
            json_obj['links'].append(d)

        # Actions
        for action in obj.actions:
            d = OrderedDict()
            if action.target_title:
                d['title'] = action.target_title
            d['uri'] = action.target_location
            assert (len(action.target_categories) == 1)
            d['type'] = str(action.target_categories[0])
            json_obj['actions'].append(d)

        # Attributes
        for name, value in obj.attributes:
            json_obj['attributes'][name] = value

        # If this is a resource instance ...
        if 'resource_instance' in obj.render_flags:
            try:
                json_obj['kind'] = json_obj['kinds'][0]
                del json_obj['kinds']
            except KeyError, IndexError:
                raise RendererError(
                    'Resource instance MUST be of one and only one Kind')
Esempio n. 8
0
class CategoryRegistry(object):
    """Registry of all Category/Kind/Mixin instances currently known to the
    OCCI server or client.

    >>> reg = CategoryRegistry()
    >>> from occi.core import Category, ExtCategory, Kind, Mixin
    >>> from occi.ext.infrastructure import *
    >>> reg.register(ComputeKind)
    >>> reg.register(StorageKind)
    >>> reg.register(StorageLinkKind)
    >>> fooKind = Kind('foo', 'http://#', related=ResourceKind, location='compute/')
    >>> reg.register(fooKind)
    Traceback (most recent call last):
    Invalid: compute/: location path already defined
    >>> reg.lookup_id(ComputeKind)
    Kind('compute', 'http://schemas.ogf.org/occi/infrastructure#')
    >>> reg.lookup_location('storage/')
    Kind('storage', 'http://schemas.ogf.org/occi/infrastructure#')
    >>> reg.lookup_recursive('/link/')
    [Kind('storagelink', 'http://schemas.ogf.org/occi/infrastructure#')]
    >>> reg.lookup_recursive('/') == reg.all()
    True
    >>> reg.unregister(StorageKind)
    >>> reg.unregister(ComputeKind)
    >>> reg.unregister(EntityKind) ; reg.unregister(ResourceKind) ; reg.unregister(LinkKind)
    >>> reg.all()
    [Kind('storagelink', 'http://schemas.ogf.org/occi/infrastructure#')]

    """

    def __init__(self):
        self._categories = OrderedDict()
        self._locations = {}

        # Always register OCCI Core types
        self.register(EntityKind)
        self.register(ResourceKind)
        self.register(LinkKind)

    def register(self, category):
        """Register a new Category/Kind/Mixin."""
        s = str(category)
        if s in self._categories:
            raise Category.Invalid('%s: Category already registered' % s)

        # Location
        if hasattr(category, 'location') and category.location:
            if category.location in self._locations:
                raise Category.Invalid('%s: location path already defined' % category.location)
            self._locations[category.location] = category

        # Register category
        self._categories[s] = category

        # Register actions
        if hasattr(category, 'actions'):
            for action in category.actions:
                if hasattr(action, 'actions'):
                    raise Category.Invalid(
                            '%s: Only the base Category type allowed to identify Actions' % action)
                self.register(action)

    def unregister(self, category):
        """Unregister a previously registered Category/Kind/Mixin."""
        try:
            category = self._categories[str(category)]
        except KeyError:
            raise Category.Invalid("%s: Category not registered" % category)

        # Unregister category
        del self._categories[str(category)]

        # Remove location entry
        if hasattr(category, 'location') and category.location:
            self._locations.pop(category.location, None)

        # Remove additional action categories
        if hasattr(category, 'actions'):
            for action in category.actions:
                self.unregister(action)

    def lookup_id(self, identifier):
        try:
            return self._categories[str(identifier)]
        except KeyError:
            raise Category.DoesNotExist('"%s": Category does not exist' % identifier)

    def lookup_location(self, path):
        loc = path.lstrip('/')
        return self._locations.get(loc)

    def lookup_recursive(self, path):
        """Find all categories registered at a location below the specified
        path.
        """
        loc = path.lstrip('/')
        if not loc:
            return self.all()
        categories = []
        for location, category in self._locations.iteritems():
            if location.startswith(loc):
                categories.append(category)
        return categories

    def all(self):
        return self._categories.values()
Esempio n. 9
0
class CategoryRegistry(object):
    """Registry of all Category/Kind/Mixin instances currently known to the
    OCCI server or client.

    >>> reg = CategoryRegistry()
    >>> from occi.core import Category, ExtCategory, Kind, Mixin
    >>> from occi.ext.infrastructure import *
    >>> reg.register(ComputeKind)
    >>> reg.register(StorageKind)
    >>> reg.register(StorageLinkKind)
    >>> fooKind = Kind('foo', 'http://#', related=ResourceKind, location='compute/')
    >>> reg.register(fooKind)
    Traceback (most recent call last):
    Invalid: compute/: location path already defined
    >>> reg.lookup_id(ComputeKind)
    Kind('compute', 'http://schemas.ogf.org/occi/infrastructure#')
    >>> reg.lookup_location('storage/')
    Kind('storage', 'http://schemas.ogf.org/occi/infrastructure#')
    >>> reg.lookup_recursive('/link/')
    [Kind('storagelink', 'http://schemas.ogf.org/occi/infrastructure#')]
    >>> reg.lookup_recursive('/') == reg.all()
    True
    >>> reg.unregister(StorageKind)
    >>> reg.unregister(ComputeKind)
    >>> reg.unregister(EntityKind) ; reg.unregister(ResourceKind) ; reg.unregister(LinkKind)
    >>> reg.all()
    [Kind('storagelink', 'http://schemas.ogf.org/occi/infrastructure#')]

    """
    def __init__(self):
        self._categories = OrderedDict()
        self._locations = {}

        # Always register OCCI Core types
        self.register(EntityKind)
        self.register(ResourceKind)
        self.register(LinkKind)

    def register(self, category):
        """Register a new Category/Kind/Mixin."""
        s = str(category)
        if s in self._categories:
            raise Category.Invalid('%s: Category already registered' % s)

        # Location
        if hasattr(category, 'location') and category.location:
            if category.location in self._locations:
                raise Category.Invalid('%s: location path already defined' %
                                       category.location)
            self._locations[category.location] = category

        # Register category
        self._categories[s] = category

        # Register actions
        if hasattr(category, 'actions'):
            for action in category.actions:
                if hasattr(action, 'actions'):
                    raise Category.Invalid(
                        '%s: Only the base Category type allowed to identify Actions'
                        % action)
                self.register(action)

    def unregister(self, category):
        """Unregister a previously registered Category/Kind/Mixin."""
        try:
            category = self._categories[str(category)]
        except KeyError:
            raise Category.Invalid("%s: Category not registered" % category)

        # Unregister category
        del self._categories[str(category)]

        # Remove location entry
        if hasattr(category, 'location') and category.location:
            self._locations.pop(category.location, None)

        # Remove additional action categories
        if hasattr(category, 'actions'):
            for action in category.actions:
                self.unregister(action)

    def lookup_id(self, identifier):
        try:
            return self._categories[str(identifier)]
        except KeyError:
            raise Category.DoesNotExist('"%s": Category does not exist' %
                                        identifier)

    def lookup_location(self, path):
        loc = path.lstrip('/')
        return self._locations.get(loc)

    def lookup_recursive(self, path):
        """Find all categories registered at a location below the specified
        path.
        """
        loc = path.lstrip('/')
        if not loc:
            return self.all()
        categories = []
        for location, category in self._locations.iteritems():
            if location.startswith(loc):
                categories.append(category)
        return categories

    def all(self):
        return self._categories.values()
Esempio n. 10
0
 def __init__(self):
     super(DummyBackend, self).__init__()
     self._db = OrderedDict()
     self._user_mixins = {}
Esempio n. 11
0
class DummyBackend(ServerBackend):
    """Very simple (and inefficient) in-memory backend for test purposes.

    >>> backend = DummyBackend()
    >>> from occi.ext.infrastructure import *
    >>> t = backend.save_entities([ComputeKind.entity_type(ComputeKind)])
    >>> compute = ComputeKind.entity_type(ComputeKind)
    >>> compute.occi_import_attributes([('occi.compute.memory', '2.0')])
    >>> storage = StorageKind.entity_type(StorageKind)
    >>> s_compute, s_storage = backend.save_entities([compute, storage])
    >>> link = StorageLinkKind.entity_type(StorageLinkKind)
    >>> link.occi_import_attributes([('occi.core.source', s_compute.id), ('occi.core.target', s_storage.id), ('occi.storagelink.deviceid', 'ide:0:0')])
    >>> s_link = backend.save_entities([link])
    >>> len(backend.filter_entities())
    4
    >>> len(backend.filter_entities(categories=[ComputeKind]))
    2
    >>> len(backend.filter_entities(categories=[ComputeKind], attributes=[('occi.compute.memory', 2.0)]))
    1
    >>> backend.get_entity(s_compute.id) == compute
    True
    >>> backend.save_entities(delete_entity_ids=[entity.id for entity in t])
    []
    >>> [entity.id for entity in backend.filter_entities(categories=[ComputeKind])] == [s_compute.id]
    True
    """
    def __init__(self):
        super(DummyBackend, self).__init__()
        self._db = OrderedDict()
        self._user_mixins = {}

    def auth_user(self, identity, secret=None, method=None, user=None):
        return None

    def get_entity(self, entity_id, user=None):
        entity_id = str(entity_id)
        try:
            return self._db[entity_id]
        except KeyError:
            raise Entity.DoesNotExist(entity_id)

    def filter_entities(self, categories=None, attributes=None, user=None):
        result = []
        for entity_id, entity in self._db.iteritems():
            skip = False

            # Filter on Categories
            cats = entity.occi_list_categories()
            for cat in categories or ():
                if str(cat) not in cats:
                    skip = True
                    break
            if skip: continue

            # Filter on Attributes
            if categories and attributes:
                for name, value in attributes:
                    t = entity.occi_get_attribute(name)
                    if str(t) != str(
                            value):  # FIXME - this implies "2.0" == 2.0
                        skip = True
                        break
            if skip: continue

            result.append(entity)

        return result

    def save_entities(self, entities=None, delete_entity_ids=None, user=None):
        if delete_entity_ids:
            self._delete_entities(delete_entity_ids, user=user)
        saved_entities = []
        for entity in entities or ():
            # Generate ID if new instance
            if not entity.id:
                entity.occi_set_attribute('occi.core.id', uuid.uuid4())

            # Links
            if isinstance(entity, Link):
                source = self.get_entity(
                    entity.occi_get_attribute('occi.core.source').id,
                    user=user)
                target = self.get_entity(
                    entity.occi_get_attribute('occi.core.target').id,
                    user=user)
                entity.occi_set_attribute('occi.core.source', source)
                entity.occi_set_attribute('occi.core.target', target)
                links = []
                for l in source.links:
                    if l.id != source.id:
                        links.append(l)
                links.append(entity)
                source.links = links

            self._db[str(entity.id)] = entity
            saved_entities.append(entity)
        return saved_entities

    def _delete_entities(self, entity_ids, user=None):
        for entity_id in entity_ids:
            entity_id = str(entity_id)
            try:
                entity = self._db[entity_id]
                if isinstance(entity, Resource):
                    for l in entity.links:
                        self._db.pop(l.id, None)
                elif isinstance(entity, Link):
                    try:
                        entity.source.links.remove(entity)
                    except ValueError:
                        pass
                del self._db[entity_id]
            except KeyError:
                raise Entity.DoesNotExist(entity_id)

    def exec_action(self, action, entity, payload=None, user=None):
        try:
            return getattr(entity, 'exec_action')(action, payload=payload)
        except AttributeError:
            return None

    def exec_action_on_collection(self,
                                  action,
                                  collection,
                                  payload=None,
                                  user=None):
        # FIXME: make atomic
        for entity in self.filter_entities(categories=[collection], user=user):
            self.exec_action(action, entity, payload=payload, user=user)
        return None

    def add_user_category(self, category, user=None):
        if not isinstance(category, Mixin):
            raise self.InvalidOperation('Permission denied')
        self._user_mixins[str(category)] = category
        return category

    def remove_user_category(self, category, user=None):
        try:
            del self._user_mixins[str(category)]
        except KeyError:
            raise self.InvalidOperation('Permission denied')
Esempio n. 12
0
 def __init__(self):
     super(DummyBackend, self).__init__()
     self._db = OrderedDict()
     self._user_mixins = {}
Esempio n. 13
0
class DummyBackend(ServerBackend):
    """Very simple (and inefficient) in-memory backend for test purposes.

    >>> backend = DummyBackend()
    >>> from occi.ext.infrastructure import *
    >>> t = backend.save_entities([ComputeKind.entity_type(ComputeKind)])
    >>> compute = ComputeKind.entity_type(ComputeKind)
    >>> compute.occi_import_attributes([('occi.compute.memory', '2.0')])
    >>> storage = StorageKind.entity_type(StorageKind)
    >>> s_compute, s_storage = backend.save_entities([compute, storage])
    >>> link = StorageLinkKind.entity_type(StorageLinkKind)
    >>> link.occi_import_attributes([('occi.core.source', s_compute.id), ('occi.core.target', s_storage.id), ('occi.storagelink.deviceid', 'ide:0:0')])
    >>> s_link = backend.save_entities([link])
    >>> len(backend.filter_entities())
    4
    >>> len(backend.filter_entities(categories=[ComputeKind]))
    2
    >>> len(backend.filter_entities(categories=[ComputeKind], attributes=[('occi.compute.memory', 2.0)]))
    1
    >>> backend.get_entity(s_compute.id) == compute
    True
    >>> backend.save_entities(delete_entity_ids=[entity.id for entity in t])
    []
    >>> [entity.id for entity in backend.filter_entities(categories=[ComputeKind])] == [s_compute.id]
    True
    """

    def __init__(self):
        super(DummyBackend, self).__init__()
        self._db = OrderedDict()
        self._user_mixins = {}

    def auth_user(self, identity, secret=None, method=None, user=None):
        return None

    def get_entity(self, entity_id, user=None):
        entity_id = str(entity_id)
        try:
            return self._db[entity_id]
        except KeyError:
            raise Entity.DoesNotExist(entity_id)

    def filter_entities(self, categories=None, attributes=None, user=None):
        result = []
        for entity_id, entity in self._db.iteritems():
            skip = False

            # Filter on Categories
            cats = entity.occi_list_categories()
            for cat in categories or ():
                if str(cat) not in cats:
                    skip=True
                    break
            if skip: continue

            # Filter on Attributes
            if categories and attributes:
                for name, value in attributes:
                    t = entity.occi_get_attribute(name)
                    if str(t) != str(value):    # FIXME - this implies "2.0" == 2.0
                        skip = True
                        break
            if skip: continue

            result.append(entity)

        return result

    def save_entities(self, entities=None, delete_entity_ids=None, user=None):
        if delete_entity_ids:
            self._delete_entities(delete_entity_ids, user=user)
        saved_entities = []
        for entity in entities or ():
            # Generate ID if new instance
            if not entity.id:
                entity.occi_set_attribute('occi.core.id', uuid.uuid4())

            # Links
            if isinstance(entity, Link):
                source = self.get_entity(entity.occi_get_attribute('occi.core.source').id, user=user)
                target = self.get_entity(entity.occi_get_attribute('occi.core.target').id, user=user)
                entity.occi_set_attribute('occi.core.source', source)
                entity.occi_set_attribute('occi.core.target', target)
                links = []
                for l in source.links:
                    if l.id != source.id:
                        links.append(l)
                links.append(entity)
                source.links = links

            self._db[str(entity.id)] = entity
            saved_entities.append(entity)
        return saved_entities

    def _delete_entities(self, entity_ids, user=None):
        for entity_id in entity_ids:
            entity_id = str(entity_id)
            try:
                entity = self._db[entity_id]
                if isinstance(entity, Resource):
                    for l in entity.links:
                        self._db.pop(l.id, None)
                elif isinstance(entity, Link):
                    try:
                        entity.source.links.remove(entity)
                    except ValueError:
                        pass
                del self._db[entity_id]
            except KeyError:
                raise Entity.DoesNotExist(entity_id)

    def exec_action(self, action, entity, payload=None, user=None):
        try:
            return getattr(entity, 'exec_action')(action, payload=payload)
        except AttributeError:
            return None

    def exec_action_on_collection(self, action, collection, payload=None, user=None):
        # FIXME: make atomic
        for entity in self.filter_entities(categories=[collection], user=user):
            self.exec_action(action, entity, payload=payload, user=user)
        return None

    def add_user_category(self, category, user=None):
        if not isinstance(category, Mixin):
            raise self.InvalidOperation('Permission denied')
        self._user_mixins[str(category)] = category
        return category

    def remove_user_category(self, category, user=None):
        try:
            del self._user_mixins[str(category)]
        except KeyError:
            raise self.InvalidOperation('Permission denied')