コード例 #1
0
ファイル: zaqar.py プロジェクト: openstack/aodh
    def notify_zaqar(self, action, message, headers=None):
        queue_info = urlparse.parse_qs(action.query)
        try:
            # NOTE(flwang): Try to get build a pre-signed client if user has
            # provide enough information about that. Otherwise, go to build
            # a client with service account and queue name for this alarm.
            conf, queue_name = self._get_presigned_client_conf(queue_info)
            if conf is not None:
                zaqar_client = self.get_zaqar_client(conf)

            if conf is None or queue_name is None or zaqar_client is None:
                zaqar_client = self.client
                # queue_name is a combination of <alarm-id>-<topic>
                queue_name = "%s-%s" % (message['body']['alarm_id'],
                                        queue_info.get('topic')[-1])

            # create a queue in zaqar
            queue = zaqar_client.queue(queue_name)

            subscriber_list = queue_info.get('subscriber', [])
            ttl = int(queue_info.get('ttl', ['3600'])[-1])
            for subscriber in subscriber_list:
                # add subscriber to the zaqar queue
                subscription_data = dict(subscriber=subscriber, ttl=ttl)
                zaqar_client.subscription(queue_name, **subscription_data)
            # post the message to the queue
            queue.post(message)
        except IndexError:
            LOG.error(
                _LE("Required query option missing in action %s"), action)
        except Exception:
            LOG.error(
                _LE("Unknown error occurred; Failed to post message to"
                    " Zaqar queue"),
                exc_info=True)
コード例 #2
0
ファイル: zaqar.py プロジェクト: bopopescu/Openstack-2
    def notify_zaqar(self, action, message):
        queue_info = urlparse.parse_qs(action.query)

        try:
            # queue_name is a combination of <alarm-id>-<topic>
            queue_name = "%s-%s" % (message['body']['alarm_id'],
                                    queue_info.get('topic')[-1])
            # create a queue in zaqar
            queue = self.client.queue(queue_name, force_create=True)
            subscriber_list = queue_info.get('subscriber', [])
            ttl = queue_info.get('ttl', [3600])[-1]
            for subscriber in subscriber_list:
                # add subscriber to the zaqar queue
                subscription_data = dict(subscriber=subscriber, ttl=ttl)
                self.client.subscription(queue_name, **subscription_data)
            # post the message to the queue
            queue.post(message)
        except IndexError:
            LOG.error(
                _LE("Required topic query option missing in action %s") %
                action)
        except Exception:
            LOG.error(_LE("Unknown error occurred; Failed to post message to"
                          " Zaqar queue"),
                      exc_info=True)
コード例 #3
0
ファイル: zaqar.py プロジェクト: bopopescu/OpenStack-Ocata
    def notify_zaqar(self, action, message, headers=None):
        queue_info = urlparse.parse_qs(action.query)
        try:
            # NOTE(flwang): Try to get build a pre-signed client if user has
            # provide enough information about that. Otherwise, go to build
            # a client with service account and queue name for this alarm.
            conf, queue_name = self._get_presigned_client_conf(queue_info)
            if conf is not None:
                zaqar_client = self.get_zaqar_client(conf)

            if conf is None or queue_name is None or zaqar_client is None:
                zaqar_client = self.client
                # queue_name is a combination of <alarm-id>-<topic>
                queue_name = "%s-%s" % (message['body']['alarm_id'],
                                        queue_info.get('topic')[-1])

            # create a queue in zaqar
            queue = zaqar_client.queue(queue_name)

            subscriber_list = queue_info.get('subscriber', [])
            ttl = int(queue_info.get('ttl', ['3600'])[-1])
            for subscriber in subscriber_list:
                # add subscriber to the zaqar queue
                subscription_data = dict(subscriber=subscriber, ttl=ttl)
                zaqar_client.subscription(queue_name, **subscription_data)
            # post the message to the queue
            queue.post(message)
        except IndexError:
            LOG.error(_LE("Required query option missing in action %s"),
                      action)
        except Exception:
            LOG.error(_LE("Unknown error occurred; Failed to post message to"
                          " Zaqar queue"),
                      exc_info=True)
コード例 #4
0
ファイル: zaqar.py プロジェクト: openstack-yak/aodh
    def notify_zaqar(self, action, message):
        queue_info = urlparse.parse_qs(action.query)

        try:
            # queue_name is a combination of <alarm-id>-<topic>
            queue_name = "%s-%s" % (message['body']['alarm_id'],
                                    queue_info.get('topic')[-1])
            # create a queue in zaqar
            queue = self.client.queue(queue_name, force_create=True)
            subscriber_list = queue_info.get('subscriber', [])
            ttl = queue_info.get('ttl', [3600])[-1]
            for subscriber in subscriber_list:
                # add subscriber to the zaqar queue
                subscription_data = dict(subscriber=subscriber,
                                         ttl=ttl)
                self.client.subscription(queue_name,
                                         **subscription_data)
            # post the message to the queue
            queue.post(message)
        except IndexError:
            LOG.error(_LE("Required topic query option missing in action %s")
                      % action)
        except Exception:
            LOG.error(_LE("Unknown error occurred; Failed to post message to"
                          " Zaqar queue"),
                      exc_info=True)
コード例 #5
0
 def _get_alarm_state(self, alarm_id):
     try:
         alarms = self._storage_conn.get_alarms(alarm_id=alarm_id)
     except Exception:
         LOG.exception(_LE('alarm %s retrieval failed'), alarm_id)
         return None
     if not alarms:
         LOG.error(_LE("alarm %s doesn't exists anymore"), alarm_id)
         return None
     return list(alarms)[0].state
コード例 #6
0
 def _get_alarm_state(self, alarm_id):
     try:
         alarms = self._storage_conn.get_alarms(alarm_id=alarm_id)
     except Exception:
         LOG.exception(_LE('alarm %s retrieval failed'), alarm_id)
         return None
     if not alarms:
         LOG.error(_LE("alarm %s doesn't exist anymore"), alarm_id)
         return None
     return list(alarms)[0].state
