Пример #1
0
 def test_random_hex_generator(self):
     """
     A completely random and unique hex encoded data is generated.
     """
     self.assertNotEqual(helper.random_hex_generator(3),
                         helper.random_hex_generator(3))
     self.assertEqual(len(helper.random_hex_generator(4)), 8)
Пример #2
0
def create_check(params):
    """
    Returns a dictionary representing a check

    :return: a Check model, which is described in `the Rackspace Cloud
        Monitoring Developer Guide, section 5.7
        <http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-checks.html>`_
    :rtype: ``dict`` mapping ``unicode`` to ``unicode``, ``float``,
        ``int``, ``bool``, ``dict`` or ``NoneType``.
    """
    params = collections.defaultdict(lambda: '', params)
    params['id'] = 'ch' + random_hex_generator(4)
    params['collectors'] = []
    for q in range(3):
        params['collectors'].append('co' + random_hex_generator(3))
    params['confd_hash'] = None
    params['confd_name'] = None
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['timeout'] = 10
    params['period'] = 60
    params['disabled'] = False
    params['metadata'] = None
    params['target_alias'] = None
    if 'count' not in params['details']:
        params['details'] = {'count': 5}  # I have no idea what count=5 is for.
    return params
Пример #3
0
 def test_random_hex_generator(self):
     """
     A completely random and unique hex encoded data is generated.
     """
     self.assertNotEqual(helper.random_hex_generator(3),
                         helper.random_hex_generator(3))
     self.assertEqual(len(helper.random_hex_generator(4)), 8)
Пример #4
0
    def add_api(self, api):
        """
        Add a new API to the listing.

        :param object api: An object implementing either the
            :obj:`IAPIMock` or :obj:`IExternalAPIMock` interfaces.
        :raises: TypeError if the object does not implement the
            correct interfaces.
        """
        # Gate check the API to make sure it implements one of the
        # supported interfaces
        if IExternalAPIMock.providedBy(api):
            this_api_id = ((api.name_key) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api_external[this_api_id] = api
        elif IAPIMock.providedBy(api):
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api_internal[this_api_id] = api
        else:
            raise TypeError(
                api.__class__.__module__ + '/' +
                api.__class__.__name__ +
                " does not implement IAPIMock or IExternalAPIMock"
            )
Пример #5
0
def createEntity(params):
    """
    Returns a dictionary representing an entity
    """
    params = collections.defaultdict(lambda: '', params)
    newentity = {}
    newentity['label'] = params[u'label'].encode("ascii")
    newentity['id'] = 'en' + random_hex_generator(4)
    newentity['agent_id'] = params['agent_id'] or random_hex_generator(12)
    newentity['created_at'] = time.time()
    newentity['updated_at'] = time.time()
    newentity['managed'] = params['managed']
    newentity['metadata'] = params['metadata']
    newentity['ip_addresses'] = params['ip_addresses'] or {}
    return newentity
Пример #6
0
class Notification(object):
    """
    Models a MaaS Notification.
    """
    created_at = attr.ib(validator=instance_of(int))
    updated_at = attr.ib(validator=instance_of(int))
    details = attr.ib(validator=instance_of(dict),
                      default=attr.Factory(dict))
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'nt' + random_hex_generator(4)))
    label = attr.ib(validator=instance_of(text_type), default='')
    metadata = attr.ib(validator=instance_of(dict),
                       default=attr.Factory(dict))
    type = attr.ib(validator=instance_of(text_type), default='email')

    USER_SPECIFIABLE_KEYS = ['details', 'label', 'metadata', 'type']

    def to_json(self):
        """
        Serializes the Notification to a JSON-encodable dict.
        """
        return attr.asdict(self)

    def update(self, **kwargs):
        """
        Updates this Notification.
        """
        for key in Notification.USER_SPECIFIABLE_KEYS:
            if key in kwargs:
                setattr(self, key, kwargs[key])
        self.updated_at = int(1000 * kwargs['clock'].seconds())
