Exemple #1
0
 def get_samples(self, manager, cache, resources):
     self._inspection_duration = self._record_poll_time()
     for instance in resources:
         instance_name = util.instance_name(instance)
         LOG.debug(_("checking net info for instance %s"), instance.id)
         try:
             vnics = self._get_vnics_for_instance(cache, manager.inspector, instance)
             for vnic, info in vnics:
                 LOG.debug(
                     self.NET_USAGE_MESSAGE,
                     instance_name,
                     vnic.name,
                     self._get_rx_info(info),
                     self._get_tx_info(info),
                 )
                 yield self._get_sample(instance, vnic, info)
         except virt_inspector.InstanceNotFoundException as err:
             # Instance was deleted while getting samples. Ignore it.
             LOG.debug(_("Exception while getting samples %s"), err)
         except NotImplementedError:
             # Selected inspector does not implement this pollster.
             LOG.debug(
                 _("%(inspector)s does not provide data for " " %(pollster)s"),
                 ({"inspector": manager.inspector.__class__.__name__, "pollster": self.__class__.__name__}),
             )
         except Exception as err:
             LOG.warning(_("Ignoring instance %(name)s: %(error)s") % ({"name": instance_name, "error": err}))
             LOG.exception(err)
Exemple #2
0
    def _process_data(self, ctxt, version, method, namespace, args):
        """Process a message in a new thread.

        If the proxy object we have has a dispatch method
        (see rpc.dispatcher.RpcDispatcher), pass it the version,
        method, and args and let it dispatch as appropriate.  If not, use
        the old behavior of magically calling the specified method on the
        proxy we have here.
        """
        ctxt.update_store()
        try:
            rval = self.proxy.dispatch(ctxt, version, method, namespace,
                                       **args)
            # Check if the result was a generator
            if inspect.isgenerator(rval):
                for x in rval:
                    ctxt.reply(x, None, connection_pool=self.connection_pool)
            else:
                ctxt.reply(rval, None, connection_pool=self.connection_pool)
            # This final None tells multicall that it is done.
            ctxt.reply(ending=True, connection_pool=self.connection_pool)
        except rpc_common.ClientException as e:
            LOG.debug(_('Expected exception during message handling (%s)') %
                      e._exc_info[1])
            ctxt.reply(None, e._exc_info,
                       connection_pool=self.connection_pool,
                       log_failure=False)
        except Exception:
            # sys.exc_info() is deleted by LOG.exception().
            exc_info = sys.exc_info()
            LOG.error(_('Exception during message handling'),
                      exc_info=exc_info)
            ctxt.reply(None, exc_info, connection_pool=self.connection_pool)
Exemple #3
0
    def __call__(self, message_data):
        """Consumer callback to call a method on a proxy object.

        Parses the message for validity and fires off a thread to call the
        proxy object method.

        Message data should be a dictionary with two keys:
            method: string representing the method to call
            args: dictionary of arg: value

        Example: {'method': 'echo', 'args': {'value': 42}}

        """
        # It is important to clear the context here, because at this point
        # the previous context is stored in local.store.context
        if hasattr(local.store, 'context'):
            del local.store.context
        rpc_common._safe_log(LOG.debug, _('received %s'), message_data)
        self.msg_id_cache.check_duplicate_message(message_data)
        ctxt = unpack_context(self.conf, message_data)
        method = message_data.get('method')
        args = message_data.get('args', {})
        version = message_data.get('version')
        namespace = message_data.get('namespace')
        if not method:
            LOG.warn(_('no method for message: %s') % message_data)
            ctxt.reply(_('No method for message: %s') % message_data,
                       connection_pool=self.connection_pool)
            return
        self.pool.spawn_n(self._process_data, ctxt, version, method,
                          namespace, args)
Exemple #4
0
    def _setup_subscription(self, ext, *args, **kwds):
        """Connect to message bus to get notifications

        Configure the RPC connection to listen for messages on the
        right exchanges and topics so we receive all of the
        notifications.

        Use a connection pool so that multiple notification agent instances
        can run in parallel to share load and without competing with each
        other for incoming messages.

        """
        handler = ext.obj
        ack_on_error = cfg.CONF.notification.ack_on_event_error
        LOG.debug(_('Event types from %(name)s: %(type)s'
                    ' (ack_on_error=%(error)s)') %
                  {'name': ext.name,
                   'type': ', '.join(handler.event_types),
                   'error': ack_on_error})

        for exchange_topic in handler.get_exchange_topics(cfg.CONF):
            for topic in exchange_topic.topics:
                try:
                    self.conn.join_consumer_pool(
                        callback=self.process_notification,
                        pool_name=topic,
                        topic=topic,
                        exchange_name=exchange_topic.exchange,
                        ack_on_error=ack_on_error)
                except Exception:
                    LOG.exception(_('Could not join consumer pool'
                                    ' %(topic)s/%(exchange)s') %
                                  {'topic': topic,
                                   'exchange': exchange_topic.exchange})
Exemple #5
0
    def _handle_action(self, action, alarm, state, reason):
        try:
            action = network_utils.urlsplit(action)
        except Exception:
            LOG.error(
                _("Unable to parse action %(action)s for alarm %(alarm)s"),
                locals())
            return

        try:
            notifier = self.notifiers[action.scheme].obj
        except KeyError:
            scheme = action.scheme
            LOG.error(
                _("Action %(scheme)s for alarm %(alarm)s is unknown, "
                  "cannot notify"),
                locals())
            return

        try:
            LOG.debug("Notifying alarm %s with action %s",
                      alarm, action)
            notifier.notify(action, alarm, state, reason)
        except Exception:
            LOG.exception(_("Unable to notify alarm %s"), alarm)
            return
Exemple #6
0
    def __init__(self, parsed_url):
        options = urlparse.parse_qs(parsed_url.query)
        # the values of the option is a list of url params values
        # only take care of the latest one if the option
        # is provided more than once
        self.per_meter_topic = bool(int(
            options.get('per_meter_topic', [0])[-1]))

        self.target = options.get('target', ['record_metering_data'])[0]

        self.policy = options.get('policy', ['default'])[-1]
        self.max_queue_length = int(options.get(
            'max_queue_length', [1024])[-1])

        self.local_queue = []

        if self.policy in ['queue', 'drop']:
            LOG.info(_('Publishing policy set to %s, \
                     override backend retry config to 1') % self.policy)
            override_backend_retry_config(1)

        elif self.policy == 'default':
            LOG.info(_('Publishing policy set to %s') % self.policy)
        else:
            LOG.warn(_('Publishing policy is unknown (%s) force to default')
                     % self.policy)
            self.policy = 'default'
    def consume(self, sock):
        #TODO(ewindisch): use zero-copy (i.e. references, not copying)
        data = sock.recv()
        LOG.debug(_("CONSUMER RECEIVED DATA: %s"), data)
        if sock in self.mapping:
            LOG.debug(_("ROUTER RELAY-OUT %(data)s") % {
                'data': data})
            self.mapping[sock].send(data)
            return

        proxy = self.proxies[sock]

        if data[2] == 'cast':  # Legacy protocol
            packenv = data[3]

            ctx, msg = _deserialize(packenv)
            request = rpc_common.deserialize_msg(msg)
            ctx = RpcContext.unmarshal(ctx)
        elif data[2] == 'impl_zmq_v2':
            packenv = data[4:]

            msg = unflatten_envelope(packenv)
            request = rpc_common.deserialize_msg(msg)

            # Unmarshal only after verifying the message.
            ctx = RpcContext.unmarshal(data[3])
        else:
            LOG.error(_("ZMQ Envelope version unsupported or unknown."))
            return

        self.pool.spawn_n(self.process, proxy, ctx, request)
