diff --git a/README.md b/README.md index 162f68d..a69f5bc 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,15 @@ dashboard or through the helper command: ```bash $ coldfront add_openstack_resource -usage: coldfront add_openstack_resource [-h] --name NAME --auth-url AUTH_URL [--users-domain USERS_DOMAIN] [--projects-domain PROJECTS_DOMAIN] --idp IDP - [--protocol PROTOCOL] [--role ROLE] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] - [--no-color] [--force-color] +usage: coldfront add_openstack_resource [-h] --name NAME --auth-url AUTH_URL [--users-domain USERS_DOMAIN] [--projects-domain PROJECTS_DOMAIN] --idp IDP [--protocol PROTOCOL] [--role ROLE] + [--public-network PUBLIC_NETWORK] [--network-cidr NETWORK_CIDR] [--esi] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] + [--no-color] [--force-color] [--skip-checks] coldfront add_openstack_resource: error: the following arguments are required: --name, --auth-url, --idp ``` +An Openstack resource can be specified as an ESI resource by setting the `--esi` command flag. +ESI resource allocations will only have quotas for network resources by default. + ### Configuring for OpenShift Note: OpenShift support requires deploying the [openshift-acct-mgt][] diff --git a/ci/run_functional_tests_openstack.sh b/ci/run_functional_tests_openstack.sh index 5c6b8a6..dbfaabd 100755 --- a/ci/run_functional_tests_openstack.sh +++ b/ci/run_functional_tests_openstack.sh @@ -13,6 +13,9 @@ export OPENSTACK_DEVSTACK_APPLICATION_CREDENTIAL_SECRET=$( export OPENSTACK_DEVSTACK_APPLICATION_CREDENTIAL_ID=$( openstack application credential show "$credential_name" -f value -c id) +export OPENSTACK_ESI_APPLICATION_CREDENTIAL_SECRET=$OPENSTACK_DEVSTACK_APPLICATION_CREDENTIAL_SECRET +export OPENSTACK_ESI_APPLICATION_CREDENTIAL_ID=$OPENSTACK_DEVSTACK_APPLICATION_CREDENTIAL_ID + export OPENSTACK_PUBLIC_NETWORK_ID=$(openstack network show public -f value -c id) if [[ ! "${CI}" == "true" ]]; then @@ -28,6 +31,7 @@ export KEYCLOAK_PASS="nomoresecret" export KEYCLOAK_REALM="master" coverage run --source="." -m django test coldfront_plugin_cloud.tests.functional.openstack +coverage run --source="." -m django test coldfront_plugin_cloud.tests.functional.esi coverage report openstack application credential delete $OPENSTACK_DEVSTACK_APPLICATION_CREDENTIAL_ID diff --git a/src/coldfront_plugin_cloud/attributes.py b/src/coldfront_plugin_cloud/attributes.py index 9f1b827..d10d261 100644 --- a/src/coldfront_plugin_cloud/attributes.py +++ b/src/coldfront_plugin_cloud/attributes.py @@ -75,6 +75,7 @@ class CloudAllocationAttribute: QUOTA_VOLUMES_GB = 'OpenStack Volume Quota (GiB)' QUOTA_FLOATING_IPS = 'OpenStack Floating IP Quota' +QUOTA_NETWORKS = 'Openstack Network Quota' QUOTA_OBJECT_GB = 'OpenStack Swift Quota (GiB)' @@ -96,6 +97,7 @@ class CloudAllocationAttribute: CloudAllocationAttribute(name=QUOTA_VCPU), CloudAllocationAttribute(name=QUOTA_VOLUMES), CloudAllocationAttribute(name=QUOTA_VOLUMES_GB), + CloudAllocationAttribute(name=QUOTA_NETWORKS), CloudAllocationAttribute(name=QUOTA_FLOATING_IPS), CloudAllocationAttribute(name=QUOTA_OBJECT_GB), CloudAllocationAttribute(name=QUOTA_GPU), diff --git a/src/coldfront_plugin_cloud/esi.py b/src/coldfront_plugin_cloud/esi.py new file mode 100644 index 0000000..b14fcf8 --- /dev/null +++ b/src/coldfront_plugin_cloud/esi.py @@ -0,0 +1,29 @@ +import logging +import functools +import os + +from keystoneauth1.identity import v3 +from keystoneauth1 import session + +from coldfront_plugin_cloud import attributes, utils +from coldfront_plugin_cloud.openstack import OpenStackResourceAllocator + +class ESIResourceAllocator(OpenStackResourceAllocator): + + QUOTA_KEY_MAPPING = { + 'network': { + 'keys': { + attributes.QUOTA_FLOATING_IPS: 'floatingip', + attributes.QUOTA_NETWORKS: 'network' + } + } + } + + QUOTA_KEY_MAPPING_ALL_KEYS = {quota_key: quota_name for k in QUOTA_KEY_MAPPING.values() for quota_key, quota_name in k['keys'].items()} + + resource_type = 'esi' + + def get_quota(self, project_id): + quotas = dict() + quotas = self._get_network_quota(quotas, project_id) + return quotas diff --git a/src/coldfront_plugin_cloud/management/commands/add_openstack_resource.py b/src/coldfront_plugin_cloud/management/commands/add_openstack_resource.py index 57f2f25..3b9124a 100644 --- a/src/coldfront_plugin_cloud/management/commands/add_openstack_resource.py +++ b/src/coldfront_plugin_cloud/management/commands/add_openstack_resource.py @@ -34,13 +34,23 @@ def add_arguments(self, parser): parser.add_argument('--network-cidr', type=str, default='192.168.0.0/24', help='CIDR for default networks. ' 'Ignored if no --public-network.') + parser.add_argument('--esi', action='store_true', + help='Indicates this is an ESI resource (default: False)') def handle(self, *args, **options): + + if options['esi']: + resource_description = 'ESI Bare Metal environment' + resource_type = 'ESI' + else: + resource_description = 'OpenStack cloud environment' + resource_type = 'OpenStack' + openstack, _ = Resource.objects.get_or_create( - resource_type=ResourceType.objects.get(name='OpenStack'), + resource_type=ResourceType.objects.get(name=resource_type), parent_resource=None, name=options['name'], - description='OpenStack cloud environment', + description=resource_description, is_available=True, is_public=True, is_allocatable=True @@ -82,18 +92,21 @@ def handle(self, *args, **options): resource=openstack, value=options['role'] ) - ResourceAttribute.objects.get_or_create( - resource_attribute_type=ResourceAttributeType.objects.get( - name='quantity_label'), - resource=openstack, - value='Units of computing to allocate to the project. 1 Unit = 1 Instance, 2 vCPU, 0 GPU, 4G RAM, 2 Volumes, 100 GB Volume Storage, and 1 GB Object Storage' - ) - ResourceAttribute.objects.get_or_create( - resource_attribute_type=ResourceAttributeType.objects.get( - name='quantity_default_value'), - resource=openstack, - value=1 - ) + + # Quantity values do not make sense for an ESI allocation + if not options['esi']: + ResourceAttribute.objects.get_or_create( + resource_attribute_type=ResourceAttributeType.objects.get( + name='quantity_label'), + resource=openstack, + value='Units of computing to allocate to the project. 1 Unit = 1 Instance, 2 vCPU, 0 GPU, 4G RAM, 2 Volumes, 100 GB Volume Storage, and 1 GB Object Storage' + ) + ResourceAttribute.objects.get_or_create( + resource_attribute_type=ResourceAttributeType.objects.get( + name='quantity_default_value'), + resource=openstack, + value=1 + ) if options['public_network']: ResourceAttribute.objects.get_or_create( diff --git a/src/coldfront_plugin_cloud/management/commands/register_cloud_attributes.py b/src/coldfront_plugin_cloud/management/commands/register_cloud_attributes.py index 1cf5243..1c50c04 100644 --- a/src/coldfront_plugin_cloud/management/commands/register_cloud_attributes.py +++ b/src/coldfront_plugin_cloud/management/commands/register_cloud_attributes.py @@ -126,6 +126,9 @@ def register_resource_type(self): resource_models.ResourceType.objects.get_or_create( name='OpenShift', description='OpenShift Cloud' ) + resource_models.ResourceType.objects.get_or_create( + name='ESI', description='ESI Bare Metal Cloud' + ) def handle(self, *args, **options): self.register_resource_type() diff --git a/src/coldfront_plugin_cloud/management/commands/validate_allocations.py b/src/coldfront_plugin_cloud/management/commands/validate_allocations.py index ff838d0..ca9d537 100644 --- a/src/coldfront_plugin_cloud/management/commands/validate_allocations.py +++ b/src/coldfront_plugin_cloud/management/commands/validate_allocations.py @@ -4,6 +4,7 @@ from coldfront_plugin_cloud import attributes from coldfront_plugin_cloud import openstack from coldfront_plugin_cloud import openshift +from coldfront_plugin_cloud import esi from coldfront_plugin_cloud import utils from coldfront_plugin_cloud import tasks @@ -66,11 +67,9 @@ def check_institution_specific_code(self, allocation, apply): def handle(self, *args, **options): - # Openstack Resources first + # Deal with Openstack and ESI resources openstack_resources = Resource.objects.filter( - resource_type=ResourceType.objects.get( - name='OpenStack' - ) + resource_type__name__in=['OpenStack', 'ESI'] ) openstack_allocations = Allocation.objects.filter( resources__in=openstack_resources, @@ -84,10 +83,7 @@ def handle(self, *args, **options): failed_validation = False - allocator = openstack.OpenStackResourceAllocator( - allocation.resources.first(), - allocation - ) + allocator = tasks.find_allocator(allocation) project_id = allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID) if not project_id: @@ -105,11 +101,11 @@ def handle(self, *args, **options): failed_validation = Command.sync_users(project_id, allocation, allocator, options["apply"]) - obj_key = openstack.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] + obj_key = openstack.OpenStackResourceAllocator.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] for attr in attributes.ALLOCATION_QUOTA_ATTRIBUTES: if 'OpenStack' in attr.name: - key = openstack.QUOTA_KEY_MAPPING_ALL_KEYS.get(attr.name, None) + key = allocator.QUOTA_KEY_MAPPING_ALL_KEYS.get(attr.name, None) if not key: # Note(knikolla): Some attributes are only maintained # for bookkeeping purposes and do not have a @@ -147,7 +143,7 @@ def handle(self, *args, **options): allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID) ) except Exception as e: - logger.error(f'setting openstack quota failed: {e}') + logger.error(f'setting {allocation.resources.first()} quota failed: {e}') continue logger.warning(f'Quota for allocation {allocation_str} was out of date. Reapplied!') diff --git a/src/coldfront_plugin_cloud/openstack.py b/src/coldfront_plugin_cloud/openstack.py index 0211ce4..79ff890 100644 --- a/src/coldfront_plugin_cloud/openstack.py +++ b/src/coldfront_plugin_cloud/openstack.py @@ -21,40 +21,8 @@ # 1 GB = 1 000 000 000 B = 10^9 B GB_IN_BYTES = 2 ** 30 -# Map the attribute name in ColdFront, to the client of the respective -# service, the version of the API, and the key in the payload. -QUOTA_KEY_MAPPING = { - 'compute': { - 'keys': { - attributes.QUOTA_INSTANCES: 'instances', - attributes.QUOTA_VCPU: 'cores', - attributes.QUOTA_RAM: 'ram', - }, - }, - 'network': { - 'keys': { - attributes.QUOTA_FLOATING_IPS: 'floatingip', - } - }, - 'object': { - 'keys': { - attributes.QUOTA_OBJECT_GB: 'x-account-meta-quota-bytes', - } - }, - 'volume': { - 'keys': { - attributes.QUOTA_VOLUMES: 'volumes', - attributes.QUOTA_VOLUMES_GB: 'gigabytes', - } - }, -} - COLDFRONT_RGW_SWIFT_INIT_USER = 'coldfront-swift-init' -QUOTA_KEY_MAPPING_ALL_KEYS = dict() -for service in QUOTA_KEY_MAPPING.keys(): - QUOTA_KEY_MAPPING_ALL_KEYS.update(QUOTA_KEY_MAPPING[service]['keys']) - def get_session_for_resource_via_password(resource, username, password, project_id): auth_url = resource.get_attribute(attributes.RESOURCE_AUTH_URL) user_domain = resource.get_attribute(attributes.RESOURCE_USER_DOMAIN) @@ -94,6 +62,35 @@ def get_session_for_resource(resource): class OpenStackResourceAllocator(base.ResourceAllocator): + # Map the attribute name in ColdFront, to the client of the respective + # service, the version of the API, and the key in the payload. + QUOTA_KEY_MAPPING = { + 'compute': { + 'keys': { + attributes.QUOTA_INSTANCES: 'instances', + attributes.QUOTA_VCPU: 'cores', + attributes.QUOTA_RAM: 'ram', + }, + }, + 'network': { + 'keys': { + attributes.QUOTA_FLOATING_IPS: 'floatingip', + } + }, + 'object': { + 'keys': { + attributes.QUOTA_OBJECT_GB: 'x-account-meta-quota-bytes', + } + }, + 'volume': { + 'keys': { + attributes.QUOTA_VOLUMES: 'volumes', + attributes.QUOTA_VOLUMES_GB: 'gigabytes', + } + }, + } + + QUOTA_KEY_MAPPING_ALL_KEYS = {quota_key: quota_name for k in QUOTA_KEY_MAPPING.values() for quota_key, quota_name in k['keys'].items()} resource_type = 'openstack' @@ -161,7 +158,7 @@ def set_quota(self, project_id): # If an attribute with the appropriate name is associated with an # allocation, set that as the quota. Otherwise, multiply # the quantity attribute via the mapping table above. - for service_name, service in QUOTA_KEY_MAPPING.items(): + for service_name, service in self.QUOTA_KEY_MAPPING.items(): # No need to do any calculations here, just go through each service # and set the value in the attribute. payload = dict() @@ -188,7 +185,7 @@ def _set_object_quota(self, project_id, payload): # Note(knikolla): For consistency with other OpenStack # quotas we're storing this as GB on the attribute and # converting to bytes for Swift. - obj_q_mapping = QUOTA_KEY_MAPPING['object']['keys'][ + obj_q_mapping = self.QUOTA_KEY_MAPPING['object']['keys'][ attributes.QUOTA_OBJECT_GB ] payload[obj_q_mapping] *= GB_IN_BYTES @@ -235,22 +232,27 @@ def _init_rgw_for_project(self, project_id): logger.debug(f'rgw swift stat for {project_id}:\n{stat}') self.remove_role_from_user(COLDFRONT_RGW_SWIFT_INIT_USER, project_id) + def _get_network_quota(self, quotas, project_id): + network_quota = self.network.show_quota(project_id)['quota'] + for k in self.QUOTA_KEY_MAPPING['network']['keys'].values(): + quotas[k] = network_quota.get(k) + + return quotas + def get_quota(self, project_id): quotas = dict() compute_quota = self.compute.quotas.get(project_id) - for k in QUOTA_KEY_MAPPING['compute']['keys'].values(): + for k in self.QUOTA_KEY_MAPPING['compute']['keys'].values(): quotas[k] = compute_quota.__getattr__(k) volume_quota = self.volume.quotas.get(project_id) - for k in QUOTA_KEY_MAPPING['volume']['keys'].values(): + for k in self.QUOTA_KEY_MAPPING['volume']['keys'].values(): quotas[k] = volume_quota.__getattr__(k) - network_quota = self.network.show_quota(project_id)['quota'] - for k in QUOTA_KEY_MAPPING['network']['keys'].values(): - quotas[k] = network_quota.get(k) + quotas = self._get_network_quota(quotas, project_id) - key = QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] + key = self.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] try: swift = self.object(project_id).head_account() quotas[key] = int(int(swift.get(key)) / GB_IN_BYTES) diff --git a/src/coldfront_plugin_cloud/tasks.py b/src/coldfront_plugin_cloud/tasks.py index 4a3c0eb..32c8f7b 100644 --- a/src/coldfront_plugin_cloud/tasks.py +++ b/src/coldfront_plugin_cloud/tasks.py @@ -10,6 +10,7 @@ base, openstack, openshift, + esi, utils) logger = logging.getLogger(__name__) @@ -35,6 +36,10 @@ attributes.QUOTA_REQUESTS_STORAGE: 20, attributes.QUOTA_REQUESTS_GPU: 0, attributes.QUOTA_PVC: 2 + }, + 'esi': { + attributes.QUOTA_FLOATING_IPS: 0, + attributes.QUOTA_NETWORKS: 0 } } @@ -48,6 +53,10 @@ }, 'openshift': { attributes.QUOTA_REQUESTS_GPU: 0, + }, + 'esi': { + attributes.QUOTA_FLOATING_IPS: 1, + attributes.QUOTA_NETWORKS: 1 } } @@ -56,6 +65,7 @@ def find_allocator(allocation) -> base.ResourceAllocator: allocators = { 'openstack': openstack.OpenStackResourceAllocator, 'openshift': openshift.OpenShiftResourceAllocator, + 'esi': esi.ESIResourceAllocator, } # TODO(knikolla): It doesn't seem to be possible to select multiple resources # when requesting a new allocation, so why is this multivalued? diff --git a/src/coldfront_plugin_cloud/tests/base.py b/src/coldfront_plugin_cloud/tests/base.py index e078a81..f2f2a35 100644 --- a/src/coldfront_plugin_cloud/tests/base.py +++ b/src/coldfront_plugin_cloud/tests/base.py @@ -41,9 +41,28 @@ def new_user(username=None) -> User: username = username or f'{uuid.uuid4().hex}@example.com' User.objects.create(username=username, email=username) return User.objects.get(username=username) + + @staticmethod + def new_esi_resource(name=None, auth_url=None) -> Resource: + resource_name = name or uuid.uuid4().hex + + call_command( + 'add_openstack_resource', + name=resource_name, + auth_url=auth_url or f'https://{resource_name}/identity/v3', + projects_domain='default', + users_domain='default', + idp='sso', + protocol='openid', + role='member', + public_network=os.getenv('OPENSTACK_PUBLIC_NETWORK_ID'), + network_cidr='192.168.0.0/24', + esi=True + ) + return Resource.objects.get(name=resource_name) @staticmethod - def new_resource(name=None, auth_url=None) -> Resource: + def new_openstack_resource(name=None, auth_url=None) -> Resource: resource_name = name or uuid.uuid4().hex call_command( @@ -57,6 +76,7 @@ def new_resource(name=None, auth_url=None) -> Resource: role='member', public_network=os.getenv('OPENSTACK_PUBLIC_NETWORK_ID'), network_cidr='192.168.0.0/24', + esi=False ) return Resource.objects.get(name=resource_name) diff --git a/src/coldfront_plugin_cloud/tests/functional/esi/__init__.py b/src/coldfront_plugin_cloud/tests/functional/esi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/coldfront_plugin_cloud/tests/functional/esi/test_allocations.py b/src/coldfront_plugin_cloud/tests/functional/esi/test_allocations.py new file mode 100644 index 0000000..73910b4 --- /dev/null +++ b/src/coldfront_plugin_cloud/tests/functional/esi/test_allocations.py @@ -0,0 +1,128 @@ +import os +import unittest +import uuid +import time + +from coldfront_plugin_cloud import attributes, openstack, esi, tasks +from coldfront_plugin_cloud.tests import base + +from django.core.management import call_command +from keystoneclient.v3 import client +from cinderclient import client as cinderclient +from neutronclient.v2_0 import client as neutronclient +from novaclient import client as novaclient + +@unittest.skipUnless(os.getenv('FUNCTIONAL_TESTS'), 'Functional tests not enabled.') +class TestAllocation(base.TestBase): + + def setUp(self) -> None: + super().setUp() + self.resource = self.new_esi_resource(name='ESI', + auth_url=os.getenv('OS_AUTH_URL')) + self.session = openstack.get_session_for_resource(self.resource) + self.identity = client.Client(session=self.session) + self.compute = novaclient.Client(session=self.session, version=2) + self.volume = cinderclient.Client(session=self.session, version=3) + self.networking = neutronclient.Client(session=self.session) + self.role_member = self.identity.roles.find(name='member') + + def test_new_ESI_allocation(self): + user = self.new_user() + project = self.new_project(pi=user) + allocation = self.new_allocation(project, self.resource, 1) + allocator = esi.ESIResourceAllocator(self.resource, + allocation) + + tasks.activate_allocation(allocation.pk) + allocation.refresh_from_db() + + # Check project + project_id = allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID) + self.assertIsNotNone(project_id) + self.assertIsNotNone(allocation.get_attribute(attributes.ALLOCATION_PROJECT_NAME)) + + openstack_project = self.identity.projects.get(project_id) + self.assertTrue(openstack_project.enabled) + + # Check user and roles + openstack_user = allocator.get_federated_user(user.username) + openstack_user = self.identity.users.get(openstack_user['id']) + + roles = self.identity.role_assignments.list(user=openstack_user.id, + project=openstack_project.id) + + self.assertEqual(len(roles), 1) + self.assertEqual(roles[0].role['id'], self.role_member.id) + + # Check default network + time.sleep(5) + network = self.networking.list_networks( + project_id=project_id, name='default_network')['networks'][0] + router = self.networking.list_routers( + project_id=project_id, name='default_router')['routers'][0] + ports = self.networking.list_ports(project_id=project_id, + network_id=network['id'], + device_id=router['id'])['ports'] + self.assertIsNotNone(ports) + self.assertEqual(ports[0]['status'], 'ACTIVE') + + # Validate get_quota + expected_quota = { + 'floatingip': 1, + 'network': 1, + } + resulting_quota = allocator.get_quota(openstack_project.id) + self.assertEqual(expected_quota, resulting_quota) + + def test_add_remove_user(self): + user = self.new_user() + project = self.new_project(pi=user) + project_user = self.new_project_user(user, project) + allocation = self.new_allocation(project, self.resource, 1) + allocation_user = self.new_allocation_user(allocation, user) + allocator = esi.ESIResourceAllocator(self.resource, + allocation) + + user2 = self.new_user() + project_user2 = self.new_project_user(user2, project) + allocation_user2 = self.new_allocation_user(allocation, user2) + + tasks.activate_allocation(allocation.pk) + allocation.refresh_from_db() + + project_id = allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID) + openstack_project = self.identity.projects.get(project_id) + + tasks.add_user_to_allocation(allocation_user2.pk) + + openstack_user = allocator.get_federated_user(user2.username) + openstack_user = self.identity.users.get(openstack_user['id']) + + roles = self.identity.role_assignments.list(user=openstack_user.id, + project=openstack_project.id) + + self.assertEqual(len(roles), 1) + self.assertEqual(roles[0].role['id'], self.role_member.id) + assert set([user.username, user2.username]) == allocator.get_users(project_id) + + tasks.remove_user_from_allocation(allocation_user2.pk) + + roles = self.identity.role_assignments.list(user=openstack_user.id, + project=openstack_project.id) + + self.assertEqual(len(roles), 0) + assert set([user.username]) == allocator.get_users(project_id) + + # use the validate_allocations command to add a new user + user3 = self.new_user() + allocation_user3 = self.new_allocation_user(allocation, user3) + assert user3.username not in allocator.get_users(project_id) + call_command('validate_allocations', apply=True) + assert user3.username in allocator.get_users(project_id) + + non_coldfront_user = uuid.uuid4().hex + allocator.get_or_create_federated_user(non_coldfront_user) + allocator.assign_role_on_user(non_coldfront_user, project_id) + assert non_coldfront_user in allocator.get_users(project_id) + call_command('validate_allocations', apply=True) + assert non_coldfront_user not in allocator.get_users(project_id) diff --git a/src/coldfront_plugin_cloud/tests/functional/openstack/test_allocation.py b/src/coldfront_plugin_cloud/tests/functional/openstack/test_allocation.py index 2c523e7..542c842 100644 --- a/src/coldfront_plugin_cloud/tests/functional/openstack/test_allocation.py +++ b/src/coldfront_plugin_cloud/tests/functional/openstack/test_allocation.py @@ -18,7 +18,7 @@ class TestAllocation(base.TestBase): def setUp(self) -> None: super().setUp() - self.resource = self.new_resource(name='Devstack', + self.resource = self.new_openstack_resource(name='Devstack', auth_url=os.getenv('OS_AUTH_URL')) self.session = openstack.get_session_for_resource(self.resource) self.identity = client.Client(session=self.session) @@ -207,7 +207,7 @@ def test_new_allocation_with_quantity(self): # Change allocation attributes for object store quota current_quota = allocator.get_quota(openstack_project.id) - obj_key = openstack.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] + obj_key = openstack.OpenStackResourceAllocator.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB] if obj_key in current_quota.keys(): utils.set_attribute_on_allocation(allocation, attributes.QUOTA_OBJECT_GB, 6) self.assertEqual(allocation.get_attribute(attributes.QUOTA_OBJECT_GB), 6) diff --git a/src/coldfront_plugin_cloud/tests/unit/test_attribute_migration.py b/src/coldfront_plugin_cloud/tests/unit/test_attribute_migration.py index 9e88699..48dae11 100644 --- a/src/coldfront_plugin_cloud/tests/unit/test_attribute_migration.py +++ b/src/coldfront_plugin_cloud/tests/unit/test_attribute_migration.py @@ -154,7 +154,7 @@ def test_rename_identity_url(self): ): call_command('register_cloud_attributes') - resource = self.new_resource('Example', auth_url_val) + resource = self.new_openstack_resource('Example', auth_url_val) self.assertEqual( resource.get_attribute(new_auth_url_name),