Пример #1
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()
Пример #2
0
    def hints_parser(self, model, hints):
        """
        Utility method to parse hints fields.

        :param model: The starting model, from ``db.models``.
        :param hints: A list of hints indicating which attributes of
                      the model will be required by the calling code.
                      Only those attributes which reference other
                      fields need be listed, although it is not an
                      error to list other fields.  It is also
                      permissible to indicate deeper levels of access
                      by separating attributes with periods.  (In the
                      case of reference fields which are represented
                      as lists, there is no need to use square
                      brackets.)
        """

        # Were any hints even given?
        if not hints:
            return {}

        # The fields dictionary maps the direct fields and the
        # corresponding models; the subhints dictionary will be used
        # to recurse later on
        fields = {}
        subhints = {}

        for hint in hints:
            field, _sep, subfield = hint.partition(".")

            # Look up the field in the model
            if field not in model._refs:
                model_name = model.__name__
                if field not in model._fields:
                    LOG.warning(_("Hint for undefined field %(field)r " "of model %(model_name)s") % locals())
                else:
                    LOG.notice(_("Unnecessary hint %(field)r " "for model %(model_name)s") % locals())
                continue

            # Have we handled this field before?
            if field not in fields:
                # Get the model it refers to
                ref_model = model._refs[field].klass

                # Save that to fields...
                fields[field] = ref_model

            # Also save the subhints
            if subfield:
                subhints.setdefault(field, set())
                subhints[field].add(subfield)

        # Now we can build and return the result dictionary tree
        results = {}
        for field, sub_model in fields.items():
            sub_results = self.hint_parser(sub_model, subhints.get(field))

            results[field] = (sub_model, sub_results)

        return results
Пример #3
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()
Пример #4
0
def notify(context, publisher_id, event_type, priority, payload):
    """Sends a notification using the specified driver

    :param publisher_id: the source worker_type.host of the message
    :param event_type:   the literal type of event (ex. Instance Creation)
    :param priority:     patterned after the enumeration of Python logging
                         levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
    :param payload:       A python dictionary of attributes

    Outgoing message format includes the above parameters, and appends the
    following:

    message_id
      a UUID representing the id for this notification

    timestamp
      the GMT timestamp the notification was sent at

    The composite message will be constructed as a dictionary of the above
    attributes, which will then be sent via the transport mechanism defined
    by the driver.

    Message example::

        {'message_id': str(uuid.uuid4()),
         'publisher_id': 'compute.host1',
         'timestamp': timeutils.utcnow(),
         'priority': 'WARN',
         'event_type': 'compute.create_instance',
         'payload': {'instance_id': 12, ... }}

    """
    if priority not in log_levels:
        raise BadPriorityException(
            _('%s not in valid priorities') % priority)

    # Ensure everything is JSON serializable.
    payload = jsonutils.to_primitive(payload, convert_instances=True)

    msg = dict(message_id=str(uuid.uuid4()),
               publisher_id=publisher_id,
               event_type=event_type,
               priority=priority,
               payload=payload,
               timestamp=str(timeutils.utcnow()))

    for driver in _get_drivers():
        try:
            driver.notify(context, msg)
        except Exception, e:
            LOG.exception(_("Problem '%(e)s' attempting to "
                            "send to notification system. "
                            "Payload=%(payload)s") % locals())
Пример #5
0
def notify(context, publisher_id, event_type, priority, payload):
    """Sends a notification using the specified driver

    :param publisher_id: the source worker_type.host of the message
    :param event_type:   the literal type of event (ex. Instance Creation)
    :param priority:     patterned after the enumeration of Python logging
                         levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
    :param payload:       A python dictionary of attributes

    Outgoing message format includes the above parameters, and appends the
    following:

    message_id
      a UUID representing the id for this notification

    timestamp
      the GMT timestamp the notification was sent at

    The composite message will be constructed as a dictionary of the above
    attributes, which will then be sent via the transport mechanism defined
    by the driver.

    Message example::

        {'message_id': str(uuid.uuid4()),
         'publisher_id': 'compute.host1',
         'timestamp': timeutils.utcnow(),
         'priority': 'WARN',
         'event_type': 'compute.create_instance',
         'payload': {'instance_id': 12, ... }}

    """
    if priority not in log_levels:
        raise BadPriorityException(_('%s not in valid priorities') % priority)

    # Ensure everything is JSON serializable.
    payload = jsonutils.to_primitive(payload, convert_instances=True)

    msg = dict(message_id=str(uuid.uuid4()),
               publisher_id=publisher_id,
               event_type=event_type,
               priority=priority,
               payload=payload,
               timestamp=str(timeutils.utcnow()))

    for driver in _get_drivers():
        try:
            driver.notify(context, msg)
        except Exception, e:
            LOG.exception(
                _("Problem '%(e)s' attempting to "
                  "send to notification system. "
                  "Payload=%(payload)s") % locals())