Exemple #8
0
 def _connect(self, params):
     """Connect to rabbit.  Re-establish any queues that may have
     been declared before if we are reconnecting.  Exceptions should
     be handled by the caller.
     """
     if self.connection:
         LOG.info(_("Reconnecting to AMQP server on "
                  "%(hostname)s:%(port)d") % params)
         try:
             self.connection.release()
         except self.connection_errors:
             pass
         # Setting this in case the next statement fails, though
         # it shouldn't be doing any network operations, yet.
         self.connection = None
     self.connection = kombu.connection.BrokerConnection(**params)
     self.connection_errors = self.connection.connection_errors
     if self.memory_transport:
         # Kludge to speed up tests.
         self.connection.transport.polling_interval = 0.0
     self.consumer_num = itertools.count(1)
     self.connection.connect()
     self.channel = self.connection.channel()
     # work around 'memory' transport bug in 1.1.3
     if self.memory_transport:
         self.channel._new_queue('ae.undeliver')
     for consumer in self.consumers:
         consumer.reconnect(self.channel)
     LOG.info(_('Connected to AMQP server on %(hostname)s:%(port)d') %
              params)
Exemple #9
0
 def _poll_lease(self, lease, done):
     try:
         state = self.invoke_api(vim_util, 'get_object_property',
                                 self.vim, lease, 'state')
         if state == 'ready':
             # done
             LOG.debug(_("Lease is ready."))
             done.send()
             return
         elif state == 'initializing':
             LOG.debug(_("Lease initializing..."))
             return
         elif state == 'error':
             error_msg = self.invoke_api(vim_util, 'get_object_property',
                                         self.vim, lease, 'error')
             LOG.exception(error_msg)
             excep = error_util.VimFaultException([], error_msg)
             done.send_exception(excep)
         else:
             # unknown state - complain
             error_msg = _("Error: unknown lease state %s.") % state
             raise error_util.VimFaultException([], error_msg)
     except Exception as excep:
         LOG.exception(excep)
         done.send_exception(excep)
 def handle_sample(self, context, s):
     """Handle a sample, converting if necessary."""
     LOG.debug(_('handling sample %s'), (s,))
     if (self.source.get('unit', s.unit) == s.unit):
         s = self._convert(s)
         LOG.debug(_('converted to: %s'), (s,))
     return s
Exemple #11
0
 def get_samples(self, manager, cache, resources):
     self._inspection_duration = self._record_poll_time()
     for instance in resources:
         LOG.debug(_('Checking memory usage for instance %s'), instance.id)
         try:
             memory_info = manager.inspector.inspect_memory_usage(
                 instance, self._inspection_duration)
             LOG.debug(_("MEMORY USAGE: %(instance)s %(usage)f"),
                       ({'instance': instance.__dict__,
                         'usage': memory_info.usage}))
             yield util.make_sample_from_instance(
                 instance,
                 name='memory.usage',
                 type=sample.TYPE_GAUGE,
                 unit='MB',
                 volume=memory_info.usage,
             )
         except virt_inspector.InstanceNotFoundException as err:
             # Instance was deleted while getting samples. Ignore it.
             LOG.debug(_('Exception while getting samples %s'), err)
         except NotImplementedError:
             # Selected inspector does not implement this pollster.
             LOG.debug(_('Obtaining Memory Usage is not implemented for %s'
                         ), manager.inspector.__class__.__name__)
         except Exception as err:
             LOG.error(_('Could not get Memory Usage for %(id)s: %(e)s'), (
                       {'id': instance.id, 'e': err}))
    def consume_in_thread(self):
        """Runs the ZmqProxy service."""
        ipc_dir = CONF.rpc_zmq_ipc_dir
        consume_in = "tcp://%s:%s" % \
            (CONF.rpc_zmq_bind_address,
             CONF.rpc_zmq_port)
        consumption_proxy = InternalContext(None)

        try:
            os.makedirs(ipc_dir)
        except os.error:
            if not os.path.isdir(ipc_dir):
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Required IPC directory does not exist at"
                                " %s") % (ipc_dir, ))
        try:
            self.register(consumption_proxy,
                          consume_in,
                          zmq.PULL,
                          out_bind=True)
        except zmq.ZMQError:
            if os.access(ipc_dir, os.X_OK):
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Permission denied to IPC directory at"
                                " %s") % (ipc_dir, ))
            with excutils.save_and_reraise_exception():
                LOG.error(_("Could not create ZeroMQ receiver daemon. "
                            "Socket may already be in use."))

        super(ZmqProxy, self).consume_in_thread()
Exemple #13
0
 def create_session(self):
     """Establish session with the server."""
     # Login and setup the session with the server for making
     # API calls
     session_manager = self.vim.service_content.sessionManager
     session = self.vim.Login(session_manager,
                              userName=self._server_username,
                              password=self._server_password)
     # Terminate the earlier session, if possible (For the sake of
     # preserving sessions as there is a limit to the number of
     # sessions we can have)
     if self._session_id:
         try:
             self.vim.TerminateSession(session_manager,
                                       sessionId=[self._session_id])
         except Exception as excep:
             # This exception is something we can live with. It is
             # just an extra caution on our side. The session may
             # have been cleared. We could have made a call to
             # SessionIsActive, but that is an overhead because we
             # anyway would have to call TerminateSession.
             LOG.exception(_("Error while terminating session: %s.") %
                           excep)
     self._session_id = session.key
     LOG.info(_("Successfully established connection to the server."))
            def publisher(waiter):
                LOG.info(_("Creating proxy for topic: %s"), topic)

                try:
                    # The topic is received over the network,
                    # don't trust this input.
                    if self.badchars.search(topic) is not None:
                        emsg = _("Topic contained dangerous characters.")
                        LOG.warn(emsg)
                        raise RPCException(emsg)

                    out_sock = ZmqSocket("ipc://%s/zmq_topic_%s" %
                                         (ipc_dir, topic),
                                         sock_type, bind=True)
                except RPCException:
                    waiter.send_exception(*sys.exc_info())
                    return

                self.topic_proxy[topic] = eventlet.queue.LightQueue(
                    CONF.rpc_zmq_topic_backlog)
                self.sockets.append(out_sock)

                # It takes some time for a pub socket to open,
                # before we can have any faith in doing a send() to it.
                if sock_type == zmq.PUB:
                    eventlet.sleep(.5)

                waiter.send(True)

                while(True):
                    data = self.topic_proxy[topic].get()
                    out_sock.send(data, copy=False)
