def validate_sort_dir(sort_dir): if sort_dir not in ['asc', 'desc']: raise wsme.exc.ClientSideError( _("Invalid sort direction: %s. " "Acceptable values are " "'asc' or 'desc'") % sort_dir) return sort_dir
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)
class CloudpulseException(Exception): """Base Cloudpulse Exception To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") code = 500 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 message: self.message = message try: self.message = self.message % kwargs except Exception as e: # kwargs doesn't match a variable in the message # log the issue and the kwargs LOG.exception(_LE('Exception in string format operation')) for name, value in kwargs.iteritems(): LOG.error( _LE("%(name)s: %(value)s") % { 'name': name, 'value': value }) try: if CONF.fatal_exception_format_errors: raise e except cfg.NoSuchOptError: # Note: work around for Bug: #1447873 if CONF.oslo_versionedobjects.fatal_exception_format_errors: raise e super(CloudpulseException, self).__init__(self.message) def __str__(self): if six.PY3: return self.message return self.message.encode('utf-8') def __unicode__(self): return self.message def format_message(self): cls_name = reflection.get_class_name(self, fully_qualified=False) if cls_name.endswith('_Remote'): return self.args[0] else: return six.text_type(self)
def validate(patch): if patch.path in patch.internal_attrs(): msg = _("'%s' is an internal attribute and can not be updated") raise wsme.exc.ClientSideError(msg % patch.path) if patch.path in patch.mandatory_attrs() and patch.op == 'remove': msg = _("'%s' is a mandatory attribute and can not be removed") raise wsme.exc.ClientSideError(msg % patch.path) if patch.op != 'remove': if not patch.value: msg = _("'add' and 'replace' operations needs value") raise wsme.exc.ClientSideError(msg) ret = {'path': patch.path, 'op': patch.op} if patch.value: ret['value'] = patch.value return ret
def validate(self, value): for t in self.types: try: return wtypes.validate_value(t, value) except (exception.InvalidUUID, ValueError): pass else: raise ValueError(_("Expected '%(type)s', got '%(value)s'") % {'type': self.types, 'value': type(value)})
class LogConfigError(Exception): message = _('Error loading logging config %(log_config)s: %(err_msg)s') def __init__(self, log_config, err_msg): self.log_config = log_config self.err_msg = err_msg def __str__(self): return self.message % dict(log_config=self.log_config, err_msg=self.err_msg)
def validate(self, value): for t in self.types: try: return wtypes.validate_value(t, value) except (exception.InvalidUUID, ValueError): pass else: raise ValueError( _("Expected '%(type)s', got '%(value)s'") % { 'type': self.types, 'value': type(value) })
def datetime_or_none(dt): """Validate a datetime or None value.""" if dt is None: return None elif isinstance(dt, datetime.datetime): if dt.utcoffset() is None: # NOTE(danms): Legacy objects from sqlalchemy are stored in UTC, # but are returned without a timezone attached. # As a transitional aid, assume a tz-naive object is in UTC. return dt.replace(tzinfo=iso8601.iso8601.Utc()) else: return dt raise ValueError(_("A datetime.datetime is required here"))
def __init__(self, app, conf, public_api_routes=[]): route_pattern_tpl = '%s(\.json|\.xml)?$' try: self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl) for route_tpl in public_api_routes] except re.error as e: msg = _('Cannot compile public API routes: %s') % e LOG.error(msg) raise exception.ConfigInvalid(error_msg=msg) super(AuthTokenMiddleware, self).__init__(app, conf)
def __init__(self, app, conf, public_api_routes=[]): route_pattern_tpl = '%s(\.json|\.xml)?$' try: self.public_api_routes = [ re.compile(route_pattern_tpl % route_tpl) for route_tpl in public_api_routes ] except re.error as e: msg = _('Cannot compile public API routes: %s') % e LOG.error(msg) raise exception.ConfigInvalid(error_msg=msg) super(AuthTokenMiddleware, self).__init__(app, conf)
def print_list(objs, fields, formatters=None, sortby_index=0, mixed_case_fields=None, field_labels=None): """Print a list or objects as a table, one row per object. :param objs: iterable of :class:`Resource` :param fields: attributes that correspond to columns, in order :param formatters: `dict` of callables for field formatting :param sortby_index: index of the field for sorting table rows :param mixed_case_fields: fields corresponding to object attributes that have mixed case names (e.g., 'serverId') :param field_labels: Labels to use in the heading of the table, default to fields. """ formatters = formatters or {} mixed_case_fields = mixed_case_fields or [] field_labels = field_labels or fields if len(field_labels) != len(fields): raise ValueError(_("Field labels list %(labels)s has different number " "of elements than fields list %(fields)s"), {'labels': field_labels, 'fields': fields}) if sortby_index is None: kwargs = {} else: kwargs = {'sortby': field_labels[sortby_index]} pt = prettytable.PrettyTable(field_labels) pt.align = 'l' for o in objs: row = [] for field in fields: if field in formatters: row.append(formatters[field](o)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, '') row.append(data) pt.add_row(row) if six.PY3: print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode()) else: print(encodeutils.safe_encode(pt.get_string(**kwargs)))
def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable.""" try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception( _('ErrorDocumentMiddleware received an invalid ' 'status %s') % status) else: if (state['status_code'] // 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type')] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info)
def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable.""" try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception(_( 'ErrorDocumentMiddleware received an invalid ' 'status %s') % status) else: if (state['status_code'] // 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type') ] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info)
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 ssh_connect(connection): """Method to connect to a remote system using ssh protocol. :param connection: a dict of connection parameters. :returns: paramiko.SSHClient -- an active ssh connection. :raises: SSHConnectFailed """ try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) key_contents = connection.get('key_contents') if key_contents: data = six.moves.StringIO(key_contents) if "BEGIN RSA PRIVATE" in key_contents: pkey = paramiko.RSAKey.from_private_key(data) elif "BEGIN DSA PRIVATE" in key_contents: pkey = paramiko.DSSKey.from_private_key(data) else: # Can't include the key contents - secure material. raise ValueError(_("Invalid private key")) else: pkey = None ssh.connect(connection.get('host'), username=connection.get('username'), password=connection.get('password'), port=connection.get('port', 22), pkey=pkey, key_filename=connection.get('key_filename'), timeout=connection.get('timeout', 10)) # send TCP keepalive packets every 20 seconds ssh.get_transport().set_keepalive(20) except Exception as e: LOG.debug("SSH connect failed: %s" % e) raise exception.SSHConnectFailed(host=connection.get('host')) return ssh
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 SSHConnectFailed(CloudpulseException): message = _("Failed to establish SSH connection to host %(host)s.")
def validator(val, objclass=objclass): if val is None or isinstance(val, objclass): return val raise ValueError(_("An object of class %s is required here") % objclass)
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_config import cfg from cloudpulse.common import cloudpulse_keystoneclient from cloudpulse.openstack.common._i18n import _ heat_client_opts = [ cfg.StrOpt('region_name', default=None, help=_('Region in Identity service catalog to use for ' 'communication with the OpenStack service.')), cfg.StrOpt('endpoint_type', default='publicURL', help=_( 'Type of endpoint in Identity service catalog to use ' 'for communication with the OpenStack service.')), cfg.StrOpt('ca_file', help=_('Optional CA cert file to use in SSL connections.')), cfg.StrOpt('cert_file', help=_('Optional PEM-formatted certificate chain file.')), cfg.StrOpt('key_file', help=_('Optional PEM-formatted file that contains the ' 'private key.')), cfg.BoolOpt('insecure', default=False, help=_("If set, then the server's certificate will not "
class TestLocked(CloudpulseException): message = _("A process has already locked the database for update")
def update_test(self, test_id, values): if 'uuid' in values: msg = _("Cannot overwrite UUID for an existing test.") raise exception.InvalidParameterValue(err=msg) return self._do_update_test(test_id, values)
def __init__(self, missing): self.missing = missing msg = _("Missing arguments: %s") % ", ".join(missing) super(MissingArgs, self).__init__(msg)
def validate_sort_dir(sort_dir): if sort_dir not in ['asc', 'desc']: raise wsme.exc.ClientSideError(_("Invalid sort direction: %s. " "Acceptable values are " "'asc' or 'desc'") % sort_dir) return sort_dir
class TestAlreadyExists(Conflict): message = _("A test with UUID %(uuid)s already exists.")
class TestInvalid(Invalid): message = _("The test name %(test)s is invalid")
class NotSupported(CloudpulseException): message = _("%(operation)s is not supported.") code = 400
from oslo_utils import importutils from cloudpulse.common import context as cloudpulse_context from cloudpulse.common import exception from cloudpulse.openstack.common._i18n import _ from cloudpulse.openstack.common._i18n import _LE from cloudpulse.openstack.common._i18n import _LI from cloudpulse.openstack.common import log as logging LOG = logging.getLogger(__name__) topts = [ cfg.ListOpt( "trusts_delegated_roles", default=["cloudpulse_assembly_update"], help=_("Subset of roles to be delegated to cloudpulse."), ) ] cfg.CONF.register_opts(topts) cfg.CONF.import_opt("auth_uri", "keystonemiddleware.auth_token", group="keystone_authtoken") class KeystoneClientV3(object): """Keystone client wrapper so we can encapsulate logic in one place.""" def __init__(self, context): # If a trust_id is specified in the context, we immediately # authenticate so we can populate the context with a trust token # otherwise, we delay client authentication until needed to avoid # unnecessary calls to keystone. #
temp_type = event_type if not temp_type: # If f has multiple decorators, they must use # functools.wraps to ensure the name is # propagated. temp_type = f.__name__ notifier.notify(context, publisher_id, temp_type, temp_level, payload) return functools.wraps(f)(wrapped) return inner OBFUSCATED_MSG = _('Your request could not be handled ' 'because of a problem in the server. ' 'Error Correlation id is: %s') def wrap_controller_exception(func, func_server_error, func_client_error): """This decorator wraps controllers methods to handle exceptions: - if an unhandled Exception or a CloudpulseException with an error code >=500 is catched, raise a http 5xx ClientSideError and correlates it with a log message - if a CloudpulseException is catched and its error code is <500, raise a http 4xx and logs the excp in debug mode """ @functools.wraps(func) def wrapped(*args, **kw): try:
class RequiredParameterNotProvided(CloudpulseException): message = _("Required parameter %(heat_param)s not provided.")
from oslo_config import cfg from oslo_utils import importutils from cloudpulse.common import context as cloudpulse_context from cloudpulse.common import exception from cloudpulse.openstack.common._i18n import _ from cloudpulse.openstack.common._i18n import _LE from cloudpulse.openstack.common._i18n import _LI from cloudpulse.openstack.common import log as logging LOG = logging.getLogger(__name__) trust_opts = [ cfg.ListOpt('trusts_delegated_roles', default=['cloudpulse_assembly_update'], help=_('Subset of roles to be delegated to cloudpulse.')), ] cfg.CONF.register_opts(trust_opts) cfg.CONF.import_opt('auth_uri', 'keystonemiddleware.auth_token', group='keystone_authtoken') class KeystoneClientV3(object): """Keystone client wrapper so we can encapsulate logic in one place.""" def __init__(self, context): # If a trust_id is specified in the context, we immediately # authenticate so we can populate the context with a trust token # otherwise, we delay client authentication until needed to avoid # unnecessary calls to keystone. #
def validate_limit(limit): if limit is not None and limit <= 0: raise wsme.exc.ClientSideError(_("Limit must be positive")) return min(CONF.api.max_limit, limit) or CONF.api.max_limit
class ImageNotFound(ResourceNotFound): message = _("Image %(image_id)s could not be found.")
class OperationInProgress(Invalid): message = _("Test %(test_name)s already has an operation in progress.")
from oslo_config import cfg from oslo_utils import importutils from cloudpulse.common import context as cloudpulse_context from cloudpulse.common import exception from cloudpulse.openstack.common._i18n import _ from cloudpulse.openstack.common._i18n import _LE from cloudpulse.openstack.common._i18n import _LI from cloudpulse.openstack.common import log as logging LOG = logging.getLogger(__name__) topts = [ cfg.ListOpt('trusts_delegated_roles', default=['cloudpulse_assembly_update'], help=_('Subset of roles to be delegated to cloudpulse.')), ] cfg.CONF.register_opts(topts) cfg.CONF.import_opt('auth_uri', 'keystonemiddleware.auth_token', group='keystone_authtoken') class KeystoneClientV3(object): """Keystone client wrapper so we can encapsulate logic in one place.""" def __init__(self, context): # If a trust_id is specified in the context, we immediately # authenticate so we can populate the context with a trust token # otherwise, we delay client authentication until needed to avoid # unnecessary calls to keystone. #
class TestNotFound(ResourceNotFound): message = _("Test %(test)s could not be found.")
class InvalidPeriodicTaskArg(Exception): message = _("Unexpected argument for periodic task creation: %(arg)s.")
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_config import cfg from cloudpulse.common import cloudpulse_keystoneclient from cloudpulse.openstack.common._i18n import _ from cloudpulse.openstack.common import log as logging LOG = logging.getLogger(__name__) heat_client_opts = [ cfg.StrOpt('region_name', default=None, help=_('Region in Identity service catalog to use for ' 'communication with the OpenStack service.')), cfg.StrOpt('endpoint_type', default='publicURL', help=_('Type of endpoint in Identity service catalog to use ' 'for communication with the OpenStack service.')), cfg.StrOpt('ca_file', help=_('Optional CA cert file to use in SSL connections.')), cfg.StrOpt('cert_file', help=_('Optional PEM-formatted certificate chain file.')), cfg.StrOpt('key_file', help=_('Optional PEM-formatted file that contains the ' 'private key.')), cfg.BoolOpt('insecure', default=False, help=_("If set, then the server's certificate will not " "be verified."))
class Urllib2InvalidScheme(CloudpulseException): message = _("The urllib2 URL %(url) has an invalid scheme.")
class DeprecatedConfig(Exception): message = _("Fatal call to deprecated config: %(msg)s") def __init__(self, msg): super(Exception, self).__init__(self.message % dict(msg=msg))
temp_type = event_type if not temp_type: # If f has multiple decorators, they must use # functools.wraps to ensure the name is # propagated. temp_type = f.__name__ notifier.notify(context, publisher_id, temp_type, temp_level, payload) return functools.wraps(f)(wrapped) return inner OBFUSCATED_MSG = _( "Your request could not be handled " "because of a problem in the server. " "Error Correlation id is: %s" ) def wrap_controller_exception(func, func_server_error, func_client_error): """This decorator wraps controllers methods to handle exceptions: - if an unhandled Exception or a CloudpulseException with an error code >=500 is catched, raise a http 5xx ClientSideError and correlates it with a log message - if a CloudpulseException is catched and its error code is <500, raise a http 4xx and logs the excp in debug mode """ @functools.wraps(func) def wrapped(*args, **kw):