Esempio n. 1
0
 def __str__(self):
     self.details = _("Requested version of King API is not" "available.")
     return (_("%(name)s (HTTP %(code)s) %(details)s") % {
         'name': reflection.get_class_name(self, fully_qualified=False),
         'code': self.code,
         'details': self.details
     })
Esempio n. 2
0
 def __str__(self):
     message = self.error['error'].get('message', 'Internal Error')
     if verbose:
         traceback = self.error['error'].get('traceback', '')
         return (_('ERROR: %(message)s\n%(traceback)s') %
                 {'message': message, 'traceback': traceback})
     else:
         return _('ERROR: %s') % message
Esempio n. 3
0
 def __str__(self):
     self.details = _("Requested version of King API is not"
                      "available.")
     return (_("%(name)s (HTTP %(code)s) %(details)s") %
             {
             'name': reflection.get_class_name(self, fully_qualified=False),
             'code': self.code,
             'details': self.details})
Esempio n. 4
0
 def __str__(self):
     message = self.error['error'].get('message', 'Internal Error')
     if verbose:
         traceback = self.error['error'].get('traceback', '')
         return (_('ERROR: %(message)s\n%(traceback)s') % {
             'message': message,
             'traceback': traceback
         })
     else:
         return _('ERROR: %s') % message
class BadRequest(HTTPClientError):
    """HTTP 400 - Bad Request.

    The request cannot be fulfilled due to bad syntax.
    """
    http_status = 400
    message = _("Bad Request")
class HttpServerError(HttpError):
    """Server-side HTTP error.

    Exception for cases in which the server is aware that it has
    erred or is incapable of performing the request.
    """
    message = _("HTTP Server Error")
class HttpError(ClientException):
    """The base exception class for all HTTP exceptions.
    """
    http_status = 0
    message = _("HTTP Error")

    def __init__(self,
                 message=None,
                 details=None,
                 response=None,
                 request_id=None,
                 url=None,
                 method=None,
                 http_status=None):
        self.http_status = http_status or self.http_status
        self.message = message or self.message
        self.details = details
        self.request_id = request_id
        self.response = response
        self.url = url
        self.method = method
        formatted_string = "%s (HTTP %s)" % (self.message, self.http_status)
        if request_id:
            formatted_string += " (Request-ID: %s)" % request_id
        super(HttpError, self).__init__(formatted_string)
