From 2ad30b5fa48f5f5d2f09a9910f3d322760c46158 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 4 Oct 2019 16:22:45 -0400 Subject: [PATCH] Implement dispatch_delete_user job --- atst/app.py | 3 ++- atst/domain/environment_roles.py | 14 ++++++++++ atst/jobs.py | 15 +++++++++++ tests/test_jobs.py | 44 ++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/atst/app.py b/atst/app.py index cd1541b0..3194a4fe 100644 --- a/atst/app.py +++ b/atst/app.py @@ -9,6 +9,7 @@ import redis from unipath import Path from flask_wtf.csrf import CSRFProtect import json +from enum import Enum from atst.database import db from atst.assets import environment as assets_environment @@ -150,7 +151,7 @@ def set_default_headers(app): # pragma: no cover def map_config(config): def sqlalchemy_dumps(dct): - def _default(self, obj): + def _default(obj): if isinstance(obj, Enum): return obj.name else: diff --git a/atst/domain/environment_roles.py b/atst/domain/environment_roles.py index 9dd59365..d16ab979 100644 --- a/atst/domain/environment_roles.py +++ b/atst/domain/environment_roles.py @@ -87,3 +87,17 @@ class EnvironmentRoles(object): .all() ) return [id_ for id_, in results] + + @classmethod + def get_environment_roles_pending_deletion(cls) -> List[UUID]: + results = ( + db.session.query(EnvironmentRole.id) + .join(Environment) + .join(ApplicationRole) + .filter(Environment.deleted == False) + .filter(Environment.baseline_info != None) + .filter(EnvironmentRole.status == EnvironmentRole.Status.PENDING_DELETE) + .filter(ApplicationRole.status == ApplicationRoleStatus.ACTIVE) + .all() + ) + return [id_ for id_, in results] diff --git a/atst/jobs.py b/atst/jobs.py index 8e5d5602..e630409e 100644 --- a/atst/jobs.py +++ b/atst/jobs.py @@ -169,6 +169,13 @@ def provision_user(self, environment_role_id=None): ) +@celery.task(bind=True) +def delete_user(self, environment_role_id=None): + do_work( + do_delete_user, self, app.csp.cloud, environment_role_id=environment_role_id + ) + + @celery.task(bind=True) def dispatch_create_environment(self): for environment_id in Environments.get_environments_pending_creation( @@ -199,3 +206,11 @@ def dispatch_provision_user(self): environment_role_id ) in EnvironmentRoles.get_environment_roles_pending_creation(): provision_user.delay(environment_role_id=environment_role_id) + + +@celery.task(bind=True) +def dispatch_delete_user(self): + for ( + environment_role_id + ) in EnvironmentRoles.get_environment_roles_pending_deletion(): + delete_user.delay(environment_role_id=environment_role_id) diff --git a/tests/test_jobs.py b/tests/test_jobs.py index 47ec1840..8e69c9f0 100644 --- a/tests/test_jobs.py +++ b/tests/test_jobs.py @@ -18,6 +18,7 @@ from atst.jobs import ( dispatch_provision_user, do_provision_user, do_delete_user, + dispatch_delete_user, ) from atst.models.utils import claim_for_update from atst.domain.exceptions import ClaimFailedException @@ -391,3 +392,46 @@ def test_do_delete_user(csp, session): session.refresh(environment_role) assert environment_role.status == EnvironmentRole.Status.DELETED + + +def test_dispatch_delete_user(csp, session, monkeypatch): + # Given that I have three environment roles: + # (A) one of which has a completed status + # (B) one of which has an environment that has not been provisioned + # (C) one of which is pending, has a provisioned environment but an inactive application role + # (D) one of which is pending, has a provisioned environment and has an active application role + # (E) one of which is pending delete, has a provisioned environment and has an active application role + provisioned_environment = EnvironmentFactory.create( + cloud_id="cloud_id", root_user_info={}, baseline_info={} + ) + unprovisioned_environment = EnvironmentFactory.create() + _er_a = EnvironmentRoleFactory.create( + environment=provisioned_environment, status=EnvironmentRole.Status.COMPLETED + ) + _er_b = EnvironmentRoleFactory.create( + environment=unprovisioned_environment, status=EnvironmentRole.Status.PENDING + ) + _er_c = EnvironmentRoleFactory.create( + environment=unprovisioned_environment, + status=EnvironmentRole.Status.PENDING, + application_role=ApplicationRoleFactory(status=ApplicationRoleStatus.PENDING), + ) + _er_d = EnvironmentRoleFactory.create( + environment=unprovisioned_environment, + status=EnvironmentRole.Status.PENDING_DELETE, + application_role=ApplicationRoleFactory(status=ApplicationRoleStatus.PENDING), + ) + er_e = EnvironmentRoleFactory.create( + environment=provisioned_environment, + status=EnvironmentRole.Status.PENDING_DELETE, + application_role=ApplicationRoleFactory(status=ApplicationRoleStatus.ACTIVE), + ) + + mock = Mock() + monkeypatch.setattr("atst.jobs.delete_user", mock) + + # When I dispatch the user deletion task + dispatch_delete_user.run() + + # I expect it to dispatch only one call, to EnvironmentRole E + mock.delay.assert_called_once_with(environment_role_id=er_e.id)