Exemple #15
0
 def get_samples(self, manager, cache, resources):
     for instance in resources:
         LOG.debug(_('Checking CPU util for instance %s'), instance.id)
         try:
             cpu_info = manager.inspector.inspect_cpu_util(instance)
             LOG.debug(_("CPU UTIL: %(instance)s %(util)d"),
                       ({'instance': instance.__dict__,
                         'util': cpu_info.util}))
             yield util.make_sample_from_instance(
                 instance,
                 name='cpu_util',
                 type=sample.TYPE_GAUGE,
                 unit='%',
                 volume=cpu_info.util,
             )
         except virt_inspector.InstanceNotFoundException as err:
             # Instance was deleted while getting samples. Ignore it.
             LOG.debug(_('Exception while getting samples %s'), err)
         except NotImplementedError:
             # Selected inspector does not implement this pollster.
             LOG.debug(_('Obtaining CPU Util is not implemented for %s'
                         ), manager.inspector.__class__.__name__)
         except Exception as err:
             LOG.error(_('Could not get CPU Util for %(id)s: %(e)s'), (
                       {'id': instance.id, 'e': err}))
def _multi_send(method, context, topic, msg, timeout=None,
                envelope=False, _msg_id=None):
    """Wraps the sending of messages.

    Dispatches to the matchmaker and sends message to all relevant hosts.
    """
    conf = CONF
    LOG.debug(_("%(msg)s") % {'msg': ' '.join(map(pformat, (topic, msg)))})

    queues = _get_matchmaker().queues(topic)
    LOG.debug(_("Sending message(s) to: %s"), queues)

    # Don't stack if we have no matchmaker results
    if not queues:
        LOG.warn(_("No matchmaker results. Not casting."))
        # While not strictly a timeout, callers know how to handle
        # this exception and a timeout isn't too big a lie.
        raise rpc_common.Timeout(_("No match from matchmaker."))

    # This supports brokerless fanout (addresses > 1)
    for queue in queues:
        (_topic, ip_addr) = queue
        _addr = "tcp://%s:%s" % (ip_addr, conf.rpc_zmq_port)

        if method.__name__ == '_cast':
            eventlet.spawn_n(method, _addr, context,
                             _topic, msg, timeout, envelope,
                             _msg_id)
            return
        return method(_addr, context, _topic, msg, timeout,
                      envelope)
    def __init__(self, addr, zmq_type, bind=True, subscribe=None):
        self.sock = _get_ctxt().socket(zmq_type)
        self.addr = addr
        self.type = zmq_type
        self.subscriptions = []

        # Support failures on sending/receiving on wrong socket type.
        self.can_recv = zmq_type in (zmq.PULL, zmq.SUB)
        self.can_send = zmq_type in (zmq.PUSH, zmq.PUB)
        self.can_sub = zmq_type in (zmq.SUB, )

        # Support list, str, & None for subscribe arg (cast to list)
        do_sub = {
            list: subscribe,
            str: [subscribe],
            type(None): []
        }[type(subscribe)]

        for f in do_sub:
            self.subscribe(f)

        str_data = {'addr': addr, 'type': self.socket_s(),
                    'subscribe': subscribe, 'bind': bind}

        LOG.debug(_("Connecting to %(addr)s with %(type)s"), str_data)
        LOG.debug(_("-> Subscribed to %(subscribe)s"), str_data)
        LOG.debug(_("-> bind: %(bind)s"), str_data)

        try:
            if bind:
                self.sock.bind(addr)
            else:
                self.sock.connect(addr)
        except Exception:
            raise RPCException(_("Could not open socket."))
    def register(self, proxy, in_addr, zmq_type_in, out_addr=None,
                 zmq_type_out=None, in_bind=True, out_bind=True,
                 subscribe=None):

        LOG.info(_("Registering reactor"))

        if zmq_type_in not in (zmq.PULL, zmq.SUB):
            raise RPCException("Bad input socktype")

        # Items push in.
        inq = ZmqSocket(in_addr, zmq_type_in, bind=in_bind,
                        subscribe=subscribe)

        self.proxies[inq] = proxy
        self.sockets.append(inq)

        LOG.info(_("In reactor registered"))

        if not out_addr:
            return

        if zmq_type_out not in (zmq.PUSH, zmq.PUB):
            raise RPCException("Bad output socktype")

        # Items push out.
        outq = ZmqSocket(out_addr, zmq_type_out, bind=out_bind)

        self.mapping[inq] = outq
        self.mapping[outq] = inq
        self.sockets.append(outq)

        LOG.info(_("Out reactor registered"))
Exemple #19
0
 def report_presence(self):
     """Report the presence of the current partition."""
     LOG.debug(_('%s reporting presence') % self.this)
     try:
         self.coordination_rpc.presence(self.this.uuid, self.this.priority)
     except Exception:
         LOG.exception(_('presence reporting failed'))
Exemple #20
0
def multicall(conf, context, topic, msg, timeout, connection_pool):
    """Make a call that returns multiple times."""
    # TODO(pekowski): Remove all these comments in Havana.
    # For amqp_rpc_single_reply_queue = False,
    # Can't use 'with' for multicall, as it returns an iterator
    # that will continue to use the connection.  When it's done,
    # connection.close() will get called which will put it back into
    # the pool
    # For amqp_rpc_single_reply_queue = True,
    # The 'with' statement is mandatory for closing the connection
    LOG.debug(_('Making synchronous call on %s ...'), topic)
    msg_id = uuid.uuid4().hex
    msg.update({'_msg_id': msg_id})
    LOG.debug(_('MSG_ID is %s') % (msg_id))
    _add_unique_id(msg)
    pack_context(msg, context)

    # TODO(pekowski): Remove this flag and the code under the if clause
    #                 in Havana.
    # (p-draigbrady): This clause is disabled to avoid qpid exchange leaks
    if False and not conf.amqp_rpc_single_reply_queue:
        conn = ConnectionContext(conf, connection_pool)
        wait_msg = MulticallWaiter(conf, conn, timeout)
        conn.declare_direct_consumer(msg_id, wait_msg)
        conn.topic_send(topic, rpc_common.serialize_msg(msg), timeout)
    else:
        with _reply_proxy_create_sem:
            if not connection_pool.reply_proxy:
                connection_pool.reply_proxy = ReplyProxy(conf, connection_pool)
        msg.update({'_reply_q': connection_pool.reply_proxy.get_reply_q()})
        wait_msg = MulticallProxyWaiter(conf, msg_id, timeout, connection_pool)
        with ConnectionContext(conf, connection_pool) as conn:
            conn.topic_send(topic, rpc_common.serialize_msg(msg), timeout)
    return wait_msg
Exemple #21
0
    def __init__(self, alarm_id, type, enabled, name, description,
                 timestamp, user_id, project_id, state, state_timestamp,
                 ok_actions, alarm_actions, insufficient_data_actions,
                 repeat_actions, rule, time_constraints):
        if not isinstance(timestamp, datetime.datetime):
            raise TypeError(_("timestamp should be datetime object"))
        if not isinstance(state_timestamp, datetime.datetime):
            raise TypeError(_("state_timestamp should be datetime object"))

        base.Model.__init__(
            self,
            alarm_id=alarm_id,
            type=type,
            enabled=enabled,
            name=name,
            description=description,
            timestamp=timestamp,
            user_id=user_id,
            project_id=project_id,
            state=state,
            state_timestamp=state_timestamp,
            ok_actions=ok_actions,
            alarm_actions=alarm_actions,
            insufficient_data_actions=insufficient_data_actions,
            repeat_actions=repeat_actions,
            rule=rule,
            time_constraints=time_constraints)
