Skip to content

Commit 4dc2e7a

Browse files
committed
Initial split into own package
1 parent 8b97f8a commit 4dc2e7a

13 files changed

+444
-1
lines changed

README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,23 @@
1-
# coldfront-plugin-openstack
1+
# OpenStack Plugin
2+
3+
## Configuration
4+
5+
The OpenStack plugin is fired automatically for resources of type `OpenStack`.
6+
7+
It expects the Resource to have the following attributes set:
8+
* `OpenStack Auth URL` - the URL of the Keystone endpoint (omitting version
9+
and ending slash)
10+
* `OpenStack Domain for Projects` - The domain id that new projects will be
11+
created in
12+
* `OpenStack Domain for Users` - The domain id that new users will be created in
13+
* `OpenStack Identity Provider` - The identity provider as configured in keystone
14+
* `OpenStack Federation Protocol` - (defaults to openid) The federation protocol
15+
used with the identity provider
16+
* `OpenStack Role for User in Project` - (defaults to member) The role name of
17+
the role that is assigned to the user on project creation
18+
19+
Authentication is done using application credentials. The application credential
20+
is stored as the pair of environment variables in the form
21+
`OPENSTACK_{resource_name}_APPLICATION_CREDENTIAL_ID` and
22+
`OPENSTACK_{resource_name}_APPLICATION_CREDENTIAL_SECRET` where `{resource_name}`
23+
is the all name of the resource as all uppercase (with spaces and `-` replaced by `_`).

pyproject.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[build-system]
2+
requires = [
3+
"setuptools>=42",
4+
"wheel"
5+
]
6+
build-backend = "setuptools.build_meta"

requirements.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
git+https://github.com/ubccr/coldfront@7bc52c05ba1246b50c5fd5877d8e9184045042ab#egg=coldfront
2+
python-cinderclient # TODO: Set version for OpenStack Clients
3+
python-keystoneclient
4+
python-memcached==1.59
5+
python-novaclient
6+
python-neutronclient

setup.cfg

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[metadata]
2+
name = coldfront_plugin_openstack
3+
version = 0.1.0
4+
author = Kristi Nikolla
5+
author_email = [email protected]
6+
description = OpenStack resource allocation plugin for ColdFront
7+
long_description = file: README.md
8+
long_description_content_type = text/markdown
9+
url = https://github.com/knikolla/coldfront-plugin-openstack
10+
project_urls =
11+
Bug Tracker = https://github.com/knikolla/coldfront-plugin-openstack/issues
12+
classifiers =
13+
Programming Language :: Python :: 3
14+
License :: OSI Approved :: MIT License
15+
Operating System :: OS Independent
16+
17+
[options]
18+
package_dir =
19+
= src
20+
packages = find:
21+
python_requires = >=3.8
22+
23+
[options.packages.find]
24+
where = src
25+
26+
[options.entry_points]
27+
console_scripts =
28+
coldfront-plugin-openstack = django:setup
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_app_config = 'coldfront_plugin_openstack.apps.OpenStackConfig'
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from django.apps import AppConfig
2+
3+
4+
class OpenStackConfig(AppConfig):
5+
name = 'coldfront_plugin_openstack'
6+
7+
def ready(self):
8+
import coldfront_plugin_openstack.signals
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from coldfront.config.base import INSTALLED_APPS
2+
from coldfront.config.env import ENV
3+
4+
INSTALLED_APPS += [
5+
'coldfront_plugin_openstack',
6+
]

