示例#1
0
 def __get__(self, instance, cls=None):
     # Does the instance already have meta data
     if instance is not None and instance._meta:
         return instance._meta.href
     else:
         if hasattr(cls, 'typeof'):
             if instance is not None:
                 element = fetch_href_by_name(
                     instance.name, filter_context=instance.typeof)
                 if element.json:
                     instance._meta = Meta(**element.json[0])
                     return instance._meta.href
                 raise ElementNotFound(
                     'Cannot find specified element: {}, type: {}'.format(
                         unicode_to_bytes(instance.name), instance.typeof))
             else:
                 try:
                     element = fetch_entry_point(cls.typeof)
                 except UnsupportedEntryPoint as e:
                     raise ElementNotFound(e)
                 return element
         else:
             raise ElementNotFound(
                 'This class does not have the required attribute '
                 'and cannot be referenced directly, type: {}'.format(
                     instance))
示例#2
0
文件: model.py 项目: m4h3/smc-python
 def __get__(self, instance, cls=None):
     #Does the instance already have meta data
     if instance.meta:
         return instance.meta.href
     else:
         if hasattr(instance, 'typeof'):
             element = search.element_info_as_json_with_filter(
                 instance.name, instance.typeof)
             if element:
                 instance.meta = Meta(**element[0])
                 return instance.meta.href
             raise ElementNotFound(
                 'Cannot find specified element: {}, type: {}'.format(
                     unicode_to_bytes(instance.name), instance.typeof))
         elif isinstance(instance, smc.core.engine.Engine):
             element = search.element_info_as_json_with_filter(
                 instance.name, 'engine_clusters')
             if element:
                 instance.meta = Meta(**element[0])
                 return instance.meta.href
             raise LoadEngineFailed(
                 'Cannot load engine name: {}, ensure the '
                 'name is correct and that the engine exists.'.format(
                     instance.name))
         else:
             raise ElementNotFound(
                 'This class does not have the required attribute '
                 'and cannot be referenced directly, type: {}'.format(
                     instance))
示例#3
0
    def get_or_create(cls, filter_key=None, **kwargs):
        """
        Convenience method to retrieve an Element or create if it does not
        exist. If an element does not have a `create` classmethod, then it
        is considered read-only and the request will be redirected to :meth:`~get`.
        Any keyword arguments passed except the optional filter_key
        will be used in a create() call. If filter_key is provided, this
        should define an attribute and value to use for an exact match on
        the element. Valid attributes are ones required on the elements
        ``create`` method or can be viewed by the elements class docs.
        If no filter_key is provided, the name field will be used to
        find the element.
        ::

            >>> Network.get_or_create(
                    filter_key={'ipv4_network': '123.123.123.0/24'},
                    name='mynetwork',
                    ipv4_network='123.123.123.0/24')
            Network(name=mynetwork)

        The kwargs should be used to satisfy the elements ``create``
        classmethod parameters to create in the event it cannot be found.

        :param dict filter_key: filter key represents the data attribute and
            value to use to find the element. If none is provided, the name
            field will be used.
        :param kwargs: keyword arguments mapping to the elements ``create``
            method.
        :raises CreateElementFailed: could not create element with reason
        :raises ElementNotFound: if read-only element does not exist
        :return: element instance by type
        :rtype: Element
        """
        if not hasattr(cls, 'create'):
            return cls.get(kwargs.get('name'))
        elif 'name' not in kwargs:
            raise ElementNotFound('Name field is a required parameter '
                'for all create type operations on an element')

        if filter_key:
            elements = cls.objects.filter(**filter_key)
            element = elements.first()
            if not element:
                element = cls.create(**kwargs)
        else:
            try:
                element = cls.get(kwargs.get('name'))
            except ElementNotFound:
                element = cls.create(**kwargs)
        
        return element
示例#4
0
 def get(cls, name, raise_exc=True):
     """
     Get the element by name. Does an exact match by element type.
     
     :param str name: name of element
     :param bool raise_exc: optionally disable exception. 
     :raises ElementNotFound: if element does not exist
     :rtype: Element
     """
     element = cls.objects.filter(name, exact_match=True).first() if \
         name is not None else None
     if not element and raise_exc:
         raise ElementNotFound('Cannot find specified element: %s, type: '
                               '%s' % (name, cls.__name__))
     return element
示例#5
0
    def update_or_create(cls, filter_key=None, with_status=False, **kwargs):
        """
        Update or create the element. If the element exists, update
        it using the kwargs provided if the provided kwargs are different from the
        existing value/s. When comparing values, strings and ints are compared
        normally. If a list is provided and is a list of strings, it will be 
        compared and updated. If the list contains unhashable elements, it is 
        automatically merged (i.e. list of dicts).
        If an element does not have a `create` classmethod, then it
        is considered read-only and the request will be redirected to
        :meth:`~get`. Provide a ``filter_key`` dict key/value if you want to
        match the element by a specific attribute and value. If no
        filter_key is provided, the name field will be used to find the
        element.
        ::

            >>> host = Host('kali')
            >>> print(host.address)
            12.12.12.12
            >>> host = Host.update_or_create(name='kali', address='10.10.10.10')
            >>> print(host, host.address)
            Host(name=kali) 10.10.10.10

        :param dict filter_key: filter key represents the data attribute and
            value to use to find the element. If none is provided, the name
            field will be used.
        :param kwargs: keyword arguments mapping to the elements ``create``
            method.
        :param bool with_status: if set to True, a 3-tuple is returned with
            (Element, modified, created), where the second and third tuple
            items are booleans indicating the status
        :raises CreateElementFailed: could not create element with reason
        :raises ElementNotFound: if read-only element does not exist
        :return: element instance by type
        :rtype: Element
        """
        was_created, was_modified = False, False
        if not hasattr(cls, 'create'):
            return cls.get(kwargs.get('name'))
        elif 'name' not in kwargs:
            raise ElementNotFound(
                'Name field is a required parameter '
                'for all create type operations on an element')

        element = None
        if filter_key:
            elements = cls.objects.filter(**filter_key)
            if elements.exists():
                element = elements.first()
        else:
            try:
                element = cls.get(kwargs.get('name'))
            except ElementNotFound:
                element = None

        if element:
            params = {}
            for key, value in kwargs.items():
                # Callable, Element or string
                if callable(value):
                    value = value()
                elif isinstance(value, Element):
                    value = value.href
                # Get value from element
                val = getattr(element, key, None)
                if isinstance(val, (string_types, int)):
                    if val != value:
                        params[key] = value
                elif isinstance(val, Element):
                    if val.href != value:
                        params[key] = value
                elif isinstance(val, list) and isinstance(value, list):
                    try:  # Try matching lists of strings
                        if set(val) ^ set(value):
                            params[key] = value
                    except TypeError:  # Unhashable, list of dicts?
                        params[key] = value
                else:
                    # Last ditch effort, might be comparing None to None
                    if val != value:
                        params[key] = value

            if params:
                element.update(**params)
                was_modified = True
        else:
            params = {k: v() if callable(v) else v for k, v in kwargs.items()}
            element = cls.create(**params)
            was_created = True

        if with_status:
            return element, was_modified, was_created
        return element
示例#6
0
    def get_or_create(cls, filter_key=None, with_status=False, **kwargs):
        """
        Convenience method to retrieve an Element or create if it does not
        exist. If an element does not have a `create` classmethod, then it
        is considered read-only and the request will be redirected to :meth:`~get`.
        Any keyword arguments passed except the optional filter_key
        will be used in a create() call. If filter_key is provided, this
        should define an attribute and value to use for an exact match on
        the element. Valid attributes are ones required on the elements
        ``create`` method or can be viewed by the elements class docs.
        If no filter_key is provided, the name field will be used to
        find the element.
        ::

            >>> Network.get_or_create(
                    filter_key={'ipv4_network': '123.123.123.0/24'},
                    name='mynetwork',
                    ipv4_network='123.123.123.0/24')
            Network(name=mynetwork)

        The kwargs should be used to satisfy the elements ``create``
        classmethod parameters to create in the event it cannot be found.

        :param dict filter_key: filter key represents the data attribute and
            value to use to find the element. If none is provided, the name
            field will be used.
        :param kwargs: keyword arguments mapping to the elements ``create``
            method.
        :param bool with_status: if set to True, a tuple is returned with
            (Element, created), where the second tuple item indicates if
            the element has been created or not.
        :raises CreateElementFailed: could not create element with reason
        :raises ElementNotFound: if read-only element does not exist
        :return: element instance by type
        :rtype: Element
        """
        was_created = False
        if 'name' not in kwargs:
            raise ElementNotFound(
                'Name field is a required parameter '
                'for all create or update_or_create type operations on an element'
            )

        if filter_key:
            elements = cls.objects.filter(**filter_key)
            element = elements.first() if elements.exists() else None
        else:
            try:
                element = cls.get(kwargs.get('name'))
            except ElementNotFound:
                if not hasattr(cls, 'create'):
                    raise CreateElementFailed(
                        '%s: %r not found and this element '
                        'type does not have a create method.' %
                        (cls.__name__, kwargs['name']))
                element = None

        if not element:
            params = {k: v() if callable(v) else v for k, v in kwargs.items()}
            try:
                element = cls.create(**params)
                was_created = True
            except TypeError:
                raise CreateElementFailed(
                    '%s: %r not found and missing '
                    'constructor arguments to properly create.' %
                    (cls.__name__, kwargs['name']))

        if with_status:
            return element, was_created
        return element
示例#7
0
    def update_or_create(cls, filter_key=None, **kwargs):
        """
        Update or create the element. If the element exists, update
        it using the kwargs provided if the provided kwargs are new. Note
        that when checking kwargs against attributes, only string values are
        compared. Lists and dicts are automatically merged.
        If an element does not have a `create` classmethod, then it
        is considered read-only and the request will be redirected to
        :meth:`~get`. Provide a ``filter_key`` dict key/value if you want to
        match the element by a specific attribute and value. If no
        filter_key is provided, the name field will be used to find the
        element.
        ::

            >>> host = Host('kali')
            >>> print(host.address)
            12.12.12.12
            >>> host = Host.update_or_create(name='kali', address='10.10.10.10')
            >>> print(host, host.address)
            Host(name=kali) 10.10.10.10

        :param dict filter_key: filter key represents the data attribute and
            value to use to find the element. If none is provided, the name
            field will be used.
        :param kwargs: keyword arguments mapping to the elements ``create``
            method.
        :raises CreateElementFailed: could not create element with reason
        :raises ElementNotFound: if read-only element does not exist
        :return: element instance by type
        :rtype: Element
        """
        if not hasattr(cls, 'create'):
            return cls.get(kwargs.get('name'))
        elif 'name' not in kwargs:
            raise ElementNotFound('Name field is a required parameter '
                'for all create type operations on an element')
        
        element = None
        if filter_key:
            elements = cls.objects.filter(**filter_key)
            if elements.exists():
                element = elements.first()
        else:
            try:
                element = cls.get(kwargs.get('name'))
            except ElementNotFound:
                element = None

        if element: 
            params = {}
            for key, value in kwargs.items():
                value = value() if callable(value) else value
                val = getattr(element, key, None)
                if isinstance(val, (string_types, int)):
                    if val != value:
                        params[key] = value
                else:
                    params[key] = value
            
            if params:
                element.update(**params)
        else:
            params = {k: v() if callable(v) else v
                      for k, v in kwargs.items()}
            element = cls.create(**params)

        return element