"""Add Configuration and Business Policy tables (RMM-style policies). Creates configurationpolicies, configurationpolicyactions, businesspolicies, and businesspolicyitems. These back the DT-authored policy feature that is gated by the computers_configpolicies_enabled setting; the tables land regardless so the switch can be flipped without a schema change, and the downgrade drops all four for a clean rollback of the whole scope. Idempotent: each create_table is skipped when the table already exists (e.g. a test DB built by db.create_all()). Revision ID: computers0004policies Revises: computers0003azurefields """ from alembic import op import sqlalchemy as sa revision = 'computers0004policies' down_revision = 'computers0003azurefields' branch_labels = None depends_on = None # TEXT rather than sa.JSON on purpose. MySQL 5.6 has no JSON type - it arrived # in 5.7 - and this migration failed there with a bare syntax error near the # word JSON. Every other JSON-bearing column in the product is TEXT for the same # reason (guides.blocksjson, geenforce.manifestjson); the model reads and writes # dicts through the JSONText type decorator, so nothing above the database # changes. def upgrade(): bind = op.get_bind() insp = sa.inspect(bind) existing = set(insp.get_table_names()) if 'configurationpolicies' not in existing: op.create_table( 'configurationpolicies', sa.Column('configurationpolicyid', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=150), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('scopejson', sa.Text(), nullable=True), sa.Column('source', sa.String(length=50), nullable=False, server_default='local'), sa.Column('createddate', sa.DateTime(), nullable=False), sa.Column('modifieddate', sa.DateTime(), nullable=False), sa.Column('isactive', sa.Boolean(), nullable=False, server_default=sa.true()), sa.PrimaryKeyConstraint('configurationpolicyid'), sa.UniqueConstraint('name', name='uq_configurationpolicy_name'), ) op.create_index('idx_configpolicy_source', 'configurationpolicies', ['source']) op.create_index('idx_configpolicy_active', 'configurationpolicies', ['isactive']) if 'configurationpolicyactions' not in existing: op.create_table( 'configurationpolicyactions', sa.Column('configurationpolicyactionid', sa.Integer(), nullable=False), sa.Column('configurationpolicyid', sa.Integer(), nullable=False), sa.Column('action', sa.String(length=100), nullable=False), sa.Column('mode', sa.String(length=20), nullable=False, server_default='gate'), sa.Column('desiredstate', sa.Text(), nullable=True), sa.Column('params', sa.Text(), nullable=True), sa.Column('intervalminutes', sa.Integer(), nullable=True), sa.Column('sortorder', sa.Integer(), nullable=False, server_default='0'), sa.Column('createddate', sa.DateTime(), nullable=False), sa.Column('modifieddate', sa.DateTime(), nullable=False), sa.Column('isactive', sa.Boolean(), nullable=False, server_default=sa.true()), sa.ForeignKeyConstraint( ['configurationpolicyid'], ['configurationpolicies.configurationpolicyid'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('configurationpolicyactionid'), sa.UniqueConstraint('configurationpolicyid', 'action', name='uq_configpolicyaction'), ) op.create_index('idx_configpolicyaction_policy', 'configurationpolicyactions', ['configurationpolicyid']) if 'businesspolicies' not in existing: op.create_table( 'businesspolicies', sa.Column('businesspolicyid', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=150), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('priority', sa.Integer(), nullable=False, server_default='100'), sa.Column('source', sa.String(length=50), nullable=False, server_default='local'), sa.Column('createddate', sa.DateTime(), nullable=False), sa.Column('modifieddate', sa.DateTime(), nullable=False), sa.Column('isactive', sa.Boolean(), nullable=False, server_default=sa.true()), sa.PrimaryKeyConstraint('businesspolicyid'), sa.UniqueConstraint('name', name='uq_businesspolicy_name'), ) op.create_index('idx_businesspolicy_priority', 'businesspolicies', ['priority']) op.create_index('idx_businesspolicy_active', 'businesspolicies', ['isactive']) if 'businesspolicyitems' not in existing: op.create_table( 'businesspolicyitems', sa.Column('businesspolicyitemid', sa.Integer(), nullable=False), sa.Column('businesspolicyid', sa.Integer(), nullable=False), sa.Column('configurationpolicyid', sa.Integer(), nullable=False), sa.Column('sortorder', sa.Integer(), nullable=False, server_default='0'), sa.Column('createddate', sa.DateTime(), nullable=False), sa.Column('modifieddate', sa.DateTime(), nullable=False), sa.Column('isactive', sa.Boolean(), nullable=False, server_default=sa.true()), sa.ForeignKeyConstraint( ['businesspolicyid'], ['businesspolicies.businesspolicyid'], ondelete='CASCADE'), sa.ForeignKeyConstraint( ['configurationpolicyid'], ['configurationpolicies.configurationpolicyid'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('businesspolicyitemid'), sa.UniqueConstraint('businesspolicyid', 'configurationpolicyid', name='uq_businesspolicyitem'), ) op.create_index('idx_bpitem_business', 'businesspolicyitems', ['businesspolicyid']) op.create_index('idx_bpitem_config', 'businesspolicyitems', ['configurationpolicyid']) def downgrade(): bind = op.get_bind() insp = sa.inspect(bind) existing = set(insp.get_table_names()) if 'businesspolicyitems' in existing: op.drop_index('idx_bpitem_config', table_name='businesspolicyitems') op.drop_index('idx_bpitem_business', table_name='businesspolicyitems') op.drop_table('businesspolicyitems') if 'businesspolicies' in existing: op.drop_index('idx_businesspolicy_active', table_name='businesspolicies') op.drop_index('idx_businesspolicy_priority', table_name='businesspolicies') op.drop_table('businesspolicies') if 'configurationpolicyactions' in existing: op.drop_index('idx_configpolicyaction_policy', table_name='configurationpolicyactions') op.drop_table('configurationpolicyactions') if 'configurationpolicies' in existing: op.drop_index('idx_configpolicy_active', table_name='configurationpolicies') op.drop_index('idx_configpolicy_source', table_name='configurationpolicies') op.drop_table('configurationpolicies')