Exemple #22
0
    def record_metering_data(self, data):
        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(_(
                'metering data %(counter_name)s '
                'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s')
                % ({'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']}))
            if publisher_utils.verify_signature(
                    meter,
                    self.conf.publisher.metering_secret):
                try:
                    # Convert the timestamp to a datetime instance.
                    # Storage engines are responsible for converting
                    # that value to something they can store.
                    if meter.get('timestamp'):
                        ts = timeutils.parse_isotime(meter['timestamp'])
                        meter['timestamp'] = timeutils.normalize_time(ts)
                    self.storage_conn.record_metering_data(meter)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'),
                                  err)
            else:
                LOG.warning(_(
                    'message signature invalid, discarding message: %r'),
                    meter)
Exemple #23
0
    def _callback_handler(self, message, callback):
        """Call callback with deserialized message.

        Messages that are processed without exception are ack'ed.

        If the message processing generates an exception, it will be
        ack'ed if ack_on_error=True. Otherwise it will be .reject()'ed.
        Rejection is better than waiting for the message to timeout.
        Rejected messages are immediately requeued.
        """

        ack_msg = False
        try:
            msg = rpc_common.deserialize_msg(message.payload)
            callback(msg)
            ack_msg = True
        except Exception:
            if self.ack_on_error:
                ack_msg = True
                LOG.exception(_("Failed to process message"
                                " ... skipping it."))
            else:
                LOG.exception(_("Failed to process message"
                                " ... will requeue."))
        finally:
            if ack_msg:
                message.ack()
            else:
                message.reject()
    def create_consumer(self, topic, proxy, fanout=False):
        # Register with matchmaker.
        _get_matchmaker().register(topic, CONF.rpc_zmq_host)

        # Subscription scenarios
        if fanout:
            sock_type = zmq.SUB
            subscribe = ('', fanout)[type(fanout) == str]
            topic = 'fanout~' + topic.split('.', 1)[0]
        else:
            sock_type = zmq.PULL
            subscribe = None
            topic = '.'.join((topic.split('.', 1)[0], CONF.rpc_zmq_host))

        if topic in self.topics:
            LOG.info(_("Skipping topic registration. Already registered."))
            return

        # Receive messages from (local) proxy
        inaddr = "ipc://%s/zmq_topic_%s" % \
            (CONF.rpc_zmq_ipc_dir, topic)

        LOG.debug(_("Consumer is a zmq.%s"),
                  ['PULL', 'SUB'][sock_type == zmq.SUB])

        self.reactor.register(proxy, inaddr, sock_type,
                              subscribe=subscribe, in_bind=False)
        self.topics.append(topic)
Exemple #25
0
    def _poll_task(self, task, done):
        """Poll the given task.

        If the task completes successfully then returns task info.
        In case of error sends back appropriate error.

        :param task: Managed object reference of the task
        :param event: Event that captures task status
        """
        try:
            task_info = self.invoke_api(vim_util, 'get_object_property',
                                        self.vim, task, 'info')
            if task_info.state in ['queued', 'running']:
                # If task already completed on server, it will not return
                # the progress.
                if hasattr(task_info, 'progress'):
                    LOG.debug(_("Task: %(task)s progress: %(prog)s.") %
                              {'task': task, 'prog': task_info.progress})
                return
            elif task_info.state == 'success':
                LOG.debug(_("Task %s status: success.") % task)
                done.send(task_info)
            else:
                error_msg = str(task_info.error.localizedMessage)
                LOG.exception(_("Task: %(task)s failed with error: %(err)s.") %
                              {'task': task, 'err': error_msg})
                done.send_exception(error_util.VimFaultException([],
                                    error_msg))
        except Exception as excep:
            LOG.exception(_("Task: %(task)s failed with error: %(err)s.") %
                          {'task': task, 'err': excep})
            done.send_exception(excep)
    def handle_sample(self, context, s):
        """Handle a sample, converting if necessary."""
        LOG.debug(_('handling sample %s'), (s,))
        key = s.name + s.resource_id
        prev = self.cache.get(key)
        timestamp = timeutils.parse_isotime(s.timestamp)
        self.cache[key] = (s.volume, timestamp)

        if prev:
            prev_volume = prev[0]
            prev_timestamp = prev[1]
            time_delta = timeutils.delta_seconds(prev_timestamp, timestamp)
            # we only allow negative deltas for noncumulative samples, whereas
            # for cumulative we assume that a reset has occurred in the interim
            # so that the current volume gives a lower bound on growth
            volume_delta = (s.volume - prev_volume
                            if (prev_volume <= s.volume or
                                s.type != sample.TYPE_CUMULATIVE)
                            else s.volume)
            rate_of_change = ((1.0 * volume_delta / time_delta)
                              if time_delta else 0.0)

            s = self._convert(s, rate_of_change)
            LOG.debug(_('converted to: %s'), (s,))
        else:
            LOG.warn(_('dropping sample with no predecessor: %s'),
                     (s,))
            s = None
        return s
Exemple #27
0
def to_bytes(text, default=0):
    """Converts a string into an integer of bytes.

    Looks at the last characters of the text to determine
    what conversion is needed to turn the input text into a byte number.
    Supports "B, K(B), M(B), G(B), and T(B)". (case insensitive)

    :param text: String input for bytes size conversion.
    :param default: Default return value when text is blank.

    """
    match = BYTE_REGEX.search(text)
    if match:
        magnitude = int(match.group(1))
        mult_key_org = match.group(2)
        if not mult_key_org:
            return magnitude
    elif text:
        msg = _('Invalid string format: %s') % text
        raise TypeError(msg)
    else:
        return default
    mult_key = mult_key_org.lower().replace('b', '', 1)
    multiplier = BYTE_MULTIPLIERS.get(mult_key)
    if multiplier is None:
        msg = _('Unknown byte multiplier: %s') % mult_key_org
        raise TypeError(msg)
    return magnitude * multiplier
Exemple #28
0
def _parse_check(rule):
    """
    Parse a single base check rule into an appropriate Check object.
    """

    # Handle the special checks
    if rule == '!':
        return FalseCheck()
    elif rule == '@':
        return TrueCheck()

    try:
        kind, match = rule.split(':', 1)
    except Exception:
        LOG.exception(_("Failed to understand rule %(rule)s") % locals())
        # If the rule is invalid, we'll fail closed
        return FalseCheck()

    # Find what implements the check
    if kind in _checks:
        return _checks[kind](kind, match)
    elif None in _checks:
        return _checks[None](kind, match)
    else:
        LOG.error(_("No handler for matches of kind %s") % kind)
        return FalseCheck()
Exemple #29
0
 def get_samples(self, manager, cache, resources):
     for instance in resources:
         LOG.info(_('checking instance %s'), instance.id)
         instance_name = util.instance_name(instance)
         try:
             cpu_info = manager.inspector.inspect_cpus(instance_name)
             LOG.info(_("CPUTIME USAGE: %(instance)s %(time)d") % (
                      {'instance': instance.__dict__,
                       'time': cpu_info.time}))
             cpu_num = {'cpu_number': cpu_info.number}
             yield util.make_sample_from_instance(
                 instance,
                 name='cpu',
                 type=sample.TYPE_CUMULATIVE,
                 unit='ns',
                 volume=cpu_info.time,
                 additional_metadata=cpu_num,
             )
         except virt_inspector.InstanceNotFoundException as err:
             # Instance was deleted while getting samples. Ignore it.
             LOG.debug(_('Exception while getting samples %s'), err)
         except NotImplementedError:
             # Selected inspector does not implement this pollster.
             LOG.debug(_('Obtaining CPU time is not implemented for %s'
                         ), manager.inspector.__class__.__name__)
         except Exception as err:
             LOG.error(_('could not get CPU time for %(id)s: %(e)s') % (
                       {'id': instance.id, 'e': err}))
             LOG.exception(err)