Esempio n. 8
0
    def find(self, base_url=None, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        :param base_url: if provided, the generated URL will be appended to it
        """
        kwargs = self._filter_kwargs(kwargs)

        rl = self._list(
            '%(base_url)s%(query)s' % {
                'base_url': self.build_url(base_url=base_url, **kwargs),
                'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
            },
            self.collection_key)
        num = len(rl)

        if num == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num > 1:
            raise exceptions.NoUniqueMatch
        else:
            return rl[0]
Esempio n. 9
0
def find_resource(manager, name_or_id):
    """Helper for the _find_* methods."""
    # first try to get entity as integer id
    try:
        if isinstance(name_or_id, int) or name_or_id.isdigit():
            return manager.get(int(name_or_id))
    except exc.NotFound:
        pass

    # now try to get entity as uuid
    try:
        uuid.UUID(str(name_or_id))
        return manager.get(name_or_id)
    except (ValueError, exc.NotFound):
        pass

    # finally try to find entity by name
    try:
        return manager.find(name=name_or_id)
    except exc.NotFound:
        msg = (_("No %(name)s with a name or ID of "
                 "'%(name_or_id)s' exists.") % {
                     'name': manager.resource_class.__name__.lower(),
                     'name_or_id': name_or_id
                 })
        raise exc.CommandError(msg)
Esempio n. 10
0
def format_parameters(params, parse_semicolon=True):
    '''Reformat parameters into dict of format expected by the API.'''

    if not params:
        return {}

    if parse_semicolon:
        # expect multiple invocations of --parameters but fall back
        # to ; delimited if only one --parameters is specified
        if len(params) == 1:
            params = params[0].split(';')

    parameters = {}
    for p in params:
        try:
            (n, v) = p.split(('='), 1)
        except ValueError:
            msg = _('Malformed parameter(%s). Use the key=value format.') % p
            raise exc.CommandError(msg)

        if n not in parameters:
            parameters[n] = v
        else:
            if not isinstance(parameters[n], list):
                parameters[n] = [parameters[n]]
            parameters[n].append(v)

    return parameters
class PaymentRequired(HTTPClientError):
    """HTTP 402 - Payment Required.

    Reserved for future use.
    """
    http_status = 402
    message = _("Payment Required")
class RequestTimeout(HTTPClientError):
    """HTTP 408 - Request Timeout.

    The server timed out waiting for the request.
    """
    http_status = 408
    message = _("Request Timeout")
class RequestUriTooLong(HTTPClientError):
    """HTTP 414 - Request-URI Too Long.

    The URI provided was too long for the server to process.
    """
    http_status = 414
    message = _("Request-URI Too Long")
Esempio n. 14
0
def find_resource(manager, name_or_id):
    """Helper for the _find_* methods."""
    # first try to get entity as integer id
    try:
        if isinstance(name_or_id, int) or name_or_id.isdigit():
            return manager.get(int(name_or_id))
    except exc.NotFound:
        pass

    # now try to get entity as uuid
    try:
        uuid.UUID(str(name_or_id))
        return manager.get(name_or_id)
    except (ValueError, exc.NotFound):
        pass

    # finally try to find entity by name
    try:
        return manager.find(name=name_or_id)
    except exc.NotFound:
        msg = (
            _("No %(name)s with a name or ID of "
              "'%(name_or_id)s' exists.")
            % {
                'name': manager.resource_class.__name__.lower(),
                'name_or_id': name_or_id
            })
        raise exc.CommandError(msg)
class InternalServerError(HttpServerError):
    """HTTP 500 - Internal Server Error.

    A generic error message, given when no more specific message is suitable.
    """
    http_status = 500
    message = _("Internal Server Error")
class ExpectationFailed(HTTPClientError):
    """HTTP 417 - Expectation Failed.

    The server cannot meet the requirements of the Expect request-header field.
    """
    http_status = 417
    message = _("Expectation Failed")
class ProxyAuthenticationRequired(HTTPClientError):
    """HTTP 407 - Proxy Authentication Required.

    The client must first authenticate itself with the proxy.
    """
    http_status = 407
    message = _("Proxy Authentication Required")
Esempio n. 18
0
def format_parameters(params, parse_semicolon=True):
    '''Reformat parameters into dict of format expected by the API.'''

    if not params:
        return {}

    if parse_semicolon:
        # expect multiple invocations of --parameters but fall back
        # to ; delimited if only one --parameters is specified
        if len(params) == 1:
            params = params[0].split(';')

    parameters = {}
    for p in params:
        try:
            (n, v) = p.split(('='), 1)
        except ValueError:
            msg = _('Malformed parameter(%s). Use the key=value format.') % p
            raise exc.CommandError(msg)

        if n not in parameters:
            parameters[n] = v
        else:
            if not isinstance(parameters[n], list):
                parameters[n] = [parameters[n]]
            parameters[n].append(v)

    return parameters
class HttpVersionNotSupported(HttpServerError):
    """HTTP 505 - HttpVersion Not Supported.

    The server does not support the HTTP protocol version used in the request.
    """
    http_status = 505
    message = _("HTTP Version Not Supported")
class ServiceUnavailable(HttpServerError):
    """HTTP 503 - Service Unavailable.

    The server is currently unavailable.
    """
    http_status = 503
    message = _("Service Unavailable")
class BadGateway(HttpServerError):
    """HTTP 502 - Bad Gateway.

    The server was acting as a gateway or proxy and received an invalid
    response from the upstream server.
    """
    http_status = 502
    message = _("Bad Gateway")
class HttpNotImplemented(HttpServerError):
    """HTTP 501 - Not Implemented.

    The server either does not recognize the request method, or it lacks
    the ability to fulfill the request.
    """
    http_status = 501
    message = _("Not Implemented")
class UnprocessableEntity(HTTPClientError):
    """HTTP 422 - Unprocessable Entity.

    The request was well-formed but was unable to be followed due to semantic
    errors.
    """
    http_status = 422
    message = _("Unprocessable Entity")
class NotAcceptable(HTTPClientError):
    """HTTP 406 - Not Acceptable.

    The requested resource is only capable of generating content not
    acceptable according to the Accept headers sent in the request.
    """
    http_status = 406
    message = _("Not Acceptable")
class PreconditionFailed(HTTPClientError):
    """HTTP 412 - Precondition Failed.

    The server does not meet one of the preconditions that the requester
    put on the request.
    """
    http_status = 412
    message = _("Precondition Failed")
class LengthRequired(HTTPClientError):
    """HTTP 411 - Length Required.

    The request did not specify the length of its content, which is
    required by the requested resource.
    """
    http_status = 411
    message = _("Length Required")
class Gone(HTTPClientError):
    """HTTP 410 - Gone.

    Indicates that the resource requested is no longer available and will
    not be available again.
    """
    http_status = 410
    message = _("Gone")
class Conflict(HTTPClientError):
    """HTTP 409 - Conflict.

    Indicates that the request could not be processed because of conflict
    in the request, such as an edit conflict.
    """
    http_status = 409
    message = _("Conflict")
Esempio n. 29
0
def format_output(output, format='yaml'):
    """Format the supplied dict as specified."""
    output_format = format.lower()
    try:
        return supported_formats[output_format](output)
    except KeyError:
        raise exc.HTTPUnsupported(_("The format(%s) is unsupported.")
                                  % output_format)
class NotFound(HTTPClientError):
    """HTTP 404 - Not Found.

    The requested resource could not be found but may be available again
    in the future.
    """
    http_status = 404
    message = _("Not Found")
class GatewayTimeout(HttpServerError):
    """HTTP 504 - Gateway Timeout.

    The server was acting as a gateway or proxy and did not receive a timely
    response from the upstream server.
    """
    http_status = 504
    message = _("Gateway Timeout")
class MethodNotAllowed(HTTPClientError):
    """HTTP 405 - Method Not Allowed.

    A request was made of a resource using a request method not supported
    by that resource.
    """
    http_status = 405
    message = _("Method Not Allowed")
class UnsupportedMediaType(HTTPClientError):
    """HTTP 415 - Unsupported Media Type.

    The request entity has a media type which the server or resource does
    not support.
    """
    http_status = 415
    message = _("Unsupported Media Type")
class Forbidden(HTTPClientError):
    """HTTP 403 - Forbidden.

    The request was a valid request, but the server is refusing to respond
    to it.
    """
    http_status = 403
    message = _("Forbidden")
Esempio n. 35
0
def format_output(output, format='yaml'):
    """Format the supplied dict as specified."""
    output_format = format.lower()
    try:
        return supported_formats[output_format](output)
    except KeyError:
        raise exc.HTTPUnsupported(
            _("The format(%s) is unsupported.") % output_format)
class RequestedRangeNotSatisfiable(HTTPClientError):
    """HTTP 416 - Requested Range Not Satisfiable.

    The client has asked for a portion of the file, but the server cannot
    supply that portion.
    """
    http_status = 416
    message = _("Requested Range Not Satisfiable")
Esempio n. 37
0
 def strip_endpoint(self, location):
     if location is None:
         message = _("Location not returned with 302")
         raise exc.InvalidEndpoint(message=message)
     if (self.endpoint_override is not None and
             location.lower().startswith(self.endpoint_override.lower())):
             return location[len(self.endpoint_override):]
     else:
         return location
Esempio n. 38
0
def read_url_content(url):
    try:
        content = request.urlopen(url).read()
    except error.URLError:
        raise exc.CommandError(_('Could not fetch contents for %s') % url)

    if content:
        try:
            content.decode('utf-8')
        except ValueError:
            content = base64.encodestring(content)
    return content
Esempio n. 39
0
def main(args=None):
    try:
        if args is None:
            args = sys.argv[1:]

        KingShell().main(args)
    except KeyboardInterrupt:
        print(_("... terminating king client"), file=sys.stderr)
        sys.exit(130)
    except Exception as e:
        if '--debug' in args or '-d' in args:
            raise
        else:
            print(encodeutils.safe_encode(six.text_type(e)), file=sys.stderr)
        sys.exit(1)
def print_list(objs, fields, formatters=None, sortby_index=0,
               mixed_case_fields=None, field_labels=None):
    """Print a list of 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)))
