Merge pull request #307 from dod-ccpo/squash-migrations

Squash migrations
This commit is contained in:
richard-dds 2018-09-21 15:53:39 -04:00 committed by GitHub
commit 3c1de2305c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 573 additions and 1640 deletions

View File

@ -109,7 +109,7 @@ that will automatically log you in as Amanda.
We have a helper script that will seed the database with requests, workspaces and
projects for all of the test users:
`pipenv run python script/seed.py`
`pipenv run python script/seed_sample.py`
## Testing

View File

@ -1,79 +0,0 @@
"""add request revision
Revision ID: 04fe150da553
Revises: 2c2a2af465d3
Create Date: 2018-08-30 13:28:16.928946
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ARRAY as Array
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '04fe150da553'
down_revision = '2c2a2af465d3'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('request_revisions',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('am_poc', sa.Boolean(), nullable=True),
sa.Column('dodid_poc', sa.String(), nullable=True),
sa.Column('email_poc', sa.String(), nullable=True),
sa.Column('fname_poc', sa.String(), nullable=True),
sa.Column('lname_poc', sa.String(), nullable=True),
sa.Column('jedi_usage', sa.String(), nullable=True),
sa.Column('start_date', sa.Date(), nullable=True),
sa.Column('cloud_native', sa.String(), nullable=True),
sa.Column('dollar_value', sa.Integer(), nullable=True),
sa.Column('dod_component', sa.String(), nullable=True),
sa.Column('data_transfers', sa.String(), nullable=True),
sa.Column('expected_completion_date', sa.String(), nullable=True),
sa.Column('jedi_migration', sa.String(), nullable=True),
sa.Column('num_software_systems', sa.Integer(), nullable=True),
sa.Column('number_user_sessions', sa.Integer(), nullable=True),
sa.Column('average_daily_traffic', sa.Integer(), nullable=True),
sa.Column('engineering_assessment', sa.String(), nullable=True),
sa.Column('technical_support_team', sa.String(), nullable=True),
sa.Column('estimated_monthly_spend', sa.Integer(), nullable=True),
sa.Column('average_daily_traffic_gb', sa.Integer(), nullable=True),
sa.Column('rationalization_software_systems', sa.String(), nullable=True),
sa.Column('organization_providing_assistance', sa.String(), nullable=True),
sa.Column('citizenship', sa.String(), nullable=True),
sa.Column('designation', sa.String(), nullable=True),
sa.Column('phone_number', sa.String(), nullable=True),
sa.Column('email_request', sa.String(), nullable=True),
sa.Column('fname_request', sa.String(), nullable=True),
sa.Column('lname_request', sa.String(), nullable=True),
sa.Column('service_branch', sa.String(), nullable=True),
sa.Column('date_latest_training', sa.Date(), nullable=True),
sa.Column('pe_id', sa.String(), nullable=True),
sa.Column('task_order_number', sa.String(), nullable=True),
sa.Column('fname_co', sa.String(), nullable=True),
sa.Column('lname_co', sa.String(), nullable=True),
sa.Column('email_co', sa.String(), nullable=True),
sa.Column('office_co', sa.String(), nullable=True),
sa.Column('fname_cor', sa.String(), nullable=True),
sa.Column('lname_cor', sa.String(), nullable=True),
sa.Column('email_cor', sa.String(), nullable=True),
sa.Column('office_cor', sa.String(), nullable=True),
sa.Column('uii_ids', Array(sa.String()), nullable=True),
sa.Column('treasury_code', sa.String(), nullable=True),
sa.Column('ba_code', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('request_revisions')
# ### end Alembic commands ###

View File

@ -1,43 +0,0 @@
"""rename request creator
Revision ID: 05d6272bdb43
Revises: 77b065750596
Create Date: 2018-08-07 20:21:22.559283
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '05d6272bdb43'
down_revision = '77b065750596'
branch_labels = None
depends_on = None
def upgrade():
db = op.get_bind()
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('requests', sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True))
op.create_foreign_key('requests_user_id_fk', 'requests', 'users', ['user_id'], ['id'])
# ### end Alembic commands ###
db.execute("UPDATE requests SET user_id = creator")
op.alter_column('requests', 'user_id', nullable=False)
op.drop_column('requests', 'creator')
def downgrade():
db = op.get_bind()
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('requests', sa.Column('creator', postgresql.UUID(), autoincrement=False, nullable=True))
op.drop_constraint('requests_user_id_fk', 'requests', type_='foreignkey')
# ### end Alembic commands ###
db.execute("UPDATE requests SET creator = user_id")
op.drop_column('requests', 'user_id')

View File