Exemple #30
0
    def _handle_action(self, action, alarm_id, previous, current, reason):
        try:
            action = network_utils.urlsplit(action)
        except Exception:
            LOG.error(
                _("Unable to parse action %(action)s for alarm %(alarm_id)s"),
                {'action': action, 'alarm_id': alarm_id})
            return

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

        try:
            LOG.debug("Notifying alarm %s with action %s",
                      alarm_id, action)
            notifier.notify(action, alarm_id, previous, current, reason)
        except Exception:
            LOG.exception(_("Unable to notify alarm %s"), alarm_id)
            return
Exemple #31
0
    def get_targets(self, conf):
        """Return a sequence of oslo.messaging.Target.

        Sequence is defining the exchange and topics to be connected for this
        plugin.
        :param conf: Configuration.
        """

        # TODO(sileht): Backwards compatibility, remove in J+1
        if hasattr(self, 'get_exchange_topics'):
            LOG.warn(
                _('get_exchange_topics API of NotificationPlugin is'
                  'deprecated, implements get_targets instead.'))

            targets = []
            for exchange, topics in self.get_exchange_topics(conf):
                targets.extend([
                    oslo.messaging.Target(topic=topic, exchange=exchange)
                    for topic in topics
                ])
            return targets
Exemple #32
0
 def notify(self, alarm, previous, reason):
     actions = getattr(alarm, Alarm.ALARM_ACTIONS_MAP[alarm.state])
     if not actions:
         LOG.debug(
             _('alarm %(alarm_id)s has no action configured '
               'for state transition from %(previous)s to '
               'state %(state)s, skipping the notification.') % {
                   'alarm_id': alarm.alarm_id,
                   'previous': previous,
                   'state': alarm.state
               })
         return
     msg = self.make_msg('notify_alarm',
                         data={
                             'actions': actions,
                             'alarm_id': alarm.alarm_id,
                             'previous': previous,
                             'current': alarm.state,
                             'reason': unicode(reason)
                         })
     self.cast(context.get_admin_context(), msg)
Exemple #33
0
    def connect(self, url):
        connection_options = pymongo.uri_parser.parse_uri(url)
        del connection_options['database']
        del connection_options['username']
        del connection_options['password']
        del connection_options['collection']
        pool_key = tuple(connection_options)

        if pool_key in self._pool:
            client = self._pool.get(pool_key)()
            if client:
                return client
        splitted_url = netutils.urlsplit(url)
        log_data = {
            'db': splitted_url.scheme,
            'nodelist': connection_options['nodelist']
        }
        LOG.info(_('Connecting to %(db)s on %(nodelist)s') % log_data)
        client = self._mongo_connect(url)
        self._pool[pool_key] = weakref.ref(client)
        return client
Exemple #34
0
 def _bound_duration(cls, alarm, constraints):
     """Bound the duration of the statistics query."""
     now = timeutils.utcnow()
     # when exclusion of weak datapoints is enabled, we extend
     # the look-back period so as to allow a clearer sample count
     # trend to be established
     look_back = (cls.look_back if not alarm.rule.get('exclude_outliers')
                  else alarm.rule['evaluation_periods'])
     window = (alarm.rule['period'] *
               (alarm.rule['evaluation_periods'] + look_back))
     start = now - datetime.timedelta(seconds=window)
     LOG.debug(
         _('query stats from %(start)s to '
           '%(now)s') % {
               'start': start,
               'now': now
           })
     after = dict(field='timestamp', op='ge', value=start.isoformat())
     before = dict(field='timestamp', op='le', value=now.isoformat())
     constraints.extend([before, after])
     return constraints
Exemple #35
0
    def _setup_transformers(self, cfg, transformer_manager):
        transformer_cfg = cfg['transformers'] or []
        transformers = []
        for transformer in transformer_cfg:
            parameter = transformer['parameters'] or {}
            try:
                ext = transformer_manager.get_ext(transformer['name'])
            except KeyError:
                raise PipelineException(
                    "No transformer named %s loaded" % transformer['name'],
                    cfg)
            transformers.append(ext.plugin(**parameter))
            LOG.info(
                _("Pipeline %(pipeline)s: Setup transformer instance %(name)s "
                  "with parameter %(param)s") % ({
                      'pipeline': self,
                      'name': transformer['name'],
                      'param': parameter
                  }))

        return transformers
Exemple #36
0
 def _get_sample(message, name):
     try:
         for metric in message['payload']['metrics']:
             if name == metric['name']:
                 info = {}
                 info['payload'] = metric
                 info['event_type'] = message['event_type']
                 info['publisher_id'] = message['publisher_id']
                 info['resource_id'] = '%s_%s' % (
                     message['payload']['host'],
                     message['payload']['nodename'])
                 info['timestamp'] = str(
                     timeutils.parse_strtime(metric['timestamp']))
                 return info
     except Exception as err:
         LOG.warning(
             _('An error occurred while building %(m)s '
               'sample: %(e)s') % {
                   'm': name,
                   'e': err
               })
Exemple #37
0
    def to_event(self, notification_body):
        event_type = notification_body['event_type']
        message_id = notification_body['message_id']
        edef = None
        for d in self.definitions:
            if d.match_type(event_type):
                edef = d
                break

        if edef is None:
            msg = (_('Dropping Notification %(type)s (uuid:%(msgid)s)') %
                   dict(type=event_type, msgid=message_id))
            if cfg.CONF.event.drop_unmatched_notifications:
                LOG.debug(msg)
            else:
                # If drop_unmatched_notifications is False, this should
                # never happen. (mdragon)
                LOG.error(msg)
            return None

        return edef.to_event(notification_body)
Exemple #38
0
    def __init__(self, url):
        """Hbase Connection Initialization."""
        opts = self._parse_connection_url(url)

        if opts['host'] == '__test__':
            url = os.environ.get('CEILOMETER_TEST_HBASE_URL')
            if url:
                # Reparse URL, but from the env variable now
                opts = self._parse_connection_url(url)
                self.conn_pool = self._get_connection_pool(opts)
            else:
                # This is a in-memory usage for unit tests
                if Connection._memory_instance is None:
                    LOG.debug(
                        _('Creating a new in-memory HBase '
                          'Connection object'))
                    Connection._memory_instance = (
                        hbase_inmemory.MConnectionPool())
                self.conn_pool = Connection._memory_instance
        else:
            self.conn_pool = self._get_connection_pool(opts)
