52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
"""Cache the warn-only reconciler drift on the endpoint state.
|
|
|
|
Adds endpointstates.driftjson: a per-asset JSON snapshot of the monitors a site
|
|
policy (or the shipped bundle) expects to be running on an endpoint but which the
|
|
latest agent report does not show as running. It is computed server-side on every
|
|
agent check-in and overwritten in place, the same ledger pattern the other state
|
|
snapshots (servicesjson, portsjson) already use - one current row per asset, no
|
|
history. Warn-only: nothing here is auto-remediated, it exists so an operator can
|
|
see the drift and intervene manually.
|
|
|
|
Nullable so an endpoint that has never checked in since the column landed reads
|
|
as "never computed" rather than "no drift".
|
|
|
|
Idempotent: the column-add checks the live schema first, so a db.create_all()
|
|
site (which built the column from the model already) and a re-run both stay clean
|
|
on strict MySQL 8.
|
|
"""
|
|
from alembic import op
|
|
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = 'endpoints0008drift'
|
|
down_revision = 'endpoints0007shippedpolicy'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def _has_column(table_name, column_name):
|
|
from sqlalchemy import inspect
|
|
|
|
inspector = inspect(op.get_bind())
|
|
if not inspector.has_table(table_name):
|
|
return False
|
|
return any(col['name'] == column_name
|
|
for col in inspector.get_columns(table_name))
|
|
|
|
|
|
def upgrade():
|
|
if _has_column('endpointstates', 'driftjson'):
|
|
return
|
|
op.add_column(
|
|
'endpointstates',
|
|
sa.Column('driftjson', sa.Text(length=16777215), nullable=True))
|
|
|
|
|
|
def downgrade():
|
|
if not _has_column('endpointstates', 'driftjson'):
|
|
return
|
|
op.drop_column('endpointstates', 'driftjson')
|