Ejemplo n.º 1
0
def parse(manifest_str):
    '''Takes a string and returns a dict containing the parsed structure.
    This includes determination of whether the string is using the
    JSON or YAML format.
    '''
    if not manifest_str:
        msg = _("'manifest' can't be empty")
        raise ValueError(msg)
    if manifest_str.startswith('{'):
        manifest = json.loads(manifest_str)
    else:
        try:
            manifest = yaml.load(manifest_str, Loader=yaml_loader)
        except yaml.YAMLError as yea:
            yea = six.text_type(yea)
            msg = _('Error parsing manifest: %s') % yea
            raise ValueError(msg)
        else:
            if manifest is None:
                manifest = {}

    if not isinstance(manifest, dict):
        raise ValueError(
            _('The manifest is not a JSON object '
              'or YAML mapping.'))
    # TODO(yuanying): check manifest version
    return manifest
Ejemplo n.º 2
0
def parse(manifest_str):
    '''Takes a string and returns a dict containing the parsed structure.
    This includes determination of whether the string is using the
    JSON or YAML format.
    '''
    if not manifest_str:
        msg = _("'manifest' can't be empty")
        raise ValueError(msg)
    if manifest_str.startswith('{'):
        manifest = json.loads(manifest_str)
    else:
        try:
            manifest = yaml.load(manifest_str, Loader=yaml_loader)
        except yaml.YAMLError as yea:
            yea = six.text_type(yea)
            msg = _('Error parsing manifest: %s') % yea
            raise ValueError(msg)
        else:
            if manifest is None:
                manifest = {}

    if not isinstance(manifest, dict):
        raise ValueError(_('The manifest is not a JSON object '
                           'or YAML mapping.'))
    # TODO(yuanying): check manifest version
    return manifest
Ejemplo n.º 3
0
    def _v3_client_init(self):
        kwargs = {
            'auth_url': self.v3_endpoint,
            'endpoint': self.v3_endpoint
        }
        # Note try trust_id first, as we can't reuse auth_token in that case
        if self.context.trust_id is not None:
            # We got a trust_id, so we use the admin credentials
            # to authenticate with the trust_id so we can use the
            # trust impersonating the trustor user.
            kwargs.update(self._service_admin_creds())
            kwargs['trust_id'] = self.context.trust_id
            kwargs.pop('project_name')
        elif self.context.auth_token_info is not None:
            # The auth_ref version must be set according to the token version
            if 'access' in self.context.auth_token_info:
                kwargs['auth_ref'] = copy.deepcopy(
                    self.context.auth_token_info['access'])
                kwargs['auth_ref']['version'] = 'v2.0'
                kwargs['auth_ref']['token']['id'] = self.context.auth_token
            elif 'token' in self.context.auth_token_info:
                kwargs['auth_ref'] = copy.deepcopy(
                    self.context.auth_token_info['token'])
                kwargs['auth_ref']['version'] = 'v3'
                kwargs['auth_ref']['auth_token'] = self.context.auth_token
            else:
                LOG.error("Unknown version in auth_token_info")
                raise exception.AuthorizationFailure()
        elif self.context.auth_token is not None:
            kwargs['token'] = self.context.auth_token
            kwargs['project_id'] = self.context.tenant
        else:
            LOG.error(_("Keystone v3 API connection failed, no password "
                        "trust or auth_token!"))
            raise exception.AuthorizationFailure()
        client = kc_v3.Client(**kwargs)
        if 'auth_ref' not in kwargs:
            client.authenticate()
        # If we are authenticating with a trust set the context auth_token
        # with the trust scoped token
        if 'trust_id' in kwargs:
            # Sanity check
            if not client.auth_ref.trust_scoped:
                LOG.error(_("trust token re-scoping failed!"))
                raise exception.AuthorizationFailure()
            # All OK so update the context with the token
            self.context.auth_token = client.auth_ref.auth_token
            self.context.auth_url = self.v3_endpoint
            self.context.user = client.auth_ref.user_id
            self.context.tenant = client.auth_ref.project_id
            self.context.user_name = client.auth_ref.username

        return client
Ejemplo n.º 4
0
    def update_service(self, service_id, values):
        # NOTE(dtantsur): this can lead to very strange errors
        if 'uuid' in values:
            msg = _("Cannot overwrite UUID for an existing Service.")
            raise exception.InvalidParameterValue(err=msg)

        return self._do_update_service(service_id, values)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    def update_service(self, service_id, values):
        # NOTE(dtantsur): this can lead to very strange errors
        if 'uuid' in values:
            msg = _("Cannot overwrite UUID for an existing Service.")
            raise exception.InvalidParameterValue(err=msg)

        return self._do_update_service(service_id, values)