Esempio n. 41
0
 def __init__(self, message=None, code=None):
     super(HTTPException, self).__init__(message)
     try:
         self.error = jsonutils.loads(message)
         if 'error' not in self.error:
             raise KeyError(_('Key "error" not exists'))
     except KeyError:
         # NOTE(jianingy): If key 'error' happens not exist,
         # self.message becomes no sense. In this case, we
         # return doc of current exception class instead.
         self.error = {'error':
                       {'message': self.__class__.__doc__}}
     except Exception:
         self.error = {'error':
                       {'message': self.message or self.__class__.__doc__}}
     if self.code == "N/A" and code is not None:
         self.code = code
Esempio n. 42
0
    def find(self, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        This isn't very efficient: it loads the entire list then filters on
        the Python side.
        """
        matches = self.findall(**kwargs)
        num_matches = len(matches)
        if num_matches == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num_matches > 1:
            raise exceptions.NoUniqueMatch()
        else:
            return matches[0]
Esempio n. 43
0
    def get_class(api_name, version, version_map):
        """Returns the client class for the requested API version

        :param api_name: the name of the API, e.g. 'compute', 'image', etc
        :param version: the requested API version
        :param version_map: a dict of client classes keyed by version
        :rtype: a client class for the requested API version
        """
        try:
            client_path = version_map[str(version)]
        except (KeyError, ValueError):
            msg = _("Invalid %(api_name)s client version '%(version)s'. "
                    "Must be one of: %(version_map)s") % {
                        'api_name': api_name,
                        'version': version,
                        'version_map': ', '.join(version_map.keys())}
            raise exceptions.UnsupportedVersion(msg)

        return importutils.import_class(client_path)
Esempio n. 44
0
    def main(self, argv):
        # Parse args once to find version
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)
        self._setup_logging(options.debug)
        self._setup_verbose(options.verbose)

        # build available subcommands based on version
        api_version = options.king_api_version
        subcommand_parser = self.get_subcommand_parser(api_version)
        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if not args and options.help or not argv:
            self.do_help(options)
            return 0

        # Parse args again and call whatever callback was selected
        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with help command right away.
        if args.func == self.do_help:
            self.do_help(args)
            return 0
        elif args.func == self.do_bash_completion:
            self.do_bash_completion(args)
            return 0

        if not args.os_username and not args.os_auth_token:
            raise exc.CommandError(_("You must provide a username via either "
                                     "--os-username or env[OS_USERNAME] "
                                     "or a token via --os-auth-token or "
                                     "env[OS_AUTH_TOKEN]"))

        if not args.os_password and not args.os_auth_token:
            raise exc.CommandError(_("You must provide a password via either "
                                     "--os-password or env[OS_PASSWORD] "
                                     "or a token via --os-auth-token or "
                                     "env[OS_AUTH_TOKEN]"))

        if args.os_no_client_auth:
            if not args.king_url:
                raise exc.CommandError(_("If you specify --os-no-client-auth "
                                         "you must also specify a King API "
                                         "URL via either --king-url or "
                                         "env[KING_URL]"))
        else:
            # Tenant/project name or ID is needed to make keystoneclient
            # retrieve a service catalog, it's not required if
            # os_no_client_auth is specified, neither is the auth URL

            if not (args.os_tenant_id or args.os_tenant_name or
                    args.os_project_id or args.os_project_name):
                raise exc.CommandError(
                    _("You must provide a tenant id via either "
                      "--os-tenant-id or env[OS_TENANT_ID] or a tenant name "
                      "via either --os-tenant-name or env[OS_TENANT_NAME] "
                      "or a project id via either --os-project-id or "
                      "env[OS_PROJECT_ID] or a project name via "
                      "either --os-project-name or env[OS_PROJECT_NAME]"))

            if not args.os_auth_url:
                raise exc.CommandError(_("You must provide an auth url via "
                                         "either --os-auth-url or via "
                                         "env[OS_AUTH_URL]"))
        kwargs = {
            'insecure': args.insecure,
            'cacert': args.os_cacert,
            'cert': args.os_cert,
            'key': args.os_key,
            'timeout': args.api_timeout
        }

        endpoint = args.king_url
        service_type = args.os_service_type or 'charging'
        if args.os_no_client_auth:
            # Do not use session since no_client_auth means using king to
            # to authenticate
            kwargs = {
                'username': args.os_username,
                'password': args.os_password,
                'auth_url': args.os_auth_url,
                'token': args.os_auth_token,
                'include_pass': args.include_password,
                'insecure': args.insecure,
                'timeout': args.api_timeout
            }
        else:
            keystone_session = self._get_keystone_session(**kwargs)
            endpoint_type = args.os_endpoint_type or 'publicURL'
            if args.os_auth_token:
                kwargs = {
                    'token': args.os_auth_token,
                    'auth_url': args.os_auth_url
                }
                keystone_auth = generic.Token(**kwargs)
            else:
                project_id = args.os_project_id or args.os_tenant_id
                project_name = args.os_project_name or args.os_tenant_name
                kwargs = {
                    'username': args.os_username,
                    'user_id': args.os_user_id,
                    'user_domain_id': args.os_user_domain_id,
                    'user_domain_name': args.os_user_domain_name,
                    'password': args.os_password,
                    'auth_url': args.os_auth_url,
                    'project_id': project_id,
                    'project_name': project_name,
                    'project_domain_id': args.os_project_domain_id,
                    'project_domain_name': args.os_project_domain_name,
                }
                keystone_auth = generic.Password(**kwargs)
            if not endpoint:
                svc_type = service_type
                region_name = args.os_region_name
                endpoint = keystone_auth.get_endpoint(keystone_session,
                                                      service_type=svc_type,
                                                      interface=endpoint_type,
                                                      region_name=region_name)
            kwargs = {
                'auth_url': args.os_auth_url,
                'session': keystone_session,
                'auth': keystone_auth,
                'service_type': service_type,
                'endpoint_type': endpoint_type,
                'region_name': args.os_region_name,
                'username': args.os_username,
                'password': args.os_password,
                'include_pass': args.include_password
            }

        client = king_client.Client(api_version, endpoint, **kwargs)

        profile = osprofiler_profiler and options.profile
        if profile:
            osprofiler_profiler.init(options.profile)

        args.func(client, args)

        if profile:
            trace_id = osprofiler_profiler.get().get_base_id()
            print(_("Trace ID: %s") % trace_id)
            print(_("To display trace use next command:\n"
                  "osprofiler trace show --html %s ") % trace_id)
Esempio n. 45
0
    def _append_global_identity_args(self, parser):
        # FIXME(gyee): these are global identity (Keystone) arguments which
        # should be consistent and shared by all service clients. Therefore,
        # they should be provided by python-keystoneclient. We will need to
        # refactor this code once this functionality is available in
        # python-keystoneclient.
        parser.add_argument(
            '-k', '--insecure', default=False, action='store_true',
            help=_('Explicitly allow kingclient to perform '
                   '\"insecure SSL\" (https) requests. '
                   'The server\'s certificate will not be verified '
                   'against any certificate authorities. '
                   'This option should be used with caution.'))

        parser.add_argument(
            '--os-cert',
            default=utils.env('OS_CERT'),
            help=_('Path of certificate file to use in SSL connection. '
                   'This file can optionally be prepended with '
                   'the private key.'))

        # for backward compatibility only
        parser.add_argument('--cert-file',
                            dest='os_cert',
                            help=_('DEPRECATED! Use %(arg)s.') %
                                 {'arg': '--os-cert'})

        parser.add_argument('--os-key',
                            default=utils.env('OS_KEY'),
                            help=_('Path of client key to use in SSL '
                                   'connection. This option is not necessary '
                                   'if your key is prepended to your cert '
                                   'file.'))

        parser.add_argument('--key-file',
                            dest='os_key',
                            help=_('DEPRECATED! Use %(arg)s.') %
                                 {'arg': '--os-key'})

        parser.add_argument('--os-cacert',
                            metavar='<ca-certificate-file>',
                            dest='os_cacert',
                            default=utils.env('OS_CACERT'),
                            help=_('Path of CA TLS certificate(s) used to '
                                   'verify the remote server\'s certificate. '
                                   'Without this option glance looks for the '
                                   'default system CA certificates.'))

        parser.add_argument('--ca-file',
                            dest='os_cacert',
                            help=_('DEPRECATED! Use %(arg)s.') %
                                 {'arg': '--os-cacert'})

        parser.add_argument('--os-username',
                            default=utils.env('OS_USERNAME'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_USERNAME]'
                            })

        parser.add_argument('--os_username',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-user-id',
                            default=utils.env('OS_USER_ID'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_USER_ID]'
                            })

        parser.add_argument('--os_user_id',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-user-domain-id',
                            default=utils.env('OS_USER_DOMAIN_ID'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_USER_DOMAIN_ID]'
                            })

        parser.add_argument('--os_user_domain_id',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-user-domain-name',
                            default=utils.env('OS_USER_DOMAIN_NAME'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_USER_DOMAIN_NAME]'
                            })

        parser.add_argument('--os_user_domain_name',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-id',
                            default=utils.env('OS_PROJECT_ID'),
                            help=(_('Another way to specify tenant ID. '
                                    'This option is mutually exclusive with '
                                    '%(arg)s. Defaults to %(value)s.') %
                                  {
                                      'arg': '--os-tenant-id',
                                      'value': 'env[OS_PROJECT_ID]'}))

        parser.add_argument('--os_project_id',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-name',
                            default=utils.env('OS_PROJECT_NAME'),
                            help=(_('Another way to specify tenant name. '
                                    'This option is mutually exclusive with '
                                    '%(arg)s. Defaults to %(value)s.') %
                                  {
                                      'arg': '--os-tenant-name',
                                      'value': 'env[OS_PROJECT_NAME]'}))

        parser.add_argument('--os_project_name',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-domain-id',
                            default=utils.env('OS_PROJECT_DOMAIN_ID'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_PROJECT_DOMAIN_ID]'
                            })

        parser.add_argument('--os_project_domain_id',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-domain-name',
                            default=utils.env('OS_PROJECT_DOMAIN_NAME'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_PROJECT_DOMAIN_NAME]'
                            })

        parser.add_argument('--os_project_domain_name',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-password',
                            default=utils.env('OS_PASSWORD'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_PASSWORD]'
                            })

        parser.add_argument('--os_password',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-id',
                            default=utils.env('OS_TENANT_ID'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_TENANT_ID]'
                            })

        parser.add_argument('--os_tenant_id',
                            default=utils.env('OS_TENANT_ID'),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            default=utils.env('OS_TENANT_NAME'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_TENANT_NAME]'
                            })

        parser.add_argument('--os_tenant_name',
                            default=utils.env('OS_TENANT_NAME'),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-auth-url',
                            default=utils.env('OS_AUTH_URL'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_AUTH_URL]'
                            })

        parser.add_argument('--os_auth_url',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-region-name',
                            default=utils.env('OS_REGION_NAME'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_REGION_NAME]'
                            })

        parser.add_argument('--os_region_name',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-auth-token',
                            default=utils.env('OS_AUTH_TOKEN'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_AUTH_TOKEN]'
                            })

        parser.add_argument('--os_auth_token',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-service-type',
                            default=utils.env('OS_SERVICE_TYPE'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_SERVICE_TYPE]'
                            })

        parser.add_argument('--os_service_type',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-endpoint-type',
                            default=utils.env('OS_ENDPOINT_TYPE'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[OS_ENDPOINT_TYPE]'
                            })

        parser.add_argument('--os_endpoint_type',
                            help=argparse.SUPPRESS)
Esempio n. 46
0
    def get_base_parser(self):
        parser = argparse.ArgumentParser(
            prog='king',
            description=__doc__.strip(),
            epilog=_('See "%(arg)s" for help on a specific command.') % {
                'arg': 'king help COMMAND'
            },
            add_help=False,
            formatter_class=HelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h', '--help',
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--version',
                            action='version',
                            version=kingclient.__version__,
                            help=_("Shows the client version and exits."))

        parser.add_argument('-d', '--debug',
                            default=bool(utils.env('KINGCLIENT_DEBUG')),
                            action='store_true',
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[KINGCLIENT_DEBUG]'
                            })

        parser.add_argument('-v', '--verbose',
                            default=False, action="store_true",
                            help=_("Print more verbose output."))

        parser.add_argument('--api-timeout',
                            help=_('Number of seconds to wait for an '
                                   'API response, '
                                   'defaults to system socket timeout'))

        # os-no-client-auth tells kingclient to use token, instead of
        # env[OS_AUTH_URL]
        parser.add_argument('--os-no-client-auth',
                            default=utils.env('OS_NO_CLIENT_AUTH'),
                            action='store_true',
                            help=(_("Do not contact keystone for a token. "
                                    "Defaults to %(value)s.") %
                                  {'value': 'env[OS_NO_CLIENT_AUTH]'}))

        parser.add_argument('--king-url',
                            default=utils.env('KING_URL'),
                            help=_('Defaults to %(value)s.') % {
                                'value': 'env[KING_URL]'
                            })

        parser.add_argument('--king_url',
                            help=argparse.SUPPRESS)

        parser.add_argument('--king-api-version',
                            default=utils.env('KING_API_VERSION', default='1'),
                            help=_('Defaults to %(value)s or 1.') % {
                                'value': 'env[KING_API_VERSION]'
                            })

        parser.add_argument('--king_api_version',
                            help=argparse.SUPPRESS)

        # This unused option should remain so that scripts that
        # use it do not break. It is suppressed so it will not
        # appear in the help.
        parser.add_argument('-t', '--token-only',
                            default=bool(False),
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--include-password',
                            default=bool(utils.env('KING_INCLUDE_PASSWORD')),
                            action='store_true',
                            help=_('Send %(arg1)s and %(arg2)s to king.') % {
                                'arg1': 'os-username',
                                'arg2': 'os-password'
                            })

        # FIXME(gyee): this method should come from python-keystoneclient.
        # Will refactor this code once it is available.
        # https://bugs.launchpad.net/python-keystoneclient/+bug/1332337

        self._append_global_identity_args(parser)

        if osprofiler_profiler:
            parser.add_argument(
                '--profile',
                metavar='HMAC_KEY',
                help=_('HMAC key to use for encrypting context data '
                       'for performance profiling of operation. '
                       'This key should be the value of HMAC key '
                       'configured in osprofiler middleware in king, '
                       'it is specified in the paste configuration '
                       '(/etc/king/api-paste.ini). Without the key, '
                       'profiling will not be triggered '
                       'even if osprofiler is enabled on server side.'))
        return parser
Esempio n. 47
0
    def client_request(self, client, method, url, **kwargs):
        """Send an http request using `client`'s endpoint and specified `url`.

        If request was rejected as unauthorized (possibly because the token is
        expired), issue one authorization attempt and send the request once
        again.

        :param client: instance of BaseClient descendant
        :param method: method of HTTP request
        :param url: URL of HTTP request
        :param kwargs: any other parameter that can be passed to
            `HTTPClient.request`
        """

        filter_args = {
            "endpoint_type": client.endpoint_type or self.endpoint_type,
            "service_type": client.service_type,
        }
        token, endpoint = (self.cached_token, client.cached_endpoint)
        just_authenticated = False
        if not (token and endpoint):
            try:
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
            except exceptions.EndpointException:
                pass
            if not (token and endpoint):
                self.authenticate()
                just_authenticated = True
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
                if not (token and endpoint):
                    raise exceptions.AuthorizationFailure(
                        _("Cannot find endpoint or token for request"))

        old_token_endpoint = (token, endpoint)
        kwargs.setdefault("headers", {})["X-Auth-Token"] = token
        self.cached_token = token
        client.cached_endpoint = endpoint
        # Perform the request once. If we get Unauthorized, then it
        # might be because the auth token expired, so try to
        # re-authenticate and try again. If it still fails, bail.
        try:
            return self.request(
                method, self.concat_url(endpoint, url), **kwargs)
        except exceptions.Unauthorized as unauth_ex:
            if just_authenticated:
                raise
            self.cached_token = None
            client.cached_endpoint = None
            if self.auth_plugin.opts.get('token'):
                self.auth_plugin.opts['token'] = None
            if self.auth_plugin.opts.get('endpoint'):
                self.auth_plugin.opts['endpoint'] = None
            self.authenticate()
            try:
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
            except exceptions.EndpointException:
                raise unauth_ex
            if (not (token and endpoint) or
                    old_token_endpoint == (token, endpoint)):
                raise unauth_ex
            self.cached_token = token
            client.cached_endpoint = endpoint
            kwargs["headers"]["X-Auth-Token"] = token
            return self.request(
                method, self.concat_url(endpoint, url), **kwargs)
Esempio n. 48
0
    def _http_request(self, url, method, **kwargs):
        """Send an http request with the specified characteristics.

        Wrapper around requests.request to handle tasks such as
        setting headers and error handling.
        """
        # Copy the kwargs so we can reuse the original in case of redirects
        kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
        kwargs['headers'].setdefault('User-Agent', USER_AGENT)
        if self.auth_token:
            kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
        else:
            kwargs['headers'].update(self.credentials_headers())
        if self.auth_url:
            kwargs['headers'].setdefault('X-Auth-Url', self.auth_url)
        if self.region_name:
            kwargs['headers'].setdefault('X-Region-Name', self.region_name)
        if self.include_pass and 'X-Auth-Key' not in kwargs['headers']:
            kwargs['headers'].update(self.credentials_headers())
        if osprofiler_web:
            kwargs['headers'].update(osprofiler_web.get_trace_id_headers())

        self.log_curl_request(method, url, kwargs)

        if self.cert_file and self.key_file:
            kwargs['cert'] = (self.cert_file, self.key_file)

        if self.verify_cert is not None:
            kwargs['verify'] = self.verify_cert

        if self.timeout is not None:
            kwargs['timeout'] = float(self.timeout)

        # Allow caller to specify not to follow redirects, in which case we
        # just return the redirect response.  Useful for using stacks:lookup.
        redirect = kwargs.pop('redirect', True)

        # Since requests does not follow the RFC when doing redirection to sent
        # back the same method on a redirect we are simply bypassing it.  For
        # example if we do a DELETE/POST/PUT on a URL and we get a 302 RFC says
        # that we should follow that URL with the same method as before,
        # requests doesn't follow that and send a GET instead for the method.
        # Hopefully this could be fixed as they say in a comment in a future
        # point version i.e.: 3.x
        # See issue: https://github.com/kennethreitz/requests/issues/1704
        allow_redirects = False

        # Use fully qualified URL from response header for redirects
        if not parse.urlparse(url).netloc:
            url = self.endpoint_url + url

        try:
            resp = requests.request(
                method,
                url,
                allow_redirects=allow_redirects,
                **kwargs)
        except socket.gaierror as e:
            message = (_("Error finding address for %(url)s: %(e)s") %
                       {'url': self.endpoint_url + url, 'e': e})
            raise exc.InvalidEndpoint(message=message)
        except (socket.error, socket.timeout) as e:
            endpoint = self.endpoint
            message = (_("Error communicating with %(endpoint)s %(e)s") %
                       {'endpoint': endpoint, 'e': e})
            raise exc.CommunicationError(message=message)

        self.log_http_response(resp)

        if not ('X-Auth-Key' in kwargs['headers']) and (
                resp.status_code == 401 or
                (resp.status_code == 500 and "(HTTP 401)" in resp.content)):
            raise exc.HTTPUnauthorized(_("Authentication failed: %s")
                                       % resp.content)
        elif 400 <= resp.status_code < 600:
            raise exc.from_response(resp)
        elif resp.status_code in (301, 302, 305):
            # Redirected. Reissue the request to the new location,
            # unless caller specified redirect=False
            if redirect:
                location = resp.headers.get('location')
                if not location:
                    message = _("Location not returned with redirect")
                    raise exc.InvalidEndpoint(message=message)
                resp = self._http_request(location, method, **kwargs)
        elif resp.status_code == 300:
            raise exc.from_response(resp)

        return resp
 def __init__(self, missing):
     self.missing = missing
     msg = _("Missing arguments: %s") % ", ".join(missing)
     super(MissingArgs, self).__init__(msg)