Exemplo n.º 1
0
    def call(self, ctxt, method, **kwargs):
        """Invoke a method and wait for a reply. See RPCClient.call()."""
        if self.target.fanout:
            raise exceptions.InvalidTarget("A call cannot be used with fanout", self.target)

        msg = self._make_message(ctxt, method, kwargs)
        msg_ctxt = self.serializer.serialize_context(ctxt)

        span_host = tomograph.getHost()

        ser_name = "%s[%s]" % ("RPC_call", self.target.topic)
        tomograph.start(ser_name, self.target.topic, span_host, 0)
        trace_info = tomograph.get_trace_info()
        msg_ctxt["trace_id"] = trace_info[0]
        msg_ctxt["span_id"] = trace_info[1]

        timeout = self.timeout
        if self.timeout is None:
            timeout = self.conf.rpc_response_timeout

        if self.version_cap:
            self._check_version_cap(msg.get("version"))

        try:
            result = self.transport._send(
                self.target, msg_ctxt, msg, wait_for_reply=True, timeout=timeout, retry=self.retry
            )

            tomograph.stop(self.target.topic)
        except driver_base.TransportDriverError as ex:
            raise ClientSendError(self.target, ex)
        return self.serializer.deserialize_entity(ctxt, result)
Exemplo n.º 2
0
    def call(self, ctxt, method, **kwargs):
        """Invoke a method and wait for a reply. See RPCClient.call()."""
        if self.target.fanout:
            raise exceptions.InvalidTarget('A call cannot be used with fanout',
                                           self.target)

        msg = self._make_message(ctxt, method, kwargs)
        msg_ctxt = self.serializer.serialize_context(ctxt)

        span_host = tomograph.getHost()

        ser_name = "%s[%s]" % ("RPC_call", self.target.topic)
        tomograph.start(ser_name, self.target.topic, span_host, 0)
        trace_info = tomograph.get_trace_info()
        msg_ctxt["trace_id"] = trace_info[0]
        msg_ctxt["span_id"] = trace_info[1]

        timeout = self.timeout
        if self.timeout is None:
            timeout = self.conf.rpc_response_timeout

        if self.version_cap:
            self._check_version_cap(msg.get('version'))

        try:
            result = self.transport._send(self.target, msg_ctxt, msg,
                                          wait_for_reply=True, timeout=timeout,
                                          retry=self.retry)

            tomograph.stop(self.target.topic)
        except driver_base.TransportDriverError as ex:
            raise ClientSendError(self.target, ex)
        return self.serializer.deserialize_entity(ctxt, result)
Exemplo n.º 3
0
 def dec(request, *args, **kwargs):
     if dashboard:
         request.horizon['dashboard'] = dashboard
     if panel:
         request.horizon['panel'] = panel
     if not tomograph.tracing_started():
         span_host = tomograph.getHost()
         ser_name = "%s[%s]" % (view_func.__module__, view_func.__name__)
         tomograph.start(ser_name, view_func.__name__, span_host, 0)
         ret = view_func(request, *args, **kwargs)
         tomograph.stop(view_func.__name__)
         return ret
     return view_func(request, *args, **kwargs)
Exemplo n.º 4
0
 def dec(request, *args, **kwargs):
     if dashboard:
         request.horizon['dashboard'] = dashboard
     if panel:
         request.horizon['panel'] = panel
     if not tomograph.tracing_started():
         span_host = tomograph.getHost()
         ser_name = "%s[%s]" % (view_func.__module__, view_func.__name__)
         tomograph.start(ser_name, view_func.__name__, span_host, 0)
         ret = view_func(request, *args, **kwargs)
         tomograph.stop(view_func.__name__)
         return ret
     return view_func(request, *args, **kwargs)
Exemplo n.º 5
0
 def inner(*args, **kwargs):
     try:
         span_host = tomograph.getHost()
         ser_name = "%s[%s]" % (func.__module__, func.__name__)
         tomograph.start(ser_name, func.__name__, span_host, 0)
         ret = func(*args, **kwargs)
         tomograph.stop(func.__name__)
         return ret
     # Take advantage of the fact that we can catch
     # multiple exception types using a tuple of
     # exception classes, with subclass detection
     # for free. Any exception that is not in or
     # derived from the args passed to us will be
     # ignored and thrown as normal.
     except exceptions:
         tomograph.stop(func.__name__)
         raise rpc_dispatcher.ExpectedException()
Exemplo n.º 6
0
    def cast(self, ctxt, method, **kwargs):
        """Invoke a method and return immediately. See RPCClient.cast()."""
        msg = self._make_message(ctxt, method, kwargs)
        msg_ctxt = self.serializer.serialize_context(ctxt)

        span_host = tomograph.getHost()
        ser_name = "%s[%s]" % ("RPC_cast", self.target.topic)
        tomograph.start(ser_name, self.target.topic, span_host, 0)
        trace_info = tomograph.get_trace_info()
        msg_ctxt["trace_id"] = trace_info[0]
        msg_ctxt["span_id"] = trace_info[1]

        if self.version_cap:
            self._check_version_cap(msg.get("version"))
        try:
            self.transport._send(self.target, msg_ctxt, msg, retry=self.retry)
            tomograph.stop(self.target.topic)
        except driver_base.TransportDriverError as ex:
            raise ClientSendError(self.target, ex)