コード例 #7
0
ファイル: data_migration.py プロジェクト: ISCAS-VDI/aodh-base
def _validate_conn_options(args):
    nosql_scheme = urlparse.urlparse(args.nosql_conn).scheme
    sql_scheme = urlparse.urlparse(args.sql_conn).scheme
    if nosql_scheme not in ('mongodb', 'hbase'):
        root_logger.error(_LE('Invalid source DB type %s, the source database '
                              'connection  should be one of: [mongodb, hbase]'
                              ), nosql_scheme)
        sys.exit(1)
    if sql_scheme not in ('mysql', 'mysql+pymysql', 'postgresql',
                          'sqlite'):
        root_logger.error(_LE('Invalid destination DB type %s, the destination'
                              ' database connection should be one of: '
                              '[mysql, postgresql, sqlite]'), sql_scheme)
        sys.exit(1)
コード例 #8
0
ファイル: __init__.py プロジェクト: openstack/aodh
 def _refresh(self, alarm, state, reason, reason_data, always_record=False):
     """Refresh alarm state."""
     try:
         previous = alarm.state
         alarm.state = state
         if previous != state or always_record:
             LOG.info(_LI('alarm %(id)s transitioning to %(state)s because '
                          '%(reason)s'), {'id': alarm.alarm_id,
                                          'state': state,
                                          'reason': reason})
             try:
                 self._storage_conn.update_alarm(alarm)
             except storage.AlarmNotFound:
                 LOG.warning(_LW("Skip updating this alarm's state, the"
                                 "alarm: %s has been deleted"),
                             alarm.alarm_id)
             else:
                 self._record_change(alarm, reason)
             self.notifier.notify(alarm, previous, reason, reason_data)
         elif alarm.repeat_actions:
             self.notifier.notify(alarm, previous, reason, reason_data)
     except Exception:
         # retry will occur naturally on the next evaluation
         # cycle (unless alarm state reverts in the meantime)
         LOG.exception(_LE('alarm state update failed'))
コード例 #9
0
ファイル: coordination.py プロジェクト: openstack/aodh
    def extract_my_subset(self, group_id, universal_set):
        """Filters an iterable, returning only objects assigned to this agent.

        We have a list of objects and get a list of active group members from
        `tooz`. We then hash all the objects into buckets and return only
        the ones that hashed into *our* bucket.
        """
        if not group_id:
            return universal_set
        if group_id not in self._groups:
            self.join_group(group_id)
        try:
            members = self._get_members(group_id)
            LOG.debug('Members of group: %s, Me: %s', members, self._my_id)
            if self._my_id not in members:
                LOG.warning(_LW('Cannot extract tasks because agent failed to '
                                'join group properly. Rejoining group.'))
                self.join_group(group_id)
                members = self._get_members(group_id)
                if self._my_id not in members:
                    raise MemberNotInGroupError(group_id, members, self._my_id)
                LOG.debug('Members of group: %s, Me: %s', members, self._my_id)
            hr = HashRing(members)
            LOG.debug('Universal set: %s', universal_set)
            my_subset = [v for v in universal_set
                         if hr.get_node(str(v)) == self._my_id]
            LOG.debug('My subset: %s', my_subset)
            return my_subset
        except tooz.coordination.ToozError:
            LOG.exception(_LE('Error getting group membership info from '
                              'coordination backend.'))
            return []
コード例 #10
0
    def extract_my_subset(self, group_id, iterable):
        """Filters an iterable, returning only objects assigned to this agent.

        We have a list of objects and get a list of active group members from
        `tooz`. We then hash all the objects into buckets and return only
        the ones that hashed into *our* bucket.
        """
        if not group_id:
            return iterable
        if group_id not in self._groups:
            self.join_group(group_id)
        try:
            members = self._get_members(group_id)
            LOG.debug('Members of group: %s', members)
            hr = HashRing(members)
            filtered = [
                v for v in iterable if hr.get_node(str(v)) == self._my_id
            ]
            LOG.debug('My subset: %s', filtered)
            return filtered
        except tooz.coordination.ToozError:
            LOG.exception(
                _LE('Error getting group membership info from '
                    'coordination backend.'))
            return []
コード例 #11
0
    def _validate(self):
        """Validate received event has mandatory parameters."""

        if not self.obj:
            LOG.error(_LE('Received invalid event (empty or None)'))
            raise InvalidEvent()

        if not self.obj.get('event_type'):
            LOG.error(_LE('Failed to extract event_type from event = %s'),
                      self.obj)
            raise InvalidEvent()

        if not self.obj.get('message_id'):
            LOG.error(_LE('Failed to extract message_id from event = %s'),
                      self.obj)
            raise InvalidEvent()
コード例 #12
0
ファイル: __init__.py プロジェクト: bopopescu/OpenStack-Ocata
 def _refresh(self, alarm, state, reason, reason_data, always_record=False):
     """Refresh alarm state."""
     try:
         previous = alarm.state
         alarm.state = state
         if previous != state or always_record:
             LOG.info(
                 _LI('alarm %(id)s transitioning to %(state)s because '
                     '%(reason)s'), {
                         'id': alarm.alarm_id,
                         'state': state,
                         'reason': reason
                     })
             try:
                 self._storage_conn.update_alarm(alarm)
             except storage.AlarmNotFound:
                 LOG.warning(
                     _LW("Skip updating this alarm's state, the"
                         "alarm: %s has been deleted"), alarm.alarm_id)
             else:
                 self._record_change(alarm, reason)
             self.notifier.notify(alarm, previous, reason, reason_data)
         elif alarm.repeat_actions:
             self.notifier.notify(alarm, previous, reason, reason_data)
     except Exception:
         # retry will occur naturally on the next evaluation
         # cycle (unless alarm state reverts in the meantime)
         LOG.exception(_LE('alarm state update failed'))