Пример #6
0
    def __init__(self, resource, param_data=None):
        """
        Initialize a SpecificResource.

        :param resource: The Resource object.
        :param param_data: The parameter data relevant to this
                           resource.  May be omitted if no parameter
                           data is needed to uniquely identify the
                           resource.
        """

        self.resource = resource

        # Filter the parameter data
        if not param_data:
            param_data = {}
        self.param_data = dict(
            (k, v) for k, v in param_data.items() if k in resource.params)

        # Make sure we got everything
        missing = resource.params - set(self.param_data.keys())
        if missing:
            raise ValueError(
                _("Missing parameter data fields: %s") %
                ', '.join(repr(f) for f in sorted(missing)))

        # Build the canonical resource name
        self.name = '%s/%s' % (resource.service.name, resource.name)
        if self.param_data:
            param_items = [
                '%s=%r' % (k, v)
                for k, v in sorted(self.param_data.items(), key=lambda x: x[0])
            ]
            self.name += '/%s' % '/'.join(param_items)
Пример #7
0
    def __init__(self, resource, param_data=None):
        """
        Initialize a SpecificResource.

        :param resource: The Resource object.
        :param param_data: The parameter data relevant to this
                           resource.  May be omitted if no parameter
                           data is needed to uniquely identify the
                           resource.
        """

        self.resource = resource

        # Filter the parameter data
        if not param_data:
            param_data = {}
        self.param_data = dict((k, v) for k, v in param_data.items()
                               if k in resource.params)

        # Make sure we got everything
        missing = resource.params - set(self.param_data.keys())
        if missing:
            raise ValueError(_("Missing parameter data fields: %s") %
                             ', '.join(repr(f) for f in sorted(missing)))

        # Build the canonical resource name
        self.name = '%s/%s' % (resource.service.name, resource.name)
        if self.param_data:
            param_items = ['%s=%r' % (k, v) for k, v in
                           sorted(self.param_data.items(),
                                  key=lambda x: x[0])]
            self.name += '/%s' % '/'.join(param_items)
Пример #8
0
    def __init__(self, user, tenant, roles=None, request_id=None,
                 is_admin=None, **kwargs):
        """
        Initialize the context.

        :param user: The ID of the user making the request.
        :param tenant: The tenant ID of the user making the request.
        :param roles: A list of the roles for the user making the
                      request.
        :param request_id: The unique ID for the request.  This is
                           used solely for generating log messages, to
                           allow all phases of a request to be matched
                           up across multiple services.
        :param is_admin: A boolean flag indicating if the context
                         allows administrative access.  This allows
                         for temporary elevation in access privileges.

        All other keyword arguments are ignored
        """

        if kwargs:
            LOG.warning(_('Arguments dropped when creating context: %s') %
                        str(kwargs))

        self.user = user
        self.tenant = tenant
        self.roles = roles or []
        self.request_id = request_id or generate_request_id()
        if is_admin is None:
            is_admin = 'admin' in [r.lower() for r in self.roles]
        self.is_admin = is_admin
        self.session = None
Пример #9
0
    def __getattr__(self, name):
        """
        Retrieve the value of a given field (attribute syntax).
        """

        try:
            return self.__getitem__(name)
        except KeyError:
            # OK, don't know that attribute
            raise AttributeError(_('cannot get %r attribute') % name)
Пример #10
0
    def __getattr__(self, name):
        """
        Retrieve the value of a given field (attribute syntax).
        """

        try:
            return self.__getitem__(name)
        except KeyError:
            # OK, don't know that attribute
            raise AttributeError(_('cannot get %r attribute') % name)
