Adds diskhealthjson with its migration in the same change, so the model never references a column the schema has not applied. Kept separate from disksjson rather than merged into it. That column is per volume and answers how full a drive is; this one is per physical device and answers whether the hardware is dying. They come from different WMI sources with different failure modes, so merging them would make a capacity collection failure indistinguishable from a health collection failure. Nullable with no backfill: a drive whose health has never been reported is not a healthy drive, and defaulting to an empty list would read as no disks have problems on every endpoint predating the column.
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""Add diskhealthjson to endpointstates.
|
|
|
|
Per-drive health, kept separate from disksjson. That column answers "how full
|
|
is this drive"; this one answers "is this drive dying". Merging them would mean
|
|
a capacity collection failure and a health collection failure could not be told
|
|
apart, and the two come from different WMI sources with different failure modes.
|
|
|
|
JSON rather than scalar columns because a machine has a variable number of
|
|
drives and each carries its own verdict, and because the agent reports the same
|
|
drive from two sources - MSFT_PhysicalDisk for NVMe and Win32_DiskDrive for
|
|
ATA/SATA - which the server keeps side by side rather than collapsing.
|
|
|
|
MEDIUMTEXT for consistency with the other snapshot columns on this table.
|
|
|
|
Nullable with no backfill. A drive whose health has never been reported is not
|
|
a healthy drive, and defaulting to an empty list would read as "no disks have
|
|
problems" on every endpoint that predates this column.
|
|
|
|
Idempotent: the column-add checks the live schema first, so a re-run and a
|
|
db.create_all() site both stay clean on strict MySQL 8.
|
|
"""
|
|
from alembic import op
|
|
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = 'endpoints0014diskhealth'
|
|
down_revision = 'endpoints0013inventorycolumns'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
TABLE_NAME = 'endpointstates'
|
|
COLUMN_NAME = 'diskhealthjson'
|
|
|
|
|
|
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 not _has_column(TABLE_NAME, COLUMN_NAME):
|
|
op.add_column(
|
|
TABLE_NAME,
|
|
sa.Column(COLUMN_NAME, sa.Text(length=16777215), nullable=True))
|
|
|
|
|
|
def downgrade():
|
|
if _has_column(TABLE_NAME, COLUMN_NAME):
|
|
op.drop_column(TABLE_NAME, COLUMN_NAME)
|