Skip to content

Commit 2b72869

Browse files
authored
Merge pull request #100 from naved001/sync-users
Sync users with `validate_allocations` command
2 parents b7724a6 + 5b9fbd7 commit 2b72869

File tree

6 files changed

+89
-2
lines changed

6 files changed

+89
-2
lines changed

.github/workflows/test-py39-functional-microshift.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
env:
1010
PYTHONWARNINGS: ignore
1111
KUBECONFIG: ${{ github.workspace }}/kubeconfig
12-
ACCT_MGT_VERSION: "acd4f462104de6cb8af46baecff2ed968612742d"
12+
ACCT_MGT_VERSION: "44f8f13e4d876249ed2ee1a77fbac86dfd8b3960"
1313

1414
jobs:
1515
build:

src/coldfront_plugin_cloud/management/commands/validate_allocations.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
from coldfront_plugin_cloud import openstack
66
from coldfront_plugin_cloud import openshift
77
from coldfront_plugin_cloud import utils
8+
from coldfront_plugin_cloud import tasks
89

910
from django.core.management.base import BaseCommand, CommandError
1011
from coldfront.core.resource.models import (Resource,
1112
ResourceType)
1213
from coldfront.core.allocation.models import (Allocation,
13-
AllocationStatusChoice)
14+
AllocationStatusChoice,
15+
AllocationUser)
1416
from keystoneauth1.exceptions import http
1517

1618

@@ -24,6 +26,31 @@ def add_arguments(self, parser):
2426
parser.add_argument('--apply', action='store_true',
2527
help='Apply expected state if validation fails.')
2628

29+
@staticmethod
30+
def sync_users(project_id, allocation, allocator, apply):
31+
coldfront_users = AllocationUser.objects.filter(allocation=allocation, status__name='Active')
32+
allocation_users = allocator.get_users(project_id)
33+
failed_validation = False
34+
35+
# Create users that exist in coldfront but not in the resource
36+
for coldfront_user in coldfront_users:
37+
if coldfront_user.user.username not in allocation_users:
38+
failed_validation = True
39+
logger.warn(f"{coldfront_user.user.username} is not part of {project_id}")
40+
if apply:
41+
tasks.add_user_to_allocation(coldfront_user.pk)
42+
43+
# remove users that are in the resource but not in coldfront
44+
users = set([coldfront_user.user.username for coldfront_user in coldfront_users])
45+
for allocation_user in allocation_users:
46+
if allocation_user not in users:
47+
failed_validation = True
48+
logger.warn(f"{allocation_user} exists in the resource {project_id} but not in coldfront")
49+
if apply:
50+
allocator.remove_role_from_user(allocation_user, project_id)
51+
52+
return failed_validation
53+
2754
def handle(self, *args, **options):
2855

2956
# Openstack Resources first
@@ -61,6 +88,9 @@ def handle(self, *args, **options):
6188
continue
6289

6390
quota = allocator.get_quota(project_id)
91+
92+
failed_validation = Command.sync_users(project_id, allocation, allocator, options["apply"])
93+
6494
for attr in attributes.ALLOCATION_QUOTA_ATTRIBUTES:
6595
if 'OpenStack' in attr:
6696
key = openstack.QUOTA_KEY_MAPPING_ALL_KEYS.get(attr, None)
@@ -130,6 +160,8 @@ def handle(self, *args, **options):
130160

131161
quota = allocator.get_quota(project_id)["Quota"]
132162

163+
failed_validation = Command.sync_users(project_id, allocation, allocator, options["apply"])
164+
133165
for attr in attributes.ALLOCATION_QUOTA_ATTRIBUTES:
134166
if "OpenShift" in attr:
135167
key_with_lambda = openshift.QUOTA_KEY_MAPPING.get(attr, None)

src/coldfront_plugin_cloud/openshift.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,8 @@ def _delete_user(self, username):
172172
url = f"{self.auth_url}/users/{username}"
173173
r = self.session.delete(url)
174174
return self.check_response(r)
175+
176+
def get_users(self, project_id):
177+
url = f"{self.auth_url}/projects/{project_id}/users"
178+
r = self.session.get(url)
179+
return set(self.check_response(r))