src/coldfront_plugin_openstack/management/commands/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from django.core.management.base import BaseCommand
2+
from django.core.management import call_command
3+
4+
from coldfront.core.resource.models import (Resource,
5+
ResourceAttribute,
6+
ResourceAttributeType,
7+
ResourceType)
8+
9+
10+
class Command(BaseCommand):
11+
help = 'Create OpenStack resource'
12+
13+
def add_arguments(self, parser):
14+
parser.add_argument('--name', type=str, required=True,
15+
help='Name of OpenStack resource')
16+
parser.add_argument('--auth-url', type=str, required=True,
17+
help='URL of the OpenStack Identity Endpoint')
18+
parser.add_argument('--users-domain', type=str, default='default',
19+
help='Domain ID to create users')
20+
parser.add_argument('--projects-domain', type=str, default='default',
21+
help='Domain ID to create projects')
22+
parser.add_argument('--idp', type=str, required=True,
23+
help='Identity provider configured in OpenStack')
24+
parser.add_argument('--protocol', type=str, default='openid',
25+
help='Federation protocol (default: openid)')
26+
parser.add_argument('--role', type=str, default='member',
27+
help='Role for user when added to project (default: member)')
28+
29+
def handle(self, *args, **options):
30+
openstack = Resource.objects.get_or_create(
31+
resource_type=ResourceType.objects.get(name='OpenStack'),
32+
parent_resource=None,
33+
name=options['name'],
34+
description='OpenStack test cloud environment',
35+
is_available=True,
36+
is_public=True,
37+
is_allocatable=True
38+
)
39+
40+
resource_models.ResourceAttribute.objects.get_or_create(
41+
resource_attribute_type=ResourceAttributeType.objects.get(
42+
name='OpenStack Auth URL'),
43+
resource=openstack,
44+
value=options['auth-url']
45+
)
46+
ResourceAttribute.objects.get_or_create(
47+
resource_attribute_type=ResourceAttributeType.objects.get(
48+
name='OpenStack Domain for Projects'),
49+
resource=openstack,
50+
value=options['projects-domain']
51+
)
52+
ResourceAttribute.objects.get_or_create(
53+
resource_attribute_type=ResourceAttributeType.objects.get(
54+
name='OpenStack Domain for Users'),
55+
resource=openstack,
56+
value=options['users-domain']
57+
)
58+
ResourceAttribute.objects.get_or_create(
59+
resource_attribute_type=ResourceAttributeType.objects.get(
60+
name='OpenStack Identity Provider'),
61+
resource=openstack,
62+
value=options['idp']
63+
)
64+
ResourceAttribute.objects.get_or_create(
65+
resource_attribute_type=ResourceAttributeType.objects.get(
66+
name='OpenStack Federation Protocol'),
67+
resource=openstack,
68+
value=options['protocol']
69+
)
70+
ResourceAttribute.objects.get_or_create(
71+
resource_attribute_type=ResourceAttributeType.objects.get(
72+
name='OpenStack Role for User in Project'),
73+
resource=openstack,
74+
value=options['role']
75+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from django.core.management.base import BaseCommand
2+
from django.core.management import call_command
3+
4+
from coldfront.core.allocation import models as allocation_models
5+
from coldfront.core.resource import models as resource_models
6+
7+
8+
class Command(BaseCommand):
9+
help = 'Add default OpenStack allocation related choices'
10+
11+
def register_allocation_attributes(self):
12+
for name, attribute_type, has_usage, is_private in (
13+
('OpenStack Compute Instance Quota', 'Int', False, False),
14+
('OpenStack Compute RAM Quota', 'Int', False, False),
15+
('OpenStack Compute vCPU Quota', 'Int', False, False),
16+
('OpenStack Project ID', 'Text', False, False),
17+
('OpenStack Project Name', 'Text', False, False),
18+
):
19+
allocation_models.AllocationAttributeType.objects.get_or_create(
20+
name=name,
21+
attribute_type=allocation_models.AttributeType.objects.get(
22+
name=attribute_type),
23+
has_usage=has_usage,
24+
is_private=is_private
25+
)
26+
27+
def register_resource_attributes(self):
28+
for resource_attribute_type, attribute_type in (
29+
('OpenStack Auth URL', 'Text'),
30+
('OpenStack Domain for Projects', 'Text'),
31+
('OpenStack Domain for Users', 'Text'),
32+
('OpenStack Federation Protocol', 'Text'),
33+
('OpenStack Identity Provider', 'Text'),
34+
('OpenStack Role for User in Project', 'Text'),
35+
):
36+
resource_models.ResourceAttributeType.objects.get_or_create(
37+
name=resource_attribute_type,
38+
attribute_type=resource_models.AttributeType.objects.get(
39+
name=attribute_type)
40+
)
41+
42+
def register_resource_type(self):
43+
resource_models.ResourceType.objects.get_or_create(
44+
name='OpenStack', description='OpenStack Cloud')
45+
46+
def handle(self, *args, **options):
47+
self.register_resource_type()
48+
self.register_resource_attributes()
49+
self.register_allocation_attributes()
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from django.dispatch import receiver
2+
3+
from coldfront_plugin_openstack.tasks import (activate_allocation,
4+
add_user_to_allocation,
5+
disable_allocation,
6+
remove_user_from_allocation)
7+
from coldfront.core.allocation.signals import (allocation_activate,
8+
allocation_activate_user,
9+
allocation_disable,
10+
allocation_remove_user)
11+
12+
13+
@receiver(allocation_activate)
14+
def activate_allocation_receiver(sender, **kwargs):
15+
allocation_pk = kwargs.get('allocation_pk')
16+
# TODO: Async implementation
17+
activate_allocation(allocation_pk)
18+
19+
20+
@receiver(allocation_disable)
21+
def allocation_disable_receiver(sender, **kwargs):
22+
allocation_pk = kwargs.get('allocation_pk')
23+
# TODO: Async implementation
24+
disable_allocation(allocation_pk)
25+
26+
27+
@receiver(allocation_activate_user)
28+
def activate_allocation_user_receiver(sender, **kwargs):
29+
allocation_user_pk = kwargs.get('allocation_user_pk')
30+
# TODO: Async implementation
31+
add_user_to_allocation(allocation_user_pk)
32+
33+
34+
@receiver(allocation_remove_user)
35+
def allocation_remove_user_receiver(sender, **kwargs):
36+
allocation_user_pk = kwargs.get('allocation_user_pk')
37+
# TODO: Async implementation
38+
remove_user_from_allocation(allocation_user_pk)

0 commit comments

Comments
 (0)