Add create_user task

This commit is contained in:
richard-dds 2019-09-18 16:39:41 -04:00
parent 4ba3e6cd97
commit d1e146f577
6 changed files with 106 additions and 7 deletions

View File

@ -0,0 +1,30 @@
"""add environment_role csp fields
Revision ID: e3d93f9caba7
Revises: 691b04ecd85e
Create Date: 2019-09-18 16:35:47.554060
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'e3d93f9caba7' # pragma: allowlist secret
down_revision = '691b04ecd85e' # pragma: allowlist secret
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('environment_roles', sa.Column('claimed_until', sa.TIMESTAMP(timezone=True), nullable=True))
op.add_column('environment_roles', sa.Column('csp_user_id', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('environment_roles', 'csp_user_id')
op.drop_column('environment_roles', 'claimed_until')
# ### end Alembic commands ###

View File

@ -194,7 +194,7 @@ class MockCloudProvider(CloudProviderInterface):
GeneralCSPException("Could not create user."), GeneralCSPException("Could not create user."),
) )
return {"id": self._id()} return self._id()
def suspend_user(self, auth_credentials, csp_user_id): def suspend_user(self, auth_credentials, csp_user_id):
self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION) self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION)

View File

@ -1,5 +1,10 @@
from sqlalchemy.orm.exc import NoResultFound
from atst.database import db from atst.database import db
from atst.models import EnvironmentRole, ApplicationRole from atst.models import EnvironmentRole, ApplicationRole
from atst.domain.exceptions import NotFoundError
from uuid import UUID
from typing import List
class EnvironmentRoles(object): class EnvironmentRoles(object):
@ -22,6 +27,15 @@ class EnvironmentRoles(object):
) )
return existing_env_role return existing_env_role
@classmethod
def get_by_id(cls, id_) -> EnvironmentRole:
try:
return (
db.session.query(EnvironmentRole).filter(EnvironmentRole.id == id_)
).one()
except NoResultFound:
raise NotFoundError(cls.resource_name)
@classmethod @classmethod
def get_by_user_and_environment(cls, user_id, environment_id): def get_by_user_and_environment(cls, user_id, environment_id):
existing_env_role = ( existing_env_role = (
@ -54,3 +68,12 @@ class EnvironmentRoles(object):
.filter(EnvironmentRole.deleted != True) .filter(EnvironmentRole.deleted != True)
.all() .all()
) )
@classmethod
def get_environment_roles_pending_creation(cls) -> List[UUID]:
results = (
db.session.query(EnvironmentRole.id)
# TODO
.filter(EnvironmentRole.status == "PENDING").all()
)
return [id_ for id_, in results]

View File

@ -6,6 +6,7 @@ from atst.queue import celery
from atst.models import EnvironmentJobFailure, EnvironmentRoleJobFailure from atst.models import EnvironmentJobFailure, EnvironmentRoleJobFailure
from atst.domain.csp.cloud import CloudProviderInterface, GeneralCSPException from atst.domain.csp.cloud import CloudProviderInterface, GeneralCSPException
from atst.domain.environments import Environments from atst.domain.environments import Environments
from atst.domain.environment_roles import EnvironmentRoles
from atst.models.utils import claim_for_update from atst.models.utils import claim_for_update
@ -101,6 +102,20 @@ def do_create_environment_baseline(csp: CloudProviderInterface, environment_id=N
db.session.commit() db.session.commit()
def do_create_user(csp: CloudProviderInterface, environment_role_id=None):
environment_role = EnvironmentRoles.get_by_id(environment_role_id)
with claim_for_update(environment_role) as environment_role:
credentials = environment_role.environment.root_user_info["credentials"]
csp_user_id = csp.create_or_update_user(
credentials, environment_role, "role_id"
)
environment_role.csp_user_id = csp_user_id
db.session.add(environment_role)
db.session.commit()
def do_work(fn, task, csp, **kwargs): def do_work(fn, task, csp, **kwargs):
try: try:
fn(csp, **kwargs) fn(csp, **kwargs)
@ -130,6 +145,13 @@ def create_environment_baseline(self, environment_id=None):
) )
@celery.task(bind=True)
def create_user(self, environment_role_id=None):
do_work(
do_create_user, self, app.csp.cloud, environment_role_id=environment_role_id
)
@celery.task(bind=True) @celery.task(bind=True)
def dispatch_create_environment(self): def dispatch_create_environment(self):
for environment_id in Environments.get_environments_pending_creation( for environment_id in Environments.get_environments_pending_creation(
@ -152,3 +174,11 @@ def dispatch_create_environment_baseline(self):
pendulum.now() pendulum.now()
): ):
create_environment_baseline.delay(environment_id=environment_id) create_environment_baseline.delay(environment_id=environment_id)
@celery.task(bind=True)
def dispatch_provision_user(self):
for (
environment_role_id
) in EnvironmentRoles.get_environment_roles_pending_creation():
create_user.delay(environment_role_id=environment_role_id)

View File

@ -1,5 +1,5 @@
from enum import Enum from enum import Enum
from sqlalchemy import Index, ForeignKey, Column, String from sqlalchemy import Index, ForeignKey, Column, String, TIMESTAMP
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@ -33,6 +33,9 @@ class EnvironmentRole(
job_failures = relationship("EnvironmentRoleJobFailure") job_failures = relationship("EnvironmentRoleJobFailure")
csp_user_id = Column(String())
claimed_until = Column(TIMESTAMP(timezone=True))
def __repr__(self): def __repr__(self):
return "<EnvironmentRole(role='{}', user='{}', environment='{}', id='{}')>".format( return "<EnvironmentRole(role='{}', user='{}', environment='{}', id='{}')>".format(
self.role, self.application_role.user_name, self.environment.name, self.id self.role, self.application_role.user_name, self.environment.name, self.id

View File

@ -16,12 +16,18 @@ from atst.jobs import (
dispatch_create_atat_admin_user, dispatch_create_atat_admin_user,
dispatch_create_environment_baseline, dispatch_create_environment_baseline,
create_environment, create_environment,
do_create_user,
) )
from atst.models.utils import claim_for_update from atst.models.utils import claim_for_update
from atst.domain.exceptions import ClaimFailedException from atst.domain.exceptions import ClaimFailedException
from tests.factories import EnvironmentFactory, EnvironmentRoleFactory, PortfolioFactory from tests.factories import EnvironmentFactory, EnvironmentRoleFactory, PortfolioFactory
@pytest.fixture(autouse=True, scope="function")
def csp():
return Mock(wraps=MockCloudProvider({}, with_delay=False, with_failure=False))
def test_environment_job_failure(celery_app, celery_worker): def test_environment_job_failure(celery_app, celery_worker):
@celery_app.task(bind=True, base=RecordEnvironmentFailure) @celery_app.task(bind=True, base=RecordEnvironmentFailure)
def _fail_hard(self, environment_id=None): def _fail_hard(self, environment_id=None):
@ -63,11 +69,6 @@ yesterday = now.subtract(days=1)
tomorrow = now.add(days=1) tomorrow = now.add(days=1)
@pytest.fixture(autouse=True, scope="function")
def csp():
return Mock(wraps=MockCloudProvider({}, with_delay=False, with_failure=False))
def test_create_environment_job(session, csp): def test_create_environment_job(session, csp):
environment = EnvironmentFactory.create() environment = EnvironmentFactory.create()
do_create_environment(csp, environment.id) do_create_environment(csp, environment.id)
@ -291,3 +292,15 @@ def test_claim_for_update(session):
# The claim is released # The claim is released
assert environment.claimed_until is None assert environment.claimed_until is None
def test_create_user(csp, session):
environment = EnvironmentFactory.create(
root_user_info={"credentials": MockCloudProvider({})._auth_credentials}
)
environment_role = EnvironmentRoleFactory.create(environment=environment)
do_create_user(csp, environment_role_id=environment_role.id)
session.refresh(environment_role)
assert environment_role.csp_user_id