Skip to content

Commit

Permalink
use dataclasses instead of dictionaries
Browse files Browse the repository at this point in the history
  • Loading branch information
jtriley committed Jan 24, 2024
1 parent 73aea53 commit 26ed63a
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 141 deletions.
182 changes: 64 additions & 118 deletions src/coldfront_plugin_cloud/attributes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
from dataclasses import dataclass


@dataclass
class CloudResourceAttribute:
"""Class for configuring Cloud Resource Attributes"""
name: str
type: str = 'Text'


@dataclass
class CloudAllocationAttribute:
"""Class for configuring Cloud Allocation Attributes"""
name: str
type: str = 'Int'
has_usage: bool = False
is_private: bool = False
is_changeable: bool = True


RESOURCE_AUTH_URL = 'Identity Endpoint URL'
RESOURCE_ROLE = 'Role for User in Project'

Expand All @@ -10,58 +30,40 @@

RESOURCE_EULA_URL = "EULA URL"

RESOURCE_ATTRIBUTES = {
RESOURCE_AUTH_URL: {
'type': 'Text',
},
RESOURCE_FEDERATION_PROTOCOL: {
'type': 'Text',
},
RESOURCE_IDP: {
'type': 'Text',
},
RESOURCE_PROJECT_DOMAIN: {
'type': 'Text',
},
RESOURCE_ROLE: {
'type': 'Text',
},
RESOURCE_USER_DOMAIN: {
'type': 'Text',
},
RESOURCE_EULA_URL: {
'type': 'Text',
},
RESOURCE_DEFAULT_PUBLIC_NETWORK: {
'type': 'Text',
},
RESOURCE_DEFAULT_NETWORK_CIDR: {
'type': 'Text',
},
}
RESOURCE_ATTRIBUTES = [
CloudResourceAttribute(name=RESOURCE_AUTH_URL),
CloudResourceAttribute(name=RESOURCE_FEDERATION_PROTOCOL),
CloudResourceAttribute(name=RESOURCE_IDP),
CloudResourceAttribute(name=RESOURCE_PROJECT_DOMAIN),
CloudResourceAttribute(name=RESOURCE_ROLE),
CloudResourceAttribute(name=RESOURCE_USER_DOMAIN),
CloudResourceAttribute(name=RESOURCE_EULA_URL),
CloudResourceAttribute(name=RESOURCE_DEFAULT_PUBLIC_NETWORK),
CloudResourceAttribute(name=RESOURCE_DEFAULT_NETWORK_CIDR),
]

# TODO: Migration to rename the OpenStack specific prefix out of these attrs
ALLOCATION_PROJECT_ID = 'Allocated Project ID'
ALLOCATION_PROJECT_NAME = 'Allocated Project Name'
ALLOCATION_INSTITUTION_SPECIFIC_CODE = 'Institution-Specific Code'

ALLOCATION_ATTRIBUTES = {
ALLOCATION_PROJECT_ID: {
'type': 'Text',
'is_private': False,
'is_changeable': False,
},
ALLOCATION_PROJECT_NAME: {
'type': 'Text',
'is_private': False,
'is_changeable': False,
},
ALLOCATION_INSTITUTION_SPECIFIC_CODE: {
'type': 'Text',
'is_private': False,
'is_changeable': True,
},
}
ALLOCATION_ATTRIBUTES = [
CloudAllocationAttribute(
name=ALLOCATION_PROJECT_ID,
type='Text',
is_changeable=False
),
CloudAllocationAttribute(
name=ALLOCATION_PROJECT_NAME,
type='Text',
is_changeable=False
),
CloudAllocationAttribute(
name=ALLOCATION_INSTITUTION_SPECIFIC_CODE,
type='Text',
is_changeable=False
),
]

###########################################################
# OpenStack Quota Attributes
Expand All @@ -88,75 +90,19 @@
QUOTA_PVC = 'OpenShift Persistent Volume Claims Quota'