Пример #11
0
    def __setattr__(self, name, value):
        """
        Set the value of a given field.
        """

        # Delegate internal attributes to regular setting
        if name[0] == '_':
            return super(BaseModel, self).__setattr__(name, value)

        try:
            return self.__setitem__(name, value)
        except KeyError:
            # Don't know that attribute
            raise AttributeError(_('cannot set %r attribute') % name)
Пример #12
0
def notify(context, message):
    """Sends a notification to the RabbitMQ"""
    if not context:
        context = req_context.get_admin_context()
    priority = message.get('priority',
                           CONF.default_notification_level)
    priority = priority.lower()
    for topic in CONF.notification_topics:
        topic = '%s.%s' % (topic, priority)
        try:
            rpc.notify(context, topic, message)
        except Exception, e:
            LOG.exception(_("Could not send notification to %(topic)s. "
                            "Payload=%(message)s"), locals())
Пример #13
0
    def __setattr__(self, name, value):
        """
        Set the value of a given field.
        """

        # Delegate internal attributes to regular setting
        if name[0] == '_':
            return super(BaseModel, self).__setattr__(name, value)

        try:
            return self.__setitem__(name, value)
        except KeyError:
            # Don't know that attribute
            raise AttributeError(_('cannot set %r attribute') % name)
Пример #14
0
def notify(context, message):
    """Sends a notification to the RabbitMQ"""
    if not context:
        context = req_context.get_admin_context()
    priority = message.get('priority', CONF.default_notification_level)
    priority = priority.lower()
    for topic in CONF.notification_topics:
        topic = '%s.%s' % (topic, priority)
        try:
            rpc.notify(context, topic, message)
        except Exception, e:
            LOG.exception(
                _("Could not send notification to %(topic)s. "
                  "Payload=%(message)s"), locals())
Пример #15
0
    def __init__(self, **kwargs):
        """
        Initialize a BosonException.
        """

        try:
            msg = self.message % kwargs
        except Exception as exc:
            # Missing a field; use the raw message and log an
            # exception
            msg = self.message
            LOG.exception(_("Exception formatting exception message: "
                            "message %(msg)r, kwargs %(kwargs)r") % locals())

        super(BosonException, self).__init__(msg)
Пример #16
0
def add_driver(notification_driver):
    """Add a notification driver at runtime."""
    # Make sure the driver list is initialized.
    _get_drivers()
    if isinstance(notification_driver, basestring):
        # Load and add
        try:
            driver = importutils.import_module(notification_driver)
            _drivers[notification_driver] = driver
        except ImportError as e:
            LOG.exception(_("Failed to load notifier %s. "
                            "These notifications will not be sent.") %
                          notification_driver)
    else:
        # Driver is already loaded; just add the object.
        _drivers[notification_driver] = notification_driver
Пример #17
0
def add_driver(notification_driver):
    """Add a notification driver at runtime."""
    # Make sure the driver list is initialized.
    _get_drivers()
    if isinstance(notification_driver, basestring):
        # Load and add
        try:
            driver = importutils.import_module(notification_driver)
            _drivers[notification_driver] = driver
        except ImportError as e:
            LOG.exception(
                _("Failed to load notifier %s. "
                  "These notifications will not be sent.") %
                notification_driver)
    else:
        # Driver is already loaded; just add the object.
        _drivers[notification_driver] = notification_driver
Пример #18
0
    def __init__(self, service, auth_data):
        """
        Initialize a ServiceUser.

        :param service: The Service object.
        :param auth_data: The authentication and authorization data
                          relevant to the user.
        """

        self.service = service

        # Filter the authentication/authorization data
        self.auth_data = dict((k, v) for k, v in auth_data.items()
                              if k in service.auth_fields)

        # Make sure we got everything
        missing = service.auth_fields - set(self.auth_data.keys())
        if missing:
            raise ValueError(_("Missing auth data fields: %s") %
                             ', '.join(repr(f) for f in sorted(missing)))