Exemplo n.º 7
0
    def cast(self, ctxt, method, **kwargs):
        """Invoke a method and return immediately. See RPCClient.cast()."""
        msg = self._make_message(ctxt, method, kwargs)
        msg_ctxt = self.serializer.serialize_context(ctxt)

        span_host = tomograph.getHost()
        ser_name = "%s[%s]" % ("RPC_cast", self.target.topic)
        tomograph.start(ser_name, self.target.topic, span_host, 0)
        trace_info = tomograph.get_trace_info()
        msg_ctxt["trace_id"] = trace_info[0]
        msg_ctxt["span_id"] = trace_info[1]

        if self.version_cap:
            self._check_version_cap(msg.get('version'))
        try:
            self.transport._send(self.target, msg_ctxt, msg, retry=self.retry)
            tomograph.stop(self.target.topic)
        except driver_base.TransportDriverError as ex:
            raise ClientSendError(self.target, ex)
Exemplo n.º 8
0
    def _do_dispatch(self, endpoint, method, ctxt, args, executor_callback):

        #pdb.set_trace()

        trace_info = None
        if ctxt.__contains__("trace_id"):
            trace_info = ctxt.pop("trace_id"), ctxt.pop("span_id")

        ctxt = self.serializer.deserialize_context(ctxt)
        new_args = dict()
        for argname, arg in six.iteritems(args):
            new_args[argname] = self.serializer.deserialize_entity(ctxt, arg)
        func = getattr(endpoint, method)

        span_host = tomograph.getHost()
        ser_name = "%s[%s]" % (func.__module__, func.__name__)
        tomograph.start(ser_name, func.__name__, span_host, 0, trace_info)

        if executor_callback:
            result = executor_callback(func, ctxt, **new_args)
        else:
            result = func(ctxt, **new_args)
        tomograph.stop(func.__name__)
        return self.serializer.serialize_entity(ctxt, result)
Exemplo n.º 9
0
    def _do_dispatch(self, endpoint, method, ctxt, args, executor_callback):

        #pdb.set_trace()

        trace_info = None
        if ctxt.__contains__("trace_id"):
            trace_info = ctxt.pop("trace_id"), ctxt.pop("span_id")

        ctxt = self.serializer.deserialize_context(ctxt)
        new_args = dict()
        for argname, arg in six.iteritems(args):
            new_args[argname] = self.serializer.deserialize_entity(ctxt, arg)
        func = getattr(endpoint, method)

        span_host = tomograph.getHost()
        ser_name = "%s[%s]" % (func.__module__, func.__name__)
        tomograph.start(ser_name, func.__name__, span_host, 0, trace_info)

        if executor_callback:
            result = executor_callback(func, ctxt, **new_args)
        else:
            result = func(ctxt, **new_args)
        tomograph.stop(func.__name__)
        return self.serializer.serialize_entity(ctxt, result)
Exemplo n.º 10
0
Arquivo: shell.py Projeto: hbkqh/patch
    def main(self, argv):
        # Parse args once to find version
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)

        # build available subcommands based on version
        api_version = options.os_identity_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 argv or options.help:
            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 args.debug:
            logging_level = logging.DEBUG
            iso_logger = logging.getLogger('iso8601')
            iso_logger.setLevel('WARN')
        else:
            logging_level = logging.WARNING

        logging.basicConfig(level=logging_level)

        # TODO(heckj): supporting backwards compatibility with environment
        # variables. To be removed after DEVSTACK is updated, ideally in
        # the Grizzly release cycle.
        args.os_token = args.os_token or env('SERVICE_TOKEN')
        args.os_endpoint = args.os_endpoint or env('SERVICE_ENDPOINT')

        if utils.isunauthenticated(args.func):
            self.cs = shell_generic.CLIENT_CLASS(endpoint=args.os_auth_url,
                                                 cacert=args.os_cacert,
                                                 key=args.os_key,
                                                 cert=args.os_cert,
                                                 insecure=args.insecure,
                                                 timeout=args.timeout)
        else:
            self.auth_check(args)
            token = None
            if args.os_token and args.os_endpoint:
                token = args.os_token
            api_version = options.os_identity_api_version
            self.cs = self.get_api_class(api_version)(
                username=args.os_username,
                tenant_name=args.os_tenant_name,
                tenant_id=args.os_tenant_id,
                token=token,
                endpoint=args.os_endpoint,
                password=args.os_password,
                auth_url=args.os_auth_url,
                region_name=args.os_region_name,
                cacert=args.os_cacert,
                key=args.os_key,
                cert=args.os_cert,
                insecure=args.insecure,
                debug=args.debug,
                use_keyring=args.os_cache,
                force_new_token=args.force_new_token,
                stale_duration=args.stale_duration,
                timeout=args.timeout)

        try:
            span_host = tomograph.getHost()
            span_name = ' '.join(sys.argv)
            tomograph.start("keystoneclient-shell", span_name, span_host, 0)
            args.func(self.cs, args)
            tomograph.stop(span_name)
        except exc.Unauthorized:
            tomograph.tag("Exception", "Unauthorized")
            tomograph.stop(span_name)
            raise exc.CommandError("Invalid OpenStack Identity credentials.")
        except exc.AuthorizationFailure:
            tomograph.tag("Exception", "AuthorizationFailure")
            tomograph.stop(span_name)
            raise exc.CommandError("Unable to authorize user")
