def test_user_and_project_id(self):
        auth = AuthPlugin()
        sess = client_session.Session()
        adpt = adapter.Adapter(sess, auth=auth)

        self.assertEqual(auth.TEST_USER_ID, adpt.get_user_id())
        self.assertEqual(auth.TEST_PROJECT_ID, adpt.get_project_id())
    def test_adapter_get_token(self):
        auth = CalledAuthPlugin()
        sess = client_session.Session()
        adpt = adapter.Adapter(sess, auth=auth)

        self.assertEqual(self.TEST_TOKEN, adpt.get_token())
        self.assertTrue(auth.get_token_called)
Beispiel #3
0
    def test_logger_object_passed(self):
        logger = logging.getLogger(uuid.uuid4().hex)
        logger.setLevel(logging.DEBUG)
        logger.propagate = False

        io = six.StringIO()
        handler = logging.StreamHandler(io)
        logger.addHandler(handler)

        auth = AuthPlugin()
        sess = client_session.Session(auth=auth)
        adpt = adapter.Adapter(sess, auth=auth, logger=logger)

        response = {uuid.uuid4().hex: uuid.uuid4().hex}

        self.stub_url('GET', json=response,
                      headers={'Content-Type': 'application/json'})

        resp = adpt.get(self.TEST_URL, logger=logger)

        self.assertEqual(response, resp.json())
        output = io.getvalue()

        self.assertIn(self.TEST_URL, output)
        self.assertIn(list(response.keys())[0], output)
        self.assertIn(list(response.values())[0], output)

        self.assertNotIn(self.TEST_URL, self.logger.output)
        self.assertNotIn(list(response.keys())[0], self.logger.output)
        self.assertNotIn(list(response.values())[0], self.logger.output)
Beispiel #4
0
    def test_logger_object_passed(self):
        logger = logging.getLogger(uuid.uuid4().hex)
        logger.setLevel(logging.DEBUG)
        logger.propagate = False

        io = six.StringIO()
        handler = logging.StreamHandler(io)
        logger.addHandler(handler)

        auth = AuthPlugin()
        sess = client_session.Session(auth=auth)
        adpt = adapter.Adapter(sess, auth=auth, logger=logger)

        response = uuid.uuid4().hex

        self.stub_url('GET',
                      text=response,
                      headers={'Content-Type': 'text/html'})

        resp = adpt.get(self.TEST_URL, logger=logger)

        self.assertEqual(response, resp.text)
        output = io.getvalue()

        self.assertIn(self.TEST_URL, output)
        self.assertIn(response, output)

        self.assertNotIn(self.TEST_URL, self.logger.output)
        self.assertNotIn(response, self.logger.output)
Beispiel #5
0
    def _create_identity_server(self):
        # NOTE(jamielennox): Loading Session here should be exactly the
        # same as calling Session.load_from_conf_options(CONF, GROUP)
        # however we can't do that because we have to use _conf_get to
        # support the paste.ini options.
        sess = session.Session.construct(
            dict(cert=self._conf_get('certfile'),
                 key=self._conf_get('keyfile'),
                 cacert=self._conf_get('cafile'),
                 insecure=self._conf_get('insecure'),
                 timeout=self._conf_get('http_connect_timeout'),
                 user_agent=self._build_useragent_string()))

        auth_plugin = self._get_auth_plugin()

        adap = adapter.Adapter(
            sess,
            auth=auth_plugin,
            service_type='identity',
            interface='admin',
            region_name=self._conf_get('region_name'),
            connect_retries=self._conf_get('http_request_max_retries'))

        auth_version = self._conf_get('auth_version')
        if auth_version is not None:
            auth_version = discover.normalize_version_number(auth_version)
        return _identity.IdentityServer(
            self.log,
            adap,
            include_service_catalog=self._include_service_catalog,
            requested_auth_version=auth_version)