ALLOCATION_QUOTA_ATTRIBUTES = {
QUOTA_INSTANCES: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_RAM: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_VCPU: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_VOLUMES: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_VOLUMES_GB: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_FLOATING_IPS: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_OBJECT_GB: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_GPU: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_LIMITS_CPU: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_LIMITS_MEMORY: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_LIMITS_EPHEMERAL_STORAGE_GB: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_REQUESTS_STORAGE: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_REQUESTS_GPU: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
QUOTA_PVC: {
'type': 'Int',
'is_private': False,
'is_changeable': True,
},
}
ALLOCATION_QUOTA_ATTRIBUTES = [
CloudAllocationAttribute(name=QUOTA_INSTANCES),
CloudAllocationAttribute(name=QUOTA_RAM),
CloudAllocationAttribute(name=QUOTA_VCPU),
CloudAllocationAttribute(name=QUOTA_VOLUMES),
CloudAllocationAttribute(name=QUOTA_VOLUMES_GB),
CloudAllocationAttribute(name=QUOTA_FLOATING_IPS),
CloudAllocationAttribute(name=QUOTA_OBJECT_GB),
CloudAllocationAttribute(name=QUOTA_GPU),
CloudAllocationAttribute(name=QUOTA_LIMITS_CPU),
CloudAllocationAttribute(name=QUOTA_LIMITS_MEMORY),
CloudAllocationAttribute(name=QUOTA_LIMITS_EPHEMERAL_STORAGE_GB),
CloudAllocationAttribute(name=QUOTA_REQUESTS_STORAGE),
CloudAllocationAttribute(name=QUOTA_REQUESTS_GPU),
CloudAllocationAttribute(name=QUOTA_PVC),
]
Original file line number Diff line number Diff line change
Expand Up @@ -74,29 +74,28 @@ def migrate_resource_attributes(self):
f' Cannot perform automatic migration.')

def register_allocation_attributes(self):
alloc_attrs = {}
alloc_attrs.update(attributes.ALLOCATION_ATTRIBUTES)
alloc_attrs.update(attributes.ALLOCATION_QUOTA_ATTRIBUTES)
alloc_attrs = (
attributes.ALLOCATION_ATTRIBUTES +
attributes.ALLOCATION_QUOTA_ATTRIBUTES
)

for attr in alloc_attrs:
cfg = alloc_attrs[attr]
allocation_models.AllocationAttributeType.objects.get_or_create(
name=attr,
name=attr.name,
attribute_type=allocation_models.AttributeType.objects.get(
name=cfg.get('type', 'Text')
name=attr.type,
),
has_usage=cfg.get('has_usage', False),
is_private=cfg.get('is_private', False),
is_changeable=cfg.get('is_changeable', 'Quota' in attr)
has_usage=attr.has_usage,
is_private=attr.is_private,
is_changeable=attr.is_changeable,
)

def register_resource_attributes(self):
for attr in attributes.RESOURCE_ATTRIBUTES:
cfg = attributes.RESOURCE_ATTRIBUTES[attr]
resource_models.ResourceAttributeType.objects.get_or_create(
name=attr,
name=attr.name,
attribute_type=resource_models.AttributeType.objects.get(
name=cfg.get('type', 'Text'))
name=attr.type),
)

def register_resource_type(self):
Expand Down
23 changes: 12 additions & 11 deletions src/coldfront_plugin_cloud/tests/unit/test_attribute_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,26 +122,27 @@ def test_rename_identity_url(self):
'coldfront_plugin_cloud.management.commands.register_cloud_attributes.RESOURCE_ATTRIBUTE_MIGRATIONS',
[]
):
resource_attrs = {}
resource_attrs.update(attributes.RESOURCE_ATTRIBUTES)
new_auth_url_attr = 'OpenStack Auth URL'
auth_url_cfg = attributes.RESOURCE_ATTRIBUTES[attributes.RESOURCE_AUTH_URL]
resource_attrs[new_auth_url_attr] = auth_url_cfg
del resource_attrs[attributes.RESOURCE_AUTH_URL]
orig_auth_url_name = attributes.RESOURCE_AUTH_URL
new_auth_url_name = 'OpenStack Auth URL'
assert orig_auth_url_name != new_auth_url_name
auth_url_val = 'https://example.com'
new_auth_attr = attributes.CloudResourceAttribute(
name=new_auth_url_name,
)
with mock.patch('coldfront_plugin_cloud.attributes.RESOURCE_AUTH_URL', new_auth_url_attr):
with mock.patch.dict('coldfront_plugin_cloud.attributes.RESOURCE_ATTRIBUTES', resource_attrs, clear=True):
with mock.patch.object('coldfront_plugin_cloud.attributes.RESOURCE_ATTRIBUTES[0]', new_auth_attr):

call_command('register_cloud_attributes')
resource = self.new_resource('Example', 'https://example.com')
resource = self.new_resource('Example', auth_url_val)

self.assertEqual(
resource.get_attribute('OpenStack Auth URL'),
'https://example.com'
resource.get_attribute(new_auth_url_name),
auth_val,
)

call_command('register_cloud_attributes')

self.assertEqual(
resource.get_attribute('Identity Endpoint URL'),
resource.get_attribute(orig_auth_url_name),
'https://example.com'
)

0 comments on commit 26ed63a

Please sign in to comment.