Exemplo n.º 11
0
Arquivo: shell.py Projeto: hbkqh/patch
    def main(self, argv):
        # Parse args once to find version
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)

        # build available subcommands based on version
        api_version = options.os_identity_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 argv or options.help:
            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 args.debug:
            logging_level = logging.DEBUG
            iso_logger = logging.getLogger('iso8601')
            iso_logger.setLevel('WARN')
        else:
            logging_level = logging.WARNING

        logging.basicConfig(level=logging_level)

        # TODO(heckj): supporting backwards compatibility with environment
        # variables. To be removed after DEVSTACK is updated, ideally in
        # the Grizzly release cycle.
        args.os_token = args.os_token or env('SERVICE_TOKEN')
        args.os_endpoint = args.os_endpoint or env('SERVICE_ENDPOINT')

        if utils.isunauthenticated(args.func):
            self.cs = shell_generic.CLIENT_CLASS(endpoint=args.os_auth_url,
                                                 cacert=args.os_cacert,
                                                 key=args.os_key,
                                                 cert=args.os_cert,
                                                 insecure=args.insecure,
                                                 timeout=args.timeout)
        else:
            self.auth_check(args)
            token = None
            if args.os_token and args.os_endpoint:
                token = args.os_token
            api_version = options.os_identity_api_version
            self.cs = self.get_api_class(api_version)(
                username=args.os_username,
                tenant_name=args.os_tenant_name,
                tenant_id=args.os_tenant_id,
                token=token,
                endpoint=args.os_endpoint,
                password=args.os_password,
                auth_url=args.os_auth_url,
                region_name=args.os_region_name,
                cacert=args.os_cacert,
                key=args.os_key,
                cert=args.os_cert,
                insecure=args.insecure,
                debug=args.debug,
                use_keyring=args.os_cache,
                force_new_token=args.force_new_token,
                stale_duration=args.stale_duration,
                timeout=args.timeout)

        try:
            span_host = tomograph.getHost()
            span_name = ' '.join(sys.argv)
            tomograph.start("keystoneclient-shell", span_name, span_host, 0)
            args.func(self.cs, args)
            tomograph.stop(span_name)
        except exc.Unauthorized:
            tomograph.tag("Exception", "Unauthorized")
            tomograph.stop(span_name)
            raise exc.CommandError("Invalid OpenStack Identity credentials.")
        except exc.AuthorizationFailure:
            tomograph.tag("Exception", "AuthorizationFailure")
            tomograph.stop(span_name)
            raise exc.CommandError("Unable to authorize user")
