def deprecated(self, msg, *args, **kwargs): """Call this method when a deprecated feature is used. If the system is configured for fatal deprecations then the message is logged at the 'critical' level and :class:`DeprecatedConfig` will be raised. Otherwise, the message will be logged (once) at the 'warn' level. :raises: :class:`DeprecatedConfig` if the system is configured for fatal deprecations. """ stdmsg = _("Deprecated: %s") % msg if CONF.fatal_deprecations: self.critical(stdmsg, *args, **kwargs) raise DeprecatedConfig(msg=stdmsg) # Using a list because a tuple with dict can't be stored in a set. sent_args = self._deprecated_messages_sent.setdefault(msg, list()) if args in sent_args: # Already logged this message, so don't log it again. return sent_args.append(args) self.warn(stdmsg, *args, **kwargs)
def acquire(self): basedir = os.path.dirname(self.fname) if not os.path.exists(basedir): fileutils.ensure_tree(basedir) LOG.info(_LI('Created lock path: %s'), basedir) self.lockfile = open(self.fname, 'w') while True: try: # Using non-blocking locks since green threads are not # patched to deal with blocking locking calls. # Also upon reading the MSDN docs for locking(), it seems # to have a laughable 10 attempts "blocking" mechanism. self.trylock() LOG.debug('Got file lock "%s"', self.fname) return True except IOError as e: if e.errno in (errno.EACCES, errno.EAGAIN): # external locks synchronise things like iptables # updates - give it some time to prevent busy spinning time.sleep(0.01) else: raise threading.ThreadError(_("Unable to acquire lock on" " `%(filename)s` due to" " %(exception)s") % { 'filename': self.fname, 'exception': e, })
def __call__(self, req): # Determine the user ID user_id = req.headers.get('X_USER_ID') if not user_id: LOG.debug(_("X_USER_ID is not found in request")) return webob.exc.HTTPUnauthorized() # Determine the tenant tenant_id = req.headers.get('X_PROJECT_ID') # Suck out the roles roles = [r.strip() for r in req.headers.get('X_ROLES', '').split(',')] # Human-friendly names tenant_name = req.headers.get('X_PROJECT_NAME') user_name = req.headers.get('X_USER_NAME') # Use request_id if already set req_id = req.environ.get(request_id.ENV_REQUEST_ID) # Create a context with the authentication data ctx = context.RequestContext(user_id, tenant_id, roles=roles, user_name=user_name, tenant_name=tenant_name, request_id=req_id) # Inject the context... req.environ['congress.context'] = ctx return self.application
def __init__(self, message=None, **kwargs): self.kwargs = kwargs if 'code' not in self.kwargs: try: self.kwargs['code'] = self.code except AttributeError: pass if not message: try: message = self.msg_fmt % kwargs except Exception: exc_info = sys.exc_info() # kwargs doesn't match a variable in the message # log the issue and the kwargs LOG.exception(_('Exception in string format operation')) for name, value in kwargs.iteritems(): LOG.error("%s: %s" % (name, value)) # noqa if CONF.fatal_exception_format_errors: raise exc_info[0], exc_info[1], exc_info[2] else: # at least get the core message out if something happened message = self.msg_fmt super(CongressException, self).__init__(message)
def bool_from_string(subject, strict=False, default=False): """Interpret a string as a boolean. A case-insensitive match is performed such that strings matching 't', 'true', 'on', 'y', 'yes', or '1' are considered True and, when `strict=False`, anything else returns the value specified by 'default'. Useful for JSON-decoded stuff and config file parsing. If `strict=True`, unrecognized values, including None, will raise a ValueError which is useful when parsing values passed in from an API call. Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'. """ if not isinstance(subject, six.string_types): subject = six.text_type(subject) lowered = subject.strip().lower() if lowered in TRUE_STRINGS: return True elif lowered in FALSE_STRINGS: return False elif strict: acceptable = ', '.join( "'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS)) msg = _("Unrecognized value '%(val)s', acceptable values are:" " %(acceptable)s") % {'val': subject, 'acceptable': acceptable} raise ValueError(msg) else: return default
def __call__(self, request): try: handler = self.resource_mgr.get_handler(request) if handler: msg = _("Handling request '%(meth)s %(path)s' with %(hndlr)s") LOG.debug(msg % {"meth": request.method, "path": request.path, "hndlr": str(handler)}) response = handler.handle_request(request) else: response = NOT_SUPPORTED_RESPONSE except Exception as e: msg = _("Exception caught for request: %s") LOG.error(msg % (request)) LOG.error(traceback.format_exc(e)) response = INTERNAL_ERROR_RESPONSE return response
def read(self, i=None): result = self.data.read(i) self.bytes_read += len(result) if self.bytes_read > self.limit: msg = _("Request is too large.") raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) return result
def __call__(self, environ, start_response): r"""Subclasses will probably want to implement __call__ like this: @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): # Any of the following objects work as responses: # Option 1: simple string res = 'message\n' # Option 2: a nicely formatted HTTP exception page res = exc.HTTPForbidden(explanation='Nice try') # Option 3: a webob Response object (in case you need to play with # headers, or you want to be treated like an iterable, or or or) res = Response(); res.app_iter = open('somefile') # Option 4: any wsgi app to be run next res = self.application # Option 5: you can get a Response object for a wsgi app, too, to # play with headers etc res = req.get_response(self.application) # You can then just return your response... return res # ... or set req.response and return None. req.response = res See the end of http://pythonpaste.org/webob/modules/dec.html for more info. """ raise NotImplementedError(_('You must implement __call__'))
def listen(self, key=None, backlog=128): """Create and start listening on socket. Call before forking worker processes. Raises Exception if this has already been called. """ if self.socket is not None: raise Exception(_("Server can only listen once.")) LOG.info( _("Starting %(arg0)s on %(host)s:%(port)s"), {"arg0": sys.argv[0], "host": self.host, "port": self.port} ) # 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(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM)[0] _socket = eventlet.listen(info[-1], family=info[0], backlog=backlog) if key: self.socket_info[key] = _socket.getsockname() # SSL is enabled if self.do_ssl: if self.cert_required: cert_reqs = ssl.CERT_REQUIRED else: cert_reqs = ssl.CERT_NONE sslsocket = eventlet.wrap_ssl( _socket, certfile=self.certfile, keyfile=self.keyfile, server_side=True, cert_reqs=cert_reqs, ca_certs=self.ca_certs, ) _socket = sslsocket # Optionally enable keepalive on the wsgi socket. if self.keepalive: _socket.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") and self.keepidle is not None: _socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, self.keepidle) self.socket = _socket
def __iter__(self): for chunk in self.data: self.bytes_read += len(chunk) if self.bytes_read > self.limit: msg = _("Request is too large.") raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) else: yield chunk
def find_paste_config(): config_path = cfg.CONF.find_file(cfg.CONF.api_paste_config) if not config_path: raise cfg.ConfigFilesNotFoundError( config_files=[cfg.CONF.api_paste_config]) config_path = os.path.abspath(config_path) LOG.info(_("Config paste file: %s"), config_path) return config_path
def string_to_bytes(text, unit_system='IEC', return_int=False): """Converts a string into an float representation of bytes. The units supported for IEC :: Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it) KB, KiB, MB, MiB, GB, GiB, TB, TiB The units supported for SI :: kb(it), Mb(it), Gb(it), Tb(it) kB, MB, GB, TB Note that the SI unit system does not support capital letter 'K' :param text: String input for bytes size conversion. :param unit_system: Unit system for byte size conversion. :param return_int: If True, returns integer representation of text in bytes. (default: decimal) :returns: Numerical representation of text in bytes. :raises ValueError: If text has an invalid value. """ try: base, reg_ex = UNIT_SYSTEM_INFO[unit_system] except KeyError: msg = _('Invalid unit system: "%s"') % unit_system raise ValueError(msg) match = reg_ex.match(text) if match: magnitude = float(match.group(1)) unit_prefix = match.group(2) if match.group(3) in ['b', 'bit']: magnitude /= 8 else: msg = _('Invalid string format: %s') % text raise ValueError(msg) if not unit_prefix: res = magnitude else: res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix]) if return_int: return int(math.ceil(res)) return res
def __call__(self, req): if (req.content_length is not None and req.content_length > CONF.max_request_body_size): msg = _("Request is too large.") raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) if req.content_length is None and req.is_body_readable: limiter = LimitingReader(req.body_file, CONF.max_request_body_size) req.body_file = limiter return self.application
def __call__(self, request): try: handler = self.resource_mgr.get_handler(request) if handler: msg = _("Handling request '%(meth)s %(path)s' with %(hndlr)s") LOG.debug(msg % {"meth": request.method, "path": request.path, "hndlr": str(handler)}) #TODO(pballand): validation response = handler.handle_request(request) else: response = NOT_FOUND_RESPONSE except DataModelException as e: # Error raised based on invalid user input return e.rest_response() except Exception as e: # Unexpected error raised by API framework or data model msg = _("Exception caught for request: %s") LOG.error(msg % (request)) LOG.error(traceback.format_exc(e)) response = INTERNAL_ERROR_RESPONSE return response
def tempdir(**kwargs): argdict = kwargs.copy() if 'dir' not in argdict: argdict['dir'] = CONF.tempdir tmpdir = tempfile.mkdtemp(**argdict) try: yield tmpdir finally: try: shutil.rmtree(tmpdir) except OSError as e: LOG.error(_('Could not remove tmpdir: %s'), str(e))
def _run(self, application, socket): """Start a WSGI server in a new green thread.""" logger = log.getLogger("eventlet.wsgi.server") try: eventlet.wsgi.server( socket, application, custom_pool=self.pool, log=EventletFilteringLogger(logger), debug=False ) except greenlet.GreenletExit: # Wait until all servers have completed running pass except Exception: LOG.exception(_("Server error")) raise
def register_handler(self, handler, search_index=None): """Register a new resource handler. Args: handler: The resource handler to register. search_index: Priority of resource handler to resolve cases where a request matches multiple handlers. """ if search_index is not None: self.handlers.insert(search_index, handler) else: self.handlers.append(handler) msg = _("Registered API handler: %s") % (handler) LOG.info(msg)
def set_rules(self, rules, overwrite=True, use_conf=False): """Create a new Rules object based on the provided dict of rules. :param rules: New rules to use. It should be an instance of dict. :param overwrite: Whether to overwrite current rules or update them with the new rules. :param use_conf: Whether to reload rules from cache or config file. """ if not isinstance(rules, dict): raise TypeError(_("Rules must be an instance of dict or Rules, " "got %s instead") % type(rules)) self.use_conf = use_conf if overwrite: self.rules = Rules(rules, self.default_rule) else: self.rules.update(rules)
def serve(*servers): if max([server[1].workers for server in servers]) > 1: #TODO(arosen) - need to provide way to communicate with DSE services launcher = service.ProcessLauncher() else: launcher = service.ServiceLauncher() for name, server in servers: try: server.launch_with(launcher) except socket.error: LOG.exception(_('Failed to start the %(name)s server') % { 'name': name}) raise # notify calling process we are ready to serve systemd.notify_once() for name, server in servers: launcher.wait()
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
cfg.IntOpt('tcp_keepidle', default=600, help='Sets the value of TCP_KEEPIDLE in seconds for each ' 'server socket. Only applies if tcp_keepalive is ' 'true. Not supported on OS X.'), cfg.StrOpt('policy_path', default=None, help="The path to the latest policy dump"), cfg.StrOpt('datasource_file', default=None, help="The file containing datasource configuration"), cfg.StrOpt('root_path', default=None, help="The absolute path to the congress repo"), cfg.IntOpt('api_workers', default=1, help='The number of worker processes to serve the congress ' 'API application.'), cfg.StrOpt('api_paste_config', default="api-paste.ini", help=_("The API paste config file to use")), cfg.StrOpt('auth_strategy', default='keystone', help=_("The type of authentication to use")), ] # Register the configuration options cfg.CONF.register_opts(core_opts) def init(args, **kwargs): cfg.CONF(args=args, project='congress', **kwargs) def setup_logging(): """Sets up logging for the congress package.""" logging.setup('congress')
from oslo.config import cfg import six import six.moves.urllib.parse as urlparse import six.moves.urllib.request as urlrequest from congress.openstack.common import fileutils from congress.openstack.common.gettextutils import _, _LE from congress.openstack.common import jsonutils from congress.openstack.common import log as logging policy_opts = [ cfg.StrOpt('policy_file', default='policy.json', help=_('The JSON file that defines policies.')), cfg.StrOpt('policy_default_rule', default='default', help=_('Default rule. Enforced when a requested rule is not ' 'found.')), ] CONF = cfg.CONF CONF.register_opts(policy_opts) LOG = logging.getLogger(__name__) _checks = {} class PolicyNotAuthorized(Exception):
def __init__(self, rule): msg = _("Policy doesn't allow %s to be performed.") % rule super(PolicyNotAuthorized, self).__init__(msg)