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()
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
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())
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())
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)
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)
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
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)
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)
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())
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())
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)
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
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
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)))
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)))
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
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)
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()
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
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
class Duplicate(BosonException): message = _("Duplicate object for %(klass)s")
def __delattr__(self, name): """ Prohibit deletion of fields. """ raise AttributeError(_('cannot delete %r attribute') % name)
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
class AmbiguousFieldUpdate(BosonException): message = _("Ambiguous update of field %(field)r")