Exemplo n.º 12
0
Arquivo: shell.py Projeto: hbkqh/patch
    def main(self, argv):
        # Parse args once to find version and debug settings
        parser = self.get_base_parser()

        # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.



        if '--endpoint_type' in argv:
            spot = argv.index('--endpoint_type')
            argv[spot] = '--endpoint-type'

        (args, args_list) = parser.parse_known_args(argv)

        self.setup_debugging(args.debug)
        self.extensions = []
        do_help = ('help' in argv) or not argv

        # Discover available auth plugins
        #tomograph.annotate("Discover available auth plugins", "novaclient-shell")
        novaclient.auth_plugin.discover_auth_systems()

        if not args.os_compute_api_version:
            api_version = api_versions.get_api_version(
                DEFAULT_MAJOR_OS_COMPUTE_API_VERSION)
        else:
            api_version = api_versions.get_api_version(
                args.os_compute_api_version)

        os_username = args.os_username
        os_user_id = args.os_user_id
        os_password = None  # Fetched and set later as needed
        os_tenant_name = args.os_tenant_name
        os_tenant_id = args.os_tenant_id
        os_auth_url = args.os_auth_url
        os_region_name = args.os_region_name
        os_auth_system = args.os_auth_system
        endpoint_type = args.endpoint_type
        insecure = args.insecure
        service_type = args.service_type
        service_name = args.service_name
        volume_service_name = args.volume_service_name
        bypass_url = args.bypass_url
        os_cache = args.os_cache
        cacert = args.os_cacert
        timeout = args.timeout

        keystone_session = None
        keystone_auth = None

        # We may have either, both or none of these.
        # If we have both, we don't need USERNAME, PASSWORD etc.
        # Fill in the blanks from the SecretsHelper if possible.
        # Finally, authenticate unless we have both.
        # Note if we don't auth we probably don't have a tenant ID so we can't
        # cache the token.
        auth_token = args.os_auth_token if args.os_auth_token else None
        management_url = bypass_url if bypass_url else None

        if os_auth_system and os_auth_system != "keystone":
            auth_plugin = novaclient.auth_plugin.load_plugin(os_auth_system)
        else:
            auth_plugin = None

        if not endpoint_type:
            endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE

        # This allow users to use endpoint_type as (internal, public or admin)
        # just like other openstack clients (glance, cinder etc)
        if endpoint_type in ['internal', 'public', 'admin']:
            endpoint_type += 'URL'

        if not service_type:
            # Note(alex_xu): We need discover version first, so if there isn't
            # service type specified, we use default nova service type.
            service_type = DEFAULT_NOVA_SERVICE_TYPE

        # If we have an auth token but no management_url, we must auth anyway.
        # Expired tokens are handled by client.py:_cs_request
        must_auth = not (auth_token and management_url)

        # Do not use Keystone session for cases with no session support. The
        # presence of auth_plugin means os_auth_system is present and is not
        # keystone.
        use_session = True
        if auth_plugin or bypass_url or os_cache or volume_service_name:
            use_session = False

        # FIXME(usrleon): Here should be restrict for project id same as
        # for os_username or os_password but for compatibility it is not.
        if must_auth and not do_help:
            if auth_plugin:
                auth_plugin.parse_opts(args)

            if not auth_plugin or not auth_plugin.opts:
                if not os_username and not os_user_id:
                    raise exc.CommandError(
                        _("You must provide a username "
                          "or user id via --os-username, --os-user-id, "
                          "env[OS_USERNAME] or env[OS_USER_ID]"))

            if not any([args.os_tenant_name, args.os_tenant_id,
                        args.os_project_id, args.os_project_name]):
                raise exc.CommandError(_("You must provide a project name or"
                                         " project id via --os-project-name,"
                                         " --os-project-id, env[OS_PROJECT_ID]"
                                         " or env[OS_PROJECT_NAME]. You may"
                                         " use os-project and os-tenant"
                                         " interchangeably."))

            if not os_auth_url:
                if os_auth_system and os_auth_system != 'keystone':
                    os_auth_url = auth_plugin.get_auth_url()

            if not os_auth_url:
                    raise exc.CommandError(
                        _("You must provide an auth url "
                          "via either --os-auth-url or env[OS_AUTH_URL] "
                          "or specify an auth_system which defines a "
                          "default url with --os-auth-system "
                          "or env[OS_AUTH_SYSTEM]"))

            project_id = args.os_project_id or args.os_tenant_id
            project_name = args.os_project_name or args.os_tenant_name
            if use_session:
                # Not using Nova auth plugin, so use keystone
                with utils.record_time(self.times, args.timings,
                                       'auth_url', args.os_auth_url):
                    keystone_session = (ksession.Session
                                        .load_from_cli_options(args))
                    keystone_auth = self._get_keystone_auth(
                        keystone_session,
                        args.os_auth_url,
                        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_token=args.os_auth_token,
                        project_id=project_id,
                        project_name=project_name,
                        project_domain_id=args.os_project_domain_id,
                        project_domain_name=args.os_project_domain_name)

        if not do_help and not any([args.os_tenant_id, args.os_tenant_name,
                                    args.os_project_id, args.os_project_name]):
            raise exc.CommandError(_("You must provide a project name or"
                                     " project id via --os-project-name,"
                                     " --os-project-id, env[OS_PROJECT_ID]"
                                     " or env[OS_PROJECT_NAME]. You may"
                                     " use os-project and os-tenant"
                                     " interchangeably."))

        if not os_auth_url and not do_help:
            raise exc.CommandError(
                _("You must provide an auth url "
                  "via either --os-auth-url or env[OS_AUTH_URL]"))

        # This client is just used to discover api version. Version API needn't
        # microversion, so we just pass version 2 at here.
        #tomograph.annotate("Discover api version", "novaclient-shell")
        self.cs = client.Client(
            api_versions.APIVersion("2.0"),
            os_username, os_password, os_tenant_name,
            tenant_id=os_tenant_id, user_id=os_user_id,
            auth_url=os_auth_url, insecure=insecure,
            region_name=os_region_name, endpoint_type=endpoint_type,
            extensions=self.extensions, service_type=service_type,
            service_name=service_name, auth_system=os_auth_system,
            auth_plugin=auth_plugin, auth_token=auth_token,
            volume_service_name=volume_service_name,
            timings=args.timings, bypass_url=bypass_url,
            os_cache=os_cache, http_log_debug=args.debug,
            cacert=cacert, timeout=timeout,
            session=keystone_session, auth=keystone_auth)

        if not do_help:
            if not api_version.is_latest():
                if api_version > api_versions.APIVersion("2.0"):
                    if not api_version.matches(novaclient.API_MIN_VERSION,
                                               novaclient.API_MAX_VERSION):
                        raise exc.CommandError(
                            _("The specified version isn't supported by "
                              "client. The valid version range is '%(min)s' "
                              "to '%(max)s'") % {
                                "min": novaclient.API_MIN_VERSION.get_string(),
                                "max": novaclient.API_MAX_VERSION.get_string()}
                        )
            api_version = api_versions.discover_version(self.cs, api_version)

        # build available subcommands based on version
        self.extensions = client.discover_extensions(api_version)
        self._run_extension_hooks('__pre_parse_args__')

        subcommand_parser = self.get_subcommand_parser(
            api_version, do_help=do_help)
        self.parser = subcommand_parser

        if args.help or not argv:
            subcommand_parser.print_help()
            return 0

        args = subcommand_parser.parse_args(argv)
        self._run_extension_hooks('__post_parse_args__', args)

        # Short-circuit and deal with help 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.service_type:
            service_type = (cliutils.get_service_type(args.func) or
                            DEFAULT_NOVA_SERVICE_TYPE)

        if cliutils.isunauthenticated(args.func):
            # NOTE(alex_xu): We need authentication for discover microversion.
            # But the subcommands may needn't it. If the subcommand needn't,
            # we clear the session arguements.
            keystone_session = None
            keystone_auth = None

        # Recreate client object with discovered version.
        self.cs = client.Client(
            api_version,
            os_username, os_password, os_tenant_name,
            tenant_id=os_tenant_id, user_id=os_user_id,
            auth_url=os_auth_url, insecure=insecure,
            region_name=os_region_name, endpoint_type=endpoint_type,
            extensions=self.extensions, service_type=service_type,
            service_name=service_name, auth_system=os_auth_system,
            auth_plugin=auth_plugin, auth_token=auth_token,
            volume_service_name=volume_service_name,
            timings=args.timings, bypass_url=bypass_url,
            os_cache=os_cache, http_log_debug=args.debug,
            cacert=cacert, timeout=timeout,
            session=keystone_session, auth=keystone_auth)

        # Now check for the password/token of which pieces of the
        # identifying keyring key can come from the underlying client
        span_host = tomograph.getHost()
        span_name = ' '.join(sys.argv)
        # for arg in argv:
        #     if arg[0] is not '-':
        #         span_name = span_name + ' ' + arg
        tomograph.start("novaclient-shell", span_name, span_host, 0)

        if must_auth:
            helper = SecretsHelper(args, self.cs.client)
            self.cs.client.keyring_saver = helper
            if (auth_plugin and auth_plugin.opts and
                    "os_password" not in auth_plugin.opts):
                use_pw = False
            else:
                use_pw = True

            tenant_id = helper.tenant_id
            # Allow commandline to override cache
            if not auth_token:
                auth_token = helper.auth_token
            if not management_url:
                management_url = helper.management_url
            if tenant_id and auth_token and management_url:
                self.cs.client.tenant_id = tenant_id
                self.cs.client.auth_token = auth_token
                self.cs.client.management_url = management_url
                self.cs.client.password_func = lambda: helper.password
            elif use_pw:
                # We're missing something, so auth with user/pass and save
                # the result in our helper.
                self.cs.client.password = helper.password

        try:
            # This does a couple of bits which are useful even if we've
            # got the token + service URL already. It exits fast in that case.
            if not cliutils.isunauthenticated(args.func):
                if not use_session:
                    # Only call authenticate() if Nova auth plugin is used.
                    # If keystone is used, authentication is handled as part
                    # of session.
                    self.cs.authenticate()
        except exc.Unauthorized:
            tomograph.tag("Exception", "Unauthorized")
            tomograph.stop(span_name)
            raise exc.CommandError(_("Invalid OpenStack Nova credentials."))
        except exc.AuthorizationFailure:
            tomograph.tag("Exception", "AuthorizationFailure")
            tomograph.stop(span_name)
            raise exc.CommandError(_("Unable to authorize user"))

        args.func(self.cs, args)

        if args.timings:
            self._dump_timings(self.times + self.cs.get_timings())

        tomograph.stop(span_name)