@ -1,32 +0,0 @@
"""make status event relation to revision non-nullable
Revision ID: 06aa23166ca9
Revises: e66a49285f23
Create Date: 2018-09-04 15:03:20.299607
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '06aa23166ca9'
down_revision = 'e66a49285f23'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('request_status_events', 'request_revision_id',
existing_type=postgresql.UUID(),
nullable=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('request_status_events', 'request_revision_id',
existing_type=postgresql.UUID(),
nullable=True)
# ### end Alembic commands ###

View File

@ -1,30 +0,0 @@
"""add request -> task order relationship
Revision ID: 0845b2f0f401
Revises: 875e4b8a05fc
Create Date: 2018-08-22 09:58:43.770718
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0845b2f0f401'
down_revision = '875e4b8a05fc'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('requests', sa.Column('task_order_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'requests', 'task_order', ['task_order_id'], ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'requests', type_='foreignkey')
op.drop_column('requests', 'task_order_id')
# ### end Alembic commands ###

View File

@ -1,79 +0,0 @@
"""remove revisions body column
Revision ID: 090e1bd0d7ce
Revises: a903ebe91ad5
Create Date: 2018-08-31 12:08:52.376027
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects import postgresql
from atst.models.request import Request
from atst.utils import deep_merge
from atst.domain.requests import create_revision_from_request_body
from atst.domain.task_orders import TaskOrders
# revision identifiers, used by Alembic.
revision = '090e1bd0d7ce'
down_revision = 'a903ebe91ad5'
branch_labels = None
depends_on = None
def delete_two_deep(body, key1, key2):
result = body.get(key1, {}).get(key2)
if result:
del(body[key1][key2])
return body
TASK_ORDER_DATA = TaskOrders.TASK_ORDER_DATA + ["task_order_id", "csrf_token"]
def create_revision(body):
financials = body.get("financial_verification")
if financials:
for column in TASK_ORDER_DATA:
if column in financials:
del(financials[column])
return create_revision_from_request_body(body)
def massaged_revision(body):
try:
return create_revision(body)
except ValueError:
# some of the data on staging has out-of-range dates like "02/29/2019";
# we don't know how to coerce them to valid dates, so we remove those
# fields.
body = delete_two_deep(body, "details_of_use", "start_date")
body = delete_two_deep(body, "information_about_you", "date_latest_training")
return create_revision(body)
from uuid import UUID
def upgrade():
Session = sessionmaker(bind=op.get_bind())
session = Session()
for request in session.query(Request).all():
(body,) = session.execute("SELECT body from requests WHERE id='{}'".format(request.id)).fetchone()
revision = massaged_revision(body)
request.revisions.append(revision)
session.add(revision)
session.add(request)
session.commit()
op.drop_column('requests', 'body')
def downgrade():
op.add_column('requests', sa.Column('body', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True))

View File

@ -1,30 +0,0 @@
"""add task order association to attachments
Revision ID: 14cd800904bc
Revises: d7db8fd35b41
Create Date: 2018-08-24 11:28:30.894412
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '14cd800904bc'
down_revision = 'd7db8fd35b41'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('task_order', sa.Column('attachment_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'task_order', 'attachments', ['attachment_id'], ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'task_order', type_='foreignkey')
op.drop_column('task_order', 'attachment_id')
# ### end Alembic commands ###

View File

@ -1,38 +0,0 @@
"""update_user_from_authnid
Revision ID: 1f57f784ed5b
Revises: 55ba973d08b9
Create Date: 2018-07-30 16:53:05.945005
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '1f57f784ed5b'
down_revision = '55ba973d08b9'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('dod_id', sa.String(), nullable=True))
op.add_column('users', sa.Column('email', sa.String(), nullable=True))
op.add_column('users', sa.Column('first_name', sa.String(), nullable=True))
op.add_column('users', sa.Column('last_name', sa.String(), nullable=True))
op.create_unique_constraint('users_dod_id_unique', 'users', ['dod_id'])
op.create_unique_constraint('users_email_unqiue', 'users', ['email'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('users_dod_id_unique', 'users', type_='unique')
op.drop_constraint('users_email_unqiue', 'users', type_='unique')
op.drop_column('users', 'last_name')
op.drop_column('users', 'first_name')
op.drop_column('users', 'email')
op.drop_column('users', 'dod_id')
# ### end Alembic commands ###

View File

@ -1,36 +0,0 @@
"""add request.internal_comments
Revision ID: 2572be7fb7fc
Revises: dea6b8e09d63
Create Date: 2018-09-11 15:28:27.252248
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '2572be7fb7fc'
down_revision = 'dea6b8e09d63'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('request_internal_comments',
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('text', sa.String(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('request_internal_comments')
# ### end Alembic commands ###

View File

@ -1,44 +0,0 @@
"""add PE numbers
Revision ID: 2c2a2af465d3
Revises: 14cd800904bc
Create Date: 2018-08-27 16:26:51.707146
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import insert
from urllib.request import urlopen
import csv
from atst.app import make_config
from atst.models.pe_number import PENumber
# revision identifiers, used by Alembic.
revision = '2c2a2af465d3'
down_revision = '14cd800904bc'
branch_labels = None
depends_on = None
def get_pe_numbers(url):
response = urlopen(url)
t = response.read().decode("utf-8")
return list(csv.reader(t.split("\r\n")))
def upgrade():
config = make_config()
pe_numbers = get_pe_numbers(config["PE_NUMBER_CSV_URL"])
db = op.get_bind()
stmt = insert(PENumber).values(pe_numbers)
do_update = stmt.on_conflict_do_update(
index_elements=["number"], set_=dict(description=stmt.excluded.description)
)
db.execute(do_update)
def downgrade():
db = op.get_bind()
db.execute("TRUNCATE TABLE pe_number")

View File

@ -0,0 +1,279 @@
"""initial
Revision ID: 359caaf8c5f1
Revises:
Create Date: 2018-09-20 10:25:44.438679
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '359caaf8c5f1'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
connection = op.get_bind()
connection.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"')
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('attachments',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('filename', sa.String(), nullable=False),
sa.Column('object_name', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('object_name')
)
op.create_table('pe_numbers',
sa.Column('number', sa.String(), nullable=False),
sa.Column('description', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('number')
)
op.create_table('roles',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('description', sa.String(), nullable=False),
sa.Column('permissions', postgresql.ARRAY(sa.String()), server_default='{}', nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_roles_name'), 'roles', ['name'], unique=True)
op.create_index(op.f('ix_roles_permissions'), 'roles', ['permissions'], unique=False)
op.create_table('task_orders',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('number', sa.String(), nullable=True),
sa.Column('source', sa.Enum('MANUAL', 'EDA', name='source', native_enum=False), nullable=True),
sa.Column('funding_type', sa.Enum('RDTE', 'OM', 'PROC', 'OTHER', name='fundingtype', native_enum=False), nullable=True),
sa.Column('funding_type_other', sa.String(), nullable=True),
sa.Column('clin_0001', sa.Integer(), nullable=True),
sa.Column('clin_0003', sa.Integer(), nullable=True),
sa.Column('clin_1001', sa.Integer(), nullable=True),
sa.Column('clin_1003', sa.Integer(), nullable=True),
sa.Column('clin_2001', sa.Integer(), nullable=True),
sa.Column('clin_2003', sa.Integer(), nullable=True),
sa.Column('expiration_date', sa.Date(), nullable=True),
sa.Column('attachment_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['attachment_id'], ['attachments.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('number')
)
op.create_table('users',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('username', sa.String(), nullable=True),
sa.Column('atat_role_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('dod_id', sa.String(), nullable=False),
sa.Column('first_name', sa.String(), nullable=True),
sa.Column('last_name', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['atat_role_id'], ['roles.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('dod_id'),
sa.UniqueConstraint('email')
)
op.create_table('request_reviews',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('comment', sa.String(), nullable=True),
sa.Column('fname_mao', sa.String(), nullable=True),
sa.Column('lname_mao', sa.String(), nullable=True),
sa.Column('email_mao', sa.String(), nullable=True),
sa.Column('phone_mao', sa.String(), nullable=True),
sa.Column('fname_ccpo', sa.String(), nullable=True),
sa.Column('lname_ccpo', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('requests',
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('task_order_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['task_order_id'], ['task_orders.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('request_internal_comments',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('text', sa.String(), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('request_revisions',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('sequence', sa.BigInteger(), nullable=False),
sa.Column('am_poc', sa.Boolean(), nullable=True),
sa.Column('dodid_poc', sa.String(), nullable=True),
sa.Column('email_poc', sa.String(), nullable=True),
sa.Column('fname_poc', sa.String(), nullable=True),
sa.Column('lname_poc', sa.String(), nullable=True),
sa.Column('jedi_usage', sa.String(), nullable=True),
sa.Column('start_date', sa.Date(), nullable=True),
sa.Column('cloud_native', sa.String(), nullable=True),
sa.Column('dollar_value', sa.Integer(), nullable=True),
sa.Column('dod_component', sa.String(), nullable=True),
sa.Column('data_transfers', sa.String(), nullable=True),
sa.Column('expected_completion_date', sa.String(), nullable=True),
sa.Column('jedi_migration', sa.String(), nullable=True),
sa.Column('num_software_systems', sa.Integer(), nullable=True),
sa.Column('number_user_sessions', sa.Integer(), nullable=True),
sa.Column('average_daily_traffic', sa.Integer(), nullable=True),
sa.Column('engineering_assessment', sa.String(), nullable=True),
sa.Column('technical_support_team', sa.String(), nullable=True),
sa.Column('estimated_monthly_spend', sa.Integer(), nullable=True),
sa.Column('average_daily_traffic_gb', sa.Integer(), nullable=True),
sa.Column('rationalization_software_systems', sa.String(), nullable=True),
sa.Column('organization_providing_assistance', sa.String(), nullable=True),
sa.Column('name', sa.String(), nullable=True),
sa.Column('citizenship', sa.String(), nullable=True),
sa.Column('designation', sa.String(), nullable=True),
sa.Column('phone_number', sa.String(), nullable=True),
sa.Column('email_request', sa.String(), nullable=True),
sa.Column('fname_request', sa.String(), nullable=True),
sa.Column('lname_request', sa.String(), nullable=True),
sa.Column('service_branch', sa.String(), nullable=True),
sa.Column('date_latest_training', sa.Date(), nullable=True),
sa.Column('pe_id', sa.String(), nullable=True),
sa.Column('task_order_number', sa.String(), nullable=True),
sa.Column('fname_co', sa.String(), nullable=True),
sa.Column('lname_co', sa.String(), nullable=True),
sa.Column('email_co', sa.String(), nullable=True),
sa.Column('office_co', sa.String(), nullable=True),
sa.Column('fname_cor', sa.String(), nullable=True),
sa.Column('lname_cor', sa.String(), nullable=True),
sa.Column('email_cor', sa.String(), nullable=True),
sa.Column('office_cor', sa.String(), nullable=True),
sa.Column('uii_ids', postgresql.ARRAY(sa.String()), nullable=True),
sa.Column('treasury_code', sa.String(), nullable=True),
sa.Column('ba_code', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('workspaces',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('projects',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('description', sa.String(), nullable=False),
sa.Column('workspace_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('request_status_events',
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('new_status', sa.Enum('STARTED', 'SUBMITTED', 'PENDING_FINANCIAL_VERIFICATION', 'PENDING_CCPO_ACCEPTANCE', 'PENDING_CCPO_APPROVAL', 'CHANGES_REQUESTED', 'CHANGES_REQUESTED_TO_FINVER', 'APPROVED', 'EXPIRED', 'DELETED', name='requeststatus', native_enum=False), nullable=True),
sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('sequence', sa.BigInteger(), nullable=False),
sa.Column('request_revision_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('request_review_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['request_review_id'], ['request_reviews.id'], ),
sa.ForeignKeyConstraint(['request_revision_id'], ['request_revisions.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('workspace_roles',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('workspace_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('role_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['role_id'], ['roles.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_workspace_roles_user_id'), 'workspace_roles', ['user_id'], unique=False)
op.create_index(op.f('ix_workspace_roles_workspace_id'), 'workspace_roles', ['workspace_id'], unique=False)
op.create_index('workspace_role_user_workspace', 'workspace_roles', ['user_id', 'workspace_id'], unique=True)
op.create_table('environments',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('environment_roles',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('environment_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('role', sa.String(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index('environments_role_user_environment', 'environment_roles', ['user_id', 'environment_id'], unique=True)
# ### end Alembic commands ###
connection.execute(
"CREATE SEQUENCE request_status_events_sequence_seq OWNED BY request_status_events.sequence;"
)
connection.execute(
"CREATE SEQUENCE request_revisions_sequence_seq OWNED BY request_revisions.sequence;"
)
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('environments_role_user_environment', table_name='environment_roles')
op.drop_table('environment_roles')
op.drop_table('environments')
op.drop_index('workspace_role_user_workspace', table_name='workspace_roles')
op.drop_index(op.f('ix_workspace_roles_workspace_id'), table_name='workspace_roles')
op.drop_index(op.f('ix_workspace_roles_user_id'), table_name='workspace_roles')
op.drop_table('workspace_roles')
op.drop_table('request_status_events')
op.drop_table('projects')
op.drop_table('workspaces')
op.drop_table('request_revisions')
op.drop_table('request_internal_comments')
op.drop_table('requests')
op.drop_table('request_reviews')
op.drop_table('users')
op.drop_table('task_orders')
op.drop_index(op.f('ix_roles_permissions'), table_name='roles')
op.drop_index(op.f('ix_roles_name'), table_name='roles')
op.drop_table('roles')
op.drop_table('pe_numbers')
op.drop_table('attachments')
# ### end Alembic commands ###
connection = op.get_bind()
connection.execute('DROP EXTENSION IF EXISTS "uuid-ossp"')

View File

@ -1,37 +0,0 @@
"""add workspaces table
Revision ID: 4be312655ceb
Revises: 05d6272bdb43
Create Date: 2018-08-16 09:25:19.888549
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '4be312655ceb'
down_revision = '05d6272bdb43'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('workspaces',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('task_order_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ),
sa.ForeignKeyConstraint(['task_order_id'], ['task_order.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('workspaces')
# ### end Alembic commands ###

View File

@ -1,43 +0,0 @@
"""add edit workspace information permission
Revision ID: 4c425f17bfe8
Revises: 2572be7fb7fc
Create Date: 2018-09-17 13:14:38.781744
"""
from alembic import op
from sqlalchemy.orm.session import Session
from atst.models.role import Role
from atst.models.permissions import Permissions
# revision identifiers, used by Alembic.
revision = '4c425f17bfe8'
down_revision = '2572be7fb7fc'
branch_labels = None
depends_on = None
def upgrade():
session = Session(bind=op.get_bind())
owner_and_admin = session.query(Role).filter(Role.name.in_(["owner", "admin"])).all()
for role in owner_and_admin:
role.add_permission(Permissions.EDIT_WORKSPACE_INFORMATION)
session.add(role)
session.flush()
session.commit()
def downgrade():
session = Session(bind=op.get_bind())
owner_and_admin = session.query(Role).filter(Role.name.in_(["owner", "admin"])).all()
for role in owner_and_admin:
role.remove_permission(Permissions.EDIT_WORKSPACE_INFORMATION)
session.add(role)
session.flush()
session.commit()

View File

@ -1,37 +0,0 @@
"""add_default_atat_role
Revision ID: 4ea5917e7781
Revises: 96a9f3537996
Create Date: 2018-07-30 13:51:29.576931
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm.session import Session
# revision identifiers, used by Alembic.
revision = '4ea5917e7781'
down_revision = '96a9f3537996'
branch_labels = None
depends_on = None
from atst.models.role import Role
from atst.models.permissions import Permissions
def upgrade():
session = Session(bind=op.get_bind())
mission_owner_role = Role(
name='default',
description='',
permissions=[
Permissions.REQUEST_JEDI_WORKSPACE,
]
)
session.add(mission_owner_role)
session.commit()
def downgrade():
pass

View File

@ -1,62 +0,0 @@
"""add_authz_models
Revision ID: 4ede1e3e50d1
Revises: b5b17d465166
Create Date: 2018-07-30 11:34:12.016857
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '4ede1e3e50d1'
down_revision = 'b5b17d465166'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('roles',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('description', sa.String(), nullable=True),
sa.Column('permissions', postgresql.ARRAY(sa.String()), server_default='{}', nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_roles_name'), 'roles', ['name'], unique=True)
op.create_index(op.f('ix_roles_permissions'), 'roles', ['permissions'], unique=False)
op.create_table('users',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('username', sa.String(), nullable=True),
sa.Column('atat_role_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['atat_role_id'], ['roles.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('workspace_role',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('workspace_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('role_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['role_id'], ['roles.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_workspace_role_user_id'), 'workspace_role', ['user_id'], unique=False)
op.create_index(op.f('ix_workspace_role_workspace_id'), 'workspace_role', ['workspace_id'], unique=False)
op.create_index('workspace_role_user_workspace', 'workspace_role', ['user_id', 'workspace_id'], unique=True)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('workspace_role_user_workspace', table_name='workspace_role')
op.drop_index(op.f('ix_workspace_role_workspace_id'), table_name='workspace_role')
op.drop_index(op.f('ix_workspace_role_user_id'), table_name='workspace_role')
op.drop_table('workspace_role')
op.drop_table('users')
op.drop_index(op.f('ix_roles_permissions'), table_name='roles')
op.drop_index(op.f('ix_roles_name'), table_name='roles')
op.drop_table('roles')
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""add expiration date to task order
Revision ID: 4f4defb7b440
Revises: 4c425f17bfe8
Create Date: 2018-09-17 15:22:33.240310
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '4f4defb7b440'
down_revision = '4c425f17bfe8'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('task_order', sa.Column('expiration_date', sa.Date(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('task_order', 'expiration_date')
# ### end Alembic commands ###

View File

@ -1,30 +0,0 @@
"""request_reviews comment column name
Revision ID: 53ab3edd334b
Revises: 777ded5c57a0
Create Date: 2018-09-10 13:29:02.648359
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '53ab3edd334b'
down_revision = '777ded5c57a0'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('request_reviews', sa.Column('comment', sa.String(), nullable=True))
op.drop_column('request_reviews', 'comments')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('request_reviews', sa.Column('comments', sa.VARCHAR(), autoincrement=False, nullable=True))
op.drop_column('request_reviews', 'comment')
# ### end Alembic commands ###

View File

@ -1,38 +0,0 @@
"""add_fundz_models
Revision ID: 55ba973d08b9
Revises: 4ea5917e7781
Create Date: 2018-07-30 14:43:34.099799
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '55ba973d08b9'
down_revision = '4ea5917e7781'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('pe_number',
sa.Column('number', sa.String(), nullable=False),
sa.Column('description', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('number')
)
op.create_table('task_order',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('number', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('task_order')
op.drop_table('pe_number')
# ### end Alembic commands ###

View File

@ -1,36 +0,0 @@
"""bigint for request review id
Revision ID: 777ded5c57a0
Revises: 7bdb2055d7c7
Create Date: 2018-09-10 13:24:36.328610
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '777ded5c57a0'
down_revision = '7bdb2055d7c7'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('request_reviews', 'id',
existing_type=sa.Integer(),
type_=sa.BigInteger(),
nullable=False)
pass
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('request_reviews', 'id',
existing_type=sa.BigInteger(),
type_=sa.Integer(),
nullable=False)
pass
# ### end Alembic commands ###

View File

@ -1,49 +0,0 @@
"""new request statuses
Revision ID: 77b065750596
Revises: 1f57f784ed5b
Create Date: 2018-08-07 16:42:11.502361
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm.session import sessionmaker
from atst.models.request_status_event import RequestStatus
# revision identifiers, used by Alembic.
revision = '77b065750596'
down_revision = '1f57f784ed5b'
branch_labels = None
depends_on = None
def upgrade():
"""
Update all existing request statuses so that the state of the
table reflects the statuses listed in RequestStatus.
This involves fixing the casing on existing statuses, and
deleting statuses that have no match.
"""
db = op.get_bind()
status_events = db.execute("SELECT * FROM request_status_events").fetchall()
for status_event in status_events:
try:
status = RequestStatus[status_event["new_status"].upper()]
query = sa.text("""
UPDATE request_status_events
SET new_status = :status
WHERE id = :id"""
)
db.execute(query, id=status_event["id"], status=status.name)
except KeyError:
query = sa.text("DELETE FROM request_status_events WHERE id = :id")
db.execute(query, id=status_event["id"])
def downgrade():
pass

View File

@ -1,46 +0,0 @@
"""add request review table
Revision ID: 7bdb2055d7c7
Revises: ad30159ef19b
Create Date: 2018-09-06 15:15:40.666840
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '7bdb2055d7c7'
down_revision = 'ad30159ef19b'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('request_reviews',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('comments', sa.String(), nullable=True),
sa.Column('fname_mao', sa.String(), nullable=True),
sa.Column('lname_mao', sa.String(), nullable=True),
sa.Column('email_mao', sa.String(), nullable=True),
sa.Column('phone_mao', sa.String(), nullable=True),
sa.Column('fname_ccpo', sa.String(), nullable=True),
sa.Column('lname_ccpo', sa.String(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.add_column('request_status_events', sa.Column('request_review_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'request_status_events', 'request_reviews', ['request_review_id'], ['id'])
op.create_foreign_key(None, 'request_reviews', 'users', ['user_id'], ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'request_status_events', type_='foreignkey')
op.drop_constraint(None, 'request_reviews', type_='foreignkey')
op.drop_column('request_status_events', 'request_review_id')
op.drop_table('request_reviews')
# ### end Alembic commands ###

View File

@ -1,44 +0,0 @@
"""add additional task order fields
Revision ID: 875e4b8a05fc
Revises: f36f130622b9
Create Date: 2018-08-21 15:52:46.636928
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '875e4b8a05fc'
down_revision = 'f36f130622b9'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('task_order', sa.Column('clin_0001', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('clin_0003', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('clin_1001', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('clin_1003', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('clin_2001', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('clin_2003', sa.Integer(), nullable=True))
op.add_column('task_order', sa.Column('funding_type', sa.String(), nullable=True))
op.add_column('task_order', sa.Column('funding_type_other', sa.String(), nullable=True))
op.add_column('task_order', sa.Column('source', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('task_order', 'source')
op.drop_column('task_order', 'funding_type_other')
op.drop_column('task_order', 'funding_type')
op.drop_column('task_order', 'clin_2003')
op.drop_column('task_order', 'clin_2001')
op.drop_column('task_order', 'clin_1003')
op.drop_column('task_order', 'clin_1001')
op.drop_column('task_order', 'clin_0003')
op.drop_column('task_order', 'clin_0001')
# ### end Alembic commands ###

View File

@ -1,172 +0,0 @@
"""add_roles_and_permissions
Revision ID: 96a9f3537996
Revises: 4ede1e3e50d1
Create Date: 2018-07-30 13:48:31.325234
"""
import os
import sys
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm.session import Session
from atst.models.role import Role
from atst.models.permissions import Permissions
# revision identifiers, used by Alembic.
revision = '96a9f3537996'
down_revision = '4ede1e3e50d1'
branch_labels = None
depends_on = None
def upgrade():
session = Session(bind=op.get_bind())
roles = [
Role(
name='ccpo',
description='',
permissions=[
Permissions.VIEW_ORIGINAL_JEDI_REQEUST,
Permissions.REVIEW_AND_APPROVE_JEDI_WORKSPACE_REQUEST,
Permissions.MODIFY_ATAT_ROLE_PERMISSIONS,
Permissions.CREATE_CSP_ROLE,
Permissions.DELETE_CSP_ROLE,
Permissions.DEACTIVE_CSP_ROLE,
Permissions.MODIFY_CSP_ROLE_PERMISSIONS,
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.DEACTIVATE_WORKSPACE,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.TRANSFER_OWNERSHIP_OF_WORKSPACE,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
Permissions.ADD_TAG_TO_WORKSPACE,
Permissions.REMOVE_TAG_FROM_WORKSPACE
]
),
Role(
name='owner',
description='',
permissions=[
Permissions.REQUEST_JEDI_WORKSPACE,
Permissions.VIEW_ORIGINAL_JEDI_REQEUST,
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.DEACTIVATE_WORKSPACE,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
]
),
Role(
name='admin',
description='',
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
]
),
Role(
name='developer',
description='',
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION
]
),
Role(
name='billing_auditor',
description='',
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
]
),
Role(
name='security_auditor',
description='',
permissions=[
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
]
),
]
session.add_all(roles)
session.commit()
def downgrade():
pass

View File

@ -1,30 +0,0 @@
"""workspace timestamps
Revision ID: a2b499a1dd62
Revises: f549c7cee17c
Create Date: 2018-08-17 10:43:13.165829
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'a2b499a1dd62'
down_revision = 'f549c7cee17c'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('workspaces', sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False))
op.add_column('workspaces', sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('workspaces', 'time_updated')
op.drop_column('workspaces', 'time_created')
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""add name to request revision
Revision ID: a496111da617
Revises: 4f4defb7b440
Create Date: 2018-09-18 16:45:59.297289
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'a496111da617'
down_revision = '4f4defb7b440'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('request_revisions', sa.Column('name', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('request_revisions', 'name')
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""add sequence to request revision
Revision ID: a903ebe91ad5
Revises: 04fe150da553
Create Date: 2018-08-30 13:45:35.561657
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'a903ebe91ad5'
down_revision = '04fe150da553'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
db = op.get_bind()
op.add_column('request_revisions', sa.Column('sequence', sa.BigInteger(), nullable=False))
db.execute("CREATE SEQUENCE request_revisions_sequence_seq OWNED BY request_revisions.sequence;")
# ### end Alembic commands ###
def downgrade():
op.drop_column('request_revisions', 'sequence')

View File

@ -1,53 +0,0 @@
"""add view_workspace_members_permission
Revision ID: ad30159ef19b
Revises: 2c2a2af465d3
Create Date: 2018-09-05 11:17:17.204089
"""
from alembic import op
from sqlalchemy.orm.session import Session
from atst.models.role import Role
from atst.models.permissions import Permissions
# revision identifiers, used by Alembic.
revision = 'ad30159ef19b'
down_revision = 'c1d074288e99'
branch_labels = None
depends_on = None
def upgrade():
session = Session(bind=op.get_bind())
all_roles_but_default = session.query(Role).filter(Role.name != "default").all()
for role in all_roles_but_default:
role.add_permission(Permissions.VIEW_WORKSPACE)
session.add(role)
owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo", "admin"])).all()
for role in owner_and_ccpo:
role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS)
session.add(role)
session.flush()
session.commit()
def downgrade():
session = Session(bind=op.get_bind())
all_roles_but_default = session.query(Role).filter(Role.name != "default").all()
for role in all_roles_but_default:
role.remove_permission(Permissions.VIEW_WORKSPACE)
session.add(role)
owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo"])).all()
for role in owner_and_ccpo:
role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS)
session.add(role)
session.flush()
session.commit()

View File

@ -1,47 +0,0 @@
"""requests
Revision ID: b5b17d465166
Revises: ff1c9c02fa61
Create Date: 2018-07-23 14:58:05.044456
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'b5b17d465166'
down_revision = 'ff1c9c02fa61'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('requests',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('creator', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('body', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('request_status_events',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('new_status', sa.String(), nullable=True),
sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('sequence', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
db = op.get_bind()
db.execute("CREATE SEQUENCE request_status_events_sequence_seq OWNED BY request_status_events.sequence;")
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('request_status_events')
op.drop_table('requests')
# ### end Alembic commands ###

View File

@ -1,38 +0,0 @@
"""create environment_roles table
Revision ID: c1d074288e99
Revises: 06aa23166ca9
Create Date: 2018-09-06 13:40:12.332241
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'c1d074288e99'
down_revision = '06aa23166ca9'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('environment_roles',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('environment_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('role', sa.String(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index('environments_role_user_environment', 'environment_roles', ['user_id', 'environment_id'], unique=True)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('environments_role_user_environment', table_name='environment_roles')
op.drop_table('environment_roles')
# ### end Alembic commands ###

View File

@ -1,36 +0,0 @@
"""add attachment table
Revision ID: d7db8fd35b41
Revises: 0845b2f0f401
Create Date: 2018-08-24 11:27:15.317181
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd7db8fd35b41'
down_revision = '0845b2f0f401'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('attachments',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('filename', sa.String(), nullable=True),
sa.Column('object_name', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('object_name')
)
op.create_unique_constraint(None, 'task_order', ['number'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'task_order', type_='unique')
op.drop_table('attachments')
# ### end Alembic commands ###

View File

@ -1,49 +0,0 @@
"""remove view project and environment permissions
Revision ID: dea6b8e09d63
Revises: ad30159ef19b
Create Date: 2018-09-10 11:06:00.017222
"""
from alembic import op
from sqlalchemy.orm.session import Session
from atst.models.role import Role
from atst.models.permissions import Permissions
# revision identifiers, used by Alembic.
revision = "dea6b8e09d63"
down_revision = "53ab3edd334b"
branch_labels = None
depends_on = None
def upgrade():
session = Session(bind=op.get_bind())
priveleged_role_names = ("owner", "admin", "ccpo")
non_priveleged_roles = (
session.query(Role).filter(Role.name.notin_(priveleged_role_names)).all()
)
for role in non_priveleged_roles:
role.remove_permission(Permissions.VIEW_APPLICATION_IN_WORKSPACE)
role.remove_permission(Permissions.VIEW_ENVIRONMENT_IN_APPLICATION)
session.add(role)
session.commit()
def downgrade():
session = Session(bind=op.get_bind())
priveleged_role_names = ("owner", "admin", "ccpo")
non_priveleged_roles = (
session.query(Role).filter(not Role.name.in_(priveleged_role_names)).all()
)
for role in non_priveleged_roles:
role.add_permission(Permissions.VIEW_APPLICATION_IN_WORKSPACE)
role.add_permission(Permissions.VIEW_ENVIRONMENT_IN_APPLICATION)
session.add(role)
session.commit()

View File

@ -1,42 +0,0 @@
"""add relationship between revision and status event
Revision ID: e66a49285f23
Revises: 090e1bd0d7ce
Create Date: 2018-09-04 14:01:31.548665
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects import postgresql
from atst.models.request import Request
# revision identifiers, used by Alembic.
revision = 'e66a49285f23'
down_revision = '090e1bd0d7ce'
branch_labels = None
depends_on = None
from uuid import UUID
def upgrade():
op.add_column('request_status_events', sa.Column('request_revision_id', postgresql.UUID(as_uuid=True)))
op.create_foreign_key(None, 'request_status_events', 'request_revisions', ['request_revision_id'], ['id'])
Session = sessionmaker(bind=op.get_bind())
session = Session()
for request in session.query(Request).all():
for status in request.status_events:
status.revision = request.latest_revision
session.add(status)
session.commit()
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'request_status_events', type_='foreignkey')
op.drop_column('request_status_events', 'request_revision_id')
# ### end Alembic commands ###

View File

@ -1,47 +0,0 @@
"""projects and environments
Revision ID: f064247f2988
Revises: a2b499a1dd62
Create Date: 2018-08-17 11:30:53.684954
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'f064247f2988'
down_revision = 'a2b499a1dd62'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('projects',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('description', sa.String(), nullable=False),
sa.Column('workspace_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('environments',
sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('environments')
op.drop_table('projects')
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""add workspace_role workspace_id fk
Revision ID: f36f130622b9
Revises: f064247f2988
Create Date: 2018-08-20 10:36:23.920881
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'f36f130622b9'
down_revision = 'f064247f2988'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_foreign_key('workspace_role_workspace_id_fk', 'workspace_role', 'workspaces', ['workspace_id'], ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('workspace_role_workspace_id_fk', 'workspace_role', type_='foreignkey')
# ### end Alembic commands ###

View File

@ -1,30 +0,0 @@
"""remove workspaces task order association
Revision ID: f549c7cee17c
Revises: 4be312655ceb
Create Date: 2018-08-16 16:42:48.581510
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'f549c7cee17c'
down_revision = '4be312655ceb'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('workspaces_task_order_id_fkey', 'workspaces', type_='foreignkey')
op.drop_column('workspaces', 'task_order_id')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('workspaces', sa.Column('task_order_id', sa.INTEGER(), autoincrement=False))
op.create_foreign_key('workspaces_task_order_id_fkey', 'workspaces', 'task_order', ['task_order_id'], ['id'])
# ### end Alembic commands ###

View File

@ -1,26 +0,0 @@
"""enable uuid extension
Revision ID: ff1c9c02fa61
Revises:
Create Date: 2018-07-23 14:54:05.422286
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ff1c9c02fa61'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
connection = op.get_bind()
connection.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"')
def downgrade():
connection = op.get_bind()
connection.execute('DROP EXTENSION IF EXISTS "uuid-ossp"')

View File

@ -1,7 +1,7 @@
from sqlalchemy import Column, Integer, String
from sqlalchemy import Column, String
from flask import current_app as app
from atst.models import Base
from atst.models import Base, types, mixins
from atst.database import db
from atst.uploader import UploadError
@ -10,12 +10,12 @@ class AttachmentError(Exception):
pass
class Attachment(Base):
class Attachment(Base, mixins.TimestampsMixin):
__tablename__ = "attachments"
id = Column(Integer, primary_key=True)
filename = Column(String)
object_name = Column(String, unique=True)
id = types.Id()
filename = Column(String, nullable=False)
object_name = Column(String, unique=True, nullable=False)
@classmethod
def attach(cls, fyle):

View File

@ -12,7 +12,7 @@ class Environment(Base, TimestampsMixin):
id = Id()
name = Column(String, nullable=False)
project_id = Column(ForeignKey("projects.id"))
project_id = Column(ForeignKey("projects.id"), nullable=False)
project = relationship("Project")
@property

View File

@ -3,24 +3,25 @@ from sqlalchemy import Index, ForeignKey, Column, String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from atst.models import Base
from .types import Id
from atst.models import Base, types, mixins
class CSPRole(Enum):
NONSENSE_ROLE = "nonesense_role"
class EnvironmentRole(Base):
class EnvironmentRole(Base, mixins.TimestampsMixin):
__tablename__ = "environment_roles"
id = Id()
environment_id = Column(UUID(as_uuid=True), ForeignKey("environments.id"))
id = types.Id()
environment_id = Column(
UUID(as_uuid=True), ForeignKey("environments.id"), nullable=False
)
environment = relationship("Environment", backref="roles")
role = Column(String())
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"))
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
user = relationship("User", backref="environment_roles")

View File

@ -4,7 +4,7 @@ from atst.models import Base
class PENumber(Base):
__tablename__ = "pe_number"
__tablename__ = "pe_numbers"
number = Column(String, primary_key=True)
description = Column(String)

View File

@ -2,8 +2,7 @@ from sqlalchemy import Column, func, ForeignKey
from sqlalchemy.types import DateTime
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models.types import Id
from atst.models import Base, types, mixins
from atst.models.request_status_event import RequestStatus
from atst.utils import first_or_none
from atst.models.request_revision import RequestRevision
@ -25,10 +24,10 @@ def update_dict_with_properties(instance, body, top_level_key, properties):
return body
class Request(Base):
class Request(Base, mixins.TimestampsMixin):
__tablename__ = "requests"
id = Id()
id = types.Id()
time_created = Column(DateTime(timezone=True), server_default=func.now())
status_events = relationship(
"RequestStatusEvent", backref="request", order_by="RequestStatusEvent.sequence"
@ -39,7 +38,7 @@ class Request(Base):
user_id = Column(ForeignKey("users.id"), nullable=False)
creator = relationship("User", backref="owned_requests")
task_order_id = Column(ForeignKey("task_order.id"))
task_order_id = Column(ForeignKey("task_orders.id"))
task_order = relationship("TaskOrder")
revisions = relationship(

View File

@ -1,16 +1,16 @@
from sqlalchemy import Column, BigInteger, String, ForeignKey
from sqlalchemy import Column, String, ForeignKey
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models import Base, types, mixins
class RequestInternalComment(Base):
class RequestInternalComment(Base, mixins.TimestampsMixin):
__tablename__ = "request_internal_comments"
id = Column(BigInteger, primary_key=True)
text = Column(String())
id = types.Id()
text = Column(String(), nullable=False)
user_id = Column(ForeignKey("users.id"), nullable=False)
user = relationship("User")
request_id = Column(ForeignKey("requests.id", ondelete="CASCADE"))
request_id = Column(ForeignKey("requests.id", ondelete="CASCADE"), nullable=False)

View File

@ -1,13 +1,13 @@
from sqlalchemy import Column, BigInteger, String, ForeignKey
from sqlalchemy import Column, String, ForeignKey
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models import Base, mixins, types
class RequestReview(Base):
class RequestReview(Base, mixins.TimestampsMixin):
__tablename__ = "request_reviews"
id = Column(BigInteger, primary_key=True)
id = types.Id()
status = relationship("RequestStatusEvent", uselist=False, back_populates="review")
user_id = Column(ForeignKey("users.id"), nullable=False)

View File

@ -1,11 +1,11 @@
from enum import Enum
from sqlalchemy import Column, func, ForeignKey, Enum as SQLAEnum
from sqlalchemy import Column, ForeignKey, Enum as SQLAEnum
from sqlalchemy.orm import relationship
from sqlalchemy.types import DateTime, BigInteger
from sqlalchemy.types import BigInteger
from sqlalchemy.schema import Sequence
from sqlalchemy.dialects.postgresql import UUID
from atst.models import Base
from atst.models import Base, mixins
from atst.models.types import Id
@ -22,14 +22,15 @@ class RequestStatus(Enum):
DELETED = "Deleted"
class RequestStatusEvent(Base):
class RequestStatusEvent(Base, mixins.TimestampsMixin):
__tablename__ = "request_status_events"
id = Id()
new_status = Column(SQLAEnum(RequestStatus))
time_created = Column(DateTime(timezone=True), server_default=func.now())
new_status = Column(SQLAEnum(RequestStatus, native_enum=False))
request_id = Column(
UUID(as_uuid=True), ForeignKey("requests.id", ondelete="CASCADE")
UUID(as_uuid=True),
ForeignKey("requests.id", ondelete="CASCADE"),
nullable=False,
)
sequence = Column(
BigInteger, Sequence("request_status_events_sequence_seq"), nullable=False

View File

@ -2,17 +2,16 @@ from sqlalchemy import String, Column
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm.attributes import flag_modified
from atst.models import Base
from .types import Id
from atst.models import Base, types, mixins
class Role(Base):
class Role(Base, mixins.TimestampsMixin):
__tablename__ = "roles"
id = Id()
name = Column(String, index=True, unique=True)
description = Column(String)
permissions = Column(ARRAY(String), index=True, server_default="{}")
id = types.Id()
name = Column(String, index=True, unique=True, nullable=False)
description = Column(String, nullable=False)
permissions = Column(ARRAY(String), index=True, server_default="{}", nullable=False)
def add_permission(self, permission):
perms_set = set(self.permissions)

View File

@ -3,7 +3,7 @@ from enum import Enum
from sqlalchemy import Column, Integer, String, ForeignKey, Enum as SQLAEnum, Date
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models import Base, types, mixins
class Source(Enum):
@ -18,13 +18,13 @@ class FundingType(Enum):
OTHER = "OTHER"
class TaskOrder(Base):
__tablename__ = "task_order"
class TaskOrder(Base, mixins.TimestampsMixin):
__tablename__ = "task_orders"
id = Column(Integer, primary_key=True)
id = types.Id()
number = Column(String, unique=True)
source = Column(SQLAEnum(Source))
funding_type = Column(SQLAEnum(FundingType))
source = Column(SQLAEnum(Source, native_enum=False))
funding_type = Column(SQLAEnum(FundingType, native_enum=False))
funding_type_other = Column(String)
clin_0001 = Column(Integer)
clin_0003 = Column(Integer)

View File

@ -2,15 +2,14 @@ from sqlalchemy import String, ForeignKey, Column
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from atst.models import Base
from .types import Id
from atst.models import Base, types, mixins
from atst.models.permissions import Permissions
class User(Base):
class User(Base, mixins.TimestampsMixin):
__tablename__ = "users"
id = Id()
id = types.Id()
username = Column(String)
atat_role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id"))
@ -18,7 +17,7 @@ class User(Base):
workspace_roles = relationship("WorkspaceRole", backref="user")
email = Column(String, unique=True)
dod_id = Column(String, unique=True)
dod_id = Column(String, unique=True, nullable=False)
first_name = Column(String)
last_name = Column(String)

View File

@ -2,21 +2,25 @@ from sqlalchemy import Index, ForeignKey, Column
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models import Base, mixins
from .types import Id
class WorkspaceRole(Base):
__tablename__ = "workspace_role"
class WorkspaceRole(Base, mixins.TimestampsMixin):
__tablename__ = "workspace_roles"
id = Id()
workspace_id = Column(UUID(as_uuid=True), ForeignKey("workspaces.id"), index=True)
workspace_id = Column(
UUID(as_uuid=True), ForeignKey("workspaces.id"), index=True, nullable=False
)
workspace = relationship("Workspace", back_populates="roles")
role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id"))
role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id"), nullable=False)
role = relationship("Role")
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), index=True)
user_id = Column(
UUID(as_uuid=True), ForeignKey("users.id"), index=True, nullable=False
)
Index(

@ -1 +1 @@
Subproject commit c55d1eb5db0255784e46aec1006e4419465ef945
Subproject commit 0a8165c27591cac67959b1f6aff8799af8933e98

View File

@ -16,11 +16,6 @@ def get_pe_numbers(url):
t = response.read().decode("utf-8")
return list(csv.reader(t.split("\r\n")))
def make_pe_number_repo(config):
deps = make_deps(config)
db = deps["db_session"]
return PENumbers(db)
if __name__ == "__main__":
config = make_config()
url = config['PE_NUMBER_CSV_URL']

165
script/seed_roles.py Normal file
View File

@ -0,0 +1,165 @@
# Add root project dir to the python path
import os
import sys
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(parent_dir)
from sqlalchemy.orm.exc import NoResultFound
from atst.app import make_config, make_app
from atst.database import db
from atst.models import Role, Permissions
roles = [
Role(
name="ccpo",
description="",
permissions=[
Permissions.VIEW_ORIGINAL_JEDI_REQEUST,
Permissions.REVIEW_AND_APPROVE_JEDI_WORKSPACE_REQUEST,
Permissions.MODIFY_ATAT_ROLE_PERMISSIONS,
Permissions.CREATE_CSP_ROLE,
Permissions.DELETE_CSP_ROLE,
Permissions.DEACTIVE_CSP_ROLE,
Permissions.MODIFY_CSP_ROLE_PERMISSIONS,
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.DEACTIVATE_WORKSPACE,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.TRANSFER_OWNERSHIP_OF_WORKSPACE,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_WORKSPACE_MEMBERS,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
Permissions.ADD_TAG_TO_WORKSPACE,
Permissions.REMOVE_TAG_FROM_WORKSPACE,
],
),
Role(
name="owner",
description="",
permissions=[
Permissions.REQUEST_JEDI_WORKSPACE,
Permissions.VIEW_ORIGINAL_JEDI_REQEUST,
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.DEACTIVATE_WORKSPACE,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_WORKSPACE_MEMBERS,
Permissions.EDIT_WORKSPACE_INFORMATION,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
],
),
Role(
name="admin",
description="",
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.ADD_AND_ASSIGN_CSP_ROLES,
Permissions.REMOVE_CSP_ROLES,
Permissions.REQUEST_NEW_CSP_ROLE,
Permissions.ASSIGN_AND_UNASSIGN_ATAT_ROLE,
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_WORKSPACE_MEMBERS,
Permissions.EDIT_WORKSPACE_INFORMATION,
Permissions.ADD_APPLICATION_IN_WORKSPACE,
Permissions.DELETE_APPLICATION_IN_WORKSPACE,
Permissions.DEACTIVATE_APPLICATION_IN_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
Permissions.RENAME_APPLICATION_IN_WORKSPACE,
Permissions.ADD_ENVIRONMENT_IN_APPLICATION,
Permissions.DELETE_ENVIRONMENT_IN_APPLICATION,
Permissions.DEACTIVATE_ENVIRONMENT_IN_APPLICATION,
Permissions.VIEW_ENVIRONMENT_IN_APPLICATION,
Permissions.RENAME_ENVIRONMENT_IN_APPLICATION,
],
),
Role(
name="developer",
description="",
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE
],
),
Role(
name="billing_auditor",
description="",
permissions=[
Permissions.VIEW_USAGE_REPORT,
Permissions.VIEW_USAGE_DOLLARS,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
],
),
Role(
name="security_auditor",
description="",
permissions=[
Permissions.VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS,
Permissions.VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS,
Permissions.VIEW_ATAT_PERMISSIONS,
Permissions.VIEW_WORKSPACE,
Permissions.VIEW_APPLICATION_IN_WORKSPACE,
],
),
Role(
name="default", description="", permissions=[Permissions.REQUEST_JEDI_WORKSPACE]
),
]
def seed_roles():
for role in roles:
try:
existing_role = db.session.query(Role).filter_by(name=role.name).one()
existing_role.description = role.description
existing_role.permissions = role.permissions
db.session.add(existing_role)
print("Updated existing role {}".format(existing_role.name))
except NoResultFound:
db.session.add(role)
print("Added new role {}".format(role.name))
db.session.commit()
if __name__ == "__main__":
config = make_config()
app = make_app(config)
with app.app_context():
seed_roles()

View File

@ -7,5 +7,7 @@ source "$(dirname "${0}")"/../script/include/global_header.inc.sh
# Before starting the server, apply any pending migrations to the DB
migrate_db
seed_db
# Launch UWSGI
run_command "uwsgi --ini ${UWSGI_CONFIG_FULLPATH}"

View File

@ -1,9 +1,10 @@
from atst.domain.projects import Projects
from tests.factories import WorkspaceFactory
from atst.domain.workspaces import Workspaces
from tests.factories import RequestFactory
def test_create_project_with_multiple_environments():
workspace = WorkspaceFactory.create()
workspace = Workspaces.create(RequestFactory.create())
project = Projects.create(
workspace.owner, workspace, "My Test Project", "Test", ["dev", "prod"]
)

View File

@ -8,13 +8,13 @@ DOD_ID = "my_dod_id"
def test_create_user():
user = Users.create("developer")
user = Users.create("developer", dod_id=DOD_ID)
assert user.atat_role.name == "developer"
def test_create_user_with_nonexistent_role():
with pytest.raises(NotFoundError):
Users.create("nonexistent")
Users.create("nonexistent", dod_id=DOD_ID)
def test_get_or_create_nonexistent_user():
@ -29,13 +29,13 @@ def test_get_or_create_existing_user():
def test_get_user():
new_user = Users.create("developer")
new_user = Users.create("developer", dod_id=DOD_ID)
user = Users.get(new_user.id)
assert user.id == new_user.id
def test_get_nonexistent_user():
Users.create("developer")
Users.create("developer", dod_id=DOD_ID)
with pytest.raises(NotFoundError):
Users.get(uuid4())
@ -47,19 +47,19 @@ def test_get_user_by_dod_id():
def test_update_user():
new_user = Users.create("developer")
new_user = Users.create("developer", dod_id=DOD_ID)
updated_user = Users.update(new_user.id, "ccpo")
assert updated_user.atat_role.name == "ccpo"
def test_update_nonexistent_user():
Users.create("developer")
Users.create("developer", dod_id=DOD_ID)
with pytest.raises(NotFoundError):
Users.update(uuid4(), "ccpo")
def test_update_existing_user_with_nonexistent_role():
new_user = Users.create("developer")
new_user = Users.create("developer", dod_id=DOD_ID)
with pytest.raises(NotFoundError):
Users.update(new_user.id, "nonexistent")

View File

@ -1,23 +1,26 @@
from atst.domain.workspace_users import WorkspaceUsers
from atst.domain.users import Users
from tests.factories import WorkspaceFactory
from tests.factories import WorkspaceFactory, UserFactory
def test_can_create_new_workspace_user():
workspace = WorkspaceFactory.create()
new_user = Users.create("developer")
new_user = UserFactory.create()
workspace_user_dicts = [{"id": new_user.id, "workspace_role": "owner"}]
workspace_users = WorkspaceUsers.add_many(workspace.id, workspace_user_dicts)
assert workspace_users[0].user.id == new_user.id
assert workspace_users[0].user.atat_role.name == "developer"
assert workspace_users[0].workspace_role.role.name == "owner"
assert workspace_users[0].user.atat_role.name == new_user.atat_role.name
assert (
workspace_users[0].workspace_role.role.name
== new_user.workspace_roles[0].role.name
)
def test_can_update_existing_workspace_user():
workspace = WorkspaceFactory.create()
new_user = Users.create("developer")
new_user = UserFactory.create()
WorkspaceUsers.add_many(
workspace.id, [{"id": new_user.id, "workspace_role": "owner"}]
@ -26,5 +29,8 @@ def test_can_update_existing_workspace_user():
workspace.id, [{"id": new_user.id, "workspace_role": "developer"}]
)
assert workspace_users[0].user.id == new_user.id
assert workspace_users[0].workspace_role.role.name == "developer"
assert workspace_users[0].user.atat_role.name == new_user.atat_role.name
assert (
workspace_users[0].workspace_role.role.name
== new_user.workspace_roles[0].role.name
)

View File

@ -27,6 +27,8 @@ class RoleFactory(Base):
class Meta:
model = Role
name = factory.Faker("job")
description = "This is a test role."
permissions = []

View File

@ -80,38 +80,36 @@ def test_annual_spend():
def test_reviews():
request = RequestFactory.create()
ccpo = UserFactory.from_atat_role("ccpo")
request.status_events = [
RequestStatusEventFactory.create(
revision=request.latest_revision,
review=RequestReviewFactory.create(reviewer=ccpo),
),
RequestStatusEventFactory.create(
revision=request.latest_revision,
review=RequestReviewFactory.create(reviewer=ccpo),
),
RequestStatusEventFactory.create(revision=request.latest_revision),
]
RequestStatusEventFactory.create(
request=request,
revision=request.latest_revision,
review=RequestReviewFactory.create(reviewer=ccpo),
),
RequestStatusEventFactory.create(
request=request,
revision=request.latest_revision,
review=RequestReviewFactory.create(reviewer=ccpo),
),
RequestStatusEventFactory.create(request=request, revision=request.latest_revision),
assert len(request.reviews) == 2
def test_review_comment():
request = RequestFactory.create()
ccpo = UserFactory.from_atat_role("ccpo")
request.status_events = [
RequestStatusEventFactory.create(
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED,
review=RequestReviewFactory.create(reviewer=ccpo, comment="do better"),
)
]
RequestStatusEventFactory.create(
request=request,
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED,
review=RequestReviewFactory.create(reviewer=ccpo, comment="do better"),
)
assert request.review_comment == "do better"
request.status_events = [
RequestStatusEventFactory.create(
revision=request.latest_revision,
new_status=RequestStatus.APPROVED,
review=RequestReviewFactory.create(reviewer=ccpo, comment="much better"),
)
]
RequestStatusEventFactory.create(
request=request,
revision=request.latest_revision,
new_status=RequestStatus.APPROVED,
review=RequestReviewFactory.create(reviewer=ccpo, comment="much better"),
)
assert not request.review_comment

View File

@ -1,12 +1,11 @@
from atst.models.task_order import TaskOrder
from tests.factories import TaskOrderFactory
from tests.assert_util import dict_contains
def test_as_dictionary():
data = TaskOrderFactory.dictionary()
real_task_order = TaskOrderFactory.create(**data)
assert real_task_order.to_dictionary() == data
assert dict_contains(real_task_order.to_dictionary(), data)
def test_budget():

View File

@ -162,14 +162,13 @@ def test_displays_ccpo_review_comment(user_session, client):
ccpo = UserFactory.from_atat_role("ccpo")
user_session(creator)
request = RequestFactory.create(creator=creator)
status = RequestStatusEventFactory.create(
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED_TO_FINVER,
request=request,
)
review_comment = "add all of the correct info, instead of the incorrect info"
request.status_events = [
RequestStatusEventFactory.create(
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED_TO_FINVER,
review=RequestReviewFactory.create(reviewer=ccpo, comment=review_comment),
)
]
RequestReviewFactory.create(reviewer=ccpo, comment=review_comment, status=status)
response = client.get("/requests/verify/{}".format(request.id))
body = response.data.decode()
assert review_comment in body

View File

@ -227,14 +227,13 @@ def test_displays_ccpo_review_comment(user_session, client):
ccpo = UserFactory.from_atat_role("ccpo")
user_session(creator)
request = RequestFactory.create(creator=creator)
status = RequestStatusEventFactory.create(
request=request,
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED,
)
review_comment = "add all of the correct info, instead of the incorrect info"
request.status_events = [
RequestStatusEventFactory.create(
revision=request.latest_revision,
new_status=RequestStatus.CHANGES_REQUESTED,
review=RequestReviewFactory.create(reviewer=ccpo, comment=review_comment),
)
]
RequestReviewFactory.create(reviewer=ccpo, comment=review_comment, status=status)
response = client.get("/requests/new/1/{}".format(request.id))
body = response.data.decode()
assert review_comment in body