Пример #7
0
class Message(object):
    """
    A Message object in Cloud Queues.
    """
    ttl = attr.ib(validator=attr.validators.instance_of(int))
    body = attr.ib(validator=attr.validators.instance_of(dict))
    queue_name = attr.ib(validator=attr.validators.instance_of(text_type))
    posted_by = attr.ib(validator=attr.validators.instance_of(text_type))
    posted_at = attr.ib(validator=attr.validators.instance_of(int))
    id = attr.ib(validator=attr.validators.instance_of(text_type),
                 default=attr.Factory(lambda: random_hex_generator(12)))

    def to_json(self, current_time):
        """
        A representation of this message that can be serialized via json.dumps.
        """
        return {
            'body': self.body,
            'age': current_time - self.posted_at,
            'href': self.href(),
            'ttl': self.ttl
        }

    def href(self):
        """
        Returns the URL path representing this message.
        """
        return '/v1/queues/{0}/messages/{1}'.format(self.queue_name, self.id)

    def is_expired_at(self, current_time):
        """
        Returns True if the message is expired at the given time.
        """
        return (self.posted_at + self.ttl) < current_time
Пример #8
0
    def rpc_send_yo(self, request):
        """
        Sends a Yo RPC style.
        """
        body = json.loads(request.content.read().decode("utf-8"))

        if 'api_key' not in body:
            request.setResponseCode(401)
            return json.dumps({'error': 'User does not have permissions for this request',
                               'errors': [{'message': ('User does not have permissions '
                                                       'for this request')}]})

        if 'username' not in body:
            request.setResponseCode(400)
            return json.dumps({'error': 'Can\'t send Yo without a recipient.',
                               'errors': [{'message': 'Can\'t send Yo without a recipient.'}]})

        if 'link' in body and 'location' in body:
            request.setResponseCode(400)
            return json.dumps({'error': 'Can\'t send Yo with location and link.',
                               'errors': [{'message': 'Can\'t send Yo with location and link.'}]})

        user = self.yo_collections.get_or_create_user(body['username'])

        request.setResponseCode(200)
        return json.dumps({'success': True,
                           'yo_id': random_hex_generator(12),
                           'recipient': user.to_json()})
Пример #9
0
 def create_token(self, request):
     """
     Create an auth token without even interrogating the POSTed credential data
     """
     request.setResponseCode(200)
     token = {"X-Auth-Token": str(random_hex_generator(16))}
     return dumps(token)
Пример #10
0
class AlarmState(object):
    """
    Models a MaaS alarm state.
    """
    alarm_id = attr.ib(validator=instance_of(text_type))
    alarm_label = attr.ib(validator=instance_of(text_type))
    check_id = attr.ib(validator=instance_of(text_type))
    entity_id = attr.ib(validator=instance_of(text_type))
    previous_state = attr.ib(validator=one_of_validator("OK", "WARNING", "CRITICAL", "UNKNOWN"))
    state = attr.ib(validator=one_of_validator("OK", "WARNING", "CRITICAL", "UNKNOWN"))
    status = attr.ib(validator=instance_of(text_type))
    timestamp = attr.ib(validator=instance_of(int))
    alarm_changelog_id = attr.ib(validator=instance_of(text_type),
                                 default=attr.Factory(lambda: text_type(uuid4())))
    analyzed_by_monitoring_zone_id = attr.ib(validator=instance_of(text_type),
                                             default='mzord')
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'as' + random_hex_generator(4)))

    def brief_json(self):
        """
        Serializes this alarm state to a JSON-encodable dict.
        """
        return attr.asdict(self, filter=lambda aa, _: aa.name not in ['alarm_label', 'id'])

    def detail_json(self):
        """
        Serializes this alarm state with additional details.
        """
        details = self.brief_json()
        details.update(alarm_label=self.alarm_label)
        return details
Пример #11
0
 def create_token(self, request):
     """
     Create an auth token without even interrogating the POSTed credential data
     """
     request.setResponseCode(200)
     token = {"X-Auth-Token": str(random_hex_generator(16))}
     return dumps(token)
Пример #12
0
    def __init__(self, clock, apis, domains=()):
        """
        Create a MimicCore with an IReactorTime to do any time-based scheduling
        against.

        :param clock: an IReactorTime which will be used for session timeouts
            and determining timestamps.
        :type clock: :obj:`twisted.internet.interfaces.IReactorTime`

        :param apis: an iterable of all :obj:`IAPIMock`s that this MimicCore
            will expose.

        :param domains: an iterable of all :obj:`IAPIDomainMock`s that this
            MimicCore will expose.
        """
        self._uuid_to_api = {}
        self.sessions = SessionStore(clock)
        self.message_store = MessageStore()
        self.contacts_store = ContactsStore()
        self.ironic_node_store = IronicNodeStore()
        self.glance_admin_image_store = GlanceAdminImageStore()
        self.valkyrie_store = ValkyrieStore()
        self.domains = list(domains)

        for api in apis:
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api[this_api_id] = api
Пример #13
0
def createSuppression(params):
    """
    Creates a suppression
    """
    for k in params.keys():
        if 'encode' in dir(params[k]):
            params[k] = params[k].encode('ascii')
    params['id'] = 'sp' + random_hex_generator(4)
    return params
