From f3bb46542baaed3eac1c0dfd625c1ce17feff043 Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Wed, 2 Oct 2019 21:58:46 +1300 Subject: [PATCH] Use dedicated service credential config The current admin credential config options are confusing Change-Id: I92c15c065edf364b955f2243b3599e0b8cae8b4f --- devstack/plugin.sh | 85 ++- doc/source/install/install-manual.rst | 6 +- tools/trove-pylint.config | 4 +- trove/backup/models.py | 6 +- trove/cluster/models.py | 12 +- trove/common/cfg.py | 72 +- trove/common/{remote.py => clients.py} | 73 +- ...ngle_tenant_remote.py => clients_admin.py} | 46 +- trove/common/glance_remote.py | 55 -- trove/common/models.py | 8 +- trove/common/neutron.py | 4 +- trove/common/server_group.py | 2 +- .../experimental/galera_common/taskmanager.py | 2 +- .../cluster/experimental/mongodb/api.py | 4 +- trove/common/strategies/storage/swift.py | 2 +- trove/common/trove_remote.py | 11 +- trove/datastore/models.py | 2 +- .../migrate_repo/versions/039_region.py | 3 +- trove/extensions/common/models.py | 2 +- trove/extensions/mgmt/datastores/service.py | 6 +- trove/extensions/mgmt/instances/models.py | 14 +- trove/extensions/mgmt/upgrade/models.py | 2 +- trove/extensions/mysql/models.py | 2 +- trove/extensions/redis/models.py | 2 +- trove/extensions/security_group/models.py | 4 +- trove/flavor/models.py | 2 +- trove/guestagent/guest_log.py | 4 +- trove/instance/models.py | 33 +- trove/instance/service.py | 6 +- trove/network/neutron.py | 4 +- trove/network/nova.py | 4 +- trove/taskmanager/manager.py | 10 +- trove/taskmanager/models.py | 11 +- .../unittests/backup/test_backup_models.py | 75 +- trove/tests/unittests/cluster/test_cluster.py | 12 +- .../unittests/cluster/test_galera_cluster.py | 30 +- trove/tests/unittests/cluster/test_models.py | 6 +- .../unittests/cluster/test_mongodb_cluster.py | 34 +- .../unittests/cluster/test_redis_cluster.py | 16 +- .../unittests/cluster/test_vertica_cluster.py | 18 +- trove/tests/unittests/common/test_remote.py | 650 ------------------ .../test_datastore_version_metadata.py | 4 +- trove/tests/unittests/guestagent/test_api.py | 2 +- .../instance/test_instance_models.py | 2 +- .../mgmt/test_datastore_controller.py | 6 +- trove/tests/unittests/mgmt/test_datastores.py | 12 +- trove/tests/unittests/mgmt/test_models.py | 4 +- .../unittests/taskmanager/test_models.py | 67 +- .../unittests/volume_type/test_volume_type.py | 4 +- trove/volume_type/models.py | 7 +- 50 files changed, 407 insertions(+), 1045 deletions(-) rename trove/common/{remote.py => clients.py} (72%) rename trove/common/{single_tenant_remote.py => clients_admin.py} (70%) delete mode 100644 trove/common/glance_remote.py delete mode 100644 trove/tests/unittests/common/test_remote.py diff --git a/devstack/plugin.sh b/devstack/plugin.sh index f5ee71ec1d..fa02b8426d 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -195,16 +195,20 @@ function configure_trove { # Create the trove conf dir and cache dirs if they don't exist sudo install -d -o $STACK_USER ${TROVE_CONF_DIR} - # Copy api-paste file over to the trove conf dir cp $TROVE_LOCAL_API_PASTE_INI $TROVE_API_PASTE_INI - + # configure apache related files + if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then + echo "Configuring Trove to use mod-wsgi and Apache" + config_trove_apache_wsgi + fi # (Re)create trove conf files rm -f $TROVE_CONF $TROVE_GUESTAGENT_CONF TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_URI/v$IDENTITY_API_VERSION - # Set common configuration values (but only if they're defined) + ################################################################ trove conf + setup_trove_logging $TROVE_CONF iniset_conditional $TROVE_CONF DEFAULT max_accepted_volume_size $TROVE_MAX_ACCEPTED_VOLUME_SIZE iniset_conditional $TROVE_CONF DEFAULT max_instances_per_tenant $TROVE_MAX_INSTANCES_PER_TENANT iniset_conditional $TROVE_CONF DEFAULT max_volumes_per_tenant $TROVE_MAX_VOLUMES_PER_TENANT @@ -214,33 +218,30 @@ function configure_trove { iniset_conditional $TROVE_CONF DEFAULT usage_timeout $TROVE_USAGE_TIMEOUT iniset_conditional $TROVE_CONF DEFAULT state_change_wait_time $TROVE_STATE_CHANGE_WAIT_TIME - # For message queue + configure_keystone_authtoken_middleware $TROVE_CONF trove + iniset $TROVE_CONF service_credentials username trove + iniset $TROVE_CONF service_credentials user_domain_name Default + iniset $TROVE_CONF service_credentials project_domain_name Default + iniset $TROVE_CONF service_credentials password $SERVICE_PASSWORD + iniset $TROVE_CONF service_credentials project_name $SERVICE_PROJECT_NAME + iniset $TROVE_CONF service_credentials region_name $REGION_NAME + iniset $TROVE_CONF service_credentials auth_url $TROVE_AUTH_ENDPOINT + + iniset $TROVE_CONF database connection `database_connection_url trove` + iniset $TROVE_CONF DEFAULT rpc_backend "rabbit" iniset $TROVE_CONF DEFAULT control_exchange trove iniset $TROVE_CONF DEFAULT transport_url rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/ - # For database - iniset $TROVE_CONF database connection `database_connection_url trove` - # For logging - setup_trove_logging $TROVE_CONF - iniset $TROVE_CONF DEFAULT trove_api_workers "$API_WORKERS" - configure_keystone_authtoken_middleware $TROVE_CONF trove - iniset $TROVE_CONF DEFAULT taskmanager_manager trove.taskmanager.manager.Manager - - iniset $TROVE_CONF DEFAULT trove_auth_url $TROVE_AUTH_ENDPOINT - iniset $TROVE_CONF DEFAULT nova_proxy_admin_user trove - iniset $TROVE_CONF DEFAULT nova_proxy_admin_tenant_name $SERVICE_PROJECT_NAME - iniset $TROVE_CONF DEFAULT nova_proxy_admin_pass $SERVICE_PASSWORD - iniset $TROVE_CONF DEFAULT nova_proxy_admin_user_domain_name default - iniset $TROVE_CONF DEFAULT nova_proxy_admin_project_domain_name default - iniset $TROVE_CONF DEFAULT os_region_name $REGION_NAME - iniset $TROVE_CONF DEFAULT remote_nova_client trove.common.single_tenant_remote.nova_client_trove_admin - iniset $TROVE_CONF DEFAULT remote_cinder_client trove.common.single_tenant_remote.cinder_client_trove_admin - iniset $TROVE_CONF DEFAULT remote_neutron_client trove.common.single_tenant_remote.neutron_client_trove_admin - iniset $TROVE_CONF DEFAULT remote_swift_client trove.common.single_tenant_remote.swift_client_trove_admin - iniset $TROVE_CONF DEFAULT default_datastore $TROVE_DATASTORE_TYPE + + iniset $TROVE_CONF DEFAULT remote_nova_client trove.common.clients_admin.nova_client_trove_admin + iniset $TROVE_CONF DEFAULT remote_cinder_client trove.common.clients_admin.cinder_client_trove_admin + iniset $TROVE_CONF DEFAULT remote_neutron_client trove.common.clients_admin.neutron_client_trove_admin + iniset $TROVE_CONF DEFAULT remote_swift_client trove.common.clients_admin.swift_client_trove_admin + iniset $TROVE_CONF DEFAULT remote_glance_client trove.common.clients_admin.glance_client_trove_admin + iniset $TROVE_CONF cassandra tcp_ports 7000,7001,7199,9042,9160 iniset $TROVE_CONF couchbase tcp_ports 8091,8092,4369,11209-11211,21100-21199 iniset $TROVE_CONF couchdb tcp_ports 5984 @@ -254,35 +255,31 @@ function configure_trove { iniset $TROVE_CONF redis tcp_ports 6379,16379 iniset $TROVE_CONF vertica tcp_ports 5433,5434,5444,5450,4803 - # configure apache related files - if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then - echo "Configuring Trove to use mod-wsgi and Apache" - config_trove_apache_wsgi - fi + ################################################################ trove guest agent conf + setup_trove_logging $TROVE_GUESTAGENT_CONF - # Use these values only if they're set iniset_conditional $TROVE_GUESTAGENT_CONF DEFAULT state_change_wait_time $TROVE_STATE_CHANGE_WAIT_TIME iniset_conditional $TROVE_GUESTAGENT_CONF DEFAULT command_process_timeout $TROVE_COMMAND_PROCESS_TIMEOUT - - # Set up Guest Agent conf iniset $TROVE_GUESTAGENT_CONF DEFAULT rpc_backend "rabbit" iniset $TROVE_GUESTAGENT_CONF DEFAULT transport_url rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$TROVE_HOST_GATEWAY:5672/ - iniset $TROVE_GUESTAGENT_CONF DEFAULT trove_auth_url $TROVE_AUTH_ENDPOINT iniset $TROVE_GUESTAGENT_CONF DEFAULT control_exchange trove iniset $TROVE_GUESTAGENT_CONF DEFAULT ignore_users os_admin iniset $TROVE_GUESTAGENT_CONF DEFAULT log_dir /var/log/trove/ iniset $TROVE_GUESTAGENT_CONF DEFAULT log_file trove-guestagent.log - iniset $TROVE_GUESTAGENT_CONF DEFAULT nova_proxy_admin_user trove - iniset $TROVE_GUESTAGENT_CONF DEFAULT nova_proxy_admin_tenant_name $SERVICE_PROJECT_NAME - iniset $TROVE_GUESTAGENT_CONF DEFAULT nova_proxy_admin_pass $SERVICE_PASSWORD - iniset $TROVE_GUESTAGENT_CONF DEFAULT nova_proxy_admin_user_domain_name default - iniset $TROVE_GUESTAGENT_CONF DEFAULT nova_proxy_admin_project_domain_name default - iniset $TROVE_GUESTAGENT_CONF DEFAULT os_region_name $REGION_NAME - iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_nova_client trove.common.single_tenant_remote.nova_client_trove_admin - iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_cinder_client trove.common.single_tenant_remote.cinder_client_trove_admin - iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_neutron_client trove.common.single_tenant_remote.neutron_client_trove_admin - iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_swift_client trove.common.single_tenant_remote.swift_client_trove_admin - setup_trove_logging $TROVE_GUESTAGENT_CONF + + iniset $TROVE_GUESTAGENT_CONF service_credentials username trove + iniset $TROVE_GUESTAGENT_CONF service_credentials user_domain_name Default + iniset $TROVE_GUESTAGENT_CONF service_credentials project_domain_name Default + iniset $TROVE_GUESTAGENT_CONF service_credentials password $SERVICE_PASSWORD + iniset $TROVE_GUESTAGENT_CONF service_credentials project_name $SERVICE_PROJECT_NAME + iniset $TROVE_GUESTAGENT_CONF service_credentials region_name $REGION_NAME + iniset $TROVE_GUESTAGENT_CONF service_credentials auth_url $TROVE_AUTH_ENDPOINT + + iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_nova_client trove.common.clients_admin.nova_client_trove_admin + iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_cinder_client trove.common.clients_admin.cinder_client_trove_admin + iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_neutron_client trove.common.clients_admin.neutron_client_trove_admin + iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_swift_client trove.common.clients_admin.swift_client_trove_admin + iniset $TROVE_GUESTAGENT_CONF DEFAULT remote_glance_client trove.common.clients_admin.glance_client_trove_admin # To avoid 'Connection timed out' error of sudo command inside the guest agent CLOUDINIT_PATH=/etc/trove/cloudinit/${TROVE_DATASTORE_TYPE}.cloudinit diff --git a/doc/source/install/install-manual.rst b/doc/source/install/install-manual.rst index 6afd02ef98..563e23a4c0 100644 --- a/doc/source/install/install-manual.rst +++ b/doc/source/install/install-manual.rst @@ -168,9 +168,9 @@ Options in trove.conf nova_proxy_admin_tenant_id = f472127c03f6410899225e26a3c1d22c nova_proxy_admin_user_domain_name = default nova_proxy_admin_project_domain_name = default - remote_nova_client = trove.common.single_tenant_remote.nova_client_trove_admin - remote_cinder_client = trove.common.single_tenant_remote.cinder_client_trove_admin - remote_neutron_client = trove.common.single_tenant_remote.neutron_client_trove_admin + remote_nova_client = trove.common.clients_admin.nova_client_trove_admin + remote_cinder_client = trove.common.clients_admin.cinder_client_trove_admin + remote_neutron_client = trove.common.clients_admin.neutron_client_trove_admin os_region_name = RegionOne #. Management config options. diff --git a/tools/trove-pylint.config b/tools/trove-pylint.config index 1682191fdd..257b394e5a 100644 --- a/tools/trove-pylint.config +++ b/tools/trove-pylint.config @@ -370,13 +370,13 @@ "ModelBase.__hash__" ], [ - "trove/common/single_tenant_remote.py", + "trove/common/clients_admin.py", "E0611", "No name 'v1_1' in module 'novaclient'", null ], [ - "trove/common/single_tenant_remote.py", + "trove/common/clients_admin.py", "no-name-in-module", "No name 'v1_1' in module 'novaclient'", null diff --git a/trove/backup/models.py b/trove/backup/models.py index 7e6bd2dc8a..993d00388a 100644 --- a/trove/backup/models.py +++ b/trove/backup/models.py @@ -21,9 +21,9 @@ from swiftclient.client import ClientException from trove.backup.state import BackupState from trove.common import cfg +from trove.common import clients from trove.common import exception from trove.common.i18n import _ -from trove.common.remote import create_swift_client from trove.common import utils from trove.datastore import models as datastore_models from trove.db.models import DatabaseModelBase @@ -285,7 +285,7 @@ class Backup(object): @classmethod def verify_swift_auth_token(cls, context): try: - client = create_swift_client(context) + client = clients.create_swift_client(context) client.get_account() except ClientException: raise exception.SwiftAuthError(tenant_id=context.project_id) @@ -348,7 +348,7 @@ class DBBackup(DatabaseModelBase): parts = self.location.split('/') obj = parts[-1] container = parts[-2] - client = create_swift_client(context) + client = clients.create_swift_client(context) LOG.debug("Checking if backup exists in %s", self.location) resp = client.head_object(container, obj) if verify_checksum: diff --git a/trove/cluster/models.py b/trove/cluster/models.py index db6cfd1935..18f9c94486 100644 --- a/trove/cluster/models.py +++ b/trove/cluster/models.py @@ -22,6 +22,7 @@ from novaclient import exceptions as nova_exceptions from trove.cluster.tasks import ClusterTask from trove.cluster.tasks import ClusterTasks from trove.common import cfg +from trove.common import clients from trove.common import exception from trove.common.i18n import _ from trove.common.notification import ( @@ -36,7 +37,6 @@ from trove.common.notification import DBaaSInstanceAttachConfiguration from trove.common.notification import DBaaSInstanceDetachConfiguration from trove.common.notification import EndNotification from trove.common.notification import StartNotification -from trove.common import remote from trove.common import server_group as srv_grp from trove.common.strategies.cluster import strategy from trove.common import utils @@ -112,9 +112,9 @@ class Cluster(object): @classmethod def get_guest(cls, instance): - return remote.create_guest_client(instance.context, - instance.db_info.id, - instance.datastore_version.manager) + return clients.create_guest_client(instance.context, + instance.db_info.id, + instance.datastore_version.manager) @classmethod def load_all(cls, context, tenant_id): @@ -572,7 +572,7 @@ def validate_instance_flavors(context, instances, if region_name in nova_cli_cache: nova_client = nova_cli_cache[region_name] else: - nova_client = remote.create_nova_client( + nova_client = clients.create_nova_client( context, region_name) nova_cli_cache[region_name] = nova_client @@ -670,7 +670,7 @@ def validate_instance_nics(context, instances): return instance_nic = instance_nics[0] try: - neutron_client = remote.create_neutron_client(context) + neutron_client = clients.create_neutron_client(context) neutron_client.find_resource('network', instance_nic) except neutron_exceptions.NotFound: raise exception.NetworkNotFound(uuid=instance_nic) diff --git a/trove/common/cfg.py b/trove/common/cfg.py index 0fefaefe16..aaaf189fa8 100644 --- a/trove/common/cfg.py +++ b/trove/common/cfg.py @@ -68,8 +68,6 @@ common_opts = [ help='Set the service and instance task statuses to ERROR ' 'when an instance fails to become active within the ' 'configured usage_timeout.'), - cfg.StrOpt('os_region_name', default='RegionOne', - help='Region name of this node. Used when searching catalog.'), cfg.URIOpt('nova_compute_url', help='URL without the tenant segment.'), cfg.StrOpt('nova_compute_service_type', default='compute', help='Service type to use when searching catalog.'), @@ -111,8 +109,6 @@ common_opts = [ help='Service type to use when searching catalog.'), cfg.StrOpt('glance_endpoint_type', default='publicURL', help='Service endpoint type to use when searching catalog.'), - cfg.URIOpt('trove_auth_url', default='http://0.0.0.0/identity/v2.0', - help='Trove authentication URL.'), cfg.StrOpt('trove_url', help='URL without the tenant segment.'), cfg.StrOpt('trove_service_type', default='database', help='Service type to use when searching catalog.'), @@ -332,28 +328,28 @@ common_opts = [ help='Maximum size (in bytes) of each segment of the backup ' 'file.'), cfg.StrOpt('remote_dns_client', - default='trove.common.remote.dns_client', + default='trove.common.clients.dns_client', help='Client to send DNS calls to.'), cfg.StrOpt('remote_guest_client', - default='trove.common.remote.guest_client', + default='trove.common.clients.guest_client', help='Client to send Guest Agent calls to.'), cfg.StrOpt('remote_nova_client', - default='trove.common.remote.nova_client', + default='trove.common.clients.nova_client', help='Client to send Nova calls to.'), cfg.StrOpt('remote_neutron_client', - default='trove.common.remote.neutron_client', + default='trove.common.clients.neutron_client', help='Client to send Neutron calls to.'), cfg.StrOpt('remote_cinder_client', - default='trove.common.remote.cinder_client', + default='trove.common.clients.cinder_client', help='Client to send Cinder calls to.'), cfg.StrOpt('remote_swift_client', - default='trove.common.remote.swift_client', + default='trove.common.clients.swift_client', help='Client to send Swift calls to.'), cfg.StrOpt('remote_trove_client', default='trove.common.trove_remote.trove_client', help='Client to send Trove calls to.'), cfg.StrOpt('remote_glance_client', - default='trove.common.glance_remote.glance_client', + default='trove.common.clients.glance_client', help='Client to send Glance calls to.'), cfg.StrOpt('exists_notification_transformer', help='Transformer for exists notifications.'), @@ -375,19 +371,6 @@ common_opts = [ 'db2': 'e040cd37-263d-4869-aaa6-c62aa97523b5', 'mariadb': '7a4f82cc-10d2-4bc6-aadc-d9aacc2a3cb5'}, help='Unique ID to tag notification events.'), - cfg.StrOpt('nova_proxy_admin_user', default='', - help="Admin username used to connect to Nova.", secret=True), - cfg.StrOpt('nova_proxy_admin_pass', default='', - help="Admin password used to connect to Nova.", secret=True), - cfg.StrOpt('nova_proxy_admin_tenant_id', default='', - help="Admin tenant ID used to connect to Nova.", secret=True), - cfg.StrOpt('nova_proxy_admin_tenant_name', default='', - help="Admin tenant name used to connect to Nova.", secret=True), - cfg.StrOpt('nova_proxy_admin_user_domain_name', default='Default', - help="User domain of the admin user used to connect to Nova."), - cfg.StrOpt('nova_proxy_admin_project_domain_name', default='Default', - help="Project domain of the admin user used to connect to " - "Nova."), cfg.StrOpt('network_label_regex', default='^private$', help='Regular expression to match Trove network labels.'), cfg.StrOpt('ip_regex', default=None, @@ -1572,6 +1555,45 @@ network_opts = [ ) ] +service_credentials_group = cfg.OptGroup( + 'service_credentials', + help="Options related to Trove service credentials." +) +service_credentials_opts = [ + cfg.URIOpt('auth_url', default='https://0.0.0.0/identity/v3', + deprecated_name='trove_auth_url', + deprecated_group='DEFAULT', + help='Keystone authentication URL.'), + cfg.StrOpt('username', default='', + help="Trove service user name.", + deprecated_name='nova_proxy_admin_user', + deprecated_group='DEFAULT'), + cfg.StrOpt('password', default='', secret=True, + help="Trove service user password.", + deprecated_name='nova_proxy_admin_pass', + deprecated_group='DEFAULT'), + cfg.StrOpt('project_id', default='', + deprecated_name='nova_proxy_admin_tenant_id', + deprecated_group='DEFAULT', + help="Trove service project ID."), + cfg.StrOpt('project_name', default='', + deprecated_name='nova_proxy_admin_tenant_name', + deprecated_group='DEFAULT', + help="Trove service project name."), + cfg.StrOpt('user_domain_name', default='Default', + deprecated_name='nova_proxy_admin_user_domain_name', + deprecated_group='DEFAULT', + help="Keystone domain name of the Trove service user."), + cfg.StrOpt('project_domain_name', default='Default', + deprecated_name='nova_proxy_admin_project_domain_name', + deprecated_group='DEFAULT', + help="Keystone domain name of the Trove service project."), + cfg.StrOpt('region_name', default='RegionOne', + deprecated_name='os_region_name', + deprecated_group='DEFAULT', + help="Keystone region name of the Trove service project."), +] + CONF = cfg.CONF CONF.register_opts(path_opts) @@ -1593,6 +1615,7 @@ CONF.register_group(vertica_group) CONF.register_group(db2_group) CONF.register_group(mariadb_group) CONF.register_group(network_group) +CONF.register_group(service_credentials_group) CONF.register_opts(mysql_opts, mysql_group) CONF.register_opts(percona_opts, percona_group) @@ -1607,6 +1630,7 @@ CONF.register_opts(vertica_opts, vertica_group) CONF.register_opts(db2_opts, db2_group) CONF.register_opts(mariadb_opts, mariadb_group) CONF.register_opts(network_opts, network_group) +CONF.register_opts(service_credentials_opts, service_credentials_group) CONF.register_opts(rpcapi_cap_opts, upgrade_levels) diff --git a/trove/common/remote.py b/trove/common/clients.py similarity index 72% rename from trove/common/remote.py rename to trove/common/clients.py index 3276dd2035..426574b59a 100644 --- a/trove/common/remote.py +++ b/trove/common/clients.py @@ -20,6 +20,9 @@ from trove.common import exception from trove.common.strategies.cluster import strategy from cinderclient.v2 import client as CinderClient +import glanceclient +from keystoneauth1.identity import v3 +from keystoneauth1 import session as ka_session from keystoneclient.service_catalog import ServiceCatalog from neutronclient.v2_0 import client as NeutronClient from novaclient.client import Client @@ -49,7 +52,7 @@ def get_endpoint(service_catalog, service_type=None, Some parts copied from glance/common/auth.py. """ - endpoint_region = endpoint_region or CONF.os_region_name + endpoint_region = endpoint_region or CONF.service_credentials.region_name if not service_catalog: raise exception.EmptyCatalog() @@ -90,10 +93,13 @@ def nova_client(context, region_name=None, password=None): 'nova_url': normalize_url(CONF.nova_compute_url), 'tenant': context.project_id} else: - url = get_endpoint(context.service_catalog, - service_type=CONF.nova_compute_service_type, - endpoint_region=region_name or CONF.os_region_name, - endpoint_type=CONF.nova_compute_endpoint_type) + region = region_name or CONF.service_credentials.region_name + url = get_endpoint( + context.service_catalog, + service_type=CONF.nova_compute_service_type, + endpoint_region=region, + endpoint_type=CONF.nova_compute_endpoint_type + ) client = Client(CONF.nova_client_version, username=context.user, @@ -102,7 +108,7 @@ def nova_client(context, region_name=None, password=None): project_id=context.project_id, project_domain_name=context.project_domain_name, user_domain_name=context.user_domain_name, - auth_url=CONF.trove_auth_url, + auth_url=CONF.service_credentials.auth_url, auth_token=context.auth_token, insecure=CONF.nova_api_insecure) client.client.auth_token = context.auth_token @@ -115,7 +121,9 @@ def create_admin_nova_client(context): Creates client that uses trove admin credentials :return: a client for nova for the trove admin """ - client = create_nova_client(context, password=CONF.nova_proxy_admin_pass) + client = create_nova_client( + context, password=CONF.service_credentials.password + ) return client @@ -125,14 +133,17 @@ def cinder_client(context, region_name=None): 'cinder_url': normalize_url(CONF.cinder_url), 'tenant': context.project_id} else: - url = get_endpoint(context.service_catalog, - service_type=CONF.cinder_service_type, - endpoint_region=region_name or CONF.os_region_name, - endpoint_type=CONF.cinder_endpoint_type) + region = region_name or CONF.service_credentials.region_name + url = get_endpoint( + context.service_catalog, + service_type=CONF.cinder_service_type, + endpoint_region=region, + endpoint_type=CONF.cinder_endpoint_type + ) client = CinderClient.Client(context.user, context.auth_token, project_id=context.project_id, - auth_url=CONF.trove_auth_url, + auth_url=CONF.service_credentials.auth_url, insecure=CONF.cinder_api_insecure) client.client.auth_token = context.auth_token client.client.management_url = url @@ -145,9 +156,10 @@ def swift_client(context, region_name=None): url = '%(swift_url)s%(tenant)s' % {'swift_url': CONF.swift_url, 'tenant': context.project_id} else: + region = region_name or CONF.service_credentials.region_name url = get_endpoint(context.service_catalog, service_type=CONF.swift_service_type, - endpoint_region=region_name or CONF.os_region_name, + endpoint_region=region, endpoint_type=CONF.swift_endpoint_type) client = Connection(preauthurl=url, @@ -163,9 +175,10 @@ def neutron_client(context, region_name=None): # neutron endpoint url / publicURL does not include tenant segment url = CONF.neutron_url else: + region = region_name or CONF.service_credentials.region_name url = get_endpoint(context.service_catalog, service_type=CONF.neutron_service_type, - endpoint_region=region_name or CONF.os_region_name, + endpoint_region=region, endpoint_type=CONF.neutron_endpoint_type) client = NeutronClient.Client(token=context.auth_token, @@ -174,6 +187,34 @@ def neutron_client(context, region_name=None): return client +def glance_client(context, region_name=None): + + # We should allow glance to get the endpoint from the service + # catalog, but to do so we would need to be able to specify + # the endpoint_filter on the API calls, but glance + # doesn't currently allow that. As a result, we must + # specify the endpoint explicitly. + if CONF.glance_url: + endpoint_url = '%(url)s%(tenant)s' % { + 'url': normalize_url(CONF.glance_url), + 'tenant': context.project_id} + else: + region = region_name or CONF.service_credentials.region_name + endpoint_url = get_endpoint( + context.service_catalog, service_type=CONF.glance_service_type, + endpoint_region=region, + endpoint_type=CONF.glance_endpoint_type + ) + + auth = v3.Token(CONF.service_credentials.auth_url, context.auth_token) + session = ka_session.Session(auth=auth) + + return glanceclient.Client( + CONF.glance_client_version, endpoint=endpoint_url, + session=session + ) + + def create_dns_client(*arg, **kwargs): return import_class(CONF.remote_dns_client)(*arg, **kwargs) @@ -196,3 +237,7 @@ def create_cinder_client(*arg, **kwargs): def create_neutron_client(*arg, **kwargs): return import_class(CONF.remote_neutron_client)(*arg, **kwargs) + + +def create_glance_client(*arg, **kwargs): + return import_class(CONF.remote_glance_client)(*arg, **kwargs) diff --git a/trove/common/single_tenant_remote.py b/trove/common/clients_admin.py similarity index 70% rename from trove/common/single_tenant_remote.py rename to trove/common/clients_admin.py index 7860b2994c..2c26dcaaf7 100644 --- a/trove/common/single_tenant_remote.py +++ b/trove/common/clients_admin.py @@ -14,6 +14,7 @@ # limitations under the License. from cinderclient.v2 import client as CinderClient +import glanceclient from keystoneauth1 import loading from keystoneauth1 import session from neutronclient.v2_0 import client as NeutronClient @@ -21,24 +22,25 @@ from novaclient.client import Client as NovaClient import swiftclient from trove.common import cfg -from trove.common.remote import normalize_url +from trove.common.clients import normalize_url CONF = cfg.CONF _SESSION = None def get_keystone_session(): + """Get trove service credential auth session.""" global _SESSION if not _SESSION: loader = loading.get_plugin_loader('password') auth = loader.load_from_options( - username=CONF.nova_proxy_admin_user, - password=CONF.nova_proxy_admin_pass, - project_name=CONF.nova_proxy_admin_tenant_name, - user_domain_name=CONF.nova_proxy_admin_user_domain_name, - project_domain_name=CONF.nova_proxy_admin_project_domain_name, - auth_url=CONF.trove_auth_url) + username=CONF.service_credentials.username, + password=CONF.service_credentials.password, + project_name=CONF.service_credentials.project_name, + user_domain_name=CONF.service_credentials.user_domain_name, + project_domain_name=CONF.service_credentials.project_domain_name, + auth_url=CONF.service_credentials.auth_url) _SESSION = session.Session(auth=auth) return _SESSION @@ -58,14 +60,14 @@ def nova_client_trove_admin(context, region_name=None, password=None): CONF.nova_client_version, session=ks_session, service_type=CONF.nova_compute_service_type, - region_name=region_name or CONF.os_region_name, + region_name=region_name or CONF.service_credentials.region_name, insecure=CONF.nova_api_insecure, endpoint_type=CONF.nova_compute_endpoint_type) - if CONF.nova_compute_url and CONF.nova_proxy_admin_tenant_id: + if CONF.nova_compute_url and CONF.service_credentials.project_id: client.client.endpoint_override = "%s/%s/" % ( normalize_url(CONF.nova_compute_url), - CONF.nova_proxy_admin_tenant_id) + CONF.service_credentials.project_id) return client @@ -81,13 +83,14 @@ def cinder_client_trove_admin(context, region_name=None): client = CinderClient.Client( session=ks_session, service_type=CONF.cinder_service_type, - region_name=region_name or CONF.os_region_name, + region_name=region_name or CONF.service_credentials.region_name, insecure=CONF.cinder_api_insecure, endpoint_type=CONF.cinder_endpoint_type) - if CONF.cinder_url and CONF.nova_proxy_admin_tenant_id: + if CONF.cinder_url and CONF.service_credentials.project_id: client.client.management_url = "%s/%s/" % ( - normalize_url(CONF.cinder_url), CONF.nova_proxy_admin_tenant_id) + normalize_url(CONF.cinder_url), + CONF.service_credentials.project_id) return client @@ -103,7 +106,7 @@ def neutron_client_trove_admin(context, region_name=None): client = NeutronClient.Client( session=ks_session, service_type=CONF.neutron_service_type, - region_name=region_name or CONF.os_region_name, + region_name=region_name or CONF.service_credentials.region_name, insecure=CONF.neutron_api_insecure, endpoint_type=CONF.neutron_endpoint_type) @@ -119,10 +122,23 @@ def swift_client_trove_admin(context, region_name=None): session=ks_session, insecure=CONF.swift_api_insecure, os_options={ - 'region_name': region_name or CONF.os_region_name, + 'region_name': region_name or CONF.service_credentials.region_name, 'service_type': CONF.swift_service_type, 'endpoint_type': CONF.swift_endpoint_type } ) return client + + +def glance_client_trove_admin(context, region_name=None): + ks_session = get_keystone_session() + client = glanceclient.Client( + version=CONF.glance_client_version, + session=ks_session, + region_name=region_name or CONF.service_credentials.region_name, + service_type=CONF.glance_service_type, + interface=CONF.glance_endpoint_type + ) + + return client diff --git a/trove/common/glance_remote.py b/trove/common/glance_remote.py deleted file mode 100644 index 3aaadb2e61..0000000000 --- a/trove/common/glance_remote.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2016 Tesora Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystoneauth1.identity import v3 -from keystoneauth1 import session as ka_session - -from oslo_utils.importutils import import_class - -from trove.common import cfg -from trove.common.remote import get_endpoint -from trove.common.remote import normalize_url - -from glanceclient import Client - -CONF = cfg.CONF - - -def glance_client(context, region_name=None): - - # We should allow glance to get the endpoint from the service - # catalog, but to do so we would need to be able to specify - # the endpoint_filter on the API calls, but glance - # doesn't currently allow that. As a result, we must - # specify the endpoint explicitly. - if CONF.glance_url: - endpoint_url = '%(url)s%(tenant)s' % { - 'url': normalize_url(CONF.glance_url), - 'tenant': context.project_id} - else: - endpoint_url = get_endpoint( - context.service_catalog, service_type=CONF.glance_service_type, - endpoint_region=region_name or CONF.os_region_name, - endpoint_type=CONF.glance_endpoint_type) - - auth = v3.Token(CONF.trove_auth_url, context.auth_token) - session = ka_session.Session(auth=auth) - - return Client(CONF.glance_client_version, endpoint=endpoint_url, - session=session) - - -def create_glance_client(*arg, **kwargs): - return import_class(CONF.remote_glance_client)(*arg, **kwargs) diff --git a/trove/common/models.py b/trove/common/models.py index 847a9dd013..2cc247d05b 100644 --- a/trove/common/models.py +++ b/trove/common/models.py @@ -18,8 +18,8 @@ from oslo_utils.importutils import import_class from trove.common import cfg +from trove.common import clients from trove.common.i18n import _ -from trove.common import remote CONF = cfg.CONF @@ -114,18 +114,18 @@ class NovaRemoteModelBase(RemoteModelBase): @classmethod def get_client(cls, context, region_name): - return remote.create_nova_client(context, region_name) + return clients.create_nova_client(context, region_name) class SwiftRemoteModelBase(RemoteModelBase): @classmethod def get_client(cls, context, region_name): - return remote.create_swift_client(context, region_name) + return clients.create_swift_client(context, region_name) class CinderRemoteModelBase(RemoteModelBase): @classmethod def get_client(cls, context): - return remote.create_cinder_client(context) + return clients.create_cinder_client(context) diff --git a/trove/common/neutron.py b/trove/common/neutron.py index 1972309ab8..5f3330b117 100644 --- a/trove/common/neutron.py +++ b/trove/common/neutron.py @@ -15,8 +15,8 @@ import netaddr from oslo_log import log as logging from trove.common import cfg +from trove.common import clients from trove.common import exception -from trove.common import remote CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -36,7 +36,7 @@ def get_management_networks(context): MGMT_NETWORKS = [] if len(CONF.management_networks) > 0: - neutron_client = remote.create_neutron_client(context) + neutron_client = clients.create_neutron_client(context) for net_id in CONF.management_networks: MGMT_NETWORKS.append( diff --git a/trove/common/server_group.py b/trove/common/server_group.py index e526a81cc0..01a393ac9f 100644 --- a/trove/common/server_group.py +++ b/trove/common/server_group.py @@ -18,7 +18,7 @@ import six from oslo_log import log as logging -from trove.common.remote import create_nova_client +from trove.common.clients import create_nova_client LOG = logging.getLogger(__name__) diff --git a/trove/common/strategies/cluster/experimental/galera_common/taskmanager.py b/trove/common/strategies/cluster/experimental/galera_common/taskmanager.py index 4752dde737..a684b8d52f 100644 --- a/trove/common/strategies/cluster/experimental/galera_common/taskmanager.py +++ b/trove/common/strategies/cluster/experimental/galera_common/taskmanager.py @@ -16,10 +16,10 @@ from eventlet.timeout import Timeout from oslo_log import log as logging from trove.common import cfg +from trove.common.clients import create_nova_client from trove.common.exception import PollTimeOut from trove.common.exception import TroveError from trove.common.i18n import _ -from trove.common.remote import create_nova_client from trove.common.strategies.cluster import base as cluster_base from trove.common.template import ClusterConfigTemplate from trove.common import utils diff --git a/trove/common/strategies/cluster/experimental/mongodb/api.py b/trove/common/strategies/cluster/experimental/mongodb/api.py index e07523a59e..a78feea44c 100644 --- a/trove/common/strategies/cluster/experimental/mongodb/api.py +++ b/trove/common/strategies/cluster/experimental/mongodb/api.py @@ -20,11 +20,11 @@ from trove.cluster import models from trove.cluster.tasks import ClusterTasks from trove.cluster.views import ClusterView from trove.common import cfg +from trove.common import clients from trove.common import exception from trove.common.i18n import _ from trove.common.notification import DBaaSClusterGrow from trove.common.notification import StartNotification -from trove.common import remote from trove.common import server_group as srv_grp from trove.common.strategies.cluster import base from trove.common import utils @@ -637,7 +637,7 @@ class MongoDbCluster(models.Cluster): if len(set(flavor_ids)) != 1: raise exception.ClusterFlavorsNotEqual() flavor_id = flavor_ids[0] - nova_client = remote.create_nova_client(context) + nova_client = clients.create_nova_client(context) try: flavor = nova_client.flavors.get(flavor_id) except nova_exceptions.NotFound: diff --git a/trove/common/strategies/storage/swift.py b/trove/common/strategies/storage/swift.py index dc2c57a2e9..f2f78523d1 100644 --- a/trove/common/strategies/storage/swift.py +++ b/trove/common/strategies/storage/swift.py @@ -21,8 +21,8 @@ from oslo_log import log as logging import six from trove.common import cfg +from trove.common.clients import create_swift_client from trove.common.i18n import _ -from trove.common.remote import create_swift_client from trove.common.strategies.storage import base LOG = logging.getLogger(__name__) diff --git a/trove/common/trove_remote.py b/trove/common/trove_remote.py index 6789e570de..212bc2eb9d 100644 --- a/trove/common/trove_remote.py +++ b/trove/common/trove_remote.py @@ -16,8 +16,8 @@ from oslo_utils.importutils import import_class from trove.common import cfg -from trove.common.remote import get_endpoint -from trove.common.remote import normalize_url +from trove.common.clients import get_endpoint +from trove.common.clients import normalize_url from troveclient.v1 import client as TroveClient @@ -26,7 +26,7 @@ CONF = cfg.CONF """ NOTE(mwj, Apr 2016): -This module is separated from remote.py because remote.py is used +This module is separated from clients.py because clients.py is used on the Trove guest, but the trove client is not installed on the guest, so the imports here would fail. """ @@ -38,14 +38,15 @@ def trove_client(context, region_name=None): 'url': normalize_url(CONF.trove_url), 'tenant': context.project_id} else: + region = region_name or CONF.service_credentials.region_name url = get_endpoint(context.service_catalog, service_type=CONF.trove_service_type, - endpoint_region=region_name or CONF.os_region_name, + endpoint_region=region, endpoint_type=CONF.trove_endpoint_type) client = TroveClient.Client(context.user, context.auth_token, project_id=context.project_id, - auth_url=CONF.trove_auth_url) + auth_url=CONF.service_credentials.auth_url) client.client.auth_token = context.auth_token client.client.management_url = url return client diff --git a/trove/datastore/models.py b/trove/datastore/models.py index f95fae6344..5a53a9f1e0 100644 --- a/trove/datastore/models.py +++ b/trove/datastore/models.py @@ -18,9 +18,9 @@ from oslo_log import log as logging from trove.common import cfg +from trove.common.clients import create_nova_client from trove.common import exception from trove.common.i18n import _ -from trove.common.remote import create_nova_client from trove.common import timeutils from trove.common import utils from trove.db import get_db_api diff --git a/trove/db/sqlalchemy/migrate_repo/versions/039_region.py b/trove/db/sqlalchemy/migrate_repo/versions/039_region.py index eda38f5681..fa0668f0cf 100644 --- a/trove/db/sqlalchemy/migrate_repo/versions/039_region.py +++ b/trove/db/sqlalchemy/migrate_repo/versions/039_region.py @@ -32,4 +32,5 @@ def upgrade(migrate_engine): meta.bind = migrate_engine instances = Table('instances', meta, autoload=True) instances.create_column(Column('region_id', String(255))) - instances.update().values(region_id=CONF.os_region_name).execute() + instances.update().values( + region_id=CONF.service_credentials.region_name).execute() diff --git a/trove/extensions/common/models.py b/trove/extensions/common/models.py index 4dbc2d2691..3cfb65a89f 100644 --- a/trove/extensions/common/models.py +++ b/trove/extensions/common/models.py @@ -15,9 +15,9 @@ from oslo_log import log as logging +from trove.common.clients import create_guest_client from trove.common.db import models as guest_models from trove.common import exception -from trove.common.remote import create_guest_client from trove.common import timeutils from trove.db import get_db_api from trove.instance import models as base_models diff --git a/trove/extensions/mgmt/datastores/service.py b/trove/extensions/mgmt/datastores/service.py index 0f09dfcd48..e0f70772cf 100644 --- a/trove/extensions/mgmt/datastores/service.py +++ b/trove/extensions/mgmt/datastores/service.py @@ -18,8 +18,8 @@ from oslo_log import log as logging from trove.common import apischema from trove.common.auth import admin_context +from trove.common import clients from trove.common import exception -from trove.common import glance_remote from trove.common import utils from trove.common import wsgi from trove.datastore import models @@ -52,7 +52,7 @@ class DatastoreVersionController(wsgi.Controller): {'tenant': tenant_id, 'version': version_name, 'datastore': datastore_name}) - client = glance_remote.create_glance_client(context) + client = clients.create_glance_client(context) try: client.images.get(image_id) except glance_exceptions.HTTPNotFound: @@ -118,7 +118,7 @@ class DatastoreVersionController(wsgi.Controller): if type(packages) is list: packages = ','.join(packages) - client = glance_remote.create_glance_client(context) + client = clients.create_glance_client(context) try: client.images.get(image_id) except glance_exceptions.HTTPNotFound: diff --git a/trove/extensions/mgmt/instances/models.py b/trove/extensions/mgmt/instances/models.py index 605704b5af..e5255d78f0 100644 --- a/trove/extensions/mgmt/instances/models.py +++ b/trove/extensions/mgmt/instances/models.py @@ -16,9 +16,9 @@ import datetime from oslo_log import log as logging from trove.common import cfg +from trove.common import clients from trove.common import exception from trove.common.i18n import _ -from trove.common import remote from trove.common import timeutils from trove.extensions.mysql import models as mysql_models from trove.instance import models as instance_models @@ -31,7 +31,9 @@ CONF = cfg.CONF def load_mgmt_instances(context, deleted=None, client=None, include_clustered=None): if not client: - client = remote.create_nova_client(context, CONF.os_region_name) + client = clients.create_nova_client( + context, CONF.service_credentials.region_name + ) try: mgmt_servers = client.rdservers.list() except AttributeError: @@ -55,7 +57,9 @@ def load_mgmt_instance(cls, context, id, include_deleted): instance = instance_models.load_instance( cls, context, id, needs_server=True, include_deleted=include_deleted) - client = remote.create_nova_client(context, CONF.os_region_name) + client = clients.create_nova_client( + context, CONF.service_credentials.region_name + ) try: server = client.rdservers.get(instance.server_id) except AttributeError: @@ -118,7 +122,7 @@ class DetailedMgmtInstance(SimpleMgmtInstance): @classmethod def load(cls, context, id, include_deleted=False): instance = load_mgmt_instance(cls, context, id, include_deleted) - client = remote.create_cinder_client(context) + client = clients.create_cinder_client(context) try: instance.volume = client.volumes.get(instance.volume_id) except Exception: @@ -249,7 +253,7 @@ class NovaNotificationTransformer(NotificationTransformer): def __init__(self, **kwargs): super(NovaNotificationTransformer, self).__init__(**kwargs) self.context = kwargs['context'] - self.nova_client = remote.create_admin_nova_client(self.context) + self.nova_client = clients.create_admin_nova_client(self.context) self._flavor_cache = {} def _lookup_flavor(self, flavor_id): diff --git a/trove/extensions/mgmt/upgrade/models.py b/trove/extensions/mgmt/upgrade/models.py index a5705226e0..03f20c9cca 100644 --- a/trove/extensions/mgmt/upgrade/models.py +++ b/trove/extensions/mgmt/upgrade/models.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from trove.common.remote import guest_client +from trove.common.clients import guest_client class UpgradeMessageSender(object): diff --git a/trove/extensions/mysql/models.py b/trove/extensions/mysql/models.py index 3071d30fc1..5b17320539 100644 --- a/trove/extensions/mysql/models.py +++ b/trove/extensions/mysql/models.py @@ -18,10 +18,10 @@ Model classes that extend the instances functionality for MySQL instances. """ from trove.common import cfg +from trove.common.clients import create_guest_client from trove.common.db.mysql import models as guest_models from trove.common import exception from trove.common.notification import StartNotification -from trove.common.remote import create_guest_client from trove.common import utils from trove.extensions.common.models import load_and_verify from trove.extensions.common.models import RootHistory diff --git a/trove/extensions/redis/models.py b/trove/extensions/redis/models.py index 62a35e2660..7d9c880d30 100644 --- a/trove/extensions/redis/models.py +++ b/trove/extensions/redis/models.py @@ -14,7 +14,7 @@ # under the License. # -from trove.common.remote import create_guest_client +from trove.common.clients import create_guest_client from trove.extensions.common.models import load_and_verify from trove.extensions.common.models import Root diff --git a/trove/extensions/security_group/models.py b/trove/extensions/security_group/models.py index f176d4c118..df53e0a583 100644 --- a/trove/extensions/security_group/models.py +++ b/trove/extensions/security_group/models.py @@ -148,8 +148,8 @@ class RemoteSecurityGroup(NetworkRemoteModelBase): msg = _("Security Group does not have id defined!") raise exception.InvalidModelError(msg) elif security_group is None: - driver = self.get_driver(context, - region_name or CONF.os_region_name) + region = region_name or CONF.service_credentials.region_name + driver = self.get_driver(context, region) self._data_object = driver.get_sec_group_by_id(group_id=id) else: self._data_object = security_group diff --git a/trove/flavor/models.py b/trove/flavor/models.py index bd8675d47b..f26760dade 100644 --- a/trove/flavor/models.py +++ b/trove/flavor/models.py @@ -17,9 +17,9 @@ from novaclient import exceptions as nova_exceptions +from trove.common.clients import create_nova_client from trove.common import exception from trove.common.models import NovaRemoteModelBase -from trove.common.remote import create_nova_client class Flavor(object): diff --git a/trove/guestagent/guest_log.py b/trove/guestagent/guest_log.py index ec84a55498..3e0c06a3e8 100644 --- a/trove/guestagent/guest_log.py +++ b/trove/guestagent/guest_log.py @@ -21,9 +21,9 @@ from oslo_log import log as logging from swiftclient.client import ClientException from trove.common import cfg +from trove.common import clients from trove.common import exception from trove.common.i18n import _ -from trove.common import remote from trove.common import stream_codecs from trove.common import timeutils from trove.guestagent.common import operating_system @@ -130,7 +130,7 @@ class GuestLog(object): def swift_client(self): if not self._cached_swift_client or ( self._cached_context != self.context): - self._cached_swift_client = remote.swift_client(self.context) + self._cached_swift_client = clients.swift_client(self.context) self._cached_context = self.context return self._cached_swift_client diff --git a/trove/instance/models.py b/trove/instance/models.py index 6df1191e9a..356fcc7d93 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -28,18 +28,18 @@ from sqlalchemy import func from trove.backup.models import Backup from trove.common import cfg +from trove.common.clients import create_cinder_client +from trove.common.clients import create_dns_client +from trove.common.clients import create_glance_client +from trove.common.clients import create_guest_client +from trove.common.clients import create_neutron_client +from trove.common.clients import create_nova_client from trove.common import crypto_utils as cu from trove.common import exception -from trove.common.glance_remote import create_glance_client from trove.common.i18n import _ from trove.common import instance as tr_instance from trove.common import neutron from trove.common import notification -from trove.common.remote import create_cinder_client -from trove.common.remote import create_dns_client -from trove.common.remote import create_guest_client -from trove.common.remote import create_neutron_client -from trove.common.remote import create_nova_client from trove.common import server_group as srv_grp from trove.common import template from trove.common import timeutils @@ -858,8 +858,6 @@ class BaseInstance(SimpleInstance): return self._neutron_client def reset_task_status(self): - LOG.info("Resetting task status to NONE on instance %s.", - self.id) self.update_db(task_status=InstanceTasks.NONE) @property @@ -958,7 +956,9 @@ class Instance(BuiltInstance): raise exception.TroveError( "Flavors differ between regions" " %(local)s and %(remote)s." % - {'local': CONF.os_region_name, 'remote': region_name}) + {'local': CONF.service_credentials.region_name, + 'remote': region_name} + ) except nova_exceptions.NotFound: raise exception.TroveError( "Flavors %(flavor)s not found in region %(remote)s." @@ -973,7 +973,9 @@ class Instance(BuiltInstance): raise exception.TroveError( "Datastore versions differ between regions " "%(local)s and %(remote)s." % - {'local': CONF.os_region_name, 'remote': region_name}) + {'local': CONF.service_credentials.region_name, + 'remote': region_name} + ) except exception.NotFound: raise exception.TroveError( "Datastore Version %(dsv)s not found in region %(remote)s." @@ -989,7 +991,8 @@ class Instance(BuiltInstance): raise exception.TroveError( "Images for Datastore %(ds)s do not match " "between regions %(local)s and %(remote)s." % - {'ds': datastore.name, 'local': CONF.os_region_name, + {'ds': datastore.name, + 'local': CONF.service_credentials.region_name, 'remote': region_name}) @classmethod @@ -1000,7 +1003,7 @@ class Instance(BuiltInstance): replica_count=None, volume_type=None, modules=None, locality=None, region_name=None, access=None): - region_name = region_name or CONF.os_region_name + region_name = region_name or CONF.service_credentials.region_name call_args = { 'name': name, @@ -1036,7 +1039,7 @@ class Instance(BuiltInstance): # If a different region is specified for the instance, ensure # that the flavor and image are the same in both regions - if region_name and region_name != CONF.os_region_name: + if region_name and region_name != CONF.service_credentials.region_name: cls._validate_remote_datastore(context, region_name, flavor, datastore, datastore_version) @@ -1695,8 +1698,8 @@ class Instances(object): db.addresses = {} else: try: - if (not db.region_id - or db.region_id == CONF.os_region_name): + region = CONF.service_credentials.region_name + if (not db.region_id or db.region_id == region): server = find_server(db.id, db.compute_instance_id) else: nova_client = create_nova_client( diff --git a/trove/instance/service.py b/trove/instance/service.py index 818208e922..ce339704bc 100644 --- a/trove/instance/service.py +++ b/trove/instance/service.py @@ -20,13 +20,13 @@ from trove.backup.models import Backup as backup_model from trove.backup import views as backup_views import trove.common.apischema as apischema from trove.common import cfg +from trove.common.clients import create_guest_client from trove.common import exception from trove.common.i18n import _ from trove.common import notification from trove.common.notification import StartNotification from trove.common import pagination from trove.common import policy -from trove.common.remote import create_guest_client from trove.common import utils from trove.common import wsgi from trove.datastore import models as datastore_models @@ -362,7 +362,9 @@ class InstanceController(wsgi.Controller): 'master.') raise exception.BadRequest(message=dupe_locality_msg) - region_name = body['instance'].get('region_name', CONF.os_region_name) + region_name = body['instance'].get( + 'region_name', CONF.service_credentials.region_name + ) access = body['instance'].get('access', None) instance = models.Instance.create(context, name, flavor_id, diff --git a/trove/network/neutron.py b/trove/network/neutron.py index 67e4a4487b..962bbf12f1 100644 --- a/trove/network/neutron.py +++ b/trove/network/neutron.py @@ -15,8 +15,8 @@ from neutronclient.common import exceptions as neutron_exceptions from oslo_log import log as logging +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.network import base LOG = logging.getLogger(__name__) @@ -26,7 +26,7 @@ class NeutronDriver(base.NetworkDriver): def __init__(self, context, region_name): try: - self.client = remote.create_neutron_client(context, region_name) + self.client = clients.create_neutron_client(context, region_name) except neutron_exceptions.NeutronClientException as e: raise exception.TroveError(str(e)) diff --git a/trove/network/nova.py b/trove/network/nova.py index b6b27cfd43..bdab054b18 100644 --- a/trove/network/nova.py +++ b/trove/network/nova.py @@ -17,8 +17,8 @@ from novaclient import exceptions as nova_exceptions from oslo_log import log as logging +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.network import base LOG = logging.getLogger(__name__) @@ -28,7 +28,7 @@ class NovaNetwork(base.NetworkDriver): def __init__(self, context, region_name): try: - self.client = remote.create_nova_client( + self.client = clients.create_nova_client( context, region_name) except nova_exceptions.ClientException as e: raise exception.TroveError(str(e)) diff --git a/trove/taskmanager/manager.py b/trove/taskmanager/manager.py index 8f4080cf34..ad1a04c9a6 100644 --- a/trove/taskmanager/manager.py +++ b/trove/taskmanager/manager.py @@ -19,13 +19,13 @@ from oslo_utils import importutils from trove.backup.models import Backup import trove.common.cfg as cfg +from trove.common import clients from trove.common.context import TroveContext from trove.common import exception from trove.common.exception import ReplicationSlaveAttachError from trove.common.exception import TroveError from trove.common.i18n import _ from trove.common.notification import DBaaSQuotas, EndNotification -from trove.common import remote from trove.common import server_group as srv_grp from trove.common.strategies.cluster import strategy from trove.datastore.models import DatastoreVersion @@ -44,9 +44,9 @@ class Manager(periodic_task.PeriodicTasks): def __init__(self): super(Manager, self).__init__(CONF) self.admin_context = TroveContext( - user=CONF.nova_proxy_admin_user, - tenant=CONF.nova_proxy_admin_tenant_id, - user_domain_name=CONF.nova_proxy_admin_user_domain_name) + user=CONF.service_credentials.username, + tenant=CONF.service_credentials.project_id, + user_domain_name=CONF.service_credentials.user_domain_name) if CONF.exists_notification_transformer: self.exists_transformer = importutils.import_object( CONF.exists_notification_transformer, @@ -482,7 +482,7 @@ class Manager(periodic_task.PeriodicTasks): if CONF.quota_notification_interval: @periodic_task.periodic_task(spacing=CONF.quota_notification_interval) def publish_quota_notifications(self, context): - nova_client = remote.create_nova_client(self.admin_context) + nova_client = clients.create_nova_client(self.admin_context) for tenant in nova_client.tenants.list(): for quota in QUOTAS.get_all_quotas_by_tenant(tenant.id): usage = QUOTAS.get_quota_usage(quota) diff --git a/trove/taskmanager/models.py b/trove/taskmanager/models.py index dda8feec28..1ad922c5dd 100755 --- a/trove/taskmanager/models.py +++ b/trove/taskmanager/models.py @@ -32,6 +32,10 @@ from trove.cluster.models import Cluster from trove.cluster.models import DBCluster from trove.cluster import tasks from trove.common import cfg +from trove.common import clients +from trove.common.clients import create_cinder_client +from trove.common.clients import create_dns_client +from trove.common.clients import create_guest_client from trove.common import crypto_utils as cu from trove.common import exception from trove.common.exception import BackupCreationError @@ -53,10 +57,6 @@ from trove.common.notification import ( TroveInstanceCreate, TroveInstanceModifyVolume, TroveInstanceModifyFlavor) -import trove.common.remote as remote -from trove.common.remote import create_cinder_client -from trove.common.remote import create_dns_client -from trove.common.remote import create_guest_client from trove.common.strategies.cluster import strategy from trove.common import template from trove.common import timeutils @@ -424,6 +424,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin): error_message = '' error_details = '' try: + LOG.info("Waiting for instance %s up and running", self.id) utils.poll_until(self._service_is_active, sleep_time=CONF.usage_sleep_time, time_out=timeout) @@ -1414,7 +1415,7 @@ class BackupTasks(object): @classmethod def delete_files_from_swift(cls, context, filename): container = CONF.backup_swift_container - client = remote.create_swift_client(context) + client = clients.create_swift_client(context) obj = client.head_object(container, filename) if 'x-static-large-object' in obj: # Static large object diff --git a/trove/tests/unittests/backup/test_backup_models.py b/trove/tests/unittests/backup/test_backup_models.py index b588b68c8b..baee820ab8 100644 --- a/trove/tests/unittests/backup/test_backup_models.py +++ b/trove/tests/unittests/backup/test_backup_models.py @@ -22,7 +22,6 @@ from trove.backup import models from trove.backup import state from trove.common import context from trove.common import exception -from trove.common import remote from trove.common import timeutils from trove.common import utils from trove.db.models import DatabaseModelBase @@ -401,48 +400,50 @@ class BackupORMTest(trove_testtools.TestCase): self.assertRaises(ValueError, _set_bad_filename) - def test_check_swift_object_exist_integrity_error(self): - mock_client = MagicMock() - mock_client.head_object.return_value = {'etag': ''} - with patch.object(remote, 'get_endpoint', return_value=None),\ - patch.object(remote, 'Connection', - return_value=mock_client): - self.assertRaises(exception.RestoreBackupIntegrityError, - self.backup.check_swift_object_exist, - self.context, True) + @patch('trove.common.clients.create_swift_client') + def test_check_swift_object_exist_integrity_error(self, mock_swift_client): + mock_swift_client.return_value.head_object.return_value = {'etag': ''} - def test_check_swift_object_exist_client_exception(self): - with patch.object(remote, 'get_endpoint', return_value=None),\ - patch.object(remote, 'Connection', - side_effect=ClientException(self.context.project_id)): - self.assertRaises(exception.SwiftAuthError, - self.backup.check_swift_object_exist, - self.context) + self.assertRaises(exception.RestoreBackupIntegrityError, + self.backup.check_swift_object_exist, + self.context, True) - def test_check_swift_object_exist_client_exception_404(self): + @patch('trove.common.clients.create_swift_client') + def test_check_swift_object_exist_client_exception(self, + mock_swift_client): + mock_swift_client.side_effect = ClientException( + self.context.project_id + ) + self.assertRaises(exception.SwiftAuthError, + self.backup.check_swift_object_exist, + self.context) + + @patch('trove.common.clients.create_swift_client') + def test_check_swift_object_exist_client_exception_404(self, + mock_swift_client): e = ClientException(self.context.project_id) e.http_status = 404 - with patch.object(remote, 'get_endpoint', return_value=None),\ - patch.object(remote, 'Connection', - side_effect=e): - self.assertFalse( - self.backup.check_swift_object_exist(self.context)) + mock_swift_client.side_effect = e - def test_swift_auth_token_client_exception(self): - with patch.object(remote, 'get_endpoint', return_value=None),\ - patch.object(remote, 'Connection', - side_effect=ClientException(self.context.project_id)): - self.assertRaises(exception.SwiftAuthError, - models.Backup.verify_swift_auth_token, - self.context) + self.assertFalse(self.backup.check_swift_object_exist(self.context)) - def test_swift_auth_token_no_service_endpoint(self): - with patch.object(remote, 'get_endpoint', return_value=None),\ - patch.object(remote, 'Connection', - side_effect=exception.NoServiceEndpoint): - self.assertRaises(exception.SwiftNotFound, - models.Backup.verify_swift_auth_token, - self.context) + @patch('trove.common.clients.create_swift_client') + def test_swift_auth_token_client_exception(self, mock_swift_client): + mock_swift_client.side_effect = ClientException( + self.context.project_id + ) + + self.assertRaises(exception.SwiftAuthError, + models.Backup.verify_swift_auth_token, + self.context) + + @patch('trove.common.clients.create_swift_client') + def test_swift_auth_token_no_service_endpoint(self, mock_swift_client): + mock_swift_client.side_effect = exception.NoServiceEndpoint + + self.assertRaises(exception.SwiftNotFound, + models.Backup.verify_swift_auth_token, + self.context) class PaginationTests(trove_testtools.TestCase): diff --git a/trove/tests/unittests/cluster/test_cluster.py b/trove/tests/unittests/cluster/test_cluster.py index 6403c24797..29df4ee85b 100644 --- a/trove/tests/unittests/cluster/test_cluster.py +++ b/trove/tests/unittests/cluster/test_cluster.py @@ -21,8 +21,8 @@ from trove.cluster.models import Cluster from trove.cluster.models import ClusterTasks from trove.cluster.models import DBCluster from trove.common import cfg +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.common.strategies.cluster.experimental.mongodb import ( api as mongodb_api) from trove.common import utils @@ -66,12 +66,12 @@ class ClusterTest(trove_testtools.TestCase): {'volume_size': 1, 'flavor_id': '1234'}, {'volume_size': 1, 'flavor_id': '1234'}] self.volume_support = CONF.get(self.dv.manager).volume_support - self.remote_nova = remote.create_nova_client + self.remote_nova = clients.create_nova_client def tearDown(self): super(ClusterTest, self).tearDown() CONF.get(self.dv.manager).volume_support = self.volume_support - remote.create_nova_client = self.remote_nova + clients.create_nova_client = self.remote_nova def test_create_empty_instances(self): self.assertRaises(exception.ClusterNumInstancesNotSupported, @@ -83,7 +83,7 @@ class ClusterTest(trove_testtools.TestCase): [], {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_unequal_flavors(self, mock_client): instances = self.instances instances[0]['flavor_id'] = '4567' @@ -96,7 +96,7 @@ class ClusterTest(trove_testtools.TestCase): instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_unequal_volumes(self, mock_client): instances = self.instances @@ -112,7 +112,7 @@ class ClusterTest(trove_testtools.TestCase): instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_storage_not_specified(self, mock_client): class FakeFlavor(object): diff --git a/trove/tests/unittests/cluster/test_galera_cluster.py b/trove/tests/unittests/cluster/test_galera_cluster.py index 8d7372977c..2557c25d68 100644 --- a/trove/tests/unittests/cluster/test_galera_cluster.py +++ b/trove/tests/unittests/cluster/test_galera_cluster.py @@ -21,8 +21,8 @@ from novaclient import exceptions as nova_exceptions from trove.cluster.models import Cluster from trove.cluster.models import ClusterTasks from trove.cluster.models import DBCluster +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.common.strategies.cluster.experimental.galera_common import ( api as galera_api) from trove.common.strategies.cluster.experimental.galera_common import ( @@ -85,7 +85,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, [], {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_flavor_not_specified(self, mock_client): instances = self.instances instances[0]['flavor_id'] = None @@ -97,7 +97,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_invalid_flavor_specified(self, mock_client): instances = [{'flavor_id': '1234'}, @@ -116,7 +116,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_volume_no_specified(self, mock_client): instances = self.instances @@ -131,7 +131,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(galera_api, 'CONF') def test_create_storage_specified_with_no_volume_support(self, mock_conf, @@ -150,7 +150,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(galera_api, 'CONF') def test_create_storage_not_specified_and_no_ephemeral_flavor(self, mock_conf, @@ -181,7 +181,7 @@ class ClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_volume_not_equal(self, mock_client): instances = self.instances instances[0]['volume_size'] = 2 @@ -200,8 +200,8 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') - @patch.object(remote, 'create_neutron_client') + @patch.object(clients, 'create_nova_client') + @patch.object(clients, 'create_neutron_client') def test_create(self, mock_neutron_client, mock_nova_client, mock_check_quotas, mock_task_api, mock_db_create, mock_ins_create, mock_find_all): @@ -223,7 +223,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_over_limit(self, mock_client, mock_check_quotas, mock_task_api, mock_db_create, mock_ins_create): instances = [{'volume_size': 1, 'flavor_id': '1234'}, @@ -247,7 +247,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_with_ephemeral_flavor(self, mock_client, mock_check_quotas, mock_task_api, mock_db_create, mock_ins_create, mock_conf, @@ -312,8 +312,8 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(inst_models.Instance, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') - @patch.object(remote, 'create_neutron_client') + @patch.object(clients, 'create_nova_client') + @patch.object(clients, 'create_neutron_client') def test_grow(self, mock_neutron_client, mock_nova_client, mock_check_quotas, mock_task_api, mock_inst_create, mock_conf, mock_update): @@ -331,8 +331,8 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(galera_api, 'CONF') @patch.object(inst_models.Instance, 'create') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') - @patch.object(remote, 'create_neutron_client') + @patch.object(clients, 'create_nova_client') + @patch.object(clients, 'create_neutron_client') def test_grow_exception(self, mock_neutron_client, mock_nova_client, mock_check_quotas, mock_inst_create, mock_conf, mock_update): diff --git a/trove/tests/unittests/cluster/test_models.py b/trove/tests/unittests/cluster/test_models.py index 8c7f4078cd..6a853e0817 100644 --- a/trove/tests/unittests/cluster/test_models.py +++ b/trove/tests/unittests/cluster/test_models.py @@ -24,14 +24,14 @@ from mock import PropertyMock from neutronclient.common import exceptions as neutron_exceptions from trove.cluster import models +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.tests.unittests import trove_testtools class TestModels(trove_testtools.TestCase): - @patch.object(remote, 'create_nova_client', return_value=MagicMock()) + @patch.object(clients, 'create_nova_client', return_value=MagicMock()) def test_validate_instance_flavors(self, create_nova_cli_mock): patch.object( create_nova_cli_mock.return_value, 'flavors', @@ -173,7 +173,7 @@ class TestModels(trove_testtools.TestCase): assert_same_instance_volumes.assert_called_once_with( test_instances, required_size=required_volume_size) - @patch.object(remote, 'create_neutron_client', return_value=MagicMock()) + @patch.object(clients, 'create_neutron_client', return_value=MagicMock()) def test_validate_instance_nics(self, create_neutron_cli_mock): test_instances = [ diff --git a/trove/tests/unittests/cluster/test_mongodb_cluster.py b/trove/tests/unittests/cluster/test_mongodb_cluster.py index a177a0f809..81d509661c 100644 --- a/trove/tests/unittests/cluster/test_mongodb_cluster.py +++ b/trove/tests/unittests/cluster/test_mongodb_cluster.py @@ -21,8 +21,8 @@ from novaclient import exceptions as nova_exceptions from trove.cluster import models from trove.cluster import tasks from trove.common import cfg +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.common.strategies.cluster.experimental.mongodb import api from trove.instance import models as inst_models from trove.instance import tasks as inst_tasks @@ -75,7 +75,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.manager = mock.Mock() self.cluster.manager = self.manager self.volume_support = CONF.get('mongodb').volume_support - self.remote_nova = remote.create_nova_client + self.remote_nova = clients.create_nova_client self.instances = [ {'volume_size': 1, 'flavor_id': '1234', 'nics': [{"net-id": "foo-bar"}], @@ -114,7 +114,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.datastore_version, instance, {}, None, None) - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_nova_client') def test_create_invalid_flavor_specified(self, mock_client): (mock_client.return_value.flavors.get) = mock.Mock( side_effect=nova_exceptions.NotFound( @@ -127,7 +127,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.datastore_version, self.instances, {}, None, None) - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_nova_client') def test_create_flavor_not_equal(self, mock_client): instances = self.instances instances[0]['flavor_id'] = '4321' @@ -141,7 +141,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_nova_client') def test_create_volume_not_equal(self, mock_client): instances = self.instances instances[0]['volume_size'] = 2 @@ -155,7 +155,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_nova_client') def test_create_volume_not_specified(self, mock_client): instances = [ {'flavor_id': '1234', @@ -177,7 +177,7 @@ class MongoDBClusterTest(trove_testtools.TestCase): self.datastore_version, instances, {}, None, None) - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_nova_client') @mock.patch.object(api, 'CONF') def test_create_storage_specified_with_no_volume_support(self, mock_conf, @@ -197,8 +197,8 @@ class MongoDBClusterTest(trove_testtools.TestCase): @mock.patch.object(task_api, 'load') @mock.patch.object(inst_models.Instance, 'create') @mock.patch.object(models.DBCluster, 'create') - @mock.patch.object(remote, 'create_neutron_client') - @mock.patch.object(remote, 'create_nova_client') + @mock.patch.object(clients, 'create_neutron_client') + @mock.patch.object(clients, 'create_nova_client') @mock.patch.object(api, 'check_quotas') def test_create_validate_volumes_deltas(self, mock_check_quotas, *args): extended_properties = { @@ -217,8 +217,8 @@ class MongoDBClusterTest(trove_testtools.TestCase): @mock.patch.object(inst_models.Instance, 'create') @mock.patch.object(models.DBCluster, 'create') @mock.patch.object(QUOTAS, 'check_quotas') - @mock.patch.object(remote, 'create_nova_client') - @mock.patch.object(remote, 'create_neutron_client') + @mock.patch.object(clients, 'create_nova_client') + @mock.patch.object(clients, 'create_neutron_client') def test_create(self, mock_neutron_client, mock_nova_client, mock_check_quotas, mock_db_create, mock_ins_create, mock_task_api): @@ -284,8 +284,8 @@ class MongoDBClusterTest(trove_testtools.TestCase): @mock.patch.object(inst_models.Instance, 'create') @mock.patch.object(models.DBCluster, 'create') @mock.patch.object(QUOTAS, 'check_quotas') - @mock.patch.object(remote, 'create_nova_client') - @mock.patch.object(remote, 'create_neutron_client') + @mock.patch.object(clients, 'create_nova_client') + @mock.patch.object(clients, 'create_neutron_client') @mock.patch.object(api, 'CONF') def test_create_with_lower_configsvr(self, mock_conf, mock_neutron_client, mock_nova_client, ock_check_quotas, @@ -311,8 +311,8 @@ class MongoDBClusterTest(trove_testtools.TestCase): @mock.patch.object(inst_models.Instance, 'create') @mock.patch.object(models.DBCluster, 'create') @mock.patch.object(QUOTAS, 'check_quotas') - @mock.patch.object(remote, 'create_nova_client') - @mock.patch.object(remote, 'create_neutron_client') + @mock.patch.object(clients, 'create_nova_client') + @mock.patch.object(clients, 'create_neutron_client') @mock.patch.object(api, 'CONF') def test_create_with_higher_configsvr(self, mock_conf, mock_neutron_client, mock_nova_client, mock_check_quotas, @@ -338,8 +338,8 @@ class MongoDBClusterTest(trove_testtools.TestCase): @mock.patch.object(inst_models.Instance, 'create') @mock.patch.object(models.DBCluster, 'create') @mock.patch.object(QUOTAS, 'check_quotas') - @mock.patch.object(remote, 'create_nova_client') - @mock.patch.object(remote, 'create_neutron_client') + @mock.patch.object(clients, 'create_nova_client') + @mock.patch.object(clients, 'create_neutron_client') @mock.patch.object(api, 'CONF') def test_create_with_higher_mongos(self, mock_conf, mock_neutron_client, mock_nova_client, mock_check_quotas, diff --git a/trove/tests/unittests/cluster/test_redis_cluster.py b/trove/tests/unittests/cluster/test_redis_cluster.py index 4710b9a411..3893404fe5 100644 --- a/trove/tests/unittests/cluster/test_redis_cluster.py +++ b/trove/tests/unittests/cluster/test_redis_cluster.py @@ -19,8 +19,8 @@ from novaclient import exceptions as nova_exceptions from trove.cluster.models import Cluster from trove.cluster.models import ClusterTasks from trove.cluster.models import DBCluster +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.common.strategies.cluster.experimental.redis import api as redis_api from trove.instance import models as inst_models from trove.instance.models import DBInstance @@ -77,7 +77,7 @@ class ClusterTest(trove_testtools.TestCase): def tearDown(self): super(ClusterTest, self).tearDown() - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_invalid_flavor_specified(self, mock_client): (mock_client.return_value.flavors.get) = Mock( @@ -93,7 +93,7 @@ class ClusterTest(trove_testtools.TestCase): self.instances_w_volumes, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(redis_api, 'CONF') def test_create_volume_no_specified(self, mock_conf, mock_client): mock_conf.get = Mock( @@ -107,7 +107,7 @@ class ClusterTest(trove_testtools.TestCase): self.instances_no_volumes, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(redis_api, 'CONF') def test_create_storage_specified_with_no_volume_support(self, mock_conf, @@ -124,7 +124,7 @@ class ClusterTest(trove_testtools.TestCase): self.instances_w_volumes, {}, None, None) - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(redis_api, 'CONF') def test_create_storage_not_specified_and_no_ephemeral_flavor(self, mock_conf, @@ -157,7 +157,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(inst_models.Instance, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create(self, mock_client, mock_check_quotas, mock_task_api, mock_ins_create, mock_conf): mock_conf.get = Mock( @@ -176,7 +176,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(inst_models.Instance, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_with_ephemeral_flavor(self, mock_client, mock_check_quotas, mock_task_api, mock_ins_create, mock_conf): @@ -209,7 +209,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(inst_models.Instance, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_grow(self, mock_client, mock_check_quotas, mock_task_api, mock_ins_create, mock_conf, mock_update): mock_conf.get = Mock( diff --git a/trove/tests/unittests/cluster/test_vertica_cluster.py b/trove/tests/unittests/cluster/test_vertica_cluster.py index 8f2794cfb8..348a1887f6 100644 --- a/trove/tests/unittests/cluster/test_vertica_cluster.py +++ b/trove/tests/unittests/cluster/test_vertica_cluster.py @@ -19,8 +19,8 @@ from novaclient import exceptions as nova_exceptions from trove.cluster.models import Cluster from trove.cluster.models import ClusterTasks from trove.cluster.models import DBCluster +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.common.strategies.cluster.experimental.vertica import ( api as vertica_api) from trove.instance import models as inst_models @@ -84,7 +84,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_flavor_not_specified(self, *args): instances = self.instances instances[0]['flavor_id'] = None @@ -99,7 +99,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_invalid_flavor_specified(self, mock_client, mock_find_all, mock_create): instances = [{'flavor_id': '1234'}, @@ -121,7 +121,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_volume_no_specified(self, mock_client, mock_find_all, mock_create): instances = self.instances @@ -139,7 +139,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(vertica_api, 'CONF') def test_create_storage_specified_with_no_volume_support(self, mock_conf, @@ -163,7 +163,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') @patch.object(vertica_api, 'CONF') def test_create_storage_not_specified_and_no_ephemeral_flavor(self, mock_conf, @@ -199,7 +199,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(inst_models.DBInstance, 'find_all') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_volume_not_equal(self, mock_client, mock_find_all, mock_create): instances = self.instances @@ -220,7 +220,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create(self, mock_client, mock_check_quotas, mock_task_api, mock_db_create, mock_ins_create, mock_find_all): instances = self.instances @@ -242,7 +242,7 @@ class ClusterTest(trove_testtools.TestCase): @patch.object(DBCluster, 'create') @patch.object(task_api, 'load') @patch.object(QUOTAS, 'check_quotas') - @patch.object(remote, 'create_nova_client') + @patch.object(clients, 'create_nova_client') def test_create_with_ephemeral_flavor(self, mock_client, mock_check_quotas, mock_task_api, mock_db_create, mock_ins_create, mock_conf, diff --git a/trove/tests/unittests/common/test_remote.py b/trove/tests/unittests/common/test_remote.py deleted file mode 100644 index 1468951763..0000000000 --- a/trove/tests/unittests/common/test_remote.py +++ /dev/null @@ -1,650 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# Copyright 2013 Rackspace Hosting -# Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -import uuid - -from mock import ANY, patch, MagicMock -import swiftclient.client -from testtools import ExpectedException, matchers - -from trove.common import cfg -from trove.common.context import TroveContext -from trove.common import exception -from trove.common import glance_remote -from trove.common import remote -from trove.tests.fakes.swift import SwiftClientStub -from trove.tests.unittests import trove_testtools - - -class TestRemote(trove_testtools.TestCase): - def setUp(self): - super(TestRemote, self).setUp() - - def tearDown(self): - super(TestRemote, self).tearDown() - - @patch.object(swiftclient.client.Connection, 'get_auth') - def test_creation(self, get_auth_mock): - self.assertIsNotNone(swiftclient.client.Connection()) - - def test_create_swift_client(self): - mock_resp = MagicMock() - with patch.object(swiftclient.client.Connection, 'get_container', - MagicMock(return_value=["text", mock_resp])): - service_catalog = [{'endpoints': [{'region': 'RegionOne', - 'publicURL': 'example.com'}], - 'type': 'object-store'}] - client = remote.create_swift_client(TroveContext( - tenant=uuid.uuid4().hex, - service_catalog=service_catalog)) - headers, container = client.get_container('bob') - self.assertIs(headers, "text") - self.assertIs(container, mock_resp) - - def test_empty_account(self): - """ - this is an account with no containers and no objects - """ - # setup expectation - with SwiftClientStub() as swift_stub: - swift_stub.with_account('123223') - # interact - conn = swiftclient.client.Connection() - account_info = conn.get_account() - self.assertThat(account_info, matchers.Not(matchers.Is(None))) - self.assertThat(len(account_info), matchers.Is(2)) - self.assertThat(account_info, matchers.IsInstance(tuple)) - self.assertThat(account_info[0], matchers.IsInstance(dict)) - self.assertThat( - account_info[0], - matchers.KeysEqual('content-length', 'accept-ranges', - 'x-timestamp', 'x-trans-id', 'date', - 'x-account-bytes-used', - 'x-account-container-count', - 'content-type', - 'x-account-object-count')) - self.assertThat(account_info[1], matchers.IsInstance(list)) - self.assertThat(len(account_info[1]), matchers.Is(0)) - - def test_one_container(self): - """ - tests to ensure behavior is normal with one container - """ - # setup expectation - with SwiftClientStub() as swift_stub: - swift_stub.with_account('123223') - cont_name = 'a-container-name' - swift_stub.with_container(cont_name) - # interact - conn = swiftclient.client.Connection() - conn.get_auth() - conn.put_container(cont_name) - # get headers plus container metadata - self.assertThat(len(conn.get_account()), matchers.Is(2)) - # verify container details - account_containers = conn.get_account()[1] - self.assertThat(len(account_containers), matchers.Is(1)) - self.assertThat(account_containers[0], - matchers.KeysEqual('count', 'bytes', 'name')) - self.assertThat(account_containers[0]['name'], - matchers.Is(cont_name)) - # get container details - cont_info = conn.get_container(cont_name) - self.assertIsNotNone(cont_info) - self.assertThat( - cont_info[0], - matchers.KeysEqual('content-length', - 'x-container-object-count', 'accept-ranges', - 'x-container-bytes-used', 'x-timestamp', - 'x-trans-id', 'date', 'content-type')) - self.assertThat(len(cont_info[1]), matchers.Equals(0)) - # remove container - swift_stub.without_container(cont_name) - with ExpectedException(swiftclient.ClientException): - conn.get_container(cont_name) - # ensure there are no more containers in account - self.assertThat(len(conn.get_account()[1]), matchers.Is(0)) - - def test_one_object(self): - with SwiftClientStub() as swift_stub: - swift_stub.with_account('123223') - swift_stub.with_container('bob') - swift_stub.with_object('bob', 'test', 'test_contents') - # create connection - conn = swiftclient.client.Connection() - # test container lightly - cont_info = conn.get_container('bob') - self.assertIsNotNone(cont_info) - self.assertThat(cont_info[0], - matchers.KeysEqual('content-length', - 'x-container-object-count', - 'accept-ranges', - 'x-container-bytes-used', - 'x-timestamp', - 'x-trans-id', - 'date', - 'content-type')) - cont_objects = cont_info[1] - self.assertThat(len(cont_objects), matchers.Equals(1)) - obj_1 = cont_objects[0] - self.assertThat(obj_1, matchers.Equals( - {'bytes': 13, 'last_modified': '2013-03-15T22:10:49.361950', - 'hash': 'ccc55aefbf92aa66f42b638802c5e7f6', 'name': 'test', - 'content_type': 'application/octet-stream', - 'contents': 'test_contents'})) - # test object api - not much to do here - self.assertThat(conn.get_object('bob', 'test')[1], - matchers.Is('test_contents')) - - # test remove object - swift_stub.without_object('bob', 'test') - # interact - with ExpectedException(swiftclient.ClientException): - conn.delete_object('bob', 'test') - self.assertThat(len(conn.get_container('bob')[1]), matchers.Is(0)) - - def test_two_objects(self): - with SwiftClientStub() as swift_stub: - swift_stub.with_account('123223') - swift_stub.with_container('bob') - swift_stub.with_container('bob2') - swift_stub.with_object('bob', 'test', 'test_contents') - swift_stub.with_object('bob', 'test2', 'test_contents2') - - conn = swiftclient.client.Connection() - - self.assertIs(len(conn.get_account()), 2) - cont_info = conn.get_container('bob') - self.assertIsNotNone(cont_info) - self.assertThat(cont_info[0], - matchers.KeysEqual('content-length', - 'x-container-object-count', - 'accept-ranges', - 'x-container-bytes-used', - 'x-timestamp', - 'x-trans-id', - 'date', - 'content-type')) - self.assertThat(len(cont_info[1]), matchers.Equals(2)) - self.assertThat(cont_info[1][0], matchers.Equals( - {'bytes': 13, 'last_modified': '2013-03-15T22:10:49.361950', - 'hash': 'ccc55aefbf92aa66f42b638802c5e7f6', 'name': 'test', - 'content_type': 'application/octet-stream', - 'contents': 'test_contents'})) - self.assertThat(conn.get_object('bob', 'test')[1], - matchers.Is('test_contents')) - self.assertThat(conn.get_object('bob', 'test2')[1], - matchers.Is('test_contents2')) - - swift_stub.without_object('bob', 'test') - with ExpectedException(swiftclient.ClientException): - conn.delete_object('bob', 'test') - self.assertThat(len(conn.get_container('bob')[1]), matchers.Is(1)) - - swift_stub.without_container('bob') - with ExpectedException(swiftclient.ClientException): - conn.get_container('bob') - - self.assertThat(len(conn.get_account()), matchers.Is(2)) - - def test_nonexisting_container(self): - """ - when a container does not exist and is accessed then a 404 is returned - """ - - with SwiftClientStub() as swift_stub: - swift_stub.with_account('123223') - swift_stub.with_container('existing') - - conn = swiftclient.client.Connection() - - with ExpectedException(swiftclient.ClientException): - conn.get_container('nonexisting') - - def test_replace_object(self): - """ - Test to ensure that if an object is updated the container object - count is the same and the contents of the object are updated - """ - with SwiftClientStub() as swift_stub: - swift_stub.with_account('1223df2') - swift_stub.with_container('new-container') - swift_stub.with_object('new-container', 'new-object', - 'new-object-contents') - - conn = swiftclient.client.Connection() - - conn.put_object('new-container', 'new-object', - 'new-object-contents') - obj_resp = conn.get_object('new-container', 'new-object') - self.assertThat(obj_resp, matchers.Not(matchers.Is(None))) - self.assertThat(len(obj_resp), matchers.Is(2)) - self.assertThat(obj_resp[1], matchers.Is('new-object-contents')) - - # set expected behavior - trivial here since it is the intended - # behavior however keep in mind this is just to support testing of - # trove components - swift_stub.with_object('new-container', 'new-object', - 'updated-object-contents') - - conn.put_object('new-container', 'new-object', - 'updated-object-contents') - obj_resp = conn.get_object('new-container', 'new-object') - self.assertThat(obj_resp, matchers.Not(matchers.Is(None))) - self.assertThat(len(obj_resp), matchers.Is(2)) - self.assertThat(obj_resp[1], matchers.Is( - 'updated-object-contents')) - # ensure object count has not increased - self.assertThat(len(conn.get_container('new-container')[1]), - matchers.Is(1)) - - -class TestCreateCinderClient(trove_testtools.TestCase): - def setUp(self): - super(TestCreateCinderClient, self).setUp() - self.volumev2_public_url = 'http://publicURL/v2' - self.volume_public_url_region_two = 'http://publicURL-r2/v1' - self.service_catalog = [ - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': self.volumev2_public_url, - } - ], - 'type': 'volumev2' - }, - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': 'http://publicURL-r1/v1', - }, - { - 'region': 'RegionTwo', - 'publicURL': self.volume_public_url_region_two, - } - ], - 'type': 'volume' - } - ] - - def tearDown(self): - super(TestCreateCinderClient, self).tearDown() - cfg.CONF.clear_override('cinder_url') - cfg.CONF.clear_override('cinder_service_type') - cfg.CONF.clear_override('os_region_name') - - def test_create_with_no_conf_no_catalog(self): - self.assertRaises(exception.EmptyCatalog, - remote.create_cinder_client, - TroveContext()) - - def test_create_with_conf_override(self): - cinder_url_from_conf = 'http://example.com' - tenant_from_ctx = uuid.uuid4().hex - cfg.CONF.set_override('cinder_url', cinder_url_from_conf) - - client = remote.create_cinder_client( - TroveContext(tenant=tenant_from_ctx)) - self.assertEqual('%s/%s' % (cinder_url_from_conf, tenant_from_ctx), - client.client.management_url) - - def test_create_with_conf_override_trailing_slash(self): - cinder_url_from_conf = 'http://example.com/' - tenant_from_ctx = uuid.uuid4().hex - cfg.CONF.set_override('cinder_url', cinder_url_from_conf) - client = remote.create_cinder_client( - TroveContext(tenant=tenant_from_ctx)) - self.assertEqual('%s%s' % (cinder_url_from_conf, tenant_from_ctx), - client.client.management_url) - - def test_create_with_catalog_and_default_service_type(self): - client = remote.create_cinder_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.volumev2_public_url, - client.client.management_url) - - def test_create_with_catalog_all_opts(self): - cfg.CONF.set_override('cinder_service_type', 'volume') - cfg.CONF.set_override('os_region_name', 'RegionTwo') - client = remote.create_cinder_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.volume_public_url_region_two, - client.client.management_url) - - -class TestCreateNovaClient(trove_testtools.TestCase): - def setUp(self): - super(TestCreateNovaClient, self).setUp() - self.compute_public_url = 'http://publicURL/v2' - self.computev3_public_url_region_two = 'http://publicURL-r2/v3' - self.service_catalog = [ - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': self.compute_public_url, - } - ], - 'type': 'compute' - }, - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': 'http://publicURL-r1/v1', - }, - { - 'region': 'RegionTwo', - 'publicURL': self.computev3_public_url_region_two, - } - ], - 'type': 'computev3' - } - ] - - def tearDown(self): - super(TestCreateNovaClient, self).tearDown() - cfg.CONF.clear_override('nova_compute_url') - cfg.CONF.clear_override('nova_compute_service_type') - cfg.CONF.clear_override('os_region_name') - cfg.CONF.clear_override('nova_proxy_admin_pass') - - def test_create_with_no_conf_no_catalog(self): - self.assertRaises(exception.EmptyCatalog, - remote.create_nova_client, - TroveContext()) - - def test_create_with_conf_override(self): - nova_url_from_conf = 'http://example.com' - tenant_from_ctx = uuid.uuid4().hex - cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) - - client = remote.create_nova_client( - TroveContext(tenant=tenant_from_ctx)) - self.assertEqual('%s/%s' % (nova_url_from_conf, tenant_from_ctx), - client.client.endpoint_override) - - def test_create_with_conf_override_trailing_slash(self): - nova_url_from_conf = 'http://example.com/' - tenant_from_ctx = uuid.uuid4().hex - cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) - client = remote.create_nova_client( - TroveContext(tenant=tenant_from_ctx)) - self.assertEqual('%s%s' % (nova_url_from_conf, tenant_from_ctx), - client.client.endpoint_override) - - def test_create_with_catalog_and_default_service_type(self): - client = remote.create_nova_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.compute_public_url, - client.client.endpoint_override) - - def test_create_with_catalog_all_opts(self): - cfg.CONF.set_override('nova_compute_service_type', 'computev3') - cfg.CONF.set_override('os_region_name', 'RegionTwo') - client = remote.create_nova_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.computev3_public_url_region_two, - client.client.endpoint_override) - - def test_create_admin_client(self): - nova_url_from_conf = 'http://adminexample.com/' - cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) - admin_user = 'admin1' - admin_pass = 'adminpwd' - admin_tenant_id = uuid.uuid4().hex - admin_client = remote.create_admin_nova_client( - TroveContext(user=admin_user, - auth_token=admin_pass, - tenant=admin_tenant_id)) - # self.assertEqual(admin_user, admin_client.client.user) - # self.assertEqual(admin_pass, admin_client.client.password) - self.assertEqual('%s%s' % (nova_url_from_conf, admin_tenant_id), - admin_client.client.endpoint_override) - - @patch('trove.common.remote.Client', autospec=True) - def test_nova_client_password_passthrough(self, nova_mock): - test_domain = 'test_domain_name' - ctx = TroveContext(user='admin1', - project_id='project_id', - user_domain_name=test_domain, - service_catalog=self.service_catalog) - remote.nova_client(ctx, password='adminpass') - nova_mock.assert_called_with(ANY, username='admin1', - password='adminpass', - user_domain_name=test_domain, - project_id='project_id', - auth_token=None, - auth_url=ANY, - endpoint_override=ANY, - project_domain_name=ANY, - insecure=False) - - @patch('trove.common.remote.create_nova_client', autospec=True) - def test_admin_client_password(self, nc_mock): - cfg.CONF.set_override('nova_proxy_admin_pass', 's3cr3t3') - remote.create_admin_nova_client('mycontext') - nc_mock.assert_called_with('mycontext', password='s3cr3t3') - - -class TestCreateSwiftClient(trove_testtools.TestCase): - def setUp(self): - super(TestCreateSwiftClient, self).setUp() - self.swift_public_url = 'http://publicURL/v2' - self.swiftv3_public_url_region_two = 'http://publicURL-r2/v3' - self.service_catalog = [ - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': self.swift_public_url, - } - ], - 'type': 'object-store' - }, - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': 'http://publicURL-r1/v1', - }, - { - 'region': 'RegionTwo', - 'publicURL': self.swiftv3_public_url_region_two, - } - ], - 'type': 'object-storev3' - } - ] - - def tearDown(self): - super(TestCreateSwiftClient, self).tearDown() - cfg.CONF.clear_override('swift_url') - cfg.CONF.clear_override('swift_service_type') - cfg.CONF.clear_override('os_region_name') - - def test_create_with_no_conf_no_catalog(self): - self.assertRaises(exception.EmptyCatalog, - remote.create_swift_client, - TroveContext()) - - def test_create_with_conf_override(self): - swift_url_from_conf = 'http://example.com/AUTH_' - tenant_from_ctx = uuid.uuid4().hex - cfg.CONF.set_override('swift_url', swift_url_from_conf) - - client = remote.create_swift_client( - TroveContext(tenant=tenant_from_ctx)) - self.assertEqual('%s%s' % (swift_url_from_conf, tenant_from_ctx), - client.url) - - def test_create_with_catalog_and_default_service_type(self): - client = remote.create_swift_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.swift_public_url, - client.url) - - def test_create_with_catalog_all_opts(self): - cfg.CONF.set_override('swift_service_type', 'object-storev3') - cfg.CONF.set_override('os_region_name', 'RegionTwo') - client = remote.create_swift_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertEqual(self.swiftv3_public_url_region_two, - client.url) - - -class TestCreateGlanceClient(trove_testtools.TestCase): - def setUp(self): - super(TestCreateGlanceClient, self).setUp() - self.glance_public_url = 'http://publicURL/v2' - self.glancev3_public_url_region_two = 'http://publicURL-r2/v3' - self.service_catalog = [ - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': self.glance_public_url, - } - ], - 'type': 'image' - }, - { - 'endpoints': [ - { - 'region': 'RegionOne', - 'publicURL': 'http://publicURL-r1/v1', - }, - { - 'region': 'RegionTwo', - 'publicURL': self.glancev3_public_url_region_two, - } - ], - 'type': 'imagev3' - } - ] - - def test_create_with_no_conf_no_catalog(self): - self.assertRaises(exception.EmptyCatalog, - glance_remote.create_glance_client, - TroveContext()) - - def test_create(self): - client = glance_remote.create_glance_client( - TroveContext(service_catalog=self.service_catalog)) - self.assertIsNotNone(client) - - -class TestEndpoints(trove_testtools.TestCase): - """ - Copied from glance/tests/unit/test_auth.py. - """ - def setUp(self): - super(TestEndpoints, self).setUp() - - self.service_catalog = [ - { - 'endpoint_links': [], - 'endpoints': [ - { - 'adminURL': 'http://localhost:8080/', - 'region': 'RegionOne', - 'internalURL': 'http://internalURL/', - 'publicURL': 'http://publicURL/', - }, - { - 'adminURL': 'http://localhost:8081/', - 'region': 'RegionTwo', - 'internalURL': 'http://internalURL2/', - 'publicURL': 'http://publicURL2/', - }, - ], - 'type': 'object-store', - 'name': 'Object Storage Service', - } - ] - - def test_get_endpoint_empty_catalog(self): - self.assertRaises(exception.EmptyCatalog, - remote.get_endpoint, - None) - - def test_get_endpoint_with_custom_server_type(self): - endpoint = remote.get_endpoint(self.service_catalog, - service_type='object-store', - endpoint_region='RegionOne') - self.assertEqual('http://publicURL/', endpoint) - - def test_get_endpoint_with_custom_endpoint_type(self): - endpoint = remote.get_endpoint(self.service_catalog, - service_type='object-store', - endpoint_type='internalURL', - endpoint_region='RegionOne') - self.assertEqual('http://internalURL/', endpoint) - - def test_get_endpoint_raises_with_invalid_service_type(self): - self.assertRaises(exception.NoServiceEndpoint, - remote.get_endpoint, - self.service_catalog, - service_type='foo') - - def test_get_endpoint_raises_with_invalid_endpoint_type(self): - self.assertRaises(exception.NoServiceEndpoint, - remote.get_endpoint, - self.service_catalog, - service_type='object-store', - endpoint_type='foo', - endpoint_region='RegionOne') - - def test_get_endpoint_raises_with_invalid_endpoint_region(self): - self.assertRaises(exception.NoServiceEndpoint, - remote.get_endpoint, - self.service_catalog, - service_type='object-store', - endpoint_region='foo', - endpoint_type='internalURL') - - def test_get_endpoint_ignores_missing_type(self): - service_catalog = [ - { - 'name': 'Other Service', - }, - { - 'endpoint_links': [], - 'endpoints': [ - { - 'adminURL': 'http://localhost:8080/', - 'region': 'RegionOne', - 'internalURL': 'http://internalURL/', - 'publicURL': 'http://publicURL/', - }, - { - 'adminURL': 'http://localhost:8081/', - 'region': 'RegionTwo', - 'internalURL': 'http://internalURL2/', - 'publicURL': 'http://publicURL2/', - }, - ], - 'type': 'object-store', - 'name': 'Object Storage Service', - } - ] - endpoint = remote.get_endpoint(service_catalog, - service_type='object-store', - endpoint_region='RegionOne') - self.assertEqual('http://publicURL/', endpoint) diff --git a/trove/tests/unittests/datastore/test_datastore_version_metadata.py b/trove/tests/unittests/datastore/test_datastore_version_metadata.py index 5d028cc7e9..973341b4cd 100644 --- a/trove/tests/unittests/datastore/test_datastore_version_metadata.py +++ b/trove/tests/unittests/datastore/test_datastore_version_metadata.py @@ -14,8 +14,8 @@ import mock +from trove.common import clients from trove.common import exception -from trove.common import remote from trove.datastore import models as datastore_models from trove.tests.unittests.datastore.base import TestDatastoreBase @@ -150,7 +150,7 @@ class TestDatastoreVersionMetadata(TestDatastoreBase): '_datastore_version_find') @mock.patch.object(datastore_models.DatastoreVersionMetadata, 'list_datastore_version_volume_type_associations') - @mock.patch.object(remote, 'create_cinder_client') + @mock.patch.object(clients, 'create_cinder_client') def _mocked_allowed_datastore_version_volume_types(self, trove_volume_types, mock_cinder_client, diff --git a/trove/tests/unittests/guestagent/test_api.py b/trove/tests/unittests/guestagent/test_api.py index 71efb963f8..b03a186c1e 100644 --- a/trove/tests/unittests/guestagent/test_api.py +++ b/trove/tests/unittests/guestagent/test_api.py @@ -17,9 +17,9 @@ import oslo_messaging as messaging from oslo_messaging.rpc.client import RemoteError from testtools.matchers import Is +from trove.common.clients import guest_client import trove.common.context as context from trove.common import exception -from trove.common.remote import guest_client from trove.guestagent import api from trove import rpc from trove.tests.unittests import trove_testtools diff --git a/trove/tests/unittests/instance/test_instance_models.py b/trove/tests/unittests/instance/test_instance_models.py index 39f9ad530c..714e72dafa 100644 --- a/trove/tests/unittests/instance/test_instance_models.py +++ b/trove/tests/unittests/instance/test_instance_models.py @@ -113,7 +113,7 @@ class SimpleInstanceTest(trove_testtools.TestCase): self.assertIn('123.123.123.123', ip) self.assertIn('15.123.123.123', ip) - @patch('trove.common.remote.create_neutron_client') + @patch('trove.common.clients.create_neutron_client') def test_filter_management_ip_addresses(self, mock_neutron_client): CONF.network_label_regex = '' CONF.management_networks = ['fake-net-id'] diff --git a/trove/tests/unittests/mgmt/test_datastore_controller.py b/trove/tests/unittests/mgmt/test_datastore_controller.py index 2cf5caf258..35e88178bf 100644 --- a/trove/tests/unittests/mgmt/test_datastore_controller.py +++ b/trove/tests/unittests/mgmt/test_datastore_controller.py @@ -17,8 +17,8 @@ import jsonschema from mock import Mock, patch, MagicMock, PropertyMock from testtools.matchers import Is, Equals +from trove.common import clients from trove.common import exception -from trove.common import glance_remote from trove.datastore import models as datastore_models from trove.extensions.mgmt.datastores.service import DatastoreVersionController from trove.tests.unittests import trove_testtools @@ -81,7 +81,7 @@ class TestDatastoreVersionController(trove_testtools.TestCase): self.assertIn("'' is too short", error_messages) self.assertIn("'' does not match '^.*[0-9a-zA-Z]+.*$'", error_messages) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') @patch.object(datastore_models.Datastore, 'load') @patch.object(datastore_models.DatastoreVersion, 'load', side_effect=exception.DatastoreVersionNotFound) @@ -127,7 +127,7 @@ class TestDatastoreVersionController(trove_testtools.TestCase): mock_ds_version_load_all.assert_called_with(only_active=False) mock_ds_version_load_by_uuid.assert_called_with(mock_id) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid') @patch.object(datastore_models, 'update_datastore_version') def test_edit_datastore_versions(self, mock_ds_version_update, diff --git a/trove/tests/unittests/mgmt/test_datastores.py b/trove/tests/unittests/mgmt/test_datastores.py index d1721f398a..2d1405a6ad 100644 --- a/trove/tests/unittests/mgmt/test_datastores.py +++ b/trove/tests/unittests/mgmt/test_datastores.py @@ -15,8 +15,8 @@ from mock import Mock, patch from glanceclient import exc as glance_exceptions +from trove.common import clients from trove.common import exception -from trove.common import glance_remote from trove.datastore import models from trove.extensions.mgmt.datastores.service import DatastoreVersionController from trove.tests.unittests import trove_testtools @@ -48,7 +48,7 @@ class TestDatastoreVersion(trove_testtools.TestCase): def tearDown(self): super(TestDatastoreVersion, self).tearDown() - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') def test_version_create(self, mock_glance_client): body = {"version": { "datastore_name": "test_ds", @@ -62,7 +62,7 @@ class TestDatastoreVersion(trove_testtools.TestCase): self.req, body, self.tenant_id) self.assertEqual(202, output.status) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') @patch.object(models.DatastoreVersion, 'load') def test_fail_already_exists_version_create(self, mock_load, mock_glance_client): @@ -79,7 +79,7 @@ class TestDatastoreVersion(trove_testtools.TestCase): "A datastore version with the name 'test_new_vr' already exists", self.version_controller.create, self.req, body, self.tenant_id) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') def test_fail_image_not_found_version_create(self, mock_glance_client): mock_glance_client.return_value.images.get = Mock( side_effect=glance_exceptions.HTTPNotFound()) @@ -112,7 +112,7 @@ class TestDatastoreVersion(trove_testtools.TestCase): exception.DatastoreVersionNotFound, err_msg, models.DatastoreVersion.load_by_uuid, ds_version1.id) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') def test_version_update(self, mock_client): body = {"image": "c022f4dc-76ed-4e3f-a25e-33e031f43f8b"} output = self.version_controller.edit(self.req, body, @@ -125,7 +125,7 @@ class TestDatastoreVersion(trove_testtools.TestCase): self.ds_version2.id) self.assertEqual(body['image'], test_ds_version.image_id) - @patch.object(glance_remote, 'create_glance_client') + @patch.object(clients, 'create_glance_client') def test_version_update_fail_image_not_found(self, mock_glance_client): mock_glance_client.return_value.images.get = Mock( side_effect=glance_exceptions.HTTPNotFound()) diff --git a/trove/tests/unittests/mgmt/test_models.py b/trove/tests/unittests/mgmt/test_models.py index 0d14ebf269..66d698e6ea 100644 --- a/trove/tests/unittests/mgmt/test_models.py +++ b/trove/tests/unittests/mgmt/test_models.py @@ -23,9 +23,9 @@ from oslo_config import cfg from testtools.matchers import Equals, Is, Not from trove.backup.models import Backup +from trove.common import clients from trove.common import exception from trove.common import instance as rd_instance -from trove.common import remote from trove.datastore import models as datastore_models import trove.extensions.mgmt.instances.models as mgmtmodels from trove.guestagent.api import API @@ -76,7 +76,7 @@ class MockMgmtInstanceTest(trove_testtools.TestCase): self.flavor_mgr = MagicMock(spec=FlavorManager) self.client.flavors = self.flavor_mgr self.admin_client_patch = patch.object( - remote, 'create_admin_nova_client', return_value=self.client) + clients, 'create_admin_nova_client', return_value=self.client) self.addCleanup(self.admin_client_patch.stop) self.admin_client_patch.start() CONF.set_override('host', '127.0.0.1') diff --git a/trove/tests/unittests/taskmanager/test_models.py b/trove/tests/unittests/taskmanager/test_models.py index f75218d053..f2cb7e7238 100644 --- a/trove/tests/unittests/taskmanager/test_models.py +++ b/trove/tests/unittests/taskmanager/test_models.py @@ -36,7 +36,6 @@ from trove.common.exception import PollTimeOut from trove.common.exception import TroveError from trove.common.instance import ServiceStatuses from trove.common.notification import TroveInstanceModifyVolume -from trove.common import remote import trove.common.template as template from trove.common import timeutils from trove.common import utils @@ -396,7 +395,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest): @patch.object(taskmanager_models.FreshInstanceTasks, '_build_volume_info') @patch.object(taskmanager_models.FreshInstanceTasks, '_guest_prepare') @patch.object(template, 'SingleInstanceConfigTemplate') - @patch('trove.common.remote.neutron_client') + @patch('trove.common.clients.neutron_client') def test_create_instance_with_mgmt_port(self, mock_neutron_client, mock_single_instance_template, @@ -1050,10 +1049,6 @@ class BackupTasksTest(trove_testtools.TestCase): self.backup.updated = 'today' self.backup.size = 2.0 self.backup.state = state.BackupState.NEW - self.container_content = (None, - [{'name': 'first'}, - {'name': 'second'}, - {'name': 'third'}]) self.bm_backup_patches = patch.multiple( backup_models.Backup, delete=MagicMock(return_value=None), @@ -1066,21 +1061,6 @@ class BackupTasksTest(trove_testtools.TestCase): self.bm_DBBackup_mock = self.bm_DBBackup_patch.start() self.addCleanup(self.bm_DBBackup_patch.stop) self.backup.delete = MagicMock(return_value=None) - self.swift_client = MagicMock() - self.create_swift_client_patch = patch.object( - remote, 'create_swift_client', - MagicMock(return_value=self.swift_client)) - self.create_swift_client_mock = self.create_swift_client_patch.start() - self.addCleanup(self.create_swift_client_patch.stop) - - self.swift_client.head_container = MagicMock( - side_effect=ClientException("foo")) - self.swift_client.head_object = MagicMock( - side_effect=ClientException("foo")) - self.swift_client.get_container = MagicMock( - return_value=self.container_content) - self.swift_client.delete_object = MagicMock(return_value=None) - self.swift_client.delete_container = MagicMock(return_value=None) def tearDown(self): super(BackupTasksTest, self).tearDown() @@ -1092,34 +1072,25 @@ class BackupTasksTest(trove_testtools.TestCase): self.backup.delete.assert_any_call() @patch('trove.taskmanager.models.LOG') - def test_delete_backup_fail_delete_manifest(self, mock_logging): - with patch.object(self.swift_client, 'delete_object', - side_effect=ClientException("foo")): - with patch.object(self.swift_client, 'head_object', - return_value={}): - self.assertRaises( - TroveError, - taskmanager_models.BackupTasks.delete_backup, - 'dummy context', self.backup.id) - self.assertFalse(backup_models.Backup.delete.called) - self.assertEqual( - state.BackupState.DELETE_FAILED, - self.backup.state, - "backup should be in DELETE_FAILED status") + @patch('trove.common.clients.create_swift_client') + def test_delete_backup_fail_delete_manifest(self, mock_swift_client, + mock_logging): + client_mock = MagicMock() + client_mock.head_object.return_value = {} + client_mock.delete_object.side_effect = ClientException("foo") + mock_swift_client.return_value = client_mock - @patch('trove.taskmanager.models.LOG') - def test_delete_backup_fail_delete_segment(self, mock_logging): - with patch.object(self.swift_client, 'delete_object', - side_effect=ClientException("foo")): - self.assertRaises( - TroveError, - taskmanager_models.BackupTasks.delete_backup, - 'dummy context', self.backup.id) - self.assertFalse(backup_models.Backup.delete.called) - self.assertEqual( - state.BackupState.DELETE_FAILED, - self.backup.state, - "backup should be in DELETE_FAILED status") + self.assertRaises( + TroveError, + taskmanager_models.BackupTasks.delete_backup, + 'dummy context', self.backup.id + ) + self.assertFalse(backup_models.Backup.delete.called) + self.assertEqual( + state.BackupState.DELETE_FAILED, + self.backup.state, + "backup should be in DELETE_FAILED status" + ) def test_parse_manifest(self): manifest = 'container/prefix' diff --git a/trove/tests/unittests/volume_type/test_volume_type.py b/trove/tests/unittests/volume_type/test_volume_type.py index 47db2fd60c..1e72d1bf8c 100644 --- a/trove/tests/unittests/volume_type/test_volume_type.py +++ b/trove/tests/unittests/volume_type/test_volume_type.py @@ -16,7 +16,7 @@ import mock -from trove.common import remote +from trove.common import clients from trove.tests.unittests import trove_testtools from trove.volume_type import models @@ -38,7 +38,7 @@ class TestVolumeType(trove_testtools.TestCase): self.assertEqual(cinder_volume_type.description, volume_type.description) - @mock.patch.object(remote, 'create_cinder_client') + @mock.patch.object(clients, 'create_cinder_client') def test_volume_types(self, mock_client): mock_context = mock.MagicMock() mock_types = [mock.MagicMock(), mock.MagicMock()] diff --git a/trove/volume_type/models.py b/trove/volume_type/models.py index 2b8184244c..5080f73386 100644 --- a/trove/volume_type/models.py +++ b/trove/volume_type/models.py @@ -17,9 +17,9 @@ """Model classes that form the core of volume-support functionality""" from cinderclient import exceptions as cinder_exception +from trove.common import clients from trove.common import exception as trove_exception from trove.common import models -from trove.common import remote class VolumeType(object): @@ -36,7 +36,7 @@ class VolumeType(object): raise trove_exception.InvalidModelError( "client or context must be provided to load a volume_type") if not client: - client = remote.create_cinder_client(context) + client = clients.create_cinder_client(context) try: volume_type = client.volume_types.get(volume_type_id) except cinder_exception.NotFound: @@ -65,7 +65,8 @@ class VolumeType(object): class VolumeTypes(models.CinderRemoteModelBase): def __init__(self, context): - volume_types = remote.create_cinder_client(context).volume_types.list() + volume_types = clients.create_cinder_client( + context).volume_types.list() self.volume_types = [VolumeType(volume_type=item) for item in volume_types]