Add keystone v3 support to client
All clients should support keystone v3 till kilo. This patch adds support for keystone sessions, keystone endpoint discovery and support for the CLI to provide keystone v3 options. Also, bumped glance client API version to 2 for the compatibility with v3 keystone API. Change-Id: I565927db7f393c0bae41ebf9c03488f9cd966e79 Co-Authored-By: David Hu <david.hu@hp.com> Co-Authored-By: Steve McLellan <steven.j.mclellan@gmail.com> Closes-Bug: #1354129 Closes-Bug: #1507932 Implements: blueprint support-keystone-v3
This commit is contained in:
parent
0907116f89
commit
c60feee45c
|
@ -18,6 +18,7 @@ import hashlib
|
|||
import os
|
||||
import socket
|
||||
|
||||
import keystoneclient.adapter as keystone_adapter
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import encodeutils
|
||||
|
@ -299,3 +300,85 @@ class HTTPClient(object):
|
|||
|
||||
def patch(self, url, **kwargs):
|
||||
return self.client_request("PATCH", url, **kwargs)
|
||||
|
||||
|
||||
class SessionClient(keystone_adapter.LegacyJsonAdapter):
|
||||
|
||||
def request(self, url, method, **kwargs):
|
||||
raise_exc = kwargs.pop('raise_exc', True)
|
||||
resp, body = super(SessionClient, self).request(url,
|
||||
method,
|
||||
raise_exc=False,
|
||||
**kwargs)
|
||||
|
||||
if raise_exc and resp.status_code >= 400:
|
||||
LOG.warning(exc.from_response(resp))
|
||||
raise exc.from_response(resp)
|
||||
|
||||
return resp, body
|
||||
|
||||
def json_request(self, method, url, **kwargs):
|
||||
# Legacy adapter expects the payload in 'body', but
|
||||
# will pass it to the non-legacy adapter in the
|
||||
# 'json' spot so encoding happens later
|
||||
if 'data' in kwargs:
|
||||
if 'body' in kwargs:
|
||||
raise ValueError("Can't provide both 'data' and "
|
||||
"'body' to a request")
|
||||
LOG.warning("Use of 'body' is deprecated; use 'data' instead")
|
||||
kwargs['body'] = kwargs.pop('data')
|
||||
|
||||
# The argument order is different, beware
|
||||
return self.request(url, method, **kwargs)
|
||||
|
||||
def json_patch_request(self, url, method='PATCH', **kwargs):
|
||||
content_type = 'application/murano-packages-json-patch'
|
||||
return self.json_request(
|
||||
method, url, content_type=content_type, **kwargs)
|
||||
|
||||
def raw_request(self, method, url, **kwargs):
|
||||
# A non-json request; instead of calling
|
||||
# super.request, need to call the grandparent
|
||||
# adapter.request
|
||||
raise_exc = kwargs.pop('raise_exc', True)
|
||||
if 'body' in kwargs:
|
||||
if 'data' in kwargs:
|
||||
raise ValueError("Can't provide both 'data' and "
|
||||
"'body' to a request")
|
||||
LOG.warning("Use of 'body' is deprecated; use 'data' instead")
|
||||
kwargs['data'] = kwargs.pop('body')
|
||||
resp = keystone_adapter.Adapter.request(self,
|
||||
url,
|
||||
method,
|
||||
raise_exc=False,
|
||||
**kwargs)
|
||||
body = resp.text
|
||||
|
||||
if raise_exc and resp.status_code >= 400:
|
||||
LOG.warning(exc.from_response(resp))
|
||||
raise exc.from_response(resp)
|
||||
|
||||
return resp, body
|
||||
|
||||
|
||||
def _construct_http_client(*args, **kwargs):
|
||||
session = kwargs.pop('session', None)
|
||||
auth = kwargs.pop('auth', None)
|
||||
endpoint = next(iter(args), None)
|
||||
|
||||
if session:
|
||||
service_type = kwargs.pop('service_type', None)
|
||||
endpoint_type = kwargs.pop('endpoint_type', None)
|
||||
region_name = kwargs.pop('region_name', None)
|
||||
service_name = kwargs.pop('service_name', None)
|
||||
return SessionClient(endpoint_override=endpoint,
|
||||
session=session,
|
||||
auth=auth,
|
||||
interface=endpoint_type,
|
||||
service_type=service_type,
|
||||
region_name=region_name,
|
||||
service_name=service_name,
|
||||
user_agent='python-muranoclient',
|
||||
**kwargs)
|
||||
else:
|
||||
return HTTPClient(*args, **kwargs)
|
||||
|
|
|
@ -22,17 +22,22 @@ import argparse
|
|||
import sys
|
||||
|
||||
import glanceclient
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
from keystoneclient.auth.identity.generic import password
|
||||
from keystoneclient.auth.identity.generic import token
|
||||
from keystoneclient.auth.identity import v3 as identity
|
||||
from keystoneclient import discover
|
||||
from keystoneclient.openstack.common.apiclient import exceptions as ks_exc
|
||||
from keystoneclient import session as ksession
|
||||
from oslo_log import handlers
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import encodeutils
|
||||
import six
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
import muranoclient
|
||||
from muranoclient import client as apiclient
|
||||
from muranoclient import client as murano_client
|
||||
from muranoclient.common import utils
|
||||
from muranoclient.openstack.common.apiclient import exceptions as exc
|
||||
from muranoclient.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -41,7 +46,15 @@ DEFAULT_REPO_URL = "http://apps.openstack.org/api/v1/murano_repo/liberty/"
|
|||
|
||||
|
||||
class MuranoShell(object):
|
||||
|
||||
def _append_global_identity_args(self, parser):
|
||||
# Register the CLI arguments that have moved to the session object.
|
||||
ksession.Session.register_cli_options(parser)
|
||||
|
||||
identity.Password.register_argparse_arguments(parser)
|
||||
|
||||
def get_base_parser(self):
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='murano',
|
||||
description=__doc__.strip(),
|
||||
|
@ -70,53 +83,25 @@ class MuranoShell(object):
|
|||
default=False, action="store_true",
|
||||
help="Print more verbose output.")
|
||||
|
||||
parser.add_argument('-k', '--insecure',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Explicitly allow muranoclient 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-cacert',
|
||||
metavar='<ca-certificate>',
|
||||
default=utils.env('OS_CACERT', default=None),
|
||||
dest='os_cacert',
|
||||
help='Specify a CA bundle file to use in '
|
||||
'verifying a TLS (https) server certificate. '
|
||||
'Defaults to env[OS_CACERT].')
|
||||
|
||||
# os-cert, os-key, insecure, ca-file are all added
|
||||
# by keystone session register_cli_opts later
|
||||
parser.add_argument('--cert-file',
|
||||
help='Path of certificate file to use in SSL '
|
||||
'connection. This file can optionally be '
|
||||
'prepended with the private key.')
|
||||
dest='os_cert',
|
||||
help='DEPRECATED! Use --os-cert.')
|
||||
|
||||
parser.add_argument('--key-file',
|
||||
help='Path of client key to use '
|
||||
'in SSL connection. This option '
|
||||
'is not necessary if your key '
|
||||
'is prepended to your cert file.')
|
||||
dest='os_key',
|
||||
help='DEPRECATED! Use --os-key.')
|
||||
|
||||
parser.add_argument('--ca-file',
|
||||
dest='os_cacert',
|
||||
help=_('DEPRECATED! Use %(arg)s.') %
|
||||
{'arg': '--os-cacert'})
|
||||
help='DEPRECATED! Use --os-cacert.')
|
||||
|
||||
parser.add_argument('--api-timeout',
|
||||
help='Number of seconds to wait for an '
|
||||
'API response, '
|
||||
'defaults to system socket timeout.')
|
||||
|
||||
parser.add_argument('--os-username',
|
||||
default=utils.env('OS_USERNAME'),
|
||||
help='Defaults to env[OS_USERNAME].')
|
||||
|
||||
parser.add_argument('--os-password',
|
||||
default=utils.env('OS_PASSWORD'),
|
||||
help='Defaults to env[OS_PASSWORD].')
|
||||
|
||||
parser.add_argument('--os-tenant-id',
|
||||
default=utils.env('OS_TENANT_ID'),
|
||||
help='Defaults to env[OS_TENANT_ID].')
|
||||
|
@ -125,10 +110,6 @@ class MuranoShell(object):
|
|||
default=utils.env('OS_TENANT_NAME'),
|
||||
help='Defaults to env[OS_TENANT_NAME].')
|
||||
|
||||
parser.add_argument('--os-auth-url',
|
||||
default=utils.env('OS_AUTH_URL'),
|
||||
help='Defaults to env[OS_AUTH_URL].')
|
||||
|
||||
parser.add_argument('--os-region-name',
|
||||
default=utils.env('OS_REGION_NAME'),
|
||||
help='Defaults to env[OS_REGION_NAME].')
|
||||
|
@ -142,7 +123,6 @@ class MuranoShell(object):
|
|||
action='store_true',
|
||||
help="Do not contact keystone for a token. "
|
||||
"Defaults to env[OS_NO_CLIENT_AUTH].")
|
||||
|
||||
parser.add_argument('--murano-url',
|
||||
default=utils.env('MURANO_URL'),
|
||||
help='Defaults to env[MURANO_URL].')
|
||||
|
@ -177,6 +157,8 @@ class MuranoShell(object):
|
|||
help=('Defaults to env[MURANO_REPO_URL] '
|
||||
'or {0}'.format(DEFAULT_REPO_URL)))
|
||||
|
||||
self._append_global_identity_args(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def get_subcommand_parser(self, version):
|
||||
|
@ -221,38 +203,82 @@ class MuranoShell(object):
|
|||
subparser.add_argument(*args, **kwargs)
|
||||
subparser.set_defaults(func=callback)
|
||||
|
||||
def _get_ksclient(self, **kwargs):
|
||||
"""Get an endpoint and auth token from Keystone.
|
||||
def _discover_auth_versions(self, session, auth_url):
|
||||
# discover the API versions the server is supporting base on the
|
||||
# given URL
|
||||
v2_auth_url = None
|
||||
v3_auth_url = None
|
||||
try:
|
||||
ks_discover = discover.Discover(session=session, auth_url=auth_url)
|
||||
v2_auth_url = ks_discover.url_for('2.0')
|
||||
v3_auth_url = ks_discover.url_for('3.0')
|
||||
except ks_exc.ClientException as e:
|
||||
# Identity service may not support discover API version.
|
||||
# Lets trying to figure out the API version from the original URL.
|
||||
url_parts = urlparse.urlparse(auth_url)
|
||||
(scheme, netloc, path, params, query, fragment) = url_parts
|
||||
path = path.lower()
|
||||
if path.startswith('/v3'):
|
||||
v3_auth_url = auth_url
|
||||
elif path.startswith('/v2'):
|
||||
v2_auth_url = auth_url
|
||||
else:
|
||||
# not enough information to determine the auth version
|
||||
msg = ('Unable to determine the Keystone version '
|
||||
'to authenticate with using the given '
|
||||
'auth_url. Identity service may not support API '
|
||||
'version discovery. Please provide a versioned '
|
||||
'auth_url instead. error=%s') % (e)
|
||||
raise exc.CommandError(msg)
|
||||
|
||||
:param username: name of user
|
||||
:param password: user's password
|
||||
:param tenant_id: unique identifier of tenant
|
||||
:param tenant_name: name of tenant
|
||||
:param auth_url: endpoint to authenticate against
|
||||
"""
|
||||
kc_args = {
|
||||
'auth_url': kwargs.get('auth_url'),
|
||||
'insecure': kwargs.get('insecure'),
|
||||
'cacert': kwargs.get('cacert')}
|
||||
return (v2_auth_url, v3_auth_url)
|
||||
|
||||
if kwargs.get('tenant_id'):
|
||||
kc_args['tenant_id'] = kwargs.get('tenant_id')
|
||||
def _get_keystone_auth(self, session, auth_url, **kwargs):
|
||||
auth_token = kwargs.pop('auth_token', None)
|
||||
if auth_token:
|
||||
return token.Token(auth_url, auth_token, **kwargs)
|
||||
|
||||
# NOTE(starodubcevna): this is a workaround for the bug:
|
||||
# https://bugs.launchpad.net/python-openstackclient/+bug/1447704
|
||||
# Change that fix this error in keystoneclient was abandoned,
|
||||
# so we should use workaround until we move to keystoneauth.
|
||||
# The idea of the code came from glanceclient.
|
||||
|
||||
(v2_auth_url, v3_auth_url) = self._discover_auth_versions(
|
||||
session=session,
|
||||
auth_url=auth_url)
|
||||
|
||||
if v3_auth_url:
|
||||
# NOTE(starodubcevna): set user_domain_id and project_domain_id
|
||||
# to default as it done in other projects.
|
||||
return password.Password(auth_url,
|
||||
username=kwargs.pop('username'),
|
||||
user_id=kwargs.pop('user_id'),
|
||||
password=kwargs.pop('password'),
|
||||
user_domain_id=kwargs.pop(
|
||||
'user_domain_id') or 'default',
|
||||
user_domain_name=kwargs.pop(
|
||||
'user_domain_name'),
|
||||
project_id=kwargs.pop('project_id'),
|
||||
project_name=kwargs.pop('project_name'),
|
||||
project_domain_id=kwargs.pop(
|
||||
'project_domain_id') or 'default')
|
||||
elif v2_auth_url:
|
||||
return password.Password(auth_url,
|
||||
username=kwargs.pop('username'),
|
||||
user_id=kwargs.pop('user_id'),
|
||||
password=kwargs.pop('password'),
|
||||
project_id=kwargs.pop('project_id'),
|
||||
project_name=kwargs.pop('project_name'))
|
||||
else:
|
||||
kc_args['tenant_name'] = kwargs.get('tenant_name')
|
||||
|
||||
if kwargs.get('token'):
|
||||
kc_args['token'] = kwargs.get('token')
|
||||
else:
|
||||
kc_args['username'] = kwargs.get('username')
|
||||
kc_args['password'] = kwargs.get('password')
|
||||
|
||||
return ksclient.Client(**kc_args)
|
||||
|
||||
def _get_endpoint(self, client, **kwargs):
|
||||
"""Get an endpoint using the provided keystone client."""
|
||||
return client.service_catalog.url_for(
|
||||
service_type=kwargs.get('service_type') or 'application_catalog',
|
||||
endpoint_type=kwargs.get('endpoint_type') or 'publicURL')
|
||||
# if we get here it means domain information is provided
|
||||
# (caller meant to use Keystone V3) but the auth url is
|
||||
# actually Keystone V2. Obviously we can't authenticate a V3
|
||||
# user using V2.
|
||||
exc.CommandError("Credential and auth_url mismatch. The given "
|
||||
"auth_url is using Keystone V2 endpoint, which "
|
||||
"may not able to handle Keystone V3 credentials. "
|
||||
"Please provide a correct Keystone V3 auth_url.")
|
||||
|
||||
def _setup_logging(self, debug):
|
||||
# Output the logs to command-line interface
|
||||
|
@ -278,6 +304,9 @@ class MuranoShell(object):
|
|||
subcommand_parser = self.get_subcommand_parser(api_version)
|
||||
self.parser = subcommand_parser
|
||||
|
||||
keystone_session = None
|
||||
keystone_auth = None
|
||||
|
||||
# Handle top-level --help/-h before attempting to parse
|
||||
# a command off the command line.
|
||||
if (not args and options.help) or not argv:
|
||||
|
@ -301,11 +330,14 @@ class MuranoShell(object):
|
|||
" 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 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 args.os_no_client_auth:
|
||||
if not args.murano_url:
|
||||
|
@ -318,10 +350,14 @@ class MuranoShell(object):
|
|||
# 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):
|
||||
raise exc.CommandError("You must provide a tenant name "
|
||||
"or tenant id via --os-tenant-name, "
|
||||
"--os-tenant-id, env[OS_TENANT_NAME] "
|
||||
"or env[OS_TENANT_ID]")
|
||||
raise exc.CommandError(
|
||||
"You must provide a tenant name "
|
||||
"or tenant id via --os-tenant-name, "
|
||||
"--os-tenant-id, env[OS_TENANT_NAME] "
|
||||
"or env[OS_TENANT_ID] OR a project name "
|
||||
"or project id via --os-project-name, "
|
||||
"--os-project-id, env[OS_PROJECT_ID] or "
|
||||
"env[OS_PROJECT_NAME]")
|
||||
|
||||
if not args.os_auth_url:
|
||||
raise exc.CommandError("You must provide an auth url via"
|
||||
|
@ -347,37 +383,72 @@ class MuranoShell(object):
|
|||
endpoint = args.murano_url
|
||||
glance_endpoint = args.glance_url
|
||||
|
||||
if not args.os_no_client_auth:
|
||||
_ksclient = self._get_ksclient(**kwargs)
|
||||
token = args.os_auth_token or _ksclient.auth_token
|
||||
|
||||
if args.os_no_client_auth:
|
||||
# Authenticate through murano, don't use session
|
||||
kwargs = {
|
||||
'token': token,
|
||||
'insecure': args.insecure,
|
||||
'cacert': args.os_cacert,
|
||||
'cert_file': args.cert_file,
|
||||
'key_file': args.key_file,
|
||||
'username': args.os_username,
|
||||
'password': args.os_password,
|
||||
'endpoint_type': args.os_endpoint_type,
|
||||
'include_pass': args.include_password
|
||||
'auth_token': args.os_auth_token,
|
||||
'auth_url': args.os_auth_url,
|
||||
'token': args.os_auth_token,
|
||||
'insecure': args.insecure,
|
||||
'timeout': args.api_timeout
|
||||
}
|
||||
glance_kwargs = kwargs.copy()
|
||||
|
||||
if args.os_region_name:
|
||||
kwargs['region_name'] = args.os_region_name
|
||||
glance_kwargs['region_name'] = args.os_region_name
|
||||
else:
|
||||
# Create a keystone session and keystone auth
|
||||
keystone_session = ksession.Session.load_from_cli_options(args)
|
||||
project_id = args.os_project_id or args.os_tenant_id
|
||||
project_name = args.os_project_name or args.os_tenant_name
|
||||
|
||||
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)
|
||||
|
||||
endpoint_type = args.os_endpoint_type or 'publicURL'
|
||||
service_type = args.os_service_type or 'application_catalog'
|
||||
|
||||
if not endpoint:
|
||||
endpoint = self._get_endpoint(_ksclient, **kwargs)
|
||||
endpoint = keystone_auth.get_endpoint(
|
||||
keystone_session,
|
||||
service_type=service_type,
|
||||
region_name=args.os_region_name)
|
||||
|
||||
kwargs = {
|
||||
'session': keystone_session,
|
||||
'auth': keystone_auth,
|
||||
'service_type': service_type,
|
||||
'endpoint_type': endpoint_type,
|
||||
'region_name': args.os_region_name,
|
||||
}
|
||||
glance_kwargs = kwargs.copy()
|
||||
del glance_kwargs['endpoint_type']
|
||||
|
||||
if args.api_timeout:
|
||||
kwargs['timeout'] = args.api_timeout
|
||||
|
||||
if not glance_endpoint:
|
||||
try:
|
||||
glance_endpoint = self._get_endpoint(
|
||||
_ksclient, service_type='image')
|
||||
glance_endpoint = keystone_auth.get_endpoint(
|
||||
keystone_session,
|
||||
service_type='image',
|
||||
region_name=args.os_region_name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
@ -385,7 +456,7 @@ class MuranoShell(object):
|
|||
if glance_endpoint:
|
||||
try:
|
||||
glance_client = glanceclient.Client(
|
||||
'1', glance_endpoint, **glance_kwargs)
|
||||
'2', glance_endpoint, **glance_kwargs)
|
||||
except Exception:
|
||||
pass
|
||||
if glance_client:
|
||||
|
@ -395,7 +466,7 @@ class MuranoShell(object):
|
|||
"Image creation will be unavailable.")
|
||||
kwargs['glance_client'] = None
|
||||
|
||||
client = apiclient.Client(api_version, endpoint, **kwargs)
|
||||
client = murano_client.Client(api_version, endpoint, **kwargs)
|
||||
|
||||
args.func(client, args)
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ import sys
|
|||
import tempfile
|
||||
|
||||
import fixtures
|
||||
from keystoneclient import fixture
|
||||
from keystoneclient.fixture import v2 as ks_v2_fixture
|
||||
from keystoneclient.fixture import v3 as ks_v3_fixture
|
||||
import mock
|
||||
from oslo_log import handlers
|
||||
from oslo_log import log
|
||||
|
@ -48,12 +51,22 @@ FIXTURE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
|||
FAKE_ENV = {'OS_USERNAME': 'username',
|
||||
'OS_PASSWORD': 'password',
|
||||
'OS_TENANT_NAME': 'tenant_name',
|
||||
'OS_AUTH_URL': 'http://no.where'}
|
||||
'OS_AUTH_URL': 'http://no.where/v2.0'}
|
||||
|
||||
FAKE_ENV2 = {'OS_USERNAME': 'username',
|
||||
'OS_PASSWORD': 'password',
|
||||
'OS_TENANT_ID': 'tenant_id',
|
||||
'OS_AUTH_URL': 'http://no.where'}
|
||||
'OS_AUTH_URL': 'http://no.where/v2.0'}
|
||||
|
||||
FAKE_ENV_v3 = {'OS_USERNAME': 'username',
|
||||
'OS_PASSWORD': 'password',
|
||||
'OS_TENANT_ID': 'tenant_id',
|
||||
'OS_USER_DOMAIN_NAME': 'domain_name',
|
||||
'OS_AUTH_URL': 'http://no.where/v3'}
|
||||
|
||||
|
||||
def _create_ver_list(versions):
|
||||
return {'versions': {'values': versions}}
|
||||
|
||||
|
||||
class TestArgs(object):
|
||||
|
@ -70,18 +83,24 @@ class ShellTest(base.TestCaseShell):
|
|||
env = dict((k, v) for k, v in fake_env.items() if k != exclude)
|
||||
self.useFixture(fixtures.MonkeyPatch('os.environ', env))
|
||||
|
||||
def setUp(self):
|
||||
super(ShellTest, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'keystoneclient.v2_0.client.Client', mock.MagicMock))
|
||||
self.client = mock.MagicMock()
|
||||
|
||||
# We don't set an endpoint (client.service_catalog.url_for is a mock)
|
||||
# and get_proxy_url doesn't like that. We don't care about testing
|
||||
# that functionality, so mock it out.
|
||||
class ShellCommandTest(ShellTest):
|
||||
|
||||
_msg_no_tenant_project = ('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.',)
|
||||
|
||||
def setUp(self):
|
||||
super(ShellCommandTest, self).setUp()
|
||||
|
||||
def get_auth_endpoint(bound_self, args):
|
||||
return ('test', {})
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'muranoclient.common.http.HTTPClient.get_proxy_url',
|
||||
mock.MagicMock))
|
||||
'muranoclient.shell.MuranoShell._get_endpoint_and_kwargs',
|
||||
get_auth_endpoint))
|
||||
self.client = mock.MagicMock()
|
||||
|
||||
# To prevent log descriptors from being closed during
|
||||
# shell tests set a custom StreamHandler
|
||||
|
@ -114,6 +133,21 @@ class ShellTest(base.TestCaseShell):
|
|||
sys.stderr = orig_stderr
|
||||
return (stdout, stderr)
|
||||
|
||||
def register_keystone_discovery_fixture(self, mreq):
|
||||
v2_url = "http://no.where/v2.0"
|
||||
v2_version = fixture.V2Discovery(v2_url)
|
||||
mreq.register_uri('GET', v2_url, json=_create_ver_list([v2_version]),
|
||||
status_code=200)
|
||||
|
||||
def register_keystone_token_fixture(self, mreq):
|
||||
v2_token = ks_v2_fixture.Token(token_id='token')
|
||||
service = v2_token.add_service('application_catalog')
|
||||
service.add_endpoint('http://no.where', region='RegionOne')
|
||||
mreq.register_uri('POST',
|
||||
'http://no.where/v2.0/tokens',
|
||||
json=v2_token,
|
||||
status_code=200)
|
||||
|
||||
def test_help_unknown_command(self):
|
||||
self.assertRaises(exceptions.CommandError, self.shell, 'help foofoo')
|
||||
|
||||
|
@ -162,10 +196,7 @@ class ShellTest(base.TestCaseShell):
|
|||
self.fail('CommandError not raised')
|
||||
|
||||
def test_no_tenant_name(self):
|
||||
required = ('You must provide a tenant name '
|
||||
'or tenant id via --os-tenant-name, '
|
||||
'--os-tenant-id, env[OS_TENANT_NAME] '
|
||||
'or env[OS_TENANT_ID]',)
|
||||
required = self._msg_no_tenant_project
|
||||
self.make_env(exclude='OS_TENANT_NAME')
|
||||
try:
|
||||
self.shell('package-list')
|
||||
|
@ -175,10 +206,7 @@ class ShellTest(base.TestCaseShell):
|
|||
self.fail('CommandError not raised')
|
||||
|
||||
def test_no_tenant_id(self):
|
||||
required = ('You must provide a tenant name '
|
||||
'or tenant id via --os-tenant-name, '
|
||||
'--os-tenant-id, env[OS_TENANT_NAME] '
|
||||
'or env[OS_TENANT_ID]',)
|
||||
required = self._msg_no_tenant_project
|
||||
self.make_env(exclude='OS_TENANT_ID', fake_env=FAKE_ENV2)
|
||||
try:
|
||||
self.shell('package-list')
|
||||
|
@ -199,15 +227,19 @@ class ShellTest(base.TestCaseShell):
|
|||
self.fail('CommandError not raised')
|
||||
|
||||
@mock.patch('muranoclient.v1.packages.PackageManager')
|
||||
def test_package_list(self, mock_package_manager):
|
||||
@requests_mock.mock()
|
||||
def test_package_list(self, mock_package_manager, m_requests):
|
||||
self.client.packages = mock_package_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('package-list')
|
||||
self.client.packages.filter.assert_called_once_with(
|
||||
include_disabled=False)
|
||||
|
||||
@mock.patch('muranoclient.v1.packages.PackageManager')
|
||||
def test_package_show(self, mock_package_manager):
|
||||
@requests_mock.mock()
|
||||
def test_package_show(self, mock_package_manager, m_requests):
|
||||
self.client.packages = mock_package_manager()
|
||||
mock_package = mock.MagicMock()
|
||||
mock_package.class_definitions = ''
|
||||
|
@ -216,11 +248,14 @@ class ShellTest(base.TestCaseShell):
|
|||
mock_package.description = ''
|
||||
self.client.packages.get.return_value = mock_package
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('package-show 1234')
|
||||
self.client.packages.get.assert_called_with('1234')
|
||||
|
||||
@mock.patch('muranoclient.v1.packages.PackageManager')
|
||||
def test_package_update(self, mock_package_manager):
|
||||
@requests_mock.mock()
|
||||
def test_package_update(self, mock_package_manager, m_requests):
|
||||
self.client.packages = mock_package_manager()
|
||||
mock_package = mock.MagicMock()
|
||||
mock_package.class_definitions = ''
|
||||
|
@ -230,6 +265,8 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.packages.get.return_value = mock_package
|
||||
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
|
||||
self.shell('package-update 123 --is-public true')
|
||||
self.shell('package-update 123 --is-public false')
|
||||
|
@ -256,27 +293,36 @@ class ShellTest(base.TestCaseShell):
|
|||
])
|
||||
|
||||
@mock.patch('muranoclient.v1.packages.PackageManager')
|
||||
def test_package_delete(self, mock_package_manager):
|
||||
@requests_mock.mock()
|
||||
def test_package_delete(self, mock_package_manager, m_requests):
|
||||
self.client.packages = mock_package_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('package-delete 1234 4321')
|
||||
self.client.packages.delete.assert_has_calls([
|
||||
mock.call('1234'), mock.call('4321')])
|
||||
self.assertEqual(2, self.client.packages.delete.call_count)
|
||||
|
||||
@mock.patch('muranoclient.v1.sessions.SessionManager')
|
||||
def test_environment_session_create(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_session_create(self, mock_manager, m_requests):
|
||||
self.client.sessions = mock_manager()
|
||||
self.client.sessions.configure.return_value.id = '123'
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-session-create 1234')
|
||||
self.client.sessions.configure.assert_has_calls([
|
||||
mock.call('1234')])
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_create(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_create(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
|
||||
self.shell('environment-create foo')
|
||||
self.client.environments.create.assert_has_calls(
|
||||
|
@ -297,9 +343,12 @@ class ShellTest(base.TestCaseShell):
|
|||
self.assertEqual(expected_call, cc.call_args)
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_list(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_list(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
|
||||
self.shell('environment-list')
|
||||
self.client.environments.list.assert_called_once_with(False)
|
||||
|
@ -309,10 +358,13 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.environments.list.assert_called_once_with(True)
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_delete(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_delete(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.client.environments.find.return_value.id = '123'
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-delete env1')
|
||||
self.client.environments.find.assert_has_calls([
|
||||
mock.call(name='env1')
|
||||
|
@ -322,10 +374,13 @@ class ShellTest(base.TestCaseShell):
|
|||
])
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_delete_with_abandon(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_delete_with_abandon(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.client.environments.find.return_value.id = '123'
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-delete env1 --abandon')
|
||||
self.client.environments.find.assert_has_calls([
|
||||
mock.call(name='env1')
|
||||
|
@ -335,94 +390,128 @@ class ShellTest(base.TestCaseShell):
|
|||
])
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_rename(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_rename(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-rename old-name-or-id new-name')
|
||||
self.client.environments.find.assert_called_once_with(
|
||||
name='old-name-or-id')
|
||||
self.assertEqual(1, self.client.environments.update.call_count)
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_show(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_show(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-show env-id-or-name')
|
||||
self.client.environments.find.assert_called_once_with(
|
||||
name='env-id-or-name')
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
@mock.patch('muranoclient.v1.sessions.SessionManager')
|
||||
def test_environment_deploy(self, mock_manager, env_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_deploy(self, mock_manager, env_manager, m_requests):
|
||||
self.client.sessions = mock_manager()
|
||||
self.client.environments = env_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-deploy 12345 --session-id 54321')
|
||||
self.client.sessions.deploy.assert_called_once_with(
|
||||
'12345', '54321')
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_show_session(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_show_session(self, mock_manager, m_requests):
|
||||
self.client.environments = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-show 12345 --session-id 12345')
|
||||
self.client.environments.get.assert_called_once_with(
|
||||
12345, session_id='12345')
|
||||
|
||||
@mock.patch('muranoclient.v1.actions.ActionManager')
|
||||
def test_environment_action_call(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_action_call(self, mock_manager, m_requests):
|
||||
self.client.actions = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-action-call 12345 --action-id 54321')
|
||||
self.client.actions.call.assert_called_once_with(
|
||||
'12345', '54321', arguments={})
|
||||
|
||||
@mock.patch('muranoclient.v1.actions.ActionManager')
|
||||
def test_environment_action_call_args(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_action_call_args(self, mock_manager, m_requests):
|
||||
self.client.actions = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-action-call 12345 --action-id 54321 '
|
||||
'--arguments foo=bar')
|
||||
self.client.actions.call.assert_called_once_with(
|
||||
'12345', '54321', arguments={'foo': 'bar'})
|
||||
|
||||
@mock.patch('muranoclient.v1.actions.ActionManager')
|
||||
def test_environment_action_get_result(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_environment_action_get_result(self, mock_manager, m_requests):
|
||||
self.client.actions = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('environment-action-get-result 12345 --task-id 54321')
|
||||
self.client.actions.call.assert_called_once_with(
|
||||
'12345', '54321')
|
||||
|
||||
@mock.patch('muranoclient.v1.templates.EnvTemplateManager')
|
||||
def test_env_template_delete(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_env_template_delete(self, mock_manager, m_requests):
|
||||
self.client.env_templates = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('env-template-delete env1 env2')
|
||||
self.client.env_templates.delete.assert_has_calls([
|
||||
mock.call('env1'), mock.call('env2')])
|
||||
|
||||
@mock.patch('muranoclient.v1.templates.EnvTemplateManager')
|
||||
def test_env_template_create(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_env_template_create(self, mock_manager, m_requests):
|
||||
self.client.env_templates = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('env-template-create env-name')
|
||||
self.client.env_templates.create.assert_called_once_with(
|
||||
{'name': 'env-name'})
|
||||
|
||||
@mock.patch('muranoclient.v1.templates.EnvTemplateManager')
|
||||
def test_env_template_show(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_env_template_show(self, mock_manager, m_requests):
|
||||
self.client.env_templates = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('env-template-show env-id')
|
||||
self.client.env_templates.get.assert_called_once_with('env-id')
|
||||
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
@mock.patch('muranoclient.v1.deployments.DeploymentManager')
|
||||
def test_deployments_show(self, mock_deployment_manager, mock_env_manager):
|
||||
@requests_mock.mock()
|
||||
def test_deployments_show(self, mock_deployment_manager, mock_env_manager,
|
||||
m_requests):
|
||||
self.client.deployments = mock_deployment_manager()
|
||||
self.client.environments = mock_env_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
self.shell('deployment-list env-id-or-name')
|
||||
self.client.environments.find.assert_called_once_with(
|
||||
name='env-id-or-name')
|
||||
|
@ -430,7 +519,9 @@ class ShellTest(base.TestCaseShell):
|
|||
|
||||
@mock.patch('muranoclient.v1.services.ServiceManager')
|
||||
@mock.patch('muranoclient.v1.environments.EnvironmentManager')
|
||||
def test_environment_apps_edit(self, mock_env_manager, mock_services):
|
||||
@requests_mock.mock()
|
||||
def test_environment_apps_edit(self, mock_env_manager, mock_services,
|
||||
m_requests):
|
||||
self.client.environments = mock_env_manager()
|
||||
self.client.services = mock_services()
|
||||
fake = collections.namedtuple('fakeEnv', 'services')
|
||||
|
@ -449,6 +540,8 @@ class ShellTest(base.TestCaseShell):
|
|||
temp_file.file.flush()
|
||||
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
|
||||
self.shell('environment-apps-edit 12345 {0} --session-id 4321'.format(
|
||||
temp_file.name))
|
||||
|
@ -461,13 +554,16 @@ class ShellTest(base.TestCaseShell):
|
|||
)
|
||||
|
||||
@mock.patch('muranoclient.v1.services.ServiceManager')
|
||||
def test_app_show(self, mock_services):
|
||||
@requests_mock.mock()
|
||||
def test_app_show(self, mock_services, m_requests):
|
||||
self.client.services = mock_services()
|
||||
mock_app = mock.MagicMock()
|
||||
mock_app.name = "app_name"
|
||||
setattr(mock_app, '?', {'type': 'app_type', 'id': 'app_id'})
|
||||
self.client.services.list.return_value = [mock_app]
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('app-show env-id')
|
||||
required = ['Id', 'Name', 'Type', 'app_id', 'app_name', 'app_type']
|
||||
for r in required:
|
||||
|
@ -475,10 +571,13 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.services.list.assert_called_once_with('env-id')
|
||||
|
||||
@mock.patch('muranoclient.v1.services.ServiceManager')
|
||||
def test_app_show_empty_list(self, mock_services):
|
||||
@requests_mock.mock()
|
||||
def test_app_show_empty_list(self, mock_services, m_requests):
|
||||
self.client.services = mock_services()
|
||||
self.client.services.list.return_value = []
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('app-show env-id')
|
||||
required = ['Id', 'Name', 'Type']
|
||||
for r in required:
|
||||
|
@ -486,9 +585,12 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.services.list.assert_called_once_with('env-id')
|
||||
|
||||
@mock.patch('muranoclient.v1.categories.CategoryManager')
|
||||
def test_category_list(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_category_list(self, mock_manager, m_requests):
|
||||
self.client.categories = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('category-list')
|
||||
required = ['ID', 'Name']
|
||||
for r in required:
|
||||
|
@ -496,9 +598,12 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.categories.list.assert_called_once_with()
|
||||
|
||||
@mock.patch('muranoclient.v1.categories.CategoryManager')
|
||||
def test_category_show(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_category_show(self, mock_manager, m_requests):
|
||||
self.client.categories = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('category-show category-id')
|
||||
required = ['Property', 'Value', 'id', 'name', 'packages']
|
||||
for r in required:
|
||||
|
@ -506,9 +611,12 @@ class ShellTest(base.TestCaseShell):
|
|||
self.client.categories.get.assert_called_once_with('category-id')
|
||||
|
||||
@mock.patch('muranoclient.v1.categories.CategoryManager')
|
||||
def test_category_create(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_category_create(self, mock_manager, m_requests):
|
||||
self.client.categories = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('category-create category-name')
|
||||
required = ['ID', 'Name']
|
||||
for r in required:
|
||||
|
@ -517,9 +625,12 @@ class ShellTest(base.TestCaseShell):
|
|||
{'name': 'category-name'})
|
||||
|
||||
@mock.patch('muranoclient.v1.categories.CategoryManager')
|
||||
def test_category_delete(self, mock_manager):
|
||||
@requests_mock.mock()
|
||||
def test_category_delete(self, mock_manager, m_requests):
|
||||
self.client.categories = mock_manager()
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
result = self.shell('category-delete category-id')
|
||||
required = ['ID', 'Name']
|
||||
for r in required:
|
||||
|
@ -533,14 +644,16 @@ class ShellTest(base.TestCaseShell):
|
|||
self.assertEqual(expected, six.text_type(ex))
|
||||
|
||||
|
||||
class ShellPackagesOperations(ShellTest):
|
||||
|
||||
def test_create_hot_based_package(self):
|
||||
class ShellPackagesOperations(ShellCommandTest):
|
||||
@requests_mock.mock()
|
||||
def test_create_hot_based_package(self, m_requests):
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'muranoclient.v1.client.Client', mock.MagicMock))
|
||||
heat_template = os.path.join(FIXTURE_DIR, 'heat-template.yaml')
|
||||
logo = os.path.join(FIXTURE_DIR, 'logo.png')
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
RESULT_PACKAGE = f.name
|
||||
c = "package-create --template={0} --output={1} -l={2}".format(
|
||||
|
@ -550,13 +663,16 @@ class ShellPackagesOperations(ShellTest):
|
|||
"Application package "
|
||||
"is available at {0}".format(RESULT_PACKAGE))
|
||||
|
||||
def test_create_mpl_package(self):
|
||||
@requests_mock.mock()
|
||||
def test_create_mpl_package(self, m_requests):
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'muranoclient.v1.client.Client', mock.MagicMock))
|
||||
classes_dir = os.path.join(FIXTURE_DIR, 'test-app', 'Classes')
|
||||
resources_dir = os.path.join(FIXTURE_DIR, 'test-app', 'Resources')
|
||||
ui = os.path.join(FIXTURE_DIR, 'test-app', 'ui.yaml')
|
||||
self.make_env()
|
||||
self.register_keystone_discovery_fixture(m_requests)
|
||||
self.register_keystone_token_fixture(m_requests)
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
RESULT_PACKAGE = f.name
|
||||
stdout, stderr = self.shell(
|
||||
|
@ -1048,3 +1164,27 @@ class ShellPackagesOperations(ShellTest):
|
|||
os.remove(expected_pkgs[i].name)
|
||||
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
|
||||
class ShellPackagesOperationsV3(ShellPackagesOperations):
|
||||
def make_env(self, exclude=None, fake_env=FAKE_ENV):
|
||||
if 'OS_AUTH_URL' in fake_env:
|
||||
fake_env.update({'OS_AUTH_URL': 'http://no.where/v3'})
|
||||
env = dict((k, v) for k, v in fake_env.items() if k != exclude)
|
||||
self.useFixture(fixtures.MonkeyPatch('os.environ', env))
|
||||
|
||||
def register_keystone_discovery_fixture(self, mreq):
|
||||
v3_url = "http://no.where/v3"
|
||||
v3_version = fixture.V3Discovery(v3_url)
|
||||
mreq.register_uri('GET', v3_url, json=_create_ver_list([v3_version]),
|
||||
status_code=200)
|
||||
|
||||
def register_keystone_token_fixture(self, mreq):
|
||||
v3_token = ks_v3_fixture.Token()
|
||||
service = v3_token.add_service('application_catalog')
|
||||
service.add_standard_endpoints(public='http://no.where')
|
||||
mreq.register_uri('POST',
|
||||
'http://no.where/v3/auth/tokens',
|
||||
json=v3_token,
|
||||
headers={'X-Subject-Token': 'tokenid'},
|
||||
status_code=200)
|
||||
|
|
|
@ -26,7 +26,7 @@ from muranoclient.v1 import sessions
|
|||
from muranoclient.v1 import templates
|
||||
|
||||
|
||||
class Client(http.HTTPClient):
|
||||
class Client(object):
|
||||
"""Client for the Murano v1 API.
|
||||
|
||||
:param string endpoint: A user-supplied endpoint URL for the service.
|
||||
|
@ -39,18 +39,18 @@ class Client(http.HTTPClient):
|
|||
"""Initialize a new client for the Murano v1 API."""
|
||||
self.glance_client = kwargs.pop('glance_client', None)
|
||||
tenant = kwargs.pop('tenant', None)
|
||||
super(Client, self).__init__(*args, **kwargs)
|
||||
self.environments = environments.EnvironmentManager(self)
|
||||
self.env_templates = templates.EnvTemplateManager(self)
|
||||
self.sessions = sessions.SessionManager(self)
|
||||
self.services = services.ServiceManager(self)
|
||||
self.deployments = deployments.DeploymentManager(self)
|
||||
self.http_client = http._construct_http_client(*args, **kwargs)
|
||||
self.environments = environments.EnvironmentManager(self.http_client)
|
||||
self.env_templates = templates.EnvTemplateManager(self.http_client)
|
||||
self.sessions = sessions.SessionManager(self.http_client)
|
||||
self.services = services.ServiceManager(self.http_client)
|
||||
self.deployments = deployments.DeploymentManager(self.http_client)
|
||||
self.request_statistics = \
|
||||
request_statistics.RequestStatisticsManager(self)
|
||||
request_statistics.RequestStatisticsManager(self.http_client)
|
||||
self.instance_statistics = \
|
||||
instance_statistics.InstanceStatisticsManager(self)
|
||||
instance_statistics.InstanceStatisticsManager(self.http_client)
|
||||
artifacts_client = kwargs.pop('artifacts_client', None)
|
||||
pkg_mgr = packages.PackageManager(self)
|
||||
pkg_mgr = packages.PackageManager(self.http_client)
|
||||
if artifacts_client:
|
||||
artifact_repo = artifact_packages.ArtifactRepo(artifacts_client,
|
||||
tenant)
|
||||
|
@ -58,5 +58,5 @@ class Client(http.HTTPClient):
|
|||
pkg_mgr, artifact_repo)
|
||||
else:
|
||||
self.packages = pkg_mgr
|
||||
self.actions = actions.ActionManager(self)
|
||||
self.categories = categories.CategoryManager(self)
|
||||
self.actions = actions.ActionManager(self.http_client)
|
||||
self.categories = categories.CategoryManager(self.http_client)
|
||||
|
|
Loading…
Reference in New Issue