Exemplo n.º 13
0
    def main(self, argv):
        # Parse args once to find version and debug settings
        parser = self.get_base_parser()

        # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.

        if '--endpoint_type' in argv:
            spot = argv.index('--endpoint_type')
            argv[spot] = '--endpoint-type'

        (args, args_list) = parser.parse_known_args(argv)

        self.setup_debugging(args.debug)
        self.extensions = []
        do_help = ('help' in argv) or not argv

        # Discover available auth plugins
        #tomograph.annotate("Discover available auth plugins", "novaclient-shell")
        novaclient.auth_plugin.discover_auth_systems()

        if not args.os_compute_api_version:
            api_version = api_versions.get_api_version(
                DEFAULT_MAJOR_OS_COMPUTE_API_VERSION)
        else:
            api_version = api_versions.get_api_version(
                args.os_compute_api_version)

        os_username = args.os_username
        os_user_id = args.os_user_id
        os_password = None  # Fetched and set later as needed
        os_tenant_name = args.os_tenant_name
        os_tenant_id = args.os_tenant_id
        os_auth_url = args.os_auth_url
        os_region_name = args.os_region_name
        os_auth_system = args.os_auth_system
        endpoint_type = args.endpoint_type
        insecure = args.insecure
        service_type = args.service_type
        service_name = args.service_name
        volume_service_name = args.volume_service_name
        bypass_url = args.bypass_url
        os_cache = args.os_cache
        cacert = args.os_cacert
        timeout = args.timeout

        keystone_session = None
        keystone_auth = None

        # We may have either, both or none of these.
        # If we have both, we don't need USERNAME, PASSWORD etc.
        # Fill in the blanks from the SecretsHelper if possible.
        # Finally, authenticate unless we have both.
        # Note if we don't auth we probably don't have a tenant ID so we can't
        # cache the token.
        auth_token = args.os_auth_token if args.os_auth_token else None
        management_url = bypass_url if bypass_url else None

        if os_auth_system and os_auth_system != "keystone":
            auth_plugin = novaclient.auth_plugin.load_plugin(os_auth_system)
        else:
            auth_plugin = None

        if not endpoint_type:
            endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE

        # This allow users to use endpoint_type as (internal, public or admin)
        # just like other openstack clients (glance, cinder etc)
        if endpoint_type in ['internal', 'public', 'admin']:
            endpoint_type += 'URL'

        if not service_type:
            # Note(alex_xu): We need discover version first, so if there isn't
            # service type specified, we use default nova service type.
            service_type = DEFAULT_NOVA_SERVICE_TYPE

        # If we have an auth token but no management_url, we must auth anyway.
        # Expired tokens are handled by client.py:_cs_request
        must_auth = not (auth_token and management_url)

        # Do not use Keystone session for cases with no session support. The
        # presence of auth_plugin means os_auth_system is present and is not
        # keystone.
        use_session = True
        if auth_plugin or bypass_url or os_cache or volume_service_name:
            use_session = False

        # FIXME(usrleon): Here should be restrict for project id same as
        # for os_username or os_password but for compatibility it is not.
        if must_auth and not do_help:
            if auth_plugin:
                auth_plugin.parse_opts(args)

            if not auth_plugin or not auth_plugin.opts:
                if not os_username and not os_user_id:
                    raise exc.CommandError(
                        _("You must provide a username "
                          "or user id via --os-username, --os-user-id, "
                          "env[OS_USERNAME] or env[OS_USER_ID]"))

            if not any([
                    args.os_tenant_name, args.os_tenant_id, args.os_project_id,
                    args.os_project_name
            ]):
                raise exc.CommandError(
                    _("You must provide a project name or"
                      " project id via --os-project-name,"
                      " --os-project-id, env[OS_PROJECT_ID]"
                      " or env[OS_PROJECT_NAME]. You may"
                      " use os-project and os-tenant"
                      " interchangeably."))

            if not os_auth_url:
                if os_auth_system and os_auth_system != 'keystone':
                    os_auth_url = auth_plugin.get_auth_url()

            if not os_auth_url:
                raise exc.CommandError(
                    _("You must provide an auth url "
                      "via either --os-auth-url or env[OS_AUTH_URL] "
                      "or specify an auth_system which defines a "
                      "default url with --os-auth-system "
                      "or env[OS_AUTH_SYSTEM]"))

            project_id = args.os_project_id or args.os_tenant_id
            project_name = args.os_project_name or args.os_tenant_name
            if use_session:
                # Not using Nova auth plugin, so use keystone
                with utils.record_time(self.times, args.timings, 'auth_url',
                                       args.os_auth_url):
                    keystone_session = (
                        ksession.Session.load_from_cli_options(args))
                    keystone_auth = self._get_keystone_auth(
                        keystone_session,
                        args.os_auth_url,
                        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_token=args.os_auth_token,
                        project_id=project_id,
                        project_name=project_name,
                        project_domain_id=args.os_project_domain_id,
                        project_domain_name=args.os_project_domain_name)

        if not do_help and not any([
                args.os_tenant_id, args.os_tenant_name, args.os_project_id,
                args.os_project_name
        ]):
            raise exc.CommandError(
                _("You must provide a project name or"
                  " project id via --os-project-name,"
                  " --os-project-id, env[OS_PROJECT_ID]"
                  " or env[OS_PROJECT_NAME]. You may"
                  " use os-project and os-tenant"
                  " interchangeably."))

        if not os_auth_url and not do_help:
            raise exc.CommandError(
                _("You must provide an auth url "
                  "via either --os-auth-url or env[OS_AUTH_URL]"))

        # This client is just used to discover api version. Version API needn't
        # microversion, so we just pass version 2 at here.
        #tomograph.annotate("Discover api version", "novaclient-shell")
        self.cs = client.Client(api_versions.APIVersion("2.0"),
                                os_username,
                                os_password,
                                os_tenant_name,
                                tenant_id=os_tenant_id,
                                user_id=os_user_id,
                                auth_url=os_auth_url,
                                insecure=insecure,
                                region_name=os_region_name,
                                endpoint_type=endpoint_type,
                                extensions=self.extensions,
                                service_type=service_type,
                                service_name=service_name,
                                auth_system=os_auth_system,
                                auth_plugin=auth_plugin,
                                auth_token=auth_token,
                                volume_service_name=volume_service_name,
                                timings=args.timings,
                                bypass_url=bypass_url,
                                os_cache=os_cache,
                                http_log_debug=args.debug,
                                cacert=cacert,
                                timeout=timeout,
                                session=keystone_session,
                                auth=keystone_auth)

        if not do_help:
            if not api_version.is_latest():
                if api_version > api_versions.APIVersion("2.0"):
                    if not api_version.matches(novaclient.API_MIN_VERSION,
                                               novaclient.API_MAX_VERSION):
                        raise exc.CommandError(
                            _("The specified version isn't supported by "
                              "client. The valid version range is '%(min)s' "
                              "to '%(max)s'") %
                            {
                                "min": novaclient.API_MIN_VERSION.get_string(),
                                "max": novaclient.API_MAX_VERSION.get_string()
                            })
            api_version = api_versions.discover_version(self.cs, api_version)

        # build available subcommands based on version
        self.extensions = client.discover_extensions(api_version)
        self._run_extension_hooks('__pre_parse_args__')

        subcommand_parser = self.get_subcommand_parser(api_version,
                                                       do_help=do_help)
        self.parser = subcommand_parser

        if args.help or not argv:
            subcommand_parser.print_help()
            return 0

        args = subcommand_parser.parse_args(argv)
        self._run_extension_hooks('__post_parse_args__', args)

        # Short-circuit and deal with help 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.service_type:
            service_type = (cliutils.get_service_type(args.func)
                            or DEFAULT_NOVA_SERVICE_TYPE)

        if cliutils.isunauthenticated(args.func):
            # NOTE(alex_xu): We need authentication for discover microversion.
            # But the subcommands may needn't it. If the subcommand needn't,
            # we clear the session arguements.
            keystone_session = None
            keystone_auth = None

        # Recreate client object with discovered version.
        self.cs = client.Client(api_version,
                                os_username,
                                os_password,
                                os_tenant_name,
                                tenant_id=os_tenant_id,
                                user_id=os_user_id,
                                auth_url=os_auth_url,
                                insecure=insecure,
                                region_name=os_region_name,
                                endpoint_type=endpoint_type,
                                extensions=self.extensions,
                                service_type=service_type,
                                service_name=service_name,
                                auth_system=os_auth_system,
                                auth_plugin=auth_plugin,
                                auth_token=auth_token,
                                volume_service_name=volume_service_name,
                                timings=args.timings,
                                bypass_url=bypass_url,
                                os_cache=os_cache,
                                http_log_debug=args.debug,
                                cacert=cacert,
                                timeout=timeout,
                                session=keystone_session,
                                auth=keystone_auth)

        # Now check for the password/token of which pieces of the
        # identifying keyring key can come from the underlying client
        span_host = tomograph.getHost()
        span_name = ' '.join(sys.argv)
        # for arg in argv:
        #     if arg[0] is not '-':
        #         span_name = span_name + ' ' + arg
        tomograph.start("novaclient-shell", span_name, span_host, 0)

        if must_auth:
            helper = SecretsHelper(args, self.cs.client)
            self.cs.client.keyring_saver = helper
            if (auth_plugin and auth_plugin.opts
                    and "os_password" not in auth_plugin.opts):
                use_pw = False
            else:
                use_pw = True

            tenant_id = helper.tenant_id
            # Allow commandline to override cache
            if not auth_token:
                auth_token = helper.auth_token
            if not management_url:
                management_url = helper.management_url
            if tenant_id and auth_token and management_url:
                self.cs.client.tenant_id = tenant_id
                self.cs.client.auth_token = auth_token
                self.cs.client.management_url = management_url
                self.cs.client.password_func = lambda: helper.password
            elif use_pw:
                # We're missing something, so auth with user/pass and save
                # the result in our helper.
                self.cs.client.password = helper.password

        try:
            # This does a couple of bits which are useful even if we've
            # got the token + service URL already. It exits fast in that case.
            if not cliutils.isunauthenticated(args.func):
                if not use_session:
                    # Only call authenticate() if Nova auth plugin is used.
                    # If keystone is used, authentication is handled as part
                    # of session.
                    self.cs.authenticate()
        except exc.Unauthorized:
            tomograph.tag("Exception", "Unauthorized")
            tomograph.stop(span_name)
            raise exc.CommandError(_("Invalid OpenStack Nova credentials."))
        except exc.AuthorizationFailure:
            tomograph.tag("Exception", "AuthorizationFailure")
            tomograph.stop(span_name)
            raise exc.CommandError(_("Unable to authorize user"))

        args.func(self.cs, args)

        if args.timings:
            self._dump_timings(self.times + self.cs.get_timings())

        tomograph.stop(span_name)