Пример #14
0
class Entity(object):
    """
    Models a MaaS Entity.
    """
    created_at = attr.ib(validator=instance_of(int))
    updated_at = attr.ib(validator=instance_of(int))
    agent_id = attr.ib(validator=optional(instance_of(text_type)),
                       default=None)
    alarms = attr.ib(validator=instance_of(collections.OrderedDict),
                     default=attr.Factory(collections.OrderedDict))
    checks = attr.ib(validator=instance_of(collections.OrderedDict),
                     default=attr.Factory(collections.OrderedDict))
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'en' + random_hex_generator(4)))
    ip_addresses = attr.ib(validator=instance_of(dict),
                           default=attr.Factory(dict))
    label = attr.ib(validator=instance_of(text_type), default='')
    managed = attr.ib(validator=instance_of(bool), default=False)
    metadata = attr.ib(validator=instance_of(dict),
                       default=attr.Factory(dict))
    uri = attr.ib(validator=optional(instance_of(text_type)),
                  default=None)

    USER_SPECIFIABLE_KEYS = ['agent_id',
                             'ip_addresses',
                             'label',
                             'managed',
                             'metadata',
                             'uri']

    def to_json(self):
        """
        Serializes the Entity to a JSON-encodable dict.
        """
        return attr.asdict(self, filter=lambda aa, _: aa.name not in ['alarms', 'checks'])

    def update(self, **kwargs):
        """
        Updates this Entity.
        """
        for key in Entity.USER_SPECIFIABLE_KEYS:
            if key in kwargs:
                setattr(self, key, kwargs[key])
        self.updated_at = int(1000 * kwargs['clock'].seconds())

    def list_checks(self):
        """
        Lists checks under this Entity.
        """
        return [check.to_json() for check in self.checks.values()]

    def list_alarms(self):
        """
        Lists alarms under this Entity.
        """
        return [alarm.to_json() for alarm in self.alarms.values()]
Пример #15
0
def createNotification(params):
    """
    Creates a notificatoin target
    """
    for k in params.keys():
        if 'encode' in dir(params[k]):  # because there are integers sometimes.
            params[k] = params[k].encode('ascii')
    params['id'] = 'nt' + random_hex_generator(4)
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['metadata'] = None
    return params
Пример #16
0
class Check(object):
    """
    Models a MaaS Check.
    """
    created_at = attr.ib(validator=instance_of(int))
    type = attr.ib(validator=instance_of(text_type))
    updated_at = attr.ib(validator=instance_of(int))
    details = attr.ib(validator=instance_of(dict),
                      default=attr.Factory(dict))
    disabled = attr.ib(validator=instance_of(bool), default=False)
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'ch' + random_hex_generator(4)))
    label = attr.ib(validator=instance_of(text_type), default='')
    metadata = attr.ib(validator=instance_of(dict),
                       default=attr.Factory(dict))
    monitoring_zones_poll = attr.ib(validator=instance_of(list),
                                    default=attr.Factory(list))
    period = attr.ib(validator=instance_of(int), default=60)
    target_alias = attr.ib(validator=optional(instance_of(text_type)),
                           default=None)
    target_hostname = attr.ib(validator=optional(instance_of(text_type)),
                              default=None)
    target_resolver = attr.ib(validator=optional(instance_of(text_type)),
                              default=None)
    timeout = attr.ib(validator=instance_of(int), default=10)

    USER_SPECIFIABLE_KEYS = ['details',
                             'disabled',
                             'label',
                             'metadata',
                             'monitoring_zones_poll',
                             'period',
                             'target_alias',
                             'target_hostname',
                             'target_resolver',
                             'timeout',
                             'type']

    def to_json(self):
        """
        Serializes the Check to a JSON-encodable dict.
        """
        return attr.asdict(self)

    def update(self, **kwargs):
        """
        Updates this Check.
        """
        for key in Check.USER_SPECIFIABLE_KEYS:
            if key in kwargs:
                setattr(self, key, kwargs[key])
        self.updated_at = int(1000 * kwargs['clock'].seconds())