Exemple #39
0
    def _sufficient_states(self, alarm, states):
        """Check for the sufficiency of the data for evaluation.

        Ensure that there is sufficient data for evaluation,
        transitioning to unknown otherwise.
        """
        # note(sileht): alarm can be evaluated only with
        # stable state of other alarm
        alarms_missing_states = [
            alarm_id for alarm_id, state in states
            if not state or state == evaluator.UNKNOWN
        ]
        sufficient = len(alarms_missing_states) == 0
        if not sufficient and alarm.state != evaluator.UNKNOWN:
            reason = (_('Alarms %(alarm_ids)s'
                        ' are in unknown state') % {
                            'alarm_ids': ",".join(alarms_missing_states)
                        })
            reason_data = self._reason_data(alarms_missing_states)
            self._refresh(alarm, evaluator.UNKNOWN, reason, reason_data)
        return sufficient
Exemple #40
0
 def inspect_disks(self, instance_name):
     domain = self._lookup_by_name(instance_name)
     state = domain.info()[0]
     if state == libvirt.VIR_DOMAIN_SHUTOFF:
         LOG.warn(_('Failed to inspect disks of %(instance_name)s, '
                    'domain is in state of SHUTOFF'),
                  {'instance_name': instance_name})
         return
     tree = etree.fromstring(domain.XMLDesc(0))
     for device in filter(
             bool,
             [target.get("dev")
              for target in tree.findall('devices/disk/target')]):
         disk = virt_inspector.Disk(device=device)
         block_stats = domain.blockStats(device)
         stats = virt_inspector.DiskStats(read_requests=block_stats[0],
                                          read_bytes=block_stats[1],
                                          write_requests=block_stats[2],
                                          write_bytes=block_stats[3],
                                          errors=block_stats[4])
         yield (disk, stats)
Exemple #41
0
    def __init__(self, cfg, transformer_manager):
        self.cfg = cfg

        try:
            self.name = cfg['name']
            try:
                self.interval = int(cfg['interval'])
            except ValueError:
                raise PipelineException("Invalid interval value", cfg)
            # Support 'counters' for backward compatibility
            self.meters = cfg.get('meters', cfg.get('counters'))
            # It's legal to have no transformer specified
            self.transformer_cfg = cfg['transformers'] or []
        except KeyError as err:
            raise PipelineException(
                "Required field %s not specified" % err.args[0], cfg)

        if self.interval <= 0:
            raise PipelineException("Interval value should > 0", cfg)

        self._check_meters()

        if not cfg.get('publishers'):
            raise PipelineException("No publisher specified", cfg)

        self.publishers = []
        for p in cfg['publishers']:
            if '://' not in p:
                # Support old format without URL
                p = p + "://"
            try:
                self.publishers.append(publisher.get_publisher(p))
            except Exception:
                LOG.exception(_("Unable to load publisher %s"), p)

        self.transformers = self._setup_transformers(cfg, transformer_manager)

        self.resources = cfg.get('resources') or []
        if not isinstance(self.resources, list):
            raise PipelineException("Resources should be a list", cfg)
Exemple #42
0
    def _get_socket(self, host, port, backlog):
        # TODO(dims): eventlet's green dns/socket module does not actually
        # support IPv6 in getaddrinfo(). We need to get around this in the
        # future or monitor upstream for a fix
        info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM)[0]
        family = info[0]
        bind_addr = info[-1]

        sock = None
        retry_until = time.time() + 30
        while not sock and time.time() < retry_until:
            try:
                sock = eventlet.listen(bind_addr,
                                       backlog=backlog,
                                       family=family)
                if sslutils.is_enabled():
                    sock = sslutils.wrap(sock)

            except socket.error as err:
                if err.args[0] != errno.EADDRINUSE:
                    raise
                eventlet.sleep(0.1)
        if not sock:
            raise RuntimeError(
                _("Could not bind to %(host)s:%(port)s "
                  "after trying for 30 seconds") % {
                      'host': host,
                      'port': port
                  })
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # sockets can hang around forever without keepalive
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

        # This option isn't available in the OS X version of eventlet
        if hasattr(socket, 'TCP_KEEPIDLE'):
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE,
                            CONF.tcp_keepidle)

        return sock
Exemple #43
0
 def get_samples(self, manager, cache, resources):
     for endpoint in resources:
         for ip in self._iter_floating_ips(manager.keystone, cache,
                                           endpoint):
             LOG.info(_("FLOATING IP USAGE: %s") % ip.ip)
             # FIXME (flwang) Now Nova API /os-floating-ips can't provide
             # those attributes were used by Ceilometer, such as project
             # id, host. In this fix, those attributes usage will be
             # removed temporarily. And they will be back after fix the
             # Nova bug 1174802.
             yield sample.Sample(name='ip.floating',
                                 type=sample.TYPE_GAUGE,
                                 unit='ip',
                                 volume=1,
                                 user_id=None,
                                 project_id=None,
                                 resource_id=ip.id,
                                 timestamp=timeutils.utcnow().isoformat(),
                                 resource_metadata={
                                     'address': ip.ip,
                                     'pool': ip.pool
                                 })
Exemple #44
0
def initialize_if_enabled():
    backdoor_locals = {
        'exit': _dont_use_this,  # So we don't exit the entire process
        'quit': _dont_use_this,  # So we don't exit the entire process
        'fo': _find_objects,
        'pgt': _print_greenthreads,
        'pnt': _print_nativethreads,
    }

    if CONF.backdoor_port is None:
        return None

    start_port, end_port = _parse_port_range(str(CONF.backdoor_port))

    # NOTE(johannes): The standard sys.displayhook will print the value of
    # the last expression and set it to __builtin__._, which overwrites
    # the __builtin__._ that gettext sets. Let's switch to using pprint
    # since it won't interact poorly with gettext, and it's easier to
    # read the output too.
    def displayhook(val):
        if val is not None:
            pprint.pprint(val)

    sys.displayhook = displayhook

    sock = _listen('localhost', start_port, end_port, eventlet.listen)

    # In the case of backdoor port being zero, a port number is assigned by
    # listen().  In any case, pull the port number out here.
    port = sock.getsockname()[1]
    LOG.info(
        _('Eventlet backdoor listening on %(port)s for process %(pid)d') % {
            'port': port,
            'pid': os.getpid()
        })
    eventlet.spawn_n(eventlet.backdoor.backdoor_server,
                     sock,
                     locals=backdoor_locals)
    return port
Exemple #45
0
def db_version(abs_path, init_version):
    """Show the current version of the repository.

    :param abs_path: Absolute path to migrate repository
    :param version:  Initial database version
    """
    repository = _find_migrate_repo(abs_path)
    try:
        return versioning_api.db_version(get_engine(), repository)
    except versioning_exceptions.DatabaseNotControlledError:
        meta = sqlalchemy.MetaData()
        engine = get_engine()
        meta.reflect(bind=engine)
        tables = meta.tables
        if len(tables) == 0:
            db_version_control(abs_path, init_version)
            return versioning_api.db_version(get_engine(), repository)
        else:
            # Some pre-Essex DB's may not be version controlled.
            # Require them to upgrade using Essex first.
            raise exception.DbMigrationError(
                message=_("Upgrade DB using Essex release first."))
