PC records now carry Entra/Azure device identity so imported machines keep a durable link back to their directory object instead of matching on hostname alone. Adds azuredeviceid, azureobjectid, and azuredevicecategory to the Computer model with matching migrations, surfaces them read-only in PCDetail as an Entra Device Info card, and lets PCForm edit the device id directly. The computers plugin registers a machineassetnumber import hook that reconciles PC-to-machine links during bulk import and warns on unresolved or conflicting relationships. Adds importsources adapters that normalize Azure device-group and Thor PC inventory exports into canonical ShopDB CSVs via hostname alignment, exposes register_import_hook and RowWarning on the shopdb.api contract surface (contract 0.21.0), and refreshes the Import Site Assets page with clearer source instructions. Includes reconcile_locations maintenance script and coverage for the new import paths.
41 lines
1.3 KiB
Python
41 lines
1.3 KiB
Python
"""Add azuredeviceid to computers (Entra/Azure device-group imports).
|
|
|
|
The core chain created computers WITHOUT an azuredeviceid column. This plugin
|
|
revision adds it so BOTH fresh installs (core chain builds the table, then this
|
|
adds the column) and existing installs get it. Guarded/idempotent: skips when
|
|
the table is absent (plugin disabled) or the column already exists (e.g. a test
|
|
DB built by db.create_all() from the model).
|
|
|
|
Revision ID: computers0002azureid
|
|
Revises: computers0001anchor
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
revision = 'computers0002azureid'
|
|
down_revision = 'computers0001anchor'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade():
|
|
bind = op.get_bind()
|
|
insp = sa.inspect(bind)
|
|
if 'computers' not in insp.get_table_names():
|
|
return
|
|
cols = {c['name'] for c in insp.get_columns('computers')}
|
|
if 'azuredeviceid' not in cols:
|
|
op.add_column('computers',
|
|
sa.Column('azuredeviceid', sa.String(length=64), nullable=True))
|
|
|
|
|
|
def downgrade():
|
|
bind = op.get_bind()
|
|
insp = sa.inspect(bind)
|
|
if 'computers' not in insp.get_table_names():
|
|
return
|
|
cols = {c['name'] for c in insp.get_columns('computers')}
|
|
if 'azuredeviceid' in cols:
|
|
op.drop_column('computers', 'azuredeviceid')
|