コード例 #13
0
    def evaluate_events(self, events):
        """Evaluate the events by referring related alarms."""

        if not isinstance(events, list):
            events = [events]

        LOG.debug('Starting event alarm evaluation: #events = %d', len(events))
        for e in events:
            LOG.debug('Evaluating event: event = %s', e)
            try:
                event = Event(e)
            except InvalidEvent:
                LOG.debug('Aborting evaluation of the event.')
                continue

            for id, alarm in six.iteritems(
                    self._get_project_alarms(event.project)):
                try:
                    self._evaluate_alarm(alarm, event)
                except Exception:
                    LOG.exception(
                        _LE('Failed to evaluate alarm (id=%(a)s) '
                            'triggered by event = %(e)s.'), {
                                'a': id,
                                'e': e
                            })

        LOG.debug('Finished event alarm evaluation.')
コード例 #14
0
    def _validate(self):
        """Validate received event has mandatory parameters."""

        if not self.obj:
            LOG.error(_LE('Received invalid event (empty or None)'))
            raise InvalidEvent()

        if not self.obj.get('event_type'):
            LOG.error(_LE('Failed to extract event_type from event = %s'),
                      self.obj)
            raise InvalidEvent()

        if not self.obj.get('message_id'):
            LOG.error(_LE('Failed to extract message_id from event = %s'),
                      self.obj)
            raise InvalidEvent()
コード例 #15
0
    def evaluate_events(self, events):
        """Evaluate the events by referring related alarms."""

        if not isinstance(events, list):
            events = [events]

        LOG.debug('Starting event alarm evaluation: #events = %d',
                  len(events))
        for e in events:
            LOG.debug('Evaluating event: event = %s', e)
            try:
                event = Event(e)
            except InvalidEvent:
                LOG.debug('Aborting evaluation of the event.')
                continue

            for id, alarm in six.iteritems(
                    self._get_project_alarms(event.project)):
                try:
                    self._evaluate_alarm(alarm, event)
                except Exception:
                    LOG.exception(_LE('Failed to evaluate alarm (id=%(a)s) '
                                      'triggered by event = %(e)s.'),
                                  {'a': id, 'e': e})

        LOG.debug('Finished event alarm evaluation.')
コード例 #16
0
    def extract_my_subset(self, group_id, universal_set):
        """Filters an iterable, returning only objects assigned to this agent.

        We have a list of objects and get a list of active group members from
        `tooz`. We then hash all the objects into buckets and return only
        the ones that hashed into *our* bucket.
        """
        if not group_id:
            return universal_set
        if group_id not in self._groups:
            self.join_group(group_id)
        try:
            members = self._get_members(group_id)
            LOG.debug('Members of group: %s, Me: %s', members, self._my_id)
            if self._my_id not in members:
                LOG.warning(
                    _LW('Cannot extract tasks because agent failed to '
                        'join group properly. Rejoining group.'))
                self.join_group(group_id)
                members = self._get_members(group_id)
                if self._my_id not in members:
                    raise MemberNotInGroupError(group_id, members, self._my_id)
                LOG.debug('Members of group: %s, Me: %s', members, self._my_id)
            hr = HashRing(members)
            LOG.debug('Universal set: %s', universal_set)
            my_subset = [
                v for v in universal_set if hr.get_node(str(v)) == self._my_id
            ]
            LOG.debug('My subset: %s', my_subset)
            return my_subset
        except tooz.coordination.ToozError:
            LOG.exception(
                _LE('Error getting group membership info from '
                    'coordination backend.'))
            return []
コード例 #17
0
ファイル: __init__.py プロジェクト: bopopescu/OpenStack-Ocata
    def _handle_action(notifiers, action, alarm_id, alarm_name, severity,
                       previous, current, reason, reason_data):
        """Process action on alarm

        :param notifiers: list of possible notifiers.
        :param action: The action that is being attended, as a parsed URL.
        :param alarm_id: The triggered alarm.
        :param alarm_name: The name of triggered alarm.
        :param severity: The level of triggered alarm
        :param previous: The previous state of the alarm.
        :param current: The current state of the alarm.
        :param reason: The reason the alarm changed its state.
        :param reason_data: A dict representation of the reason.
        """

        try:
            action = netutils.urlsplit(action)
        except Exception:
            LOG.error(
                _LE("Unable to parse action %(action)s for alarm "
                    "%(alarm_id)s"), {
                        'action': action,
                        'alarm_id': alarm_id
                    })
            return

        try:
            notifier = notifiers[action.scheme].obj
        except KeyError:
            scheme = action.scheme
            LOG.error(
                _LE("Action %(scheme)s for alarm %(alarm_id)s is unknown, "
                    "cannot notify"), {
                        'scheme': scheme,
                        'alarm_id': alarm_id
                    })
            return

        try:
            LOG.debug("Notifying alarm %(id)s with action %(act)s", {
                'id': alarm_id,
                'act': action
            })
            notifier.notify(action, alarm_id, alarm_name, severity, previous,
                            current, reason, reason_data)
        except Exception:
            LOG.exception(_LE("Unable to notify alarm %s"), alarm_id)
コード例 #18
0
ファイル: zaqar.py プロジェクト: openstack/aodh
 def get_zaqar_client(self, conf):
     try:
         from zaqarclient.queues import client as zaqar_client
         return zaqar_client.Client(
             self._get_endpoint(), version=2, conf=conf)
     except Exception:
         LOG.error(
             _LE("Failed to connect to Zaqar service "), exc_info=True)
コード例 #19
0
 def __init__(self, group_id, members, my_id):
     super(MemberNotInGroupError, self).__init__(
         _LE('Group ID: %{group_id}s, Members: %{members}s, Me: %{me}s: '
             'Current agent is not part of group and cannot take tasks') % {
                 'group_id': group_id,
                 'members': members,
                 'me': my_id
             })
コード例 #20
0
ファイル: __init__.py プロジェクト: openstack/aodh
 def _evaluate_assigned_alarms(self):
     try:
         alarms = self._assigned_alarms()
         LOG.info(_LI('initiating evaluation cycle on %d alarms'),
                  len(alarms))
         for alarm in alarms:
             self._evaluate_alarm(alarm)
     except Exception:
         LOG.exception(_LE('alarm evaluation cycle failed'))