Exemplo n.º 14
0
Arquivo: shell.py Projeto: hbkqh/patch
    def main(self, argv):
        # Parse args once to find version

        # NOTE(flepied) Under Python3, parsed arguments are removed
        # from the list so make a copy for the first parsing
        base_argv = copy.deepcopy(argv)
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(base_argv)

        span_host = tomograph.getHost()
        span_name = ' '.join(sys.argv)
        tomograph.start("glanceclient-shell", span_name, span_host, 0)

        try:
            # NOTE(flaper87): Try to get the version from the
            # image-url first. If no version was specified, fallback
            # to the api-image-version arg. If both of these fail then
            # fallback to the minimum supported one and let keystone
            # do the magic.
            endpoint = self._get_image_url(options)
            endpoint, url_version = utils.strip_version(endpoint)
        except ValueError:
            # NOTE(flaper87): ValueError is raised if no endpoint is povided
            url_version = None

        # build available subcommands based on version
        try:
            api_version = int(options.os_image_api_version or url_version or 2)
            if api_version not in SUPPORTED_VERSIONS:
                raise ValueError
        except ValueError:
            msg = ("Invalid API version parameter. "
                   "Supported values are %s" % SUPPORTED_VERSIONS)
            utils.exit(msg=msg)

        if api_version == 2:
            switch_version = self._cache_schemas(options)
            if switch_version:
                print('WARNING: The client is falling back to v1 because'
                      ' the accessing to v2 failed. This behavior will'
                      ' be removed in future versions')
                api_version = 1

        try:
            subcommand_parser = self.get_subcommand_parser(api_version)
        except ImportError as e:
            if options.debug:
                traceback.print_exc()
            if not str(e):
                # Add a generic import error message if the raised ImportError
                # has none.
                raise ImportError('Unable to import module. Re-run '
                                  'with --debug for more info.')
            raise
        except Exception:
            if options.debug:
                traceback.print_exc()
            raise

        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if 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

        LOG = logging.getLogger('glanceclient')
        LOG.addHandler(logging.StreamHandler())
        LOG.setLevel(logging.DEBUG if args.debug else logging.INFO)

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

        client = self._get_versioned_client(api_version,
                                            args,
                                            force_auth=False)

        try:
            # pdb.set_trace()
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError("Invalid OpenStack Identity credentials.")
        except Exception:
            # NOTE(kragniz) Print any exceptions raised to stderr if the
            # --debug flag is set
            if args.debug:
                traceback.print_exc()
            raise
        finally:
            tomograph.stop(span_name)
            if profile:
                trace_id = osprofiler_profiler.get().get_base_id()
                print("Profiling trace ID: %s" % trace_id)
                print("To display trace use next command:\n"
                      "osprofiler trace show --html %s " % trace_id)