Пример #17
0
def create_entity(params):
    """
    Returns a dictionary representing an entity

    :return: an Entity model, which is described in `the Rackspace Cloud
        Monitoring Developer Guide, section 5.4
        <http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-entities.html>`_
    :rtype: ``dict`` mapping ``unicode`` to ``unicode``, ``float``,
        ``bool``, ``dict`` or ``NoneType``.
    """
    params = collections.defaultdict(lambda: '', params)
    newentity = {}
    newentity['label'] = params['label']
    newentity['id'] = 'en' + random_hex_generator(4)
    newentity['agent_id'] = params['agent_id'] or random_hex_generator(12)
    newentity['created_at'] = time.time()
    newentity['updated_at'] = time.time()
    newentity['managed'] = params['managed'] or False
    newentity['metadata'] = params['metadata']
    newentity['ip_addresses'] = params['ip_addresses'] or {}
    newentity['uri'] = params['uri'] or None
    return newentity
Пример #18
0
def createCheck(params):
    """
    Returns a dictionary representing a check
    """
    params = collections.defaultdict(lambda: '', params)
    for k in params.keys():
        if 'encode' in dir(params[k]):
            params[k] = params[k].encode('ascii')
    params['id'] = 'ch' + random_hex_generator(4)
    params['collectors'] = []
    for q in range(3):
        params['collectors'].append('co' + random_hex_generator(3))
    params['confd_hash'] = None
    params['confd_name'] = None
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['timeout'] = 10
    params['period'] = 60
    params['disabled'] = False
    params['metadata'] = None
    params['target_alias'] = None
    if 'count' not in params['details']:
        params['details'] = {'count': 5}  # I have no idea what count=5 is for.
    return params
Пример #19
0
def createNotificationPlan(params):
    """
    Creates a notification plan
    """
    for k in params.keys():
        if 'encode' in dir(params[k]):  # because there are integers sometimes.
            params[k] = params[k].encode('ascii')
    params['id'] = 'np' + random_hex_generator(4)
    params['critical_state'] = None
    params['warning_state'] = None
    params['ok_state'] = None
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['metadata'] = None
    return params
Пример #20
0
def create_notification(params):
    """
    Creates a notification target

    :return: a Notification model, which is described in `the Rackspace
        Cloud Monitoring Developer Guide, section 5.10
        <http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-notifications.html>`_
    :rtype: ``dict`` mapping ``unicode`` to ``unicode``, ``float``,
        ``dict`` or ``NoneType``.
    """
    params['id'] = 'nt' + random_hex_generator(4)
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['metadata'] = None
    return params
Пример #21
0
def createAlarm(params):
    """
    Returns a dictionary representing an alarm
    """
    params = collections.defaultdict(lambda: '', params)
    for k in params.keys():
        if 'encode' in dir(params[k]):
            params[k] = params[k].encode('ascii')
    params['id'] = 'al' + random_hex_generator(4)
    params['confd_hash'] = None
    params['confd_name'] = None
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['disabled'] = False
    params['metadata'] = None
    return params
Пример #22
0
    def rpc_send_yo(self, request):
        """
        Sends a Yo RPC style.
        """
        body = json.loads(request.content.read().decode("utf-8"))

        if 'api_key' not in body:
            request.setResponseCode(401)
            return json.dumps({
                'error':
                'User does not have permissions for this request',
                'errors': [{
                    'message': ('User does not have permissions '
                                'for this request')
                }]
            })

        if 'username' not in body:
            request.setResponseCode(400)
            return json.dumps({
                'error':
                'Can\'t send Yo without a recipient.',
                'errors': [{
                    'message': 'Can\'t send Yo without a recipient.'
                }]
            })

        if 'link' in body and 'location' in body:
            request.setResponseCode(400)
            return json.dumps({
                'error':
                'Can\'t send Yo with location and link.',
                'errors': [{
                    'message': 'Can\'t send Yo with location and link.'
                }]
            })

        user = self.yo_collections.get_or_create_user(body['username'])

        request.setResponseCode(200)
        return json.dumps({
            'success': True,
            'yo_id': random_hex_generator(12),
            'recipient': user.to_json()
        })