コード例 #21
0
ファイル: coordination.py プロジェクト: openstack/aodh
 def start(self):
     if self.backend_url:
         try:
             self._coordinator = tooz.coordination.get_coordinator(
                 self.backend_url, self._my_id)
             self._coordinator.start()
             LOG.info(_LI('Coordination backend started successfully.'))
         except tooz.coordination.ToozError:
             LOG.exception(_LE('Error connecting to coordination backend.'))
コード例 #22
0
 def start(self):
     if self.backend_url:
         try:
             self._coordinator = tooz.coordination.get_coordinator(
                 self.backend_url, self._my_id)
             self._coordinator.start()
             LOG.info(_LI('Coordination backend started successfully.'))
         except tooz.coordination.ToozError:
             LOG.exception(_LE('Error connecting to coordination backend.'))
コード例 #23
0
ファイル: query.py プロジェクト: bopopescu/OpenStack-Ocata
 def _convert_to_datetime(isotime):
     try:
         date_time = timeutils.parse_isotime(isotime)
         date_time = date_time.replace(tzinfo=None)
         return date_time
     except ValueError:
         LOG.exception(_LE("String %s is not a valid isotime"), isotime)
         msg = _('Failed to parse the timestamp value %s') % isotime
         raise base.ClientSideError(msg)
コード例 #24
0
ファイル: zaqar.py プロジェクト: bopopescu/OpenStack-Ocata
 def get_zaqar_client(self, conf):
     try:
         from zaqarclient.queues import client as zaqar_client
         return zaqar_client.Client(self._get_endpoint(),
                                    version=2,
                                    conf=conf)
     except Exception:
         LOG.error(_LE("Failed to connect to Zaqar service "),
                   exc_info=True)
コード例 #25
0
ファイル: __init__.py プロジェクト: bopopescu/OpenStack-Ocata
 def _evaluate_assigned_alarms(self):
     try:
         alarms = self._assigned_alarms()
         LOG.info(_LI('initiating evaluation cycle on %d alarms'),
                  len(alarms))
         for alarm in alarms:
             self._evaluate_alarm(alarm)
     except Exception:
         LOG.exception(_LE('alarm evaluation cycle failed'))
コード例 #26
0
ファイル: coordination.py プロジェクト: openstack/aodh
 def heartbeat(self):
     if self._coordinator:
         if not self._coordinator.is_started:
             # re-connect
             self.start()
         try:
             self._coordinator.heartbeat()
         except tooz.coordination.ToozError:
             LOG.exception(_LE('Error sending a heartbeat to coordination '
                               'backend.'))
コード例 #27
0
ファイル: zaqar.py プロジェクト: openstack/aodh
    def notify_zaqar(self, action, message, headers):
        queue_info = urlparse.parse_qs(action.query)
        try:
            queue_name = queue_info.get('queue_name')[-1]
        except IndexError:
            LOG.error(_LE("Required 'queue_name' query option missing in"
                          " action %s"),
                      action)
            return

        try:
            conf = self._get_client_conf(headers['X-Auth-Token'])
            client = self.get_zaqar_client(conf)
            queue = client.queue(queue_name)
            queue.post(message)
        except Exception:
            LOG.error(_LE("Unknown error occurred; Failed to post message to"
                          " Zaqar queue"),
                      exc_info=True)
コード例 #28
0
ファイル: zaqar.py プロジェクト: bopopescu/OpenStack-Ocata
    def notify_zaqar(self, action, message, headers):
        queue_info = urlparse.parse_qs(action.query)
        try:
            queue_name = queue_info.get('queue_name')[-1]
        except IndexError:
            LOG.error(
                _LE("Required 'queue_name' query option missing in"
                    " action %s"), action)
            return

        try:
            conf = self._get_client_conf(headers['X-Auth-Token'])
            client = self.get_zaqar_client(conf)
            queue = client.queue(queue_name)
            queue.post(message)
        except Exception:
            LOG.error(_LE("Unknown error occurred; Failed to post message to"
                          " Zaqar queue"),
                      exc_info=True)
コード例 #29
0
ファイル: zaqar.py プロジェクト: openstack-yak/aodh
 def _get_endpoint(self):
     try:
         ks_client = keystone_client.get_client(self.conf)
         return ks_client.service_catalog.url_for(
             service_type=cfg.CONF.service_types.zaqar,
             endpoint_type=self.conf.service_credentials.os_endpoint_type)
     except Exception:
         LOG.error(_LE("Aodh was configured to use zaqar:// action,"
                       " but Zaqar endpoint could not be found in Keystone"
                       " service catalog."))
コード例 #30
0
ファイル: coordination.py プロジェクト: paperandsoap/aodh
 def heartbeat(self):
     if self._coordinator:
         if not self._coordinator.is_started:
             # re-connect
             self.start()
         try:
             self._coordinator.heartbeat()
         except tooz.coordination.ToozError:
             LOG.exception(_LE('Error sending a heartbeat to coordination '
                               'backend.'))
コード例 #31
0
ファイル: alarms.py プロジェクト: bopopescu/OpenStack-Ocata
    def post(self, data):
        """Create a new alarm.

        :param data: an alarm within the request body.
        """
        rbac.enforce('create_alarm', pecan.request.headers,
                     pecan.request.enforcer, {})

        conn = pecan.request.storage
        now = timeutils.utcnow()

        data.alarm_id = uuidutils.generate_uuid()
        user_limit, project_limit = rbac.get_limited_to(
            pecan.request.headers, pecan.request.enforcer)

        def _set_ownership(aspect, owner_limitation, header):
            attr = '%s_id' % aspect
            requested_owner = getattr(data, attr)
            explicit_owner = requested_owner != wtypes.Unset
            caller = pecan.request.headers.get(header)
            if (owner_limitation and explicit_owner
                    and requested_owner != caller):
                raise base.ProjectNotAuthorized(requested_owner, aspect)

            actual_owner = (owner_limitation or requested_owner
                            if explicit_owner else caller)
            setattr(data, attr, actual_owner)

        _set_ownership('user', user_limit, 'X-User-Id')
        _set_ownership('project', project_limit, 'X-Project-Id')

        # Check if there's room for one more alarm
        if is_over_quota(conn, data.project_id, data.user_id):
            raise OverQuota(data)

        data.timestamp = now
        data.state_timestamp = now

        ALARMS_RULES[data.type].plugin.create_hook(data)

        change = data.as_dict(models.Alarm)

        data.update_actions()

        try:
            alarm_in = models.Alarm(**change)
        except Exception:
            LOG.exception(_LE("Error while posting alarm: %s"), change)
            raise base.ClientSideError(_("Alarm incorrect"))

        alarm = conn.create_alarm(alarm_in)
        self._record_creation(conn, change, alarm.alarm_id, now)
        v2_utils.set_resp_location_hdr("/alarms/" + alarm.alarm_id)
        return Alarm.from_db_model(alarm)