Ejemplo n.º 7
0
def report_deprecated_feature(logger, msg, *args, **kwargs):
    """Call this function 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
    CONF.register_opts(deprecated_opts)
    if CONF.fatal_deprecations:
        logger.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 = _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)
    logger.warn(stdmsg, *args, **kwargs)
Ejemplo n.º 8
0
    def save(self, context):
        """Save the changed fields back to the store.

        This is optional for subclasses, but is presented here in the base
        class for consistency among those that do.
        """
        raise NotImplementedError(_("Cannot save anything in the base class"))
Ejemplo n.º 9
0
    def save(self, context):
        """Save the changed fields back to the store.

        This is optional for subclasses, but is presented here in the base
        class for consistency among those that do.
        """
        raise NotImplementedError(_("Cannot save anything in the base class"))
Ejemplo n.º 10
0
def report_deprecated_feature(logger, msg, *args, **kwargs):
    """Call this function 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
    CONF.register_opts(deprecated_opts)
    if CONF.fatal_deprecations:
        logger.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 = _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)
    logger.warn(stdmsg, *args, **kwargs)
Ejemplo n.º 11
0
def apply_jsonpatch(doc, patch):
    for p in patch:
        if p['op'] == 'add' and p['path'].count('/') == 1:
            if p['path'].lstrip('/') not in doc:
                msg = _('Adding a new attribute (%s) to the root of '
                        ' the resource is not allowed')
                raise wsme.exc.ClientSideError(msg % p['path'])
    return jsonpatch.apply_patch(doc, jsonpatch.JsonPatch(patch))
Ejemplo n.º 12
0
def apply_jsonpatch(doc, patch):
    for p in patch:
        if p['op'] == 'add' and p['path'].count('/') == 1:
            if p['path'].lstrip('/') not in doc:
                msg = _('Adding a new attribute (%s) to the root of '
                        ' the resource is not allowed')
                raise wsme.exc.ClientSideError(msg % p['path'])
    return jsonpatch.apply_patch(doc, jsonpatch.JsonPatch(patch))
Ejemplo n.º 13
0
    def obj_load_attr(self, attrname):
        """Load an additional attribute from the real object.

        This should use self._conductor, and cache any data that might
        be useful for future load operations.
        """
        raise NotImplementedError(
            _("Cannot load '%(attrname)s' in the base class") %
            {'attrname': attrname})
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
    def obj_load_attr(self, attrname):
        """Load an additional attribute from the real object.

        This should use self._conductor, and cache any data that might
        be useful for future load operations.
        """
        raise NotImplementedError(
            _("Cannot load '%(attrname)s' in the base class") %
            {'attrname': attrname})
Ejemplo n.º 17
0
def get(url, allowed_schemes=('http', 'https')):
    """Get the data at the specified URL.

    The URL must use the http: or https: schemes.
    The file: scheme is also supported if you override
    the allowed_schemes argument.
    Raise an IOError if getting the data fails.
    """
    LOG.info(_LI('Fetching data from %s'), url)

    components = urllib.parse.urlparse(url)

    if components.scheme not in allowed_schemes:
        raise URLFetchError(_('Invalid URL scheme %s') % components.scheme)

    if components.scheme == 'file':
        try:
            return urllib.request.urlopen(url).read()
        except urllib.error.URLError as uex:
            raise URLFetchError(_('Failed to retrieve manifest: %s') % uex)

    try:
        resp = requests.get(url, stream=True)
        resp.raise_for_status()

        # We cannot use resp.text here because it would download the
        # entire file, and a large enough file would bring down the
        # engine.  The 'Content-Length' header could be faked, so it's
        # necessary to download the content in chunks to until
        # max_manifest_size is reached.  The chunk_size we use needs
        # to balance CPU-intensive string concatenation with accuracy
        # (eg. it's possible to fetch 1000 bytes greater than
        # max_manifest_size with a chunk_size of 1000).
        reader = resp.iter_content(chunk_size=1000)
        result = ""
        for chunk in reader:
            result += chunk
            if len(result) > cfg.CONF.max_manifest_size:
                raise URLFetchError("Manifest exceeds maximum allowed size (%s"
                                    " bytes)" % cfg.CONF.max_manifest_size)
        return result

    except exceptions.RequestException as ex:
        raise URLFetchError(_('Failed to retrieve manifest: %s') % ex)