Exemple #46
0
    def get_meters(self, user=None, project=None, resource=None, source=None,
                   metaquery={}, pagination=None):
        """Return an iterable of models.Meter instances

        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param resource: Optional resource filter.
        :param source: Optional source filter.
        :param metaquery: Optional dict with metadata to match on.
        :param pagination: Optional pagination query.
        """

        if pagination:
            raise NotImplementedError(_('Pagination not implemented'))

        q = {}
        if user is not None:
            q['user_id'] = user
        if project is not None:
            q['project_id'] = project
        if resource is not None:
            q['_id'] = resource
        if source is not None:
            q['source'] = source
        q.update(metaquery)

        for r in self.db.resource.find(q):
            for r_meter in r['meter']:
                yield models.Meter(
                    name=r_meter['counter_name'],
                    type=r_meter['counter_type'],
                    # Return empty string if 'counter_unit' is not valid for
                    # backward compatibility.
                    unit=r_meter.get('counter_unit', ''),
                    resource_id=r['_id'],
                    project_id=r['project_id'],
                    source=r['source'],
                    user_id=r['user_id'],
                )
Exemple #47
0
 def _lookup_by_uuid(self, instance):
     instance_name = util.instance_name(instance)
     try:
         return self._get_connection().lookupByUUIDString(instance.id)
     except Exception as ex:
         if not libvirt or not isinstance(ex, libvirt.libvirtError):
             raise virt_inspector.InspectorException(six.text_type(ex))
         error_code = ex.get_error_code()
         if (error_code == libvirt.VIR_ERR_SYSTEM_ERROR
                 and ex.get_error_domain()
                 in (libvirt.VIR_FROM_REMOTE, libvirt.VIR_FROM_RPC)):
             raise
         msg = _("Error from libvirt while looking up instance "
                 "<name=%(name)s, id=%(id)s>: "
                 "[Error Code %(error_code)s] "
                 "%(ex)s") % {
                     'name': instance_name,
                     'id': instance.id,
                     'error_code': error_code,
                     'ex': ex
                 }
         raise virt_inspector.InstanceNotFoundException(msg)
    def _message_to_event(self, body):
        """Convert message to Ceilometer Event.

        NOTE: this is currently based on the Nova notification format.
        We will need to make this driver-based to support other formats.

        NOTE: the rpc layer currently rips out the notification
        delivery_info, which is critical to determining the
        source of the notification. This will have to get added back later.
        """
        event_name = body['event_type']
        when = self._extract_when(body)

        LOG.debug('Saving event "%s"', event_name)

        message_id = body.get('message_id')

        # TODO(sandy) - check we have not already saved this notification.
        #               (possible on retries) Use message_id to spot dups.
        publisher = body.get('publisher_id')
        request_id = body.get('_context_request_id')
        tenant_id = body.get('_context_tenant')

        text = models.Trait.TEXT_TYPE
        all_traits = [models.Trait('message_id', text, message_id),
                      models.Trait('service', text, publisher),
                      models.Trait('request_id', text, request_id),
                      models.Trait('tenant_id', text, tenant_id),
                      ]
        # Only store non-None value traits ...
        traits = [trait for trait in all_traits if trait.value is not None]

        event = models.Event(event_name, when, traits)
        try:
            self.storage_conn.record_events([event, ])
        except Exception as err:
            LOG.exception(_("Unable to store events: %s"), err)
            # By re-raising we avoid ack()'ing the message.
            raise
Exemple #49
0
    def get_alarms(self,
                   name=None,
                   user=None,
                   project=None,
                   enabled=True,
                   alarm_id=None,
                   pagination=None):
        """Yields a lists of alarms that match filters
        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param enabled: Optional boolean to list disable alarm.
        :param alarm_id: Optional alarm_id to return one alarm.
        :param metaquery: Optional dict with metadata to match on.
        :param resource: Optional resource filter.
        :param pagination: Optional pagination query.
        """

        if pagination:
            raise NotImplementedError(_('Pagination not implemented'))

        q = {}
        if user is not None:
            q['user_id'] = user
        if project is not None:
            q['project_id'] = project
        if name is not None:
            q['name'] = name
        if enabled is not None:
            q['enabled'] = enabled
        if alarm_id is not None:
            q['alarm_id'] = alarm_id

        for alarm in self.db.alarm.find(q):
            a = {}
            a.update(alarm)
            del a['_id']
            a['matching_metadata'] = \
                self._decode_matching_metadata(a['matching_metadata'])
            yield models.Alarm(**a)
Exemple #50
0
    def get_samples(self, sample_filter, limit=None):
        """Return an iterable of models.Sample instances.

        :param sample_filter: Filter.
        :param limit: Maximum number of results to return.
        """
        with self.conn_pool.connection() as conn:
            meter_table = conn.table(self.METER_TABLE)

            q, start, stop = make_sample_query_from_filter(sample_filter,
                                                           require_meter=False)
            LOG.debug(_("Query Meter Table: %s") % q)
            gen = meter_table.scan(filter=q, row_start=start, row_stop=stop)
            for ignored, meter in gen:
                if limit is not None:
                    if limit == 0:
                        break
                    else:
                        limit -= 1
                d_meter = deserialize_entry(meter)[0]
                d_meter['message']['recorded_at'] = d_meter['recorded_at']
                yield models.Sample(**d_meter['message'])
Exemple #51
0
def _find_facility_from_conf():
    facility_names = logging.handlers.SysLogHandler.facility_names
    facility = getattr(logging.handlers.SysLogHandler,
                       CONF.syslog_log_facility,
                       None)

    if facility is None and CONF.syslog_log_facility in facility_names:
        facility = facility_names.get(CONF.syslog_log_facility)

    if facility is None:
        valid_facilities = facility_names.keys()
        consts = ['LOG_AUTH', 'LOG_AUTHPRIV', 'LOG_CRON', 'LOG_DAEMON',
                  'LOG_FTP', 'LOG_KERN', 'LOG_LPR', 'LOG_MAIL', 'LOG_NEWS',
                  'LOG_AUTH', 'LOG_SYSLOG', 'LOG_USER', 'LOG_UUCP',
                  'LOG_LOCAL0', 'LOG_LOCAL1', 'LOG_LOCAL2', 'LOG_LOCAL3',
                  'LOG_LOCAL4', 'LOG_LOCAL5', 'LOG_LOCAL6', 'LOG_LOCAL7']
        valid_facilities.extend(consts)
        raise TypeError(_('syslog facility must be one of: %s') %
                        ', '.join("'%s'" % fac
                                  for fac in valid_facilities))

    return facility
Exemple #52
0
def db_version(engine, abs_path, init_version):
    """Show the current version of the repository.

    :param engine:  SQLAlchemy engine instance for a given database
    :param abs_path: Absolute path to migrate repository
    :param version:  Initial database version
    """
    repository = _find_migrate_repo(abs_path)
    try:
        return versioning_api.db_version(engine, repository)
    except versioning_exceptions.DatabaseNotControlledError:
        meta = sqlalchemy.MetaData()
        meta.reflect(bind=engine)
        tables = meta.tables
        if len(tables) == 0 or 'alembic_version' in tables:
            db_version_control(engine, abs_path, version=init_version)
            return versioning_api.db_version(engine, repository)
        else:
            raise exception.DbMigrationError(message=_(
                "The database is not under version control, but has "
                "tables. Please stamp the current version of the schema "
                "manually."))