コード例 #32
0
ファイル: alarms.py プロジェクト: openstack/aodh
    def post(self, data):
        """Create a new alarm.

        :param data: an alarm within the request body.
        """
        rbac.enforce('create_alarm', pecan.request.headers,
                     pecan.request.enforcer, {})

        conn = pecan.request.storage
        now = timeutils.utcnow()

        data.alarm_id = str(uuid.uuid4())
        user_limit, project_limit = rbac.get_limited_to(pecan.request.headers,
                                                        pecan.request.enforcer)

        def _set_ownership(aspect, owner_limitation, header):
            attr = '%s_id' % aspect
            requested_owner = getattr(data, attr)
            explicit_owner = requested_owner != wtypes.Unset
            caller = pecan.request.headers.get(header)
            if (owner_limitation and explicit_owner
                    and requested_owner != caller):
                raise base.ProjectNotAuthorized(requested_owner, aspect)

            actual_owner = (owner_limitation or
                            requested_owner if explicit_owner else caller)
            setattr(data, attr, actual_owner)

        _set_ownership('user', user_limit, 'X-User-Id')
        _set_ownership('project', project_limit, 'X-Project-Id')

        # Check if there's room for one more alarm
        if is_over_quota(conn, data.project_id, data.user_id):
            raise OverQuota(data)

        data.timestamp = now
        data.state_timestamp = now

        ALARMS_RULES[data.type].plugin.create_hook(data)

        change = data.as_dict(models.Alarm)

        data.update_actions()

        try:
            alarm_in = models.Alarm(**change)
        except Exception:
            LOG.exception(_LE("Error while posting alarm: %s"), change)
            raise base.ClientSideError(_("Alarm incorrect"))

        alarm = conn.create_alarm(alarm_in)
        self._record_creation(conn, change, alarm.alarm_id, now)
        v2_utils.set_resp_location_hdr("/v2/alarms/" + alarm.alarm_id)
        return Alarm.from_db_model(alarm)
コード例 #33
0
ファイル: zaqar.py プロジェクト: bopopescu/Openstack-2
 def _get_endpoint(self):
     try:
         ks_client = keystone_client.get_client(self.conf)
         return ks_client.service_catalog.url_for(
             service_type=cfg.CONF.service_types.zaqar,
             endpoint_type=self.conf.service_credentials.os_endpoint_type)
     except Exception:
         LOG.error(
             _LE("Aodh was configured to use zaqar:// action,"
                 " but Zaqar endpoint could not be found in Keystone"
                 " service catalog."))
コード例 #34
0
ファイル: __init__.py プロジェクト: bopopescu/OpenStack-Ocata
    def _evaluate_alarm(self, alarm):
        """Evaluate the alarms assigned to this evaluator."""
        if alarm.type not in self.evaluators:
            LOG.debug('skipping alarm %s: type unsupported', alarm.alarm_id)
            return

        LOG.debug('evaluating alarm %s', alarm.alarm_id)
        try:
            self.evaluators[alarm.type].obj.evaluate(alarm)
        except Exception:
            LOG.exception(_LE('Failed to evaluate alarm %s'), alarm.alarm_id)
コード例 #35
0
ファイル: __init__.py プロジェクト: openstack/aodh
    def _evaluate_alarm(self, alarm):
        """Evaluate the alarms assigned to this evaluator."""
        if alarm.type not in self.evaluators:
            LOG.debug('skipping alarm %s: type unsupported', alarm.alarm_id)
            return

        LOG.debug('evaluating alarm %s', alarm.alarm_id)
        try:
            self.evaluators[alarm.type].obj.evaluate(alarm)
        except Exception:
            LOG.exception(_LE('Failed to evaluate alarm %s'), alarm.alarm_id)
コード例 #36
0
ファイル: coordination.py プロジェクト: chungg/aodh
 def start(self):
     backend_url = cfg.CONF.coordination.backend_url
     if backend_url:
         try:
             self._coordinator = tooz.coordination.get_coordinator(
                 backend_url, self._my_id)
             self._coordinator.start()
             self._started = True
             LOG.info(_LI('Coordination backend started successfully.'))
         except tooz.coordination.ToozError:
             self._started = False
             LOG.exception(_LE('Error connecting to coordination backend.'))
コード例 #37
0
ファイル: __init__.py プロジェクト: ISCAS-VDI/aodh-base
    def _handle_action(notifiers, action, alarm_id, alarm_name, severity,
                       previous, current, reason, reason_data):
        """Process action on alarm

        :param notifiers: list of possible notifiers.
        :param action: The action that is being attended, as a parsed URL.
        :param alarm_id: The triggered alarm.
        :param alarm_name: The name of triggered alarm.
        :param severity: The level of triggered alarm
        :param previous: The previous state of the alarm.
        :param current: The current state of the alarm.
        :param reason: The reason the alarm changed its state.
        :param reason_data: A dict representation of the reason.
        """

        try:
            action = netutils.urlsplit(action)
        except Exception:
            LOG.error(
                _LE("Unable to parse action %(action)s for alarm "
                    "%(alarm_id)s"), {'action': action, 'alarm_id': alarm_id})
            return

        try:
            notifier = notifiers[action.scheme].obj
        except KeyError:
            scheme = action.scheme
            LOG.error(
                _LE("Action %(scheme)s for alarm %(alarm_id)s is unknown, "
                    "cannot notify"),
                {'scheme': scheme, 'alarm_id': alarm_id})
            return

        try:
            LOG.debug("Notifying alarm %(id)s with action %(act)s",
                      {'id': alarm_id, 'act': action})
            notifier.notify(action, alarm_id, alarm_name, severity,
                            previous, current, reason, reason_data)
        except Exception:
            LOG.exception(_LE("Unable to notify alarm %s"), alarm_id)