Beispiel #6
0
    def test_setting_variables(self):
        response = uuid.uuid4().hex
        self.stub_url(httpretty.GET, body=response)

        auth = CalledAuthPlugin()
        sess = client_session.Session()
        adpt = adapter.Adapter(sess,
                               auth=auth,
                               service_type=self.SERVICE_TYPE,
                               service_name=self.SERVICE_NAME,
                               interface=self.INTERFACE,
                               region_name=self.REGION_NAME,
                               user_agent=self.USER_AGENT)

        resp = adpt.get('/')
        self.assertEqual(resp.text, response)

        self.assertEqual(self.SERVICE_TYPE,
                         auth.endpoint_arguments['service_type'])
        self.assertEqual(self.SERVICE_NAME,
                         auth.endpoint_arguments['service_name'])
        self.assertEqual(self.INTERFACE, auth.endpoint_arguments['interface'])
        self.assertEqual(self.REGION_NAME,
                         auth.endpoint_arguments['region_name'])

        self.assertTrue(auth.get_token_called)
        self.assertRequestHeaderEqual('User-Agent', self.USER_AGENT)
    def test_adapter_invalidate(self):
        auth = CalledAuthPlugin()
        sess = client_session.Session()
        adpt = adapter.Adapter(sess, auth=auth)

        adpt.invalidate()

        self.assertTrue(auth.invalidate_called)
    def test_adapter_get_token(self):
        auth = CalledAuthPlugin()
        sess = client_session.Session()
        adpt = adapter.Adapter(sess, auth=auth)

        with self.deprecations.expect_deprecations_here():
            self.assertEqual(self.TEST_TOKEN, adpt.get_token())
        self.assertTrue(auth.get_token_called)
    def test_methods(self):
        sess = client_session.Session()
        adpt = adapter.Adapter(sess)
        url = 'http://url'

        for method in ['get', 'head', 'post', 'put', 'patch', 'delete']:
            with mock.patch.object(adpt, 'request') as m:
                getattr(adpt, method)(url)
                m.assert_called_once_with(url, method.upper())
 def _create_loaded_adapter(self):
     auth = CalledAuthPlugin()
     sess = client_session.Session()
     return adapter.Adapter(sess,
                            auth=auth,
                            service_type=self.SERVICE_TYPE,
                            service_name=self.SERVICE_NAME,
                            interface=self.INTERFACE,
                            region_name=self.REGION_NAME,
                            user_agent=self.USER_AGENT,
                            version=self.VERSION)
Beispiel #11
0
    def test_setting_endpoint_override(self):
        endpoint_override = 'http://overrideurl'
        path = '/path'
        endpoint_url = endpoint_override + path

        auth = CalledAuthPlugin()
        sess = client_session.Session(auth=auth)
        adpt = adapter.Adapter(sess, endpoint_override=endpoint_override)

        response = uuid.uuid4().hex
        self.requests.register_uri('GET', endpoint_url, text=response)

        resp = adpt.get(path)

        self.assertEqual(response, resp.text)
        self.assertEqual(endpoint_url, self.requests.last_request.url)
    def test_adapter_connect_retries(self):
        retries = 2
        sess = client_session.Session()
        adpt = adapter.Adapter(sess, connect_retries=retries)

        def _refused_error(request, context):
            raise requests.exceptions.ConnectionError()

        self.stub_url('GET', text=_refused_error)

        with mock.patch('time.sleep') as m:
            self.assertRaises(exceptions.ConnectionRefused, adpt.get,
                              self.TEST_URL)
            self.assertEqual(retries, m.call_count)

        # we count retries so there will be one initial request + 2 retries
        self.assertThat(self.requests.request_history,
                        matchers.HasLength(retries + 1))