Exemple #53
0
    def get_samples(self, manager, cache, resources=None):
        resources = resources or []

        for member in resources:
            LOG.debug("Load Balancer Member : %s" % member)
            status = self.get_status_id(member['status'])
            if status == -1:
                LOG.warn(_("Unknown status %(stat)s received on member %(id)s,"
                         "skipping sample") % {'stat': member['status'],
                                               'id': member['id']})
                continue
            yield sample.Sample(
                name='network.services.lb.member',
                type=sample.TYPE_GAUGE,
                unit='member',
                volume=status,
                user_id=None,
                project_id=member['tenant_id'],
                resource_id=member['id'],
                timestamp=timeutils.utcnow().isoformat(),
                resource_metadata=self.extract_metadata(member)
            )
Exemple #54
0
 def notify(self, alarm, previous, reason, reason_data):
     actions = getattr(alarm, models.Alarm.ALARM_ACTIONS_MAP[alarm.state])
     if not actions:
         LOG.debug(
             _('alarm %(alarm_id)s has no action configured '
               'for state transition from %(previous)s to '
               'state %(state)s, skipping the notification.') % {
                   'alarm_id': alarm.alarm_id,
                   'previous': previous,
                   'state': alarm.state
               })
         return
     self.client.cast(context.get_admin_context(),
                      'notify_alarm',
                      data={
                          'actions': actions,
                          'alarm_id': alarm.alarm_id,
                          'previous': previous,
                          'current': alarm.state,
                          'reason': six.text_type(reason),
                          'reason_data': reason_data
                      })
Exemple #55
0
    def process_notification(self, message):
        LOG.info(_('network notification %r') % message)
        counter_name = getattr(self, 'counter_name', self.resource_name)
        unit_value = getattr(self, 'unit', self.resource_name)

        resource = message['payload'].get(self.resource_name)
        if resource:
            # NOTE(liusheng): In %s.update.start notifications, the id is in
            # message['payload'] instead of resource itself.
            if message['event_type'].endswith('update.start'):
                resource['id'] = message['payload']['id']
            resources = [resource]
        else:
            resources = message['payload'].get(self.resource_name + 's')

        resource_message = message.copy()
        for resource in resources:
            resource_message['payload'] = resource
            yield sample.Sample.from_notification(
                name=counter_name,
                type=sample.TYPE_GAUGE,
                unit=unit_value,
                volume=1,
                user_id=resource_message['_context_user_id'],
                project_id=resource_message['_context_tenant_id'],
                resource_id=resource['id'],
                message=resource_message)
            event_type_split = resource_message['event_type'].split('.')
            if len(event_type_split) > 2:
                yield sample.Sample.from_notification(
                    name=counter_name + "." + event_type_split[1],
                    type=sample.TYPE_DELTA,
                    unit=unit_value,
                    volume=1,
                    user_id=resource_message['_context_user_id'],
                    project_id=resource_message['_context_tenant_id'],
                    resource_id=resource['id'],
                    message=resource_message)
Exemple #56
0
    def record_metering_data(self, data):
        """Write the data to the backend storage system.

        :param data: a dictionary such as returned by
                     ceilometer.meter.meter_message_from_counter
        """
        session = self._engine_facade.get_session()
        with session.begin():
            # Record the raw data for the sample.
            rmetadata = data['resource_metadata']
            meter = self._create_meter(session, data['counter_name'],
                                       data['counter_type'],
                                       data['counter_unit'])
            sample = models.Sample(meter_id=meter.id)
            session.add(sample)
            sample.resource_id = data['resource_id']
            sample.project_id = data['project_id']
            sample.user_id = data['user_id']
            sample.timestamp = data['timestamp']
            sample.resource_metadata = rmetadata
            sample.volume = data['counter_volume']
            sample.message_signature = data['message_signature']
            sample.message_id = data['message_id']
            sample.source_id = data['source']
            session.flush()

            if rmetadata:
                if isinstance(rmetadata, dict):
                    for key, v in utils.dict_to_keyval(rmetadata):
                        try:
                            _model = sql_utils.META_TYPE_MAP[type(v)]
                        except KeyError:
                            LOG.warn(
                                _("Unknown metadata type. Key (%s) will "
                                  "not be queryable."), key)
                        else:
                            session.add(
                                _model(id=sample.id, meta_key=key, value=v))
Exemple #57
0
def serialize_remote_exception(failure_info, log_failure=True):
    """Prepares exception data to be sent over rpc.

    Failure_info should be a sys.exc_info() tuple.

    """
    tb = traceback.format_exception(*failure_info)
    failure = failure_info[1]
    if log_failure:
        LOG.error(_("Returning exception %s to caller"),
                  six.text_type(failure))
        LOG.error(tb)

    kwargs = {}
    if hasattr(failure, 'kwargs'):
        kwargs = failure.kwargs

    # NOTE(matiu): With cells, it's possible to re-raise remote, remote
    # exceptions. Lets turn it back into the original exception type.
    cls_name = str(failure.__class__.__name__)
    mod_name = str(failure.__class__.__module__)
    if (cls_name.endswith(_REMOTE_POSTFIX) and
            mod_name.endswith(_REMOTE_POSTFIX)):
        cls_name = cls_name[:-len(_REMOTE_POSTFIX)]
        mod_name = mod_name[:-len(_REMOTE_POSTFIX)]

    data = {
        'class': cls_name,
        'module': mod_name,
        'message': six.text_type(failure),
        'tb': tb,
        'args': failure.args,
        'kwargs': kwargs
    }

    json_data = jsonutils.dumps(data)

    return json_data
Exemple #58
0
    def reply(self, ctx, proxy,
              msg_id=None, context=None, topic=None, msg=None):
        """Reply to a casted call."""
        # NOTE(ewindisch): context kwarg exists for Grizzly compat.
        #                  this may be able to be removed earlier than
        #                  'I' if ConsumerBase.process were refactored.
        if type(msg) is list:
            payload = msg[-1]
        else:
            payload = msg

        response = ConsumerBase.normalize_reply(
            self._get_response(ctx, proxy, topic, payload),
            ctx.replies)

        LOG.debug(_("Sending reply"))
        _multi_send(_cast, ctx, topic, {
            'method': '-process_reply',
            'args': {
                'msg_id': msg_id,  # Include for Folsom compat.
                'response': response
            }
        }, _msg_id=msg_id)
Exemple #59
0
def _parse_text_rule(rule):
    """
    Translates a policy written in the policy language into a tree of
    Check objects.
    """

    # Empty rule means always accept
    if not rule:
        return TrueCheck()

    # Parse the token stream
    state = ParseState()
    for tok, value in _parse_tokenize(rule):
        state.shift(tok, value)

    try:
        return state.result
    except ValueError:
        # Couldn't parse the rule
        LOG.exception(_("Failed to understand rule %(rule)r") % locals())

        # Fail closed
        return FalseCheck()
Exemple #60
0
    def notify_alarm(self, context, data):
        """Notify that alarm has been triggered.

           :param context: Request context.
           :param data: (dict):

             - actions, the URL of the action to run; this is mapped to
               extensions automatically
             - alarm_id, the ID of the alarm that has been triggered
             - previous, the previous state of the alarm
             - current, the new state the alarm has transitioned to
             - reason, the reason the alarm changed its state
             - reason_data, a dict representation of the reason
        """
        actions = data.get('actions')
        if not actions:
            LOG.error(_("Unable to notify for an alarm with no action"))
            return

        for action in actions:
            self._handle_action(action, data.get('alarm_id'),
                                data.get('previous'), data.get('current'),
                                data.get('reason'), data.get('reason_data'))