コード例 #38
0
ファイル: coordination.py プロジェクト: openstack/aodh
    def stop(self):
        if not self._coordinator:
            return

        for group in list(self._groups):
            self.leave_group(group)

        try:
            self._coordinator.stop()
        except tooz.coordination.ToozError:
            LOG.exception(_LE('Error connecting to coordination backend.'))
        finally:
            self._coordinator = None
コード例 #39
0
    def stop(self):
        if not self._coordinator:
            return

        for group in list(self._groups):
            self.leave_group(group)

        try:
            self._coordinator.stop()
        except tooz.coordination.ToozError:
            LOG.exception(_LE('Error connecting to coordination backend.'))
        finally:
            self._coordinator = None
コード例 #40
0
ファイル: zaqar.py プロジェクト: openstack/aodh
 def _get_endpoint(self):
     if self._zendpoint is None:
         try:
             ks_client = keystone_client.get_client(self.conf)
             z_srv = ks_client.services.find(
                 type=self.conf.service_types.zaqar)
             endpoint_type = self.conf.service_credentials.interface
             z_endpoint = ks_client.endpoints.find(service_id=z_srv.id,
                                                   interface=endpoint_type)
             self._zendpoint = z_endpoint.url
         except Exception:
             LOG.error(_LE("Aodh was configured to use zaqar:// action,"
                           " but Zaqar endpoint could not be found in"
                           " Keystone service catalog."))
     return self._zendpoint
コード例 #41
0
ファイル: alarms.py プロジェクト: bopopescu/OpenStack-Ocata
    def put(self, data):
        """Modify this alarm.

        :param data: an alarm within the request body.
        """

        # Ensure alarm exists
        alarm_in = self._enforce_rbac('change_alarm')

        now = timeutils.utcnow()

        data.alarm_id = self._id

        user, project = rbac.get_limited_to(pecan.request.headers,
                                            pecan.request.enforcer)
        if user:
            data.user_id = user
        elif data.user_id == wtypes.Unset:
            data.user_id = alarm_in.user_id
        if project:
            data.project_id = project
        elif data.project_id == wtypes.Unset:
            data.project_id = alarm_in.project_id
        data.timestamp = now
        if alarm_in.state != data.state:
            data.state_timestamp = now
        else:
            data.state_timestamp = alarm_in.state_timestamp

        ALARMS_RULES[data.type].plugin.update_hook(data)

        old_data = Alarm.from_db_model(alarm_in)
        old_alarm = old_data.as_dict(models.Alarm)
        data.update_actions(old_data)
        updated_alarm = data.as_dict(models.Alarm)
        try:
            alarm_in = models.Alarm(**updated_alarm)
        except Exception:
            LOG.exception(_LE("Error while putting alarm: %s"), updated_alarm)
            raise base.ClientSideError(_("Alarm incorrect"))

        alarm = pecan.request.storage.update_alarm(alarm_in)

        change = dict(
            (k, v) for k, v in updated_alarm.items()
            if v != old_alarm[k] and k not in ['timestamp', 'state_timestamp'])
        self._record_change(change, now, on_behalf_of=alarm.project_id)
        return Alarm.from_db_model(alarm)
コード例 #42
0
ファイル: alarms.py プロジェクト: openstack/aodh
    def put(self, data):
        """Modify this alarm.

        :param data: an alarm within the request body.
        """

        # Ensure alarm exists
        alarm_in = self._enforce_rbac('change_alarm')

        now = timeutils.utcnow()

        data.alarm_id = self._id

        user, project = rbac.get_limited_to(pecan.request.headers,
                                            pecan.request.enforcer)
        if user:
            data.user_id = user
        elif data.user_id == wtypes.Unset:
            data.user_id = alarm_in.user_id
        if project:
            data.project_id = project
        elif data.project_id == wtypes.Unset:
            data.project_id = alarm_in.project_id
        data.timestamp = now
        if alarm_in.state != data.state:
            data.state_timestamp = now
        else:
            data.state_timestamp = alarm_in.state_timestamp

        ALARMS_RULES[data.type].plugin.update_hook(data)

        old_data = Alarm.from_db_model(alarm_in)
        old_alarm = old_data.as_dict(models.Alarm)
        data.update_actions(old_data)
        updated_alarm = data.as_dict(models.Alarm)
        try:
            alarm_in = models.Alarm(**updated_alarm)
        except Exception:
            LOG.exception(_LE("Error while putting alarm: %s"), updated_alarm)
            raise base.ClientSideError(_("Alarm incorrect"))

        alarm = pecan.request.storage.update_alarm(alarm_in)

        change = dict((k, v) for k, v in updated_alarm.items()
                      if v != old_alarm[k] and k not in
                      ['timestamp', 'state_timestamp'])
        self._record_change(change, now, on_behalf_of=alarm.project_id)
        return Alarm.from_db_model(alarm)
コード例 #43
0
ファイル: zaqar.py プロジェクト: bopopescu/OpenStack-Ocata
 def _get_endpoint(self):
     if self._zendpoint is None:
         try:
             ks_client = keystone_client.get_client(self.conf)
             z_srv = ks_client.services.find(
                 type=self.conf.service_types.zaqar)
             endpoint_type = self.conf.service_credentials.interface
             z_endpoint = ks_client.endpoints.find(service_id=z_srv.id,
                                                   interface=endpoint_type)
             self._zendpoint = z_endpoint.url
         except Exception:
             LOG.error(
                 _LE("Aodh was configured to use zaqar:// action,"
                     " but Zaqar endpoint could not be found in"
                     " Keystone service catalog."))
     return self._zendpoint