Exemplo n.º 15
0
Arquivo: shell.py Projeto: hbkqh/patch
    def main(self, argv):
        # Parse args once to find version

        # NOTE(flepied) Under Python3, parsed arguments are removed
        # from the list so make a copy for the first parsing
        base_argv = copy.deepcopy(argv)
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(base_argv)

        span_host = tomograph.getHost()
        span_name = ' '.join(sys.argv)
        tomograph.start("glanceclient-shell", span_name, span_host, 0)

        try:
            # NOTE(flaper87): Try to get the version from the
            # image-url first. If no version was specified, fallback
            # to the api-image-version arg. If both of these fail then
            # fallback to the minimum supported one and let keystone
            # do the magic.
            endpoint = self._get_image_url(options)
            endpoint, url_version = utils.strip_version(endpoint)
        except ValueError:
            # NOTE(flaper87): ValueError is raised if no endpoint is povided
            url_version = None

        # build available subcommands based on version
        try:
            api_version = int(options.os_image_api_version or url_version or 2)
            if api_version not in SUPPORTED_VERSIONS:
                raise ValueError
        except ValueError:
            msg = ("Invalid API version parameter. "
                   "Supported values are %s" % SUPPORTED_VERSIONS)
            utils.exit(msg=msg)

        if api_version == 2:
            switch_version = self._cache_schemas(options)
            if switch_version:
                print('WARNING: The client is falling back to v1 because'
                      ' the accessing to v2 failed. This behavior will'
                      ' be removed in future versions')
                api_version = 1

        try:
            subcommand_parser = self.get_subcommand_parser(api_version)
        except ImportError as e:
            if options.debug:
                traceback.print_exc()
            if not str(e):
                # Add a generic import error message if the raised ImportError
                # has none.
                raise ImportError('Unable to import module. Re-run '
                                  'with --debug for more info.')
            raise
        except Exception:
            if options.debug:
                traceback.print_exc()
            raise

        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if 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

        LOG = logging.getLogger('glanceclient')
        LOG.addHandler(logging.StreamHandler())
        LOG.setLevel(logging.DEBUG if args.debug else logging.INFO)

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

        client = self._get_versioned_client(api_version, args,
                                            force_auth=False)

        try:
            # pdb.set_trace()
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError("Invalid OpenStack Identity credentials.")
        except Exception:
            # NOTE(kragniz) Print any exceptions raised to stderr if the
            # --debug flag is set
            if args.debug:
                traceback.print_exc()
            raise
        finally:
            tomograph.stop(span_name)
            if profile:
                trace_id = osprofiler_profiler.get().get_base_id()
                print("Profiling trace ID: %s" % trace_id)
                print("To display trace use next command:\n"
                      "osprofiler trace show --html %s " % trace_id)