Example #1
0
def upgrade():
    op.create_table(
        'networks',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, unique=True, nullable=False),
        sa.Column('current_task_id', sau.UUIDType, sa.ForeignKey('tasks.id')),
        sa.Column('port_group', sa.String, unique=True, nullable=False),
        sa.Column('gateway', sau.IPAddressType, nullable=False),
        sa.Column('dns_servers', sa.ARRAY(sau.IPAddressType), nullable=False),
        sa.Column('region_id',
                  sau.UUIDType,
                  sa.ForeignKey('regions.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('state',
                  sa.Enum(NetworkState),
                  default=NetworkState.CREATING,
                  nullable=False),
        sa.Column('cidr', IPv4Network, nullable=False),
        sa.Column('pool_start', sau.IPAddressType, nullable=False),
        sa.Column('pool_end', sau.IPAddressType, nullable=False),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
    )
def upgrade():
    op.create_table(
        'network_ports',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('network_id',
                  sau.UUIDType,
                  sa.ForeignKey('networks.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE'),
                  nullable=False,
                  index=True), sa.Column('ip_address', sau.IPAddressType),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))
def upgrade():
    op.create_table(
        'images',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('file_name', sa.String, unique=True, nullable=False),
        sa.Column('locked', sa.Boolean, default=False, nullable=False),
        sa.Column('state',
                  sa.Enum(ImageState),
                  default=ImageState.CREATING,
                  nullable=False),
        sa.Column('visibility',
                  sa.Enum(ImageVisibility),
                  default=ImageVisibility.PRIVATE,
                  nullable=False),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('region_id',
                  sau.UUIDType,
                  sa.ForeignKey('regions.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('current_task_id', sau.UUIDType, sa.ForeignKey('tasks.id')),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
    )

    op.create_table(
        'image_members',
        sa.Column('image_id',
                  sau.UUIDType,
                  sa.ForeignKey('images.id', ondelete='CASCADE'),
                  nullable=False,
                  primary_key=True),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE'),
                  nullable=False,
                  primary_key=True),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
    )
Example #4
0
class TimestampMixin(object):
    created_at = db.Column(sau.ArrowType(),
                           nullable=False,
                           index=True,
                           default=arrow.utcnow)
    updated_at = db.Column(sau.ArrowType(),
                           nullable=False,
                           index=True,
                           default=arrow.utcnow,
                           onupdate=arrow.utcnow)
Example #5
0
def upgrade():
    op.create_table(
        'projects',
        sa.Column('id', sau.UUIDType, server_default=sa.text("uuid_generate_v4()"), primary_key=True),
        sa.Column('name', sa.String, unique=True, nullable=False),
        sa.Column('state', sa.Enum(ProjectState), default=ProjectState.CREATED, nullable=False),

        sa.Column('created_at', sau.ArrowType(timezone=True), server_default=sa.text('clock_timestamp()'),
                  nullable=False, index=True),
        sa.Column('updated_at', sau.ArrowType(timezone=True), server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False)
    )
Example #6
0
def upgrade():
    op.create_table(
        'tasks',
        sa.Column('id', sau.UUIDType, server_default=sa.text("uuid_generate_v4()"), primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('state', sa.Enum(TaskState), default=TaskState.PENDING, nullable=False),
        sa.Column('error_message', sa.Text),

        sa.Column('created_at', sau.ArrowType(timezone=True), server_default=sa.text('clock_timestamp()'),
                  nullable=False, index=True),
        sa.Column('updated_at', sau.ArrowType(timezone=True), server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
        sa.Column('stopped_at', sau.ArrowType(timezone=True)),
    )
def upgrade():
    op.create_table(
        'instances',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('tags', HSTORE),
        sa.Column('state',
                  sa.Enum(InstanceState),
                  default=InstanceState.BUILDING,
                  nullable=False),
        sa.Column('network_port_id',
                  sau.UUIDType,
                  sa.ForeignKey('network_ports.id', ondelete='RESTRICT'),
                  index=True),
        sa.Column('region_id',
                  sau.UUIDType,
                  sa.ForeignKey('regions.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('zone_id', sau.UUIDType,
                  sa.ForeignKey('zones.id', ondelete='RESTRICT')),
        sa.Column('service_account_id',
                  sau.UUIDType,
                  sa.ForeignKey('authn_service_accounts.id',
                                ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('current_task_id', sau.UUIDType, sa.ForeignKey('tasks.id')),
        sa.Column('image_id', sau.UUIDType,
                  sa.ForeignKey('images.id', ondelete='SET NULL')),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
    )
Example #8
0
def upgrade():
    op.create_table(
        'keypairs',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('public_key', sa.Text, nullable=False),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE'),
                  nullable=False),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))

    op.create_table(
        'instance_keypairs',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('keypair_id', sau.UUIDType,
                  sa.ForeignKey('keypairs.id', ondelete='CASCADE')),
        sa.Column('instance_id', sau.UUIDType,
                  sa.ForeignKey('instances.id', ondelete='CASCADE')),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))
def upgrade():
    op.create_table(
        'authn_users',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('username', sa.String, nullable=False),
        sa.Column('driver', sa.String, nullable=False),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))
    op.create_unique_constraint('uq_username_driver', 'authn_users',
                                ['username', 'driver'])
Example #10
0
 class Tester(SQLAlchemyJsonMixin, Base):
     __tablename__ = 'tester'
     intField = sqlalchemy.Column(sqlalchemy.BigInteger(),
                                  primary_key=True)
     strField = sqlalchemy.Column(sqlalchemy.UnicodeText())
     noneField = sqlalchemy.Column(sqlalchemy.Integer())
     floatField = sqlalchemy.Column(sqlalchemy.Float())
     boolField = sqlalchemy.Column(sqlalchemy.Boolean())
     dateTimeField = sqlalchemy.Column(sqlalchemy.DateTime())
     arrowField = sqlalchemy.Column(sqlalchemy_utils.ArrowType())
     relFieldId = sqlalchemy.Column(
         sqlalchemy.BigInteger(), sqlalchemy.ForeignKey('submodel.id'))
     relField = sqlalchemy.orm.relationship('SubModel')
def upgrade():
    op.create_table(
        'builtin_users',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('username', sa.String, nullable=False, unique=True),
        sa.Column('password',
                  sau.PasswordType(schemes=['bcrypt']),
                  nullable=False),
        sa.Column('roles', ARRAY(sa.String), default=list),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('resources',
    sa.Column('created_at', sau.ArrowType(), nullable=False),
    sa.Column('updated_at', sau.ArrowType(), nullable=False),
    sa.Column('id', sa.BigInteger(), nullable=False),
    sa.Column('category_id', sa.BigInteger(), nullable=False),
    sa.Column('user_id', sa.BigInteger(), nullable=False),
    sa.Column('type', sa.String(8), nullable=True),
    sa.Column('quantity_available', sa.BigInteger(), nullable=True),
    sa.Column('quantity_needed', sa.BigInteger(), nullable=True),
    sa.Column('fulfilled', sa.Boolean(), server_default='0', nullable=False),
    sa.ForeignKeyConstraint(['category_id'], ['categories.id'], onupdate='CASCADE', ondelete='RESTRICT'),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], onupdate='CASCADE', ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_resources_created_at'), 'resources', ['created_at'], unique=False)
    op.create_index(op.f('ix_resources_type'), 'resources', ['type'], unique=False)
    op.create_index(op.f('ix_resources_updated_at'), 'resources', ['updated_at'], unique=False)
    op.drop_constraint('user_resource_fulfillment_ibfk_2', 'user_resource_fulfillment', type_='foreignkey')
    op.drop_constraint('user_resource_fulfillment_ibfk_1', 'user_resource_fulfillment', type_='foreignkey')
    op.drop_table('user_resources')
    op.create_foreign_key('fk_urf_resources_fulfilling', 'user_resource_fulfillment', 'resources', ['fulfilling_resource_id'], ['id'], onupdate='CASCADE', ondelete='RESTRICT')
    op.create_foreign_key('fk_urf_resources_fulfilled', 'user_resource_fulfillment', 'resources', ['fulfilled_resource_id'], ['id'], onupdate='CASCADE', ondelete='RESTRICT')
Example #13
0
def upgrade():
    policies_table = op.create_table(
        'authz_policies',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False, unique=True),
        sa.Column('description', sa.String),
        sa.Column('tags', sa.ARRAY(sa.String)),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))

    roles_table = op.create_table(
        'authz_roles',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('project_id', sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE')),
        sa.Column('description', sa.String),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))
    op.create_unique_constraint('uq_name_project_id', 'authz_roles',
                                ['name', 'project_id'])

    role_policies_table = op.create_table(
        'authz_role_policies',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('role_id',
                  sau.UUIDType,
                  sa.ForeignKey('authz_roles.id', ondelete='CASCADE'),
                  index=True,
                  nullable=False),
        sa.Column('policy_id',
                  sau.UUIDType,
                  sa.ForeignKey('authz_policies.id', ondelete='CASCADE'),
                  index=True,
                  nullable=False),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))

    op.create_table(
        'authn_service_accounts',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, nullable=False),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE'),
                  nullable=False),
        sa.Column('role_id',
                  sau.UUIDType,
                  sa.ForeignKey('authz_roles.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))

    # TODO: add project_members
    op.create_table(
        'project_members',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('user_id',
                  sau.UUIDType,
                  sa.ForeignKey('authn_users.id', ondelete='CASCADE'),
                  nullable=False,
                  index=True),
        sa.Column('project_id',
                  sau.UUIDType,
                  sa.ForeignKey('projects.id', ondelete='CASCADE'),
                  nullable=False,
                  index=True),
        sa.Column('role_id',
                  sau.UUIDType,
                  sa.ForeignKey('authz_roles.id', ondelete='RESTRICT'),
                  nullable=False,
                  index=True),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False))

    op.bulk_insert(roles_table, [{
        "name": "admin",
        "description": "Administrator Role"
    }, {
        "name":
        "viewer",
        "description":
        "Viewer role; has the ability to view non-project level objects"
    }])

    # Policy Tags:
    # viewer - policies the viewer role should have
    # project_member - policies the default project member role should have
    # service_account - policies the default project service account role should have
    op.bulk_insert(
        policies_table,
        [
            # Policies
            {
                "name": "policies:create",
                "description": "Ability to create a policy",
            },
            {
                "name": "policies:get",
                "description": "Ability to get a policy",
                "tags": ["viewer"]
            },
            {
                "name": "policies:update",
                "description": "Ability to update a policy"
            },
            {
                "name": "policies:list",
                "description": "Ability to list policies",
                "tags": ["viewer"]
            },
            {
                "name": "policies:delete",
                "description": "Ability to delete a policy"
            },

            # Roles
            {
                "name": "roles:create:global",
                "description": "Ability to create a global role"
            },
            {
                "name": "roles:delete:global",
                "description": "Ability to delete a global role"
            },
            {
                "name": "roles:create:project",
                "description": "Ability to create a project role",
                "tags": ["project_member"]
            },
            {
                "name": "roles:delete:project",
                "description": "Ability to delete a project role",
                "tags": ["project_member"]
            },
            {
                "name": "roles:get",
                "description": "Ability to get a role",
                "tags": ["viewer"]
            },
            {
                "name": "roles:list",
                "description": "Ability to list roles",
                "tags": ["viewer"]
            },

            # Regions
            {
                "name": "regions:create",
                "description": "Ability to create a region"
            },
            {
                "name": "regions:get",
                "description": "Ability to get a region",
                "tags": ["viewer"]
            },
            {
                "name": "regions:list",
                "description": "Ability to list regions",
                "tags": ["viewer"]
            },
            {
                "name": "regions:delete",
                "description": "Ability to delete a region"
            },
            {
                "name": "regions:action:schedule",
                "description":
                "Ability to change the schedule mode of the region"
            },

            # Zones
            {
                "name": "zones:create",
                "description": "Ability to create a zone"
            },
            {
                "name": "zones:get",
                "description": "Ability to get a zone",
                "tags": ["viewer"]
            },
            {
                "name": "zones:list",
                "description": "Ability to list zones",
                "tags": ["viewer"]
            },
            {
                "name": "zones:delete",
                "description": "Ability to delete a zone"
            },
            {
                "name": "zones:action:schedule",
                "description":
                "Ability to change the schedule mode of the zone"
            },

            # Projects
            {
                "name": "projects:create",
                "description": "Ability to create a project"
            },
            {
                "name": "projects:get",
                "description": "Ability to get a project",
                "tags": ["viewer"]
            },
            {
                "name": "projects:list",
                "description": "Ability to list projects",
                "tags": ["viewer"]
            },
            {
                "name": "projects:delete",
                "description": "Ability to delete a project"
            },
            # TODO: add policies for project:members

            # Tasks

            # Images
            {
                "name": "images:create",
                "description": "Ability to create an image",
                "tags": ["project_member"]
            },
            {
                "name": "images:create:public",
                "description": "Ability to create a public image"
            },
            {
                "name": "images:get",
                "description": "Ability to get an image",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "images:list",
                "description": "Ability to list images",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "images:delete",
                "description": "Ability to delete an image",
                "tags": ["project_member"]
            },
            {
                "name": "images:action:lock",
                "description": "Ability to lock an image",
                "tags": ["project_member"]
            },
            {
                "name": "images:action:unlock",
                "description": "Ability to unlock an image",
                "tags": ["project_member"]
            },

            # Instances
            {
                "name": "instances:create",
                "description": "Ability to create an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:get",
                "description": "Ability to get an instance",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "instances:list",
                "description": "Ability to list instances",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "instances:delete",
                "description": "Ability to delete an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:stop",
                "description": "Ability to stop an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:start",
                "description": "Ability to start an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:restart",
                "description": "Ability to restart an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:image",
                "description": "Ability to create an image from an instance",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:image:public",
                "description":
                "Ability to create a public image from an instance"
            },
            {
                "name": "instances:action:reset_state",
                "description":
                "Ability to reset the state of an instance to error",
                "tags": ["project_member"]
            },
            {
                "name": "instances:action:reset_state:active",
                "description":
                "Ability to reset the state of an instance to active",
                "tags": ["project_member"]
            },

            # Networks
            {
                "name": "networks:create",
                "description": "Ability to create a network"
            },
            {
                "name": "networks:get",
                "description": "Ability to get a network",
                "tags": ["viewer"]
            },
            {
                "name": "networks:list",
                "description": "Ability to list networks",
                "tags": ["viewer"]
            },
            {
                "name": "networks:delete",
                "description": "Ability to delete a network"
            },

            # Service Accounts
            {
                "name": "service_accounts:create",
                "description": "Ability to create a service account",
                "tags": ["project_member"]
            },
            {
                "name": "service_accounts:get",
                "description": "Ability to get a service account",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "service_accounts:list",
                "description": "Ability to list service accounts",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "service_accounts:delete",
                "description": "Ability to delete a service account",
                "tags": ["project_member"]
            },

            # BuiltIn Users
            {
                "name": "builtin:users:create",
                "description": "Ability to create users",
            },
            {
                "name": "builtin:users:get",
                "description": "Ability to get a user",
                "tags": ["viewer"]
            },
            {
                "name": "builtin:users:list",
                "description": "Ability to list users",
                "tags": ["viewer"]
            },
            {
                "name": "builtin:users:delete",
                "description": "Ability to delete a user"
            },
            {
                "name": "builtin:users:password",
                "description": "Ability to change a user's password"
            },
            {
                "name": "builtin:users:role:add",
                "description": "Ability to add a role to a user"
            },
            {
                "name": "builtin:users:role:remove",
                "description": "Ability to remove a user from a role"
            },

            # Keypairs
            {
                "name": "keypairs:create",
                "description": "Ability to create a keypair",
                "tags": ["project_member"]
            },
            {
                "name": "keypairs:get",
                "description": "Ability to get a keypair",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "keypairs:list",
                "description": "Ability to list keypairs",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "keypairs:delete",
                "description": "Ability to delete a keypair",
                "tags": ["project_member"]
            },

            # Network Ports
            {
                "name": "network_ports:get",
                "description": "Ability to get a network port",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "network_ports:list",
                "description": "Ability to list  network ports",
                "tags": ["project_member", "service_account"]
            },
            {
                "name": "network_ports:delete",
                "description": "Ability to delete a network port",
                "tags": ["project_member"]
            }
        ],
        multiinsert=False  # Needed so the list insert works correctly
    )

    connection = op.get_bind()
    admin_role = connection.execute(
        roles_table.select().where(roles_table.c.name == "admin")).fetchone()
    viewer_role = connection.execute(
        roles_table.select().where(roles_table.c.name == "viewer")).fetchone()
    for policy in connection.execute(policies_table.select()):
        connection.execute(role_policies_table.insert().values(
            role_id=admin_role.id, policy_id=policy.id))
        if policy.tags is not None:
            if 'viewer' in policy.tags:
                connection.execute(role_policies_table.insert().values(
                    role_id=viewer_role.id, policy_id=policy.id))
def upgrade():
    op.create_table(
        'regions',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, unique=True, nullable=False),
        sa.Column('datacenter', sa.String, unique=True, nullable=False),
        sa.Column('image_datastore', sa.String, nullable=False),
        sa.Column('image_folder', sa.String),
        sa.Column('schedulable', sa.Boolean, nullable=False),
        sa.Column('state',
                  sa.Enum(RegionState),
                  default=RegionState.CREATING,
                  nullable=False),
        sa.Column('current_task_id', sau.UUIDType, sa.ForeignKey('tasks.id')),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
    )

    op.create_table(
        'zones',
        sa.Column('id',
                  sau.UUIDType,
                  server_default=sa.text("uuid_generate_v4()"),
                  primary_key=True),
        sa.Column('name', sa.String, unique=True, nullable=False),
        sa.Column('region_id',
                  sau.UUIDType,
                  sa.ForeignKey('regions.id', ondelete='RESTRICT'),
                  nullable=False),
        sa.Column('vm_cluster', sa.String, nullable=False),
        sa.Column('vm_datastore', sa.String, nullable=False),
        sa.Column('vm_folder', sa.String),
        sa.Column('core_provision_percent', sa.Integer, nullable=False),
        sa.Column('ram_provision_percent', sa.Integer, nullable=False),
        sa.Column('schedulable', sa.Boolean, nullable=False),
        sa.Column('state',
                  sa.Enum(ZoneState),
                  default=ZoneState.CREATING,
                  nullable=False),
        sa.Column('current_task_id', sau.UUIDType, sa.ForeignKey('tasks.id')),
        sa.Column('created_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  nullable=False,
                  index=True),
        sa.Column('updated_at',
                  sau.ArrowType(timezone=True),
                  server_default=sa.text('clock_timestamp()'),
                  onupdate=sa.text('clock_timestamp()'),
                  nullable=False),
    )
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('resources',
                    sa.Column('id', sa.BigInteger(), nullable=False),
                    sa.Column('name', sa.UnicodeText(), nullable=True),
                    sa.PrimaryKeyConstraint('id'))
    op.create_table(
        'users', sa.Column('created_at', sau.ArrowType(), nullable=False),
        sa.Column('updated_at', sau.ArrowType(), nullable=False),
        sa.Column('id', sa.BigInteger(), nullable=False),
        sa.Column('name', sa.UnicodeText(), nullable=False),
        sa.Column('username', sa.Unicode(length=64), nullable=False),
        sa.Column('password', sa.UnicodeText(), nullable=False),
        sa.Column('email', sa.UnicodeText(), nullable=True),
        sa.Column('phone', sa.BigInteger(), nullable=True),
        sa.Column('secondary_phone', sa.BigInteger(), nullable=True),
        sa.Column('bio', sa.UnicodeText(), nullable=False),
        sa.Column('immigration_status', sa.String(length=32), nullable=True),
        sa.Column('primary_role', sa.String(length=32), nullable=True),
        sa.Column('language', sa.String(length=2), nullable=False),
        sa.Column('country', sa.String(length=2), nullable=False),
        sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('username'))
    op.create_index(op.f('ix_users_created_at'),
                    'users', ['created_at'],
                    unique=False)
    op.create_index(op.f('ix_users_immigration_status'),
                    'users', ['immigration_status'],
                    unique=False)
    op.create_index(op.f('ix_users_updated_at'),
                    'users', ['updated_at'],
                    unique=False)
    op.create_table(
        'user_resources',
        sa.Column('created_at', sau.ArrowType(), nullable=False),
        sa.Column('updated_at', sau.ArrowType(), nullable=False),
        sa.Column('id', sa.BigInteger(), nullable=False),
        sa.Column('resource_id', sa.BigInteger(), nullable=False),
        sa.Column('user_id', sa.BigInteger(), nullable=False),
        sa.Column('type', sa.String(length=8), nullable=True),
        sa.Column('quantity_available', sa.BigInteger(), nullable=True),
        sa.Column('quantity_needed', sa.BigInteger(), nullable=True),
        sa.Column('fulfilled',
                  sa.Boolean(),
                  server_default='0',
                  nullable=False),
        sa.ForeignKeyConstraint(['resource_id'], ['resources.id'],
                                onupdate='CASCADE',
                                ondelete='RESTRICT'),
        sa.ForeignKeyConstraint(['user_id'], ['users.id'],
                                onupdate='CASCADE',
                                ondelete='CASCADE'),
        sa.PrimaryKeyConstraint('id'))
    op.create_index(op.f('ix_user_resources_created_at'),
                    'user_resources', ['created_at'],
                    unique=False)
    op.create_index(op.f('ix_user_resources_type'),
                    'user_resources', ['type'],
                    unique=False)
    op.create_index(op.f('ix_user_resources_updated_at'),
                    'user_resources', ['updated_at'],
                    unique=False)
    op.create_table(
        'user_resource_fulfillment',
        sa.Column('created_at', sau.ArrowType(), nullable=False),
        sa.Column('updated_at', sau.ArrowType(), nullable=False),
        sa.Column('id', sa.BigInteger(), nullable=False),
        sa.Column('fulfilling_resource_id', sa.BigInteger(), nullable=False),
        sa.Column('fulfilled_resource_id', sa.BigInteger(), nullable=False),
        sa.Column('fulfilled_quantity', sa.BigInteger(), nullable=False),
        sa.Column('confirmed_by_recipient',
                  sa.Boolean(),
                  server_default='0',
                  nullable=False),
        sa.ForeignKeyConstraint(['fulfilled_resource_id'],
                                ['user_resources.id'],
                                onupdate='CASCADE',
                                ondelete='RESTRICT'),
        sa.ForeignKeyConstraint(['fulfilling_resource_id'],
                                ['user_resources.id'],
                                onupdate='CASCADE',
                                ondelete='RESTRICT'),
        sa.PrimaryKeyConstraint('id'))
    op.create_index(op.f('ix_user_resource_fulfillment_created_at'),
                    'user_resource_fulfillment', ['created_at'],
                    unique=False)
    op.create_index(op.f('ix_user_resource_fulfillment_updated_at'),
                    'user_resource_fulfillment', ['updated_at'],
                    unique=False)