Пример #23
0
class User(object):
    """
    Models a Yo user.
    """
    display_name = attr.ib(validator=instance_of(text_type))
    username = attr.ib(validator=instance_of(text_type))
    is_api_user = attr.ib(validator=instance_of(bool), default=False)
    is_subscribable = attr.ib(validator=instance_of(bool), default=False)
    type = attr.ib(validator=instance_of(text_type), default='user')
    user_id = attr.ib(validator=instance_of(text_type),
                      default=attr.Factory(lambda: random_hex_generator(12)))
    yo_count = attr.ib(validator=instance_of(int), default=0)

    def to_json(self):
        """
        Serializes this Yo user to a JSON-encodable dict.
        """
        return attr.asdict(self)
Пример #24
0
    def __init__(self, clock, apis):
        """
        Create a MimicCore with an IReactorTime to do any time-based scheduling
        against.

        :param clock: an IReactorTime which will be used for session timeouts
            and determining timestamps.
        :type clock: :obj:`twisted.internet.interfaces.IReactorTime`

        :param apis: an iterable of all :obj:`IAPIMock`s that this MimicCore
            will expose.
        """
        self._uuid_to_api = {}
        self.sessions = SessionStore(clock)

        for api in apis:
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api[this_api_id] = api
Пример #25
0
def create_alarm(params):
    """
    Returns a dictionary representing an alarm

    :return: an Alarm model, which is described in `the Rackspace Cloud
        Monitoring Developer Guide, section 5.12
        <http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-alarms.html>`_
    :rtype: ``dict`` mapping ``unicode`` to ``unicode``, ``float``,
        ``bool``, ``dict``, or ``NoneType``.
    """
    params = collections.defaultdict(lambda: '', params)
    params['id'] = 'al' + random_hex_generator(4)
    params['confd_hash'] = None
    params['confd_name'] = None
    params['created_at'] = time.time()
    params['updated_at'] = time.time()
    params['disabled'] = False
    params['metadata'] = None
    return params
Пример #26
0
def create_suppression(params):
    """
    Creates a suppression

    :return: a Suppression model, which is described in `the Rackspace
        Cloud Monitoring Developer Guide, section 5.16
        <http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-suppressions.html>`_
    :rtype: ``dict`` mapping ``unicode`` to ``unicode`` or ``list``.
    """
    params['id'] = 'sp' + random_hex_generator(4)
    if 'notification_plans' not in params:
        params['notification_plans'] = []
    if 'entities' not in params:
        params['entities'] = []
    if 'checks' not in params:
        params['checks'] = []
    if 'alarms' not in params:
        params['alarms'] = []
    return params
Пример #27
0
class Suppression(object):
    """
    Models a MaaS suppression.
    """
    created_at = attr.ib(validator=instance_of(int))
    updated_at = attr.ib(validator=instance_of(int))
    alarms = attr.ib(validator=instance_of(list),
                     default=attr.Factory(list))
    checks = attr.ib(validator=instance_of(list),
                     default=attr.Factory(list))
    end_time = attr.ib(validator=instance_of(int), default=0)
    entities = attr.ib(validator=instance_of(list),
                       default=attr.Factory(list))
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'sp' + random_hex_generator(4)))
    label = attr.ib(validator=instance_of(text_type), default='')
    notification_plans = attr.ib(validator=instance_of(list),
                                 default=attr.Factory(list))
    start_time = attr.ib(validator=instance_of(int), default=0)

    USER_SPECIFIABLE_KEYS = ['alarms',
                             'checks',
                             'end_time',
                             'entities',
                             'label',
                             'notification_plans',
                             'start_time']

    def to_json(self):
        """
        Serializes the Suppression to a JSON-encodable dict.
        """
        return attr.asdict(self)

    def update(self, **kwargs):
        """
        Updates this Suppression.
        """
        for key in Suppression.USER_SPECIFIABLE_KEYS:
            if key in kwargs:
                setattr(self, key, kwargs[key])
        self.updated_at = int(1000 * kwargs['clock'].seconds())