コード例 #44
0
ファイル: coordination.py プロジェクト: paperandsoap/aodh
 def _inner():
     try:
         join_req = self._coordinator.join_group(group_id)
         join_req.get()
         LOG.info(_LI('Joined partitioning group %s'), group_id)
     except tooz.coordination.MemberAlreadyExist:
         return
     except tooz.coordination.GroupNotCreated:
         create_grp_req = self._coordinator.create_group(group_id)
         try:
             create_grp_req.get()
         except tooz.coordination.GroupAlreadyExist:
             pass
         raise ErrorJoiningPartitioningGroup()
     except tooz.coordination.ToozError:
         LOG.exception(_LE('Error joining partitioning group %s,'
                           ' re-trying'), group_id)
         raise ErrorJoiningPartitioningGroup()
     self._groups.add(group_id)
コード例 #45
0
ファイル: coordination.py プロジェクト: openstack/aodh
 def _inner():
     try:
         join_req = self._coordinator.join_group(group_id)
         join_req.get()
         LOG.info(_LI('Joined partitioning group %s'), group_id)
     except tooz.coordination.MemberAlreadyExist:
         return
     except tooz.coordination.GroupNotCreated:
         create_grp_req = self._coordinator.create_group(group_id)
         try:
             create_grp_req.get()
         except tooz.coordination.GroupAlreadyExist:
             pass
         raise ErrorJoiningPartitioningGroup()
     except tooz.coordination.ToozError:
         LOG.exception(_LE('Error joining partitioning group %s,'
                           ' re-trying'), group_id)
         raise ErrorJoiningPartitioningGroup()
     self._groups.add(group_id)
コード例 #46
0
ファイル: zaqar.py プロジェクト: zqfan/aodh
    def get_zaqar_client(self):
        conf = self.conf.service_credentials
        params = {
            "auth_opts": {
                "backend": "keystone",
                "options": {
                    "os_username": conf.os_username,
                    "os_password": conf.os_password,
                    "os_project_name": conf.os_tenant_name,
                    "os_auth_url": conf.os_auth_url,
                    "insecure": "",
                },
            }
        }
        try:
            from zaqarclient.queues import client as zaqar_client

            return zaqar_client.Client(self._get_endpoint(), version=1.1, conf=params)
        except Exception:
            LOG.error(_LE("Failed to connect to Zaqar service "), exc_info=True)
コード例 #47
0
ファイル: zaqar.py プロジェクト: openstack-yak/aodh
 def get_zaqar_client(self):
     conf = self.conf.service_credentials
     params = {
         'auth_opts': {
             'backend': 'keystone',
             'options': {
                 'os_username': conf.os_username,
                 'os_password': conf.os_password,
                 'os_project_name': conf.os_tenant_name,
                 'os_auth_url': conf.os_auth_url,
                 'insecure': ''
             }
         }
     }
     try:
         from zaqarclient.queues import client as zaqar_client
         return zaqar_client.Client(self._get_endpoint(),
                                    version=1.1, conf=params)
     except Exception:
         LOG.error(_LE("Failed to connect to Zaqar service "),
                   exc_info=True)
コード例 #48
0
ファイル: __init__.py プロジェクト: ISCAS-VDI/aodh-base
    def _process_alarm(notifiers, data):
        """Notify that alarm has been triggered.

        :param notifiers: list of possible notifiers
        :param data: (dict): alarm data
        """

        actions = data.get('actions')
        if not actions:
            LOG.error(_LE("Unable to notify for an alarm with no action"))
            return

        for action in actions:
            AlarmEndpoint._handle_action(notifiers, action,
                                         data.get('alarm_id'),
                                         data.get('alarm_name'),
                                         data.get('severity'),
                                         data.get('previous'),
                                         data.get('current'),
                                         data.get('reason'),
                                         data.get('reason_data'))
コード例 #49
0
ファイル: __init__.py プロジェクト: bopopescu/OpenStack-Ocata
    def _process_alarm(notifiers, data):
        """Notify that alarm has been triggered.

        :param notifiers: list of possible notifiers
        :param data: (dict): alarm data
        """

        actions = data.get('actions')
        if not actions:
            LOG.error(_LE("Unable to notify for an alarm with no action"))
            return

        for action in actions:
            AlarmEndpoint._handle_action(notifiers, action,
                                         data.get('alarm_id'),
                                         data.get('alarm_name'),
                                         data.get('severity'),
                                         data.get('previous'),
                                         data.get('current'),
                                         data.get('reason'),
                                         data.get('reason_data'))
コード例 #50
0
ファイル: zaqar.py プロジェクト: bopopescu/Openstack-2
 def get_zaqar_client(self):
     conf = self.conf.service_credentials
     params = {
         'auth_opts': {
             'backend': 'keystone',
             'options': {
                 'os_username': conf.os_username,
                 'os_password': conf.os_password,
                 'os_project_name': conf.os_tenant_name,
                 'os_auth_url': conf.os_auth_url,
                 'insecure': ''
             }
         }
     }
     try:
         from zaqarclient.queues import client as zaqar_client
         return zaqar_client.Client(self._get_endpoint(),
                                    version=1.1,
                                    conf=params)
     except Exception:
         LOG.error(_LE("Failed to connect to Zaqar service "),
                   exc_info=True)
コード例 #51
0
ファイル: coordination.py プロジェクト: chungg/aodh
    def extract_my_subset(self, group_id, iterable):
        """Filters an iterable, returning only objects assigned to this agent.

        We have a list of objects and get a list of active group members from
        `tooz`. We then hash all the objects into buckets and return only
        the ones that hashed into *our* bucket.
        """
        if not group_id:
            return iterable
        if group_id not in self._groups:
            self.join_group(group_id)
        try:
            members = self._get_members(group_id)
            LOG.debug('Members of group: %s', members)
            hr = utils.HashRing(members)
            filtered = [v for v in iterable
                        if hr.get_node(str(v)) == self._my_id]
            LOG.debug('My subset: %s', filtered)
            return filtered
        except tooz.coordination.ToozError:
            LOG.exception(_LE('Error getting group membership info from '
                              'coordination backend.'))
            return []