Ejemplo n.º 18
0
 def validate(self, value):
     for t in self.types:
         try:
             return wtypes.validate_value(t, value)
         except (exception.InvalidUUID, ValueError):
             pass
     else:
         raise ValueError(
                  _("Wrong type. Expected '%(type)s', got '%(value)s'")
                  % {'type': self.types, 'value': type(value)})
Ejemplo n.º 19
0
 def validate(self, value):
     for t in self.types:
         if t is wsme.types.text and isinstance(value, wsme.types.bytes):
             value = value.decode()
         if isinstance(value, t):
             return value
     else:
         raise ValueError(
                  _("Wrong type. Expected '%(type)s', got '%(value)s'")
                  % {'type': self.types, 'value': type(value)})
Ejemplo n.º 20
0
    def update_node(self, node_id, values):
        # NOTE(dtantsur): this can lead to very strange errors
        if 'uuid' in values:
            msg = _("Cannot overwrite UUID for an existing Node.")
            raise exception.InvalidParameterValue(err=msg)

        try:
            return self._do_update_node(node_id, values)
        except db_exc.DBDuplicateEntry:
            raise exception.InstanceAssociated(
                instance_uuid=values['ironic_node_id'], node=node_id)
Ejemplo n.º 21
0
class MagnumException(Exception):
    """Base Magnum 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
                    })

            if CONF.fatal_exception_format_errors:
                raise e

        super(MagnumException, 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):
        if self.__class__.__name__.endswith('_Remote'):
            return self.args[0]
        else:
            return six.text_type(self)
Ejemplo n.º 22
0
def install(app, conf):
    if conf.get('enable_authentication'):
        return AuthProtocolWrapper(app, conf=dict(conf.get(OPT_GROUP_NAME)))
    else:
        LOG.warning(_('Keystone authentication is disabled by Magnum '
                      'configuration parameter enable_authentication. '
                      'Magnum will not authenticate incoming request. '
                      'In order to enable authentication set '
                      'enable_authentication option to True.'))

    return app
Ejemplo n.º 23
0
    def _get_roles(self, req):
        """Get the list of roles."""

        if 'X-Roles' in req.headers:
            roles = req.headers.get('X-Roles', '')
        else:
            # Fallback to deprecated role header:
            roles = req.headers.get('X-Role', '')
            if roles:
                LOG.warn(_("X-Roles is missing. Using deprecated X-Role "
                           "header"))
        return [r.strip() for r in roles.split(',')]
Ejemplo n.º 24
0
    def obj_attr_is_set(self, attrname):
        """Test object to see if attrname is present.

        Returns True if the named attribute has a value set, or
        False if not. Raises AttributeError if attrname is not
        a valid attribute for this object.
        """
        if attrname not in self.obj_fields:
            raise AttributeError(
                _("%(objname)s object has no attribute '%(attrname)s'") %
                {'objname': self.obj_name(), 'attrname': attrname})
        return hasattr(self, get_attrname(attrname))
Ejemplo n.º 25
0
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)))
Ejemplo n.º 26
0
    def update_node(self, node_id, values):
        # NOTE(dtantsur): this can lead to very strange errors
        if 'uuid' in values:
            msg = _("Cannot overwrite UUID for an existing Node.")
            raise exception.InvalidParameterValue(err=msg)

        try:
            return self._do_update_node(node_id, values)
        except db_exc.DBDuplicateEntry:
            raise exception.InstanceAssociated(
                instance_uuid=values['ironic_node_id'],
                node=node_id)
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
    def get(self, key, value=NotSpecifiedSentinel):
        """For backwards-compatibility with dict-based objects.

        NOTE(danms): May be removed in the future.
        """
        if key not in self.obj_fields:
            raise AttributeError(
                _("'%(objclass)s' object has no attribute '%(attrname)s'") %
                {'objclass': self.__class__, 'attrname': key})
        if value != NotSpecifiedSentinel and not self.obj_attr_is_set(key):
            return value
        else:
            return self[key]
Ejemplo n.º 30
0
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"))
Ejemplo n.º 31
0
def main():
    service.prepare_service(sys.argv)

    app = api_app.setup_app()

    # Create the WSGI server and start it
    host, port = cfg.CONF.api.host, cfg.CONF.api.port
    srv = simple_server.make_server(host, port, app)

    LOG.info(_('Starting server in PID %s') % os.getpid())
    LOG.debug("Configuration:")
    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)

    if host == '0.0.0.0':
        LOG.info(_('serving on 0.0.0.0:%(port)s, '
                   'view at http://127.0.0.1:%(port)s') %
                 dict(port=port))
    else:
        LOG.info(_('serving on http://%(host)s:%(port)s') %
                 dict(host=host, port=port))

    srv.serve_forever()
Ejemplo n.º 32
0
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"))
Ejemplo n.º 33
0
    def obj_attr_is_set(self, attrname):
        """Test object to see if attrname is present.

        Returns True if the named attribute has a value set, or
        False if not. Raises AttributeError if attrname is not
        a valid attribute for this object.
        """
        if attrname not in self.obj_fields:
            raise AttributeError(
                _("%(objname)s object has no attribute '%(attrname)s'") % {
                    'objname': self.obj_name(),
                    'attrname': attrname
                })
        return hasattr(self, get_attrname(attrname))
Ejemplo n.º 34
0
    def get(self, key, value=NotSpecifiedSentinel):
        """For backwards-compatibility with dict-based objects.

        NOTE(danms): May be removed in the future.
        """
        if key not in self.obj_fields:
            raise AttributeError(
                _("'%(objclass)s' object has no attribute '%(attrname)s'") % {
                    'objclass': self.__class__,
                    'attrname': key
                })
        if value != NotSpecifiedSentinel and not self.obj_attr_is_set(key):
            return value
        else:
            return self[key]
Ejemplo n.º 35
0
def check_object_version(server, client):
    try:
        client_major, _client_minor = client.split('.')
        server_major, _server_minor = server.split('.')
        client_minor = int(_client_minor)
        server_minor = int(_server_minor)
    except ValueError:
        raise exception.IncompatibleObjectVersion(_('Invalid version string'))

    if client_major != server_major:
        raise exception.IncompatibleObjectVersion(
            dict(client=client_major, server=server_major))
    if client_minor > server_minor:
        raise exception.IncompatibleObjectVersion(
            dict(client=client_minor, server=server_minor))
Ejemplo n.º 36
0
def main():
    cfg.CONF(sys.argv[1:], project='magnum')
    logging.setup('magnum')

    LOG.info(_('Starting server in PID %s') % os.getpid())
    LOG.debug("Configuration:")
    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)

    cfg.CONF.import_opt('topic', 'magnum.conductor.config', group='conductor')
    cfg.CONF.import_opt('host', 'magnum.conductor.config', group='conductor')
    endpoints = [
        default_handler.Handler(),
    ]
    server = service.Service(cfg.CONF.conductor.topic,
                             cfg.CONF.conductor.host, endpoints)
    server.serve()
Ejemplo n.º 37
0
def check_object_version(server, client):
    try:
        client_major, _client_minor = client.split('.')
        server_major, _server_minor = server.split('.')
        client_minor = int(_client_minor)
        server_minor = int(_server_minor)
    except ValueError:
        raise exception.IncompatibleObjectVersion(
            _('Invalid version string'))

    if client_major != server_major:
        raise exception.IncompatibleObjectVersion(
            dict(client=client_major, server=server_major))
    if client_minor > server_minor:
        raise exception.IncompatibleObjectVersion(
            dict(client=client_minor, server=server_minor))
Ejemplo n.º 38
0
def get_id(source_uuid):
    """Derive a short (12 character) id from a random UUID.

    The supplied UUID must be a version 4 UUID object.
    """
    if isinstance(source_uuid, six.string_types):
        source_uuid = uuid.UUID(source_uuid)
    if source_uuid.version != 4:
        raise ValueError(_('Invalid UUID version (%d)') % source_uuid.version)

    # The "time" field of a v4 UUID contains 60 random bits
    # (see RFC4122, Section 4.4)
    random_bytes = _to_byte_string(source_uuid.time, 60)
    # The first 12 bytes (= 60 bits) of base32-encoded output is our data
    encoded = base64.b32encode(random_bytes)[:12]

    return encoded.lower()
Ejemplo n.º 39
0
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)))
Ejemplo n.º 40
0
 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)
Ejemplo n.º 41
0
def main():
    cfg.CONF(sys.argv[1:], project='magnum')
    logging.setup('magnum')

    LOG.info(_('Starting server in PID %s') % os.getpid())
    LOG.debug("Configuration:")
    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)

    cfg.CONF.import_opt('topic', 'magnum.backend.config', group='backend')
    cfg.CONF.import_opt('host', 'magnum.backend.config', group='backend')
    endpoints = [
        docker_backend.Handler(),
        k8s_backend.Handler(),
        bay_heat.Handler(),
        bay_ironic.Handler()
    ]
    server = service.Service(cfg.CONF.backend.topic,
                             cfg.CONF.backend.host, endpoints)
    server.serve()
Ejemplo n.º 42
0
 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)
Ejemplo n.º 43
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
Ejemplo n.º 44
0
    def __init__(self, **kwargs):
        self.kwargs = kwargs

        if CONF.fatal_exception_format_errors:
            assert isinstance(self.msg_fmt, six.text_type)

        try:
            self.message = self.msg_fmt % kwargs
        except KeyError:
            # kwargs doesn't match a variable in the message
            # log the issue and the kwargs
            LOG.exception(_('Exception in string format operation'),
                          extra=dict(
                              private=dict(
                                  msg=self.msg_fmt,
                                  args=kwargs
                                  )
                              )
                          )

            if CONF.fatal_exception_format_errors:
                raise
Ejemplo n.º 45
0
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
Ejemplo n.º 46
0
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
Ejemplo n.º 47
0
    def bay_update(self, context, bay):
        LOG.debug('k8s_heat bay_update')

        osc = clients.OpenStackClients(context)
        stack = osc.heat().stacks.get(bay.stack_id)
        if (stack.stack_status != 'CREATE_COMPLETE' and
            stack.stack_status != 'UPDATE_COMPLETE'):
            operation = _('Updating a bay when stack status is '
                          '"%s"') % stack.stack_status
            raise exception.NotSupported(operation=operation)

        delta = set(bay.obj_what_changed())
        if 'node_count' in delta:
            delta.remove('node_count')

            _update_stack(context, osc, bay)
            self._poll_and_check(osc, bay)

        if delta:
            raise exception.InvalidParameterValue(err=(
                "cannot change bay property(ies) %s." % ", ".join(delta)))

        bay.save()
        return bay
Ejemplo n.º 48
0
from oslo_config import cfg

from magnum.common import clients
from magnum.common import exception
from magnum.conductor.handlers.common import kube_utils
from magnum import objects
from magnum.openstack.common._i18n import _
from magnum.openstack.common._i18n import _LW
from magnum.openstack.common import log as logging

LOG = logging.getLogger(__name__)

kubernetes_opts = [
    cfg.StrOpt('k8s_protocol',
               default='http',
               help=_('Default protocol of k8s master endpoint'
                      ' (http or https).')),
    cfg.IntOpt('k8s_port',
               default=8080,
               help=_('Default port of the k8s master endpoint.')),
]

cfg.CONF.register_opts(kubernetes_opts, group='kubernetes')


def _retrieve_bay(context, obj):
    bay_uuid = obj.bay_uuid
    return objects.Bay.get_by_uuid(context, bay_uuid)


def _retrieve_baymodel(context, obj):
    return objects.BayModel.get_by_uuid(context, obj.baymodel_id)
Ejemplo n.º 49
0
    def update_rc(self, rc_id, values):
        if 'uuid' in values:
            msg = _("Cannot overwrite UUID for an existing rc.")
            raise exception.InvalidParameterValue(err=msg)

        return self._do_update_rc(rc_id, values)
Ejemplo n.º 50
0
class ReplicationControllerNotFound(ResourceNotFound):
    message = _("ReplicationController %(rc)s could not be found.")
Ejemplo n.º 51
0
class ContainerAlreadyExists(Conflict):
    message = _("A container with UUID %(uuid)s already exists.")
Ejemplo n.º 52
0
class NotSupported(MagnumException):
    message = _("%(operation)s is not supported.")
    code = 400
Ejemplo n.º 53
0
class ServiceAlreadyExists(Conflict):
    message = _("A node with UUID %(uuid)s already exists.")
Ejemplo n.º 54
0
class ServiceNotFound(ResourceNotFound):
    message = _("Service %(service)s could not be found.")
Ejemplo n.º 55
0
class ReplicationControllerAlreadyExists(Conflict):
    message = _("A ReplicationController with UUID %(uuid)s already exists.")
Ejemplo n.º 56
0
class ContainerNotFound(ResourceNotFound):
    message = _("Container %(container)s could not be found.")
Ejemplo n.º 57
0
class PodNotFound(ResourceNotFound):
    message = _("Pod %(pod)s could not be found.")