Пример #28
0
    def add_api(self, api):
        """
        Add a new API to the listing.

        :param object api: An object implementing either the
            :obj:`IAPIMock` or :obj:`IExternalAPIMock` interfaces.
        :raises: TypeError if the object does not implement the
            correct interfaces.
        """
        # Gate check the API to make sure it implements one of the
        # supported interfaces
        if IExternalAPIMock.providedBy(api):
            # External APIs need to be able to be easily managed by
            # the same object so long as they have the same uuid
            this_api_id = api.uuid_key

            if this_api_id in self._uuid_to_api_external:
                raise ServiceIdExists(
                    'An Existing API already exists with the given UUID'
                )

            for existing_api in self._uuid_to_api_external.values():
                if existing_api.name_key == api.name_key:
                    raise ServiceNameExists(
                        'An Existing API with UUID ' + existing_api.uuid_key +
                        ' is already using that name'
                    )
            self._uuid_to_api_external[this_api_id] = api
        elif IAPIMock.providedBy(api):
            # Internal APIs can be added easily on the fly since
            # they also provide the resource for implementing the API
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api_internal[this_api_id] = api
        else:
            raise ServiceBadInterface(
                api.__class__.__module__ + '/' +
                api.__class__.__name__ +
                " does not implement IAPIMock or IExternalAPIMock"
            )
Пример #29
0
class Alarm(object):
    """
    Models a MaaS Alarm.
    """
    check_id = attr.ib(validator=instance_of(text_type))
    created_at = attr.ib(validator=instance_of(int))
    entity_id = attr.ib(validator=instance_of(text_type))
    notification_plan_id = attr.ib(validator=instance_of(text_type))
    updated_at = attr.ib(validator=instance_of(int))
    criteria = attr.ib(validator=instance_of(text_type), default='')
    disabled = attr.ib(validator=instance_of(bool), default=False)
    id = attr.ib(validator=instance_of(text_type),
                 default=attr.Factory(lambda: 'al' + random_hex_generator(4)))
    label = attr.ib(validator=instance_of(text_type), default='')
    metadata = attr.ib(validator=instance_of(dict),
                       default=attr.Factory(dict))

    USER_SPECIFIABLE_KEYS = ['check_id',
                             'criteria',
                             'disabled',
                             'label',
                             'metadata',
                             'notification_plan_id']

    def to_json(self):
        """
        Serializes the Alarm to a JSON-encodable dict.
        """
        return attr.asdict(self)

    def update(self, **kwargs):
        """
        Updates this Alarm.
        """
        for key in Alarm.USER_SPECIFIABLE_KEYS:
            if key in kwargs:
                setattr(self, key, kwargs[key])
        self.updated_at = int(1000 * kwargs['clock'].seconds())
Пример #30
0
    def __init__(self, clock, apis):
        """
        Create a MimicCore with an IReactorTime to do any time-based scheduling
        against.

        :param clock: an IReactorTime which will be used for session timeouts
            and determining timestamps.
        :type clock: :obj:`twisted.internet.interfaces.IReactorTime`

        :param apis: an iterable of all :obj:`IAPIMock`s that this MimicCore
            will expose.
        """
        self._uuid_to_api = {}
        self.sessions = SessionStore(clock)
        self.message_store = MessageStore()
        self.contacts_store = ContactsStore()
        self.ironic_node_store = IronicNodeStore()
        self.glance_admin_image_store = GlanceAdminImageStore()
        self.valkyrie_store = ValkyrieStore()

        for api in apis:
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api[this_api_id] = api
Пример #31
0
    def add_api(self, api):
        """
        Add a new API to the listing.

        :param object api: An object implementing either the
            :obj:`IAPIMock` or :obj:`IExternalAPIMock` interfaces.
        :raises: TypeError if the object does not implement the
            correct interfaces.
        """
        # Gate check the API to make sure it implements one of the
        # supported interfaces
        if IExternalAPIMock.providedBy(api):
            # External APIs need to be able to be easily managed by
            # the same object so long as they have the same uuid
            this_api_id = api.uuid_key

            if this_api_id in self._uuid_to_api_external:
                raise ServiceIdExists(
                    'An Existing API already exists with the given UUID')

            for existing_api in self._uuid_to_api_external.values():
                if existing_api.name_key == api.name_key:
                    raise ServiceNameExists('An Existing API with UUID ' +
                                            existing_api.uuid_key +
                                            ' is already using that name')
            self._uuid_to_api_external[this_api_id] = api
        elif IAPIMock.providedBy(api):
            # Internal APIs can be added easily on the fly since
            # they also provide the resource for implementing the API
            this_api_id = ((api.__class__.__name__) + '-' +
                           random_hex_generator(3))
            self._uuid_to_api_internal[this_api_id] = api
        else:
            raise ServiceBadInterface(
                api.__class__.__module__ + '/' + api.__class__.__name__ +
                " does not implement IAPIMock or IExternalAPIMock")