Пример #19
0
    def __init__(self, service, auth_data):
        """
        Initialize a ServiceUser.

        :param service: The Service object.
        :param auth_data: The authentication and authorization data
                          relevant to the user.
        """

        self.service = service

        # Filter the authentication/authorization data
        self.auth_data = dict(
            (k, v) for k, v in auth_data.items() if k in service.auth_fields)

        # Make sure we got everything
        missing = service.auth_fields - set(self.auth_data.keys())
        if missing:
            raise ValueError(
                _("Missing auth data fields: %s") %
                ', '.join(repr(f) for f in sorted(missing)))
Пример #20
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
Пример #21
0
class BosonException(Exception):
    """
    Base class for all Boson exceptions.
    """

    message = _("An unknown exception occurred")

    def __init__(self, **kwargs):
        """
        Initialize a BosonException.
        """

        try:
            msg = self.message % kwargs
        except Exception as exc:
            # Missing a field; use the raw message and log an
            # exception
            msg = self.message
            LOG.exception(_("Exception formatting exception message: "
                            "message %(msg)r, kwargs %(kwargs)r") % locals())

        super(BosonException, self).__init__(msg)
Пример #22
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()
Пример #23
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
Пример #24
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()
Пример #25
0
    def __init__(self,
                 user,
                 tenant,
                 roles=None,
                 request_id=None,
                 is_admin=None,
                 **kwargs):
        """
        Initialize the context.

        :param user: The ID of the user making the request.
        :param tenant: The tenant ID of the user making the request.
        :param roles: A list of the roles for the user making the
                      request.
        :param request_id: The unique ID for the request.  This is
                           used solely for generating log messages, to
                           allow all phases of a request to be matched
                           up across multiple services.
        :param is_admin: A boolean flag indicating if the context
                         allows administrative access.  This allows
                         for temporary elevation in access privileges.

        All other keyword arguments are ignored
        """

        if kwargs:
            LOG.warning(
                _('Arguments dropped when creating context: %s') % str(kwargs))

        self.user = user
        self.tenant = tenant
        self.roles = roles or []
        self.request_id = request_id or generate_request_id()
        if is_admin is None:
            is_admin = 'admin' in [r.lower() for r in self.roles]
        self.is_admin = is_admin
        self.session = None
Пример #26
0
class Duplicate(BosonException):
    message = _("Duplicate object for %(klass)s")
Пример #27
0
    def __delattr__(self, name):
        """
        Prohibit deletion of fields.
        """

        raise AttributeError(_('cannot delete %r attribute') % name)
Пример #28
0
    def __delattr__(self, name):
        """
        Prohibit deletion of fields.
        """

        raise AttributeError(_('cannot delete %r attribute') % name)
Пример #29
0
    def hints_parser(self, model, hints):
        """
        Utility method to parse hints fields.

        :param model: The starting model, from ``db.models``.
        :param hints: A list of hints indicating which attributes of
                      the model will be required by the calling code.
                      Only those attributes which reference other
                      fields need be listed, although it is not an
                      error to list other fields.  It is also
                      permissible to indicate deeper levels of access
                      by separating attributes with periods.  (In the
                      case of reference fields which are represented
                      as lists, there is no need to use square
                      brackets.)
        """

        # Were any hints even given?
        if not hints:
            return {}

        # The fields dictionary maps the direct fields and the
        # corresponding models; the subhints dictionary will be used
        # to recurse later on
        fields = {}
        subhints = {}

        for hint in hints:
            field, _sep, subfield = hint.partition('.')

            # Look up the field in the model
            if field not in model._refs:
                model_name = model.__name__
                if field not in model._fields:
                    LOG.warning(
                        _("Hint for undefined field %(field)r "
                          "of model %(model_name)s") % locals())
                else:
                    LOG.notice(
                        _("Unnecessary hint %(field)r "
                          "for model %(model_name)s") % locals())
                continue

            # Have we handled this field before?
            if field not in fields:
                # Get the model it refers to
                ref_model = model._refs[field].klass

                # Save that to fields...
                fields[field] = ref_model

            # Also save the subhints
            if subfield:
                subhints.setdefault(field, set())
                subhints[field].add(subfield)

        # Now we can build and return the result dictionary tree
        results = {}
        for field, sub_model in fields.items():
            sub_results = self.hint_parser(sub_model, subhints.get(field))

            results[field] = (sub_model, sub_results)

        return results
Пример #30
0
class AmbiguousFieldUpdate(BosonException):
    message = _("Ambiguous update of field %(field)r")