src/coldfront_plugin_cloud/openstack.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,13 @@ def create_project_defaults(self, project_id):
419419
else:
420420
logger.info(f'No public network configured. Skipping default '
421421
f'network creation for project {project_id}.')
422+
423+
def get_users(self, project_id):
424+
""" Return users with a role in a project"""
425+
role_name = self.resource.get_attribute(attributes.RESOURCE_ROLE)
426+
role = self.identity.roles.find(name=role_name)
427+
role_assignments = self.identity.role_assignments.list(role=role.id,
428+
project=project_id,
429+
include_names=True)
430+
user_names = set(role_assignment.user["name"] for role_assignment in role_assignments)
431+
return user_names

src/coldfront_plugin_cloud/tests/functional/openshift/test_allocation.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import time
33
import unittest
4+
import uuid
45

56
from coldfront_plugin_cloud import attributes, openshift, tasks, utils
67
from coldfront_plugin_cloud.tests import base
@@ -77,12 +78,32 @@ def test_add_remove_user(self):
7778
allocator._get_role(user.username, project_id)
7879
allocator._get_role(user2.username, project_id)
7980

81+
assert set([user.username, user2.username]) == allocator.get_users(project_id)
82+
8083
tasks.remove_user_from_allocation(allocation_user2.pk)
8184

8285
allocator._get_role(user.username, project_id)
8386
with self.assertRaises(openshift.NotFound):
8487
allocator._get_role(user2.username, project_id)
8588

89+
assert set([user.username]) == allocator.get_users(project_id)
90+
91+
# use the validate_allocations command to add a new user
92+
user3 = self.new_user()
93+
allocation_user3 = self.new_allocation_user(allocation, user3)
94+
assert user3.username not in allocator.get_users(project_id)
95+
call_command('validate_allocations', apply=True)
96+
assert user3.username in allocator.get_users(project_id)
97+
98+
# directly add a user to openshift which should then be
99+
# deleted when validate_allocations is called
100+
non_coldfront_user = uuid.uuid4().hex
101+
allocator.get_or_create_federated_user(non_coldfront_user)
102+
allocator.assign_role_on_user(non_coldfront_user, project_id)
103+
assert non_coldfront_user in allocator.get_users(project_id)
104+
call_command('validate_allocations', apply=True)
105+
assert non_coldfront_user not in allocator.get_users(project_id)
106+
86107
def test_new_allocation_quota(self):
87108
user = self.new_user()
88109
project = self.new_project(pi=user)

src/coldfront_plugin_cloud/tests/functional/openstack/test_allocation.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import unittest
3+
import uuid
34

45
from coldfront_plugin_cloud import attributes, openstack, tasks, utils
56
from coldfront_plugin_cloud.tests import base
@@ -257,13 +258,31 @@ def test_add_remove_user(self):
257258

258259
self.assertEqual(len(roles), 1)
259260
self.assertEqual(roles[0].role['id'], self.role_member.id)
261+
assert set([user.username, user2.username]) == allocator.get_users(project_id)
260262

261263
tasks.remove_user_from_allocation(allocation_user2.pk)
262264

263265
roles = self.identity.role_assignments.list(user=openstack_user.id,
264266
project=openstack_project.id)
265267

266268
self.assertEqual(len(roles), 0)
269+
assert set([user.username]) == allocator.get_users(project_id)
270+
271+
# use the validate_allocations command to add a new user
272+
user3 = self.new_user()
273+
allocation_user3 = self.new_allocation_user(allocation, user3)
274+
assert user3.username not in allocator.get_users(project_id)
275+
call_command('validate_allocations', apply=True)
276+
assert user3.username in allocator.get_users(project_id)
277+
278+
# directly add a user to openstack which should then be
279+
# deleted when validate_allocations is called
280+
non_coldfront_user = uuid.uuid4().hex
281+
allocator.get_or_create_federated_user(non_coldfront_user)
282+
allocator.assign_role_on_user(non_coldfront_user, project_id)
283+
assert non_coldfront_user in allocator.get_users(project_id)
284+
call_command('validate_allocations', apply=True)
285+
assert non_coldfront_user not in allocator.get_users(project_id)
267286

268287
def test_add_remove_user_existing(self):
269288
user = self.new_user()

0 commit comments

Comments
 (0)