Update atst to atat
This commit is contained in:
172
atat/domain/portfolios/portfolios.py
Normal file
172
atat/domain/portfolios/portfolios.py
Normal file
@@ -0,0 +1,172 @@
|
||||
from sqlalchemy import or_
|
||||
from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
from atat.database import db
|
||||
from atat.domain.permission_sets import PermissionSets
|
||||
from atat.domain.authz import Authorization
|
||||
from atat.domain.portfolio_roles import PortfolioRoles
|
||||
|
||||
from atat.domain.invitations import PortfolioInvitations
|
||||
from atat.models import (
|
||||
Portfolio,
|
||||
PortfolioStateMachine,
|
||||
FSMStates,
|
||||
Permissions,
|
||||
PortfolioRole,
|
||||
PortfolioRoleStatus,
|
||||
TaskOrder,
|
||||
CLIN,
|
||||
)
|
||||
|
||||
from .query import PortfoliosQuery, PortfolioStateMachinesQuery
|
||||
from .scopes import ScopedPortfolio
|
||||
|
||||
|
||||
class PortfolioError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PortfolioDeletionApplicationsExistError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PortfolioStateMachines(object):
|
||||
@classmethod
|
||||
def create(cls, portfolio, **sm_attrs):
|
||||
sm_attrs.update({"portfolio": portfolio})
|
||||
sm = PortfolioStateMachinesQuery.create(**sm_attrs)
|
||||
return sm
|
||||
|
||||
|
||||
class Portfolios(object):
|
||||
@classmethod
|
||||
def get_or_create_state_machine(cls, portfolio):
|
||||
"""
|
||||
get or create Portfolio State Machine for a Portfolio
|
||||
"""
|
||||
return portfolio.state_machine or PortfolioStateMachines.create(portfolio)
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, portfolio_attrs):
|
||||
portfolio = PortfoliosQuery.create(**portfolio_attrs)
|
||||
perms_sets = PermissionSets.get_many(PortfolioRoles.PORTFOLIO_PERMISSION_SETS)
|
||||
Portfolios._create_portfolio_role(
|
||||
user,
|
||||
portfolio,
|
||||
status=PortfolioRoleStatus.ACTIVE,
|
||||
permission_sets=perms_sets,
|
||||
)
|
||||
PortfoliosQuery.add_and_commit(portfolio)
|
||||
return portfolio
|
||||
|
||||
@classmethod
|
||||
def get(cls, user, portfolio_id):
|
||||
portfolio = PortfoliosQuery.get(portfolio_id)
|
||||
return ScopedPortfolio(user, portfolio)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, portfolio):
|
||||
if len(portfolio.applications) != 0:
|
||||
raise PortfolioDeletionApplicationsExistError()
|
||||
|
||||
for portfolio_role in portfolio.roles:
|
||||
PortfolioRoles.disable(portfolio_role=portfolio_role, commit=False)
|
||||
|
||||
portfolio.deleted = True
|
||||
|
||||
db.session.add(portfolio)
|
||||
db.session.commit()
|
||||
|
||||
return portfolio
|
||||
|
||||
@classmethod
|
||||
def get_for_update(cls, portfolio_id):
|
||||
portfolio = PortfoliosQuery.get(portfolio_id)
|
||||
|
||||
return portfolio
|
||||
|
||||
@classmethod
|
||||
def for_user(cls, user):
|
||||
if Authorization.has_atat_permission(user, Permissions.VIEW_PORTFOLIO):
|
||||
portfolios = PortfoliosQuery.get_all()
|
||||
else:
|
||||
portfolios = PortfoliosQuery.get_for_user(user)
|
||||
return portfolios
|
||||
|
||||
@classmethod
|
||||
def add_member(cls, portfolio, member, permission_sets=None):
|
||||
portfolio_role = PortfolioRoles.add(member, portfolio.id, permission_sets)
|
||||
return portfolio_role
|
||||
|
||||
@classmethod
|
||||
def invite(cls, portfolio, inviter, member_data):
|
||||
permission_sets = PortfolioRoles._permission_sets_for_names(
|
||||
member_data.get("permission_sets", [])
|
||||
)
|
||||
role = PortfolioRole(portfolio=portfolio, permission_sets=permission_sets)
|
||||
|
||||
invitation = PortfolioInvitations.create(
|
||||
inviter=inviter, role=role, member_data=member_data["user_data"]
|
||||
)
|
||||
|
||||
PortfoliosQuery.add_and_commit(role)
|
||||
|
||||
return invitation
|
||||
|
||||
@classmethod
|
||||
def update_member(cls, member, permission_sets):
|
||||
return PortfolioRoles.update(member, permission_sets)
|
||||
|
||||
@classmethod
|
||||
def _create_portfolio_role(
|
||||
cls, user, portfolio, status=PortfolioRoleStatus.PENDING, permission_sets=None
|
||||
):
|
||||
if permission_sets is None:
|
||||
permission_sets = []
|
||||
|
||||
portfolio_role = PortfoliosQuery.create_portfolio_role(
|
||||
user, portfolio, status=status, permission_sets=permission_sets
|
||||
)
|
||||
PortfoliosQuery.add_and_commit(portfolio_role)
|
||||
return portfolio_role
|
||||
|
||||
@classmethod
|
||||
def update(cls, portfolio, new_data):
|
||||
if "name" in new_data:
|
||||
portfolio.name = new_data["name"]
|
||||
|
||||
if "description" in new_data:
|
||||
portfolio.description = new_data["description"]
|
||||
|
||||
PortfoliosQuery.add_and_commit(portfolio)
|
||||
|
||||
@classmethod
|
||||
def base_provision_query(cls):
|
||||
return db.session.query(Portfolio.id)
|
||||
|
||||
@classmethod
|
||||
def get_portfolios_pending_provisioning(cls, now) -> List[UUID]:
|
||||
"""
|
||||
Any portfolio with a corresponding State Machine that is either:
|
||||
not started yet,
|
||||
failed in creating a tenant
|
||||
failed
|
||||
"""
|
||||
|
||||
results = (
|
||||
db.session.query(Portfolio.id)
|
||||
.join(PortfolioStateMachine)
|
||||
.join(TaskOrder)
|
||||
.join(CLIN)
|
||||
.filter(Portfolio.deleted == False)
|
||||
.filter(CLIN.start_date <= now)
|
||||
.filter(CLIN.end_date > now)
|
||||
.filter(
|
||||
or_(
|
||||
PortfolioStateMachine.state == FSMStates.UNSTARTED,
|
||||
PortfolioStateMachine.state.like("%CREATED"),
|
||||
)
|
||||
)
|
||||
)
|
||||
return [id_ for id_, in results]
|
||||
Reference in New Issue
Block a user