コード例 #52
0
ファイル: coordination.py プロジェクト: openstack/aodh
 def __init__(self, group_id, members, my_id):
     super(MemberNotInGroupError, self).__init__(_LE(
         'Group ID: %(group_id)s, Members: %(members)s, Me: %(me)s: '
         'Current agent is not part of group and cannot take tasks') %
         {'group_id': group_id, 'members': members, 'me': my_id})
コード例 #53
0
ファイル: coordination.py プロジェクト: openstack/aodh
 def __init__(self):
     super(ErrorJoiningPartitioningGroup, self).__init__(_LE(
         'Error occurred when joining partitioning group'))
コード例 #54
0
    def __call__(self, environ, start_response):
        # Request for this state, modified by replace_start_response()
        # and used when an error is being reported.
        state = {}

        def replacement_start_response(status, headers, exc_info=None):
            """Overrides the default response to make errors parsable."""
            try:
                status_code = int(status.split(' ')[0])
                state['status_code'] = status_code
            except (ValueError, TypeError):  # pragma: nocover
                raise Exception(('ErrorDocumentMiddleware received an invalid '
                                 'status %s' % status))
            else:
                if (state['status_code'] // 100) not in (2, 3):
                    # Remove some headers so we can replace them later
                    # when we have the full error message and can
                    # compute the length.
                    headers = [(h, v) for (h, v) in headers
                               if h not in ('Content-Length', 'Content-Type')]
                # Save the headers in case we need to modify them.
                state['headers'] = headers
                return start_response(status, headers, exc_info)

        app_iter = self.app(environ, replacement_start_response)
        if (state['status_code'] // 100) not in (2, 3):
            req = webob.Request(environ)
            error = environ.get('translatable_error')
            user_locale = self.best_match_language(req.accept_language)
            if (req.accept.best_match(['application/json', 'application/xml'
                                       ]) == 'application/xml'):
                content_type = 'application/xml'
                try:
                    # simple check xml is valid
                    fault = etree.fromstring(b'\n'.join(app_iter))
                    # Add the translated error to the xml data
                    if error is not None:
                        for fault_string in fault.findall('faultstring'):
                            fault_string.text = i18n.translate(
                                error, user_locale)
                    error_message = etree.tostring(fault)
                    body = b''.join((b'<error_message>', error_message,
                                     b'</error_message>'))
                except etree.XMLSyntaxError as err:
                    LOG.error(_LE('Error parsing HTTP response: %s'), err)
                    error_message = state['status_code']
                    body = '<error_message>%s</error_message>' % error_message
                    if six.PY3:
                        body = body.encode('utf-8')
            else:
                content_type = 'application/json'
                app_data = b'\n'.join(app_iter)
                if six.PY3:
                    app_data = app_data.decode('utf-8')
                try:
                    fault = json.loads(app_data)
                    if error is not None and 'faultstring' in fault:
                        fault['faultstring'] = i18n.translate(
                            error, user_locale)
                except ValueError as err:
                    fault = app_data
                body = json.dumps({'error_message': fault})
                if six.PY3:
                    body = body.encode('utf-8')

            state['headers'].append(('Content-Length', str(len(body))))
            state['headers'].append(('Content-Type', content_type))
            body = [body]
        else:
            body = app_iter
        return body
コード例 #55
0
 def __init__(self):
     super(ErrorJoiningPartitioningGroup, self).__init__(
         _LE('Error occurred when joining partitioning group'))
コード例 #56
0
ファイル: middleware.py プロジェクト: openstack/aodh
    def __call__(self, environ, start_response):
        # Request for this state, modified by replace_start_response()
        # and used when an error is being reported.
        state = {}

        def replacement_start_response(status, headers, exc_info=None):
            """Overrides the default response to make errors parsable."""
            try:
                status_code = int(status.split(" ")[0])
                state["status_code"] = status_code
            except (ValueError, TypeError):  # pragma: nocover
                raise Exception(("ErrorDocumentMiddleware received an invalid " "status %s" % status))
            else:
                if (state["status_code"] // 100) not in (2, 3):
                    # Remove some headers so we can replace them later
                    # when we have the full error message and can
                    # compute the length.
                    headers = [(h, v) for (h, v) in headers if h not in ("Content-Length", "Content-Type")]
                # Save the headers in case we need to modify them.
                state["headers"] = headers
                return start_response(status, headers, exc_info)

        app_iter = self.app(environ, replacement_start_response)
        if (state["status_code"] // 100) not in (2, 3):
            req = webob.Request(environ)
            error = environ.get("translatable_error")
            user_locale = self.best_match_language(req.accept_language)
            if req.accept.best_match(["application/json", "application/xml"]) == "application/xml":
                content_type = "application/xml"
                try:
                    # simple check xml is valid
                    fault = etree.fromstring(b"\n".join(app_iter))
                    # Add the translated error to the xml data
                    if error is not None:
                        for fault_string in fault.findall("faultstring"):
                            fault_string.text = i18n.translate(error, user_locale)
                    error_message = etree.tostring(fault)
                    body = b"".join((b"<error_message>", error_message, b"</error_message>"))
                except etree.XMLSyntaxError as err:
                    LOG.error(_LE("Error parsing HTTP response: %s"), err)
                    error_message = state["status_code"]
                    body = "<error_message>%s</error_message>" % error_message
                    if six.PY3:
                        body = body.encode("utf-8")
            else:
                content_type = "application/json"
                app_data = b"\n".join(app_iter)
                if six.PY3:
                    app_data = app_data.decode("utf-8")
                try:
                    fault = json.loads(app_data)
                    if error is not None and "faultstring" in fault:
                        fault["faultstring"] = i18n.translate(error, user_locale)
                except ValueError as err:
                    fault = app_data
                body = json.dumps({"error_message": fault})
                if six.PY3:
                    body = body.encode("utf-8")

            state["headers"].append(("Content-Length", str(len(body))))
            state["headers"].append(("Content-Type", content_type))
            body = [body]
        else:
            body = app_iter
        return body