Beispiel #13
0
    def main(self, argv):
        # Parse args once to find version and debug settings
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)
        self.setup_debugging(options.debug)
        api_version_input = True
        service_type_input = True
        self.options = options

        if not options.os_volume_api_version:
            # Environment variable OS_VOLUME_API_VERSION was
            # not set and '--os-volume-api-version' option doesn't
            # specify a value.  Fall back to default.
            options.os_volume_api_version = DEFAULT_OS_VOLUME_API_VERSION
            api_version_input = False

        version = (options.os_volume_api_version, )

        # build available subcommands based on version
        self.extensions = self._discover_extensions(
            options.os_volume_api_version)
        self._run_extension_hooks('__pre_parse_args__')

        subcommand_parser = self.get_subcommand_parser(
            options.os_volume_api_version)
        self.parser = subcommand_parser

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

        argv = self._delimit_metadata_args(argv)
        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

        (os_username, os_password, os_tenant_name, os_auth_url, os_region_name,
         os_tenant_id, endpoint_type, insecure, service_type, service_name,
         volume_service_name, bypass_url, cacert,
         os_auth_system) = (args.os_username, args.os_password,
                            args.os_tenant_name, args.os_auth_url,
                            args.os_region_name, args.os_tenant_id,
                            args.endpoint_type, args.insecure,
                            args.service_type, args.service_name,
                            args.volume_service_name, args.bypass_url,
                            args.os_cacert, args.os_auth_system)
        if os_auth_system and os_auth_system != "keystone":
            auth_plugin = cinderclient.auth_plugin.load_plugin(os_auth_system)
        else:
            auth_plugin = None

        if not endpoint_type:
            endpoint_type = DEFAULT_CINDER_ENDPOINT_TYPE

        if not service_type:
            service_type = DEFAULT_CINDER_SERVICE_TYPE
            service_type = utils.get_service_type(args.func) or service_type
            service_type_input = 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 not utils.isunauthenticated(args.func):
            if auth_plugin:
                auth_plugin.parse_opts(args)

            if not auth_plugin or not auth_plugin.opts:
                if not os_username:
                    raise exc.CommandError("You must provide a user name "
                                           "through --os-username or "
                                           "env[OS_USERNAME].")

            if not os_password:
                # No password, If we've got a tty, try prompting for it
                if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
                    # Check for Ctl-D
                    try:
                        os_password = getpass.getpass('OS Password: '******'t have a tty or the
                # user Ctl-D when prompted.
                if not os_password:
                    raise exc.CommandError("You must provide a password "
                                           "through --os-password, "
                                           "env[OS_PASSWORD] "
                                           "or, prompted response.")

            if not (os_tenant_name or os_tenant_id):
                raise exc.CommandError("You must provide a tenant ID "
                                       "through --os-tenant-id or "
                                       "env[OS_TENANT_ID].")

            # V3 stuff
            project_info_provided = self.options.os_tenant_name or \
                self.options.os_tenant_id or \
                (self.options.os_project_name and
                 (self.options.project_domain_name or
                  self.options.project_domain_id)) or \
                self.options.os_project_id

            if (not project_info_provided):
                raise exc.CommandError(
                    _("You must provide a tenant_name, tenant_id, "
                      "project_id or project_name (with "
                      "project_domain_name or project_domain_id) via "
                      "  --os-tenant-name (env[OS_TENANT_NAME]),"
                      "  --os-tenant-id (env[OS_TENANT_ID]),"
                      "  --os-project-id (env[OS_PROJECT_ID])"
                      "  --os-project-name (env[OS_PROJECT_NAME]),"
                      "  --os-project-domain-id "
                      "(env[OS_PROJECT_DOMAIN_ID])"
                      "  --os-project-domain-name "
                      "(env[OS_PROJECT_DOMAIN_NAME])"))

            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 authentication URL "
                    "through --os-auth-url or env[OS_AUTH_URL].")

        if not (os_tenant_name or os_tenant_id):
            raise exc.CommandError(
                "You must provide a tenant ID "
                "through --os-tenant-id or env[OS_TENANT_ID].")

        if not os_auth_url:
            raise exc.CommandError(
                "You must provide an authentication URL "
                "through --os-auth-url or env[OS_AUTH_URL].")

        auth_session = self._get_keystone_session()
        if not service_type_input or not api_version_input:
            # NOTE(thingee): Unfortunately the v2 shell is tied to volumev2
            # service_type. If the service_catalog just contains service_type
            # volume with x.x.x.x:8776 for discovery, and the user sets version
            # 2 for the client, it'll default to volumev2 and raise
            # EndpointNotFound. This is a workaround until we feel comfortable
            # with removing the volumev2 assumption.
            keystone_adapter = adapter.Adapter(auth_session)
            try:
                # Try just the client's defaults
                endpoint = keystone_adapter.get_endpoint(
                    service_type=service_type,
                    version=version,
                    interface='public')

                # Service was found, but wrong version. Lets try a different
                # version, if the user did not specify one.
                if not endpoint and not api_version_input:
                    if version == ('1', ):
                        version = ('2', )
                    else:
                        version = ('1', )

                    endpoint = keystone_adapter.get_endpoint(
                        service_type=service_type,
                        version=version,
                        interface='public')

            except keystoneclient_exc.EndpointNotFound as e:
                # No endpoint found with that service_type, lets fall back to
                # other service_types if the user did not specify one.
                if not service_type_input:
                    if service_type == 'volume':
                        service_type = 'volumev2'
                    else:
                        service_type = 'volume'

                try:
                    endpoint = keystone_adapter.get_endpoint(
                        version=version,
                        service_type=service_type,
                        interface='public')

                    # Service was found, but wrong version. Lets try
                    # a different version, if the user did not specify one.
                    if not endpoint and not api_version_input:
                        if version == ('1', ):
                            version = ('2', )
                        else:
                            version = ('1', )

                        endpoint = keystone_adapter.get_endpoint(
                            service_type=service_type,
                            version=version,
                            interface='public')

                except keystoneclient_exc.EndpointNotFound:
                    raise e

        self.cs = client.Client(version[0],
                                os_username,
                                os_password,
                                os_tenant_name,
                                os_auth_url,
                                region_name=os_region_name,
                                tenant_id=os_tenant_id,
                                endpoint_type=endpoint_type,
                                extensions=self.extensions,
                                service_type=service_type,
                                service_name=service_name,
                                volume_service_name=volume_service_name,
                                bypass_url=bypass_url,
                                retries=options.retries,
                                http_log_debug=args.debug,
                                cacert=cacert,
                                auth_system=os_auth_system,
                                auth_plugin=auth_plugin,
                                session=auth_session)

        try:
            if not utils.isunauthenticated(args.func):
                self.cs.authenticate()
        except exc.Unauthorized:
            raise exc.CommandError("OpenStack credentials are not valid.")
        except exc.AuthorizationFailure:
            raise exc.CommandError("Unable to authorize user.")

        endpoint_api_version = None
        # Try to get the API version from the endpoint URL.  If that fails fall
        # back to trying to use what the user specified via
        # --os-volume-api-version or with the OS_VOLUME_API_VERSION environment
        # variable.  Fail safe is to use the default API setting.
        try:
            endpoint_api_version = \
                self.cs.get_volume_api_version_from_endpoint()
            if (endpoint_api_version != options.os_volume_api_version
                    and api_version_input):
                msg = (("OpenStack Block Storage API version is set to %s "
                        "but you are accessing a %s endpoint. "
                        "Change its value through --os-volume-api-version "
                        "or env[OS_VOLUME_API_VERSION].") %
                       (options.os_volume_api_version, endpoint_api_version))
                raise exc.InvalidAPIVersion(msg)
        except exc.UnsupportedVersion:
            endpoint_api_version = options.os_volume_api_version
            if api_version_input:
                logger.warning("Cannot determine the API version from "
                               "the endpoint URL. Falling back to the "
                               "user-specified version: %s" %
                               endpoint_api_version)
            else:
                logger.warning("Cannot determine the API version from the "
                               "endpoint URL or user input. Falling back "
                               "to the default API version: %s" %
                               endpoint_api_version)

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

        args.func(self.cs, 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)
 def test_init_with_session(self):
     session = keystone_session.Session()
     adapted = adapter.Adapter(session=session)
     client = Client(session=adapted)
     assert client.session