Пример #32
0
from characteristic import attributes, Attribute
from six import text_type

from mimic.util.helper import random_hex_generator, random_string

METRIC_TYPE_INTEGER = 'i'
METRIC_TYPE_NUMBER = 'n'
METRIC_TYPE_STRING = 's'


@attributes([
    Attribute('agent_id', default_value=None),
    Attribute('created_at', instance_of=int),
    Attribute('id',
              default_factory=(lambda: u'en' + random_hex_generator(4)),
              instance_of=text_type),
    Attribute('ip_addresses', default_factory=dict, instance_of=dict),
    Attribute('label', default_value=u'', instance_of=text_type),
    Attribute('managed', default_value=False, instance_of=bool),
    Attribute('metadata', default_factory=dict, instance_of=dict),
    Attribute('updated_at', instance_of=int),
    Attribute('uri', default_value=None)
])
class Entity(object):
    """
    Models a MaaS Entity.
    """
    USER_SPECIFIABLE_KEYS = [
        'agent_id', 'ip_addresses', 'label', 'managed', 'metadata', 'uri'
    ]
Пример #33
0
class Queue(object):
    """
    A Queue object in Cloud Queues.
    """
    name = attr.ib(validator=attr.validators.instance_of(text_type))
    id = attr.ib(validator=attr.validators.instance_of(text_type),
                 default=attr.Factory(lambda: random_hex_generator(4)))
    _messages = attr.ib(default=attr.Factory(list))

    def _clear_expired_messages(self, current_time):
        """
        Clears expired messages from the queue.
        """
        self._messages[:] = [
            message for message in self._messages
            if not message.is_expired_at(current_time)
        ]

    def brief_json(self):
        """
        A brief representation of this queue that can be serialized
        via json.dumps.
        """
        return {'href': '/v1/queues/{0}'.format(self.name), 'name': self.name}

    def post_messages(self, messages, client_id, current_time):
        """
        Posts a series of messages to the message queue.
        """
        self._clear_expired_messages(current_time)
        new_messages = [
            Message(ttl=message['ttl'],
                    body=message['body'],
                    queue_name=self.name,
                    posted_by=client_id,
                    posted_at=current_time) for message in messages
        ]
        self._messages.extend(new_messages)
        response_json = {
            'partial': False,
            'resources': [message.href() for message in new_messages]
        }
        return response_json, 201

    def list_messages(self, client_id, current_time, echo):
        """
        Lists messages (that the client can see).

        If the echo parameter is set to true, the client sees all messages.
        Otherwise, the client only sees messages posted by other clients.
        """
        self._clear_expired_messages(current_time)
        response_json = {
            'messages': [
                message.to_json(current_time) for message in self._messages
                if echo or message.posted_by != client_id
            ],
            'links': []
        }
        return (response_json, 200) if response_json['messages'] else (None,
                                                                       204)
Пример #34
0
class Node(object):
    """
    A :obj:`Node` is a representation of all the state associated with a ironic
    node.  It can produce JSON-serializable objects for various pieces of
    state that are required for API responses.
    """

    static_defaults = {
        "target_power_state": None,
        "target_provision_state": None,
        "updated_at": "2015-08-09T04:30:05+00:00",
        "last_error": None,
        "console_enabled": False,
        "maintenance_reason": None,
        "provision_updated_at": "2015-08-07T06:57:24+00:00",
        "reservation": None,
        "created_at": "2014-09-26T18:56:03+00:00",
        "instance_info": None,
        "inspection_finished_at": None,
        "inspection_started_at": None,
        "clean_step": {},
        "driver_internal_info": {
            "clean_steps": None,
            "hardware_manager_version":
            {
                "generic_hardware_manager": "1",
                "onmetal_hardware_manager": "1"
            },
                "is_whole_disk_image": True,
                "agent_erase_devices_iterations": 1,
                "agent_url": "http://127.0.0.1:8900",
                "cleaning_reboot": True,
                "agent_last_heartbeat": 1440117499
        }
    }

    static_instance_info = {
        "root_gb": "32",
        "image_source": str(uuid4()),
        "ephemeral_gb": "3200",
        "configdrive": str(random_hex_generator(100)),
        "image_url": "http://127.0.0.1/mimic-image-url",
        "image_container_format": "bare_mimic",
        "image_disk_format": "mimic",
        "image_checksum": str(random_hex_generator(6)),
        "swap_mb": "0"
    }

    def links_json(self):
        """
        Create a JSON-serializable data structure describing the links to this
        node.
        """
        return [
            {
                "href": "http://link-to-ironic/v1/nodes/".format(self.node_id),
                "rel": "self"
            },
            {
                "href": "http://link-to-ironic/nodes/".format(self.node_id),
                "rel": "bookmark"
            }
        ]

    def port_links_json(self):
        """
        Create a JSON-serializable data structure describing the port links to this
        node.
        """
        return [
            {
                "href": "http://link-to-ironic/v1/nodes/{0}/ports".format(self.node_id),
                "rel": "self"
            },
            {
                "href": "http://link-to-ironic/nodes/{0}/ports".format(self.node_id),
                "rel": "bookmark"
            }
        ]

    def brief_json(self):
        """
        Brief JSON-serializable version of this server, for the non-details
        list nodes request.
        """
        return {
            "instance_uuid": self.instance_uuid,
            "uuid": self.node_id,
            "links": self.links_json(),
            "maintenance": self.maintenance,
            "provision_state": self.provision_state,
            "power_state": self.power_state,
            "name": self.name
        }

    def detail_json(self):
        """
        Long-form JSON-serializable object representation of this node, as
        returned by either a GET on this individual node or a member in the
        list returned by the list-details request.
        """
        template = self.static_defaults.copy()
        template.update({
            "instance_uuid": self.instance_uuid,
            "chassis_uuid": self.chassis_uuid,
            "name": self.name,
            "uuid": self.node_id,
            "links": self.links_json(),
            "maintenance": self.maintenance,
            "provision_state": self.provision_state,
            "power_state": self.power_state,
            "ports": self.port_links_json(),
            "extra": {
                "flavor": self.flavor_id,
                "hardware/inventory/disks/0/size": "31016853504",
                "hardware/interfaces/0/switch_port_id": "Mimic0/01",
                "rackid": "Mimic_rackid",
                "hardware/interfaces/1/switch_chassis_id": "mimic-chassis1",
                "core_id": "00000",
                "hardware/inventory/disks/2/size": "1861817990000",
                "uutsn": "Mimic-uutsn",
                "hardware/inventory/disks/1/size": "1861817990000",
                "hardware/inventory/cpu/count": "40",
                "hardware/inventory/memory/total": "135234740224",
                "hardware/inventory/disks/2/rotational": "False",
                "hardware/inventory/disks/0/rotational": "False",
                "hardware/inventory/disks/1/rotational": "False",
                "racklocation": "Mimic00",
                "hardware/interfaces/1/switch_port_id": "Mimic1/10",
                "hardware/interfaces/0/switch_chassis_id": "mimic-chassis1"
            },
            "properties": self.properties or {
                "memory_mb": self.memory_mb,
                "cpu_arch": "amd64",
                "local_gb": 32,
                "cpus": 40
            },
            "driver": self.driver,
            "driver_info": self.driver_info or {
                "ipmi_username": "******",
                "ipmi_address": "127.0.0.0",
                "ipmi_password": "******",
                "cache_image_id": self.cache_image_id,
                "cache_status": 'cached' if self.cache_image_id else None
            }
        })
        if self.instance_uuid:
            template["instance_info"] = self.static_instance_info
            template["provision_state"] = "active"
        if not self.driver:
            template["driver"] = "fake"
        return template
Пример #35
0
from uuid import uuid4

from characteristic import attributes, Attribute
from six import text_type

from mimic.util.helper import random_hex_generator, random_string

METRIC_TYPE_INTEGER = 'i'
METRIC_TYPE_NUMBER = 'n'
METRIC_TYPE_STRING = 's'


@attributes([Attribute('agent_id', default_value=None),
             Attribute('created_at', instance_of=int),
             Attribute('id',
                       default_factory=(lambda: u'en' + random_hex_generator(4)),
                       instance_of=text_type),
             Attribute('ip_addresses', default_factory=dict, instance_of=dict),
             Attribute('label', default_value=u'', instance_of=text_type),
             Attribute('managed', default_value=False, instance_of=bool),
             Attribute('metadata', default_factory=dict, instance_of=dict),
             Attribute('updated_at', instance_of=int),
             Attribute('uri', default_value=None)])
class Entity(object):
    """
    Models a MaaS Entity.
    """
    USER_SPECIFIABLE_KEYS = ['agent_id',
                             'ip_addresses',
                             'label',
                             'managed',