dashboarddefaults: key display mappings by stable FQDN (from BIOS serial), IP fallback
A display's DHCP IP can change; its FQDN (F<serial>.<domain>, domain from the display_fqdn_domain setting) is stable and the collector already reports the serial. Add a nullable unique fqdn column (varchar191 so the index fits utf8mb4 without innodb_large_prefix), make ipaddress nullable, and require fqdn OR ip. visitor-location + display-role resolve by FQDN first, then IP; create/update accept fqdn. Core migration 7d31, verified up/down/idempotent on MySQL 5.6. 'Business unit' wording -> 'location' in the validation messages.
This commit is contained in:
62
migrations/versions/7d31_dashboarddefault_fqdn.py
Normal file
62
migrations/versions/7d31_dashboarddefault_fqdn.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""dashboarddefaults: add fqdn, make ipaddress nullable.
|
||||
|
||||
Map a display PC to its role/location by its STABLE FQDN (derived from the BIOS
|
||||
serial, F<serial>.<domain>) instead of only its DHCP-changeable IP. IP stays as
|
||||
a nullable fallback. Idempotent.
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7d31_dashboarddefault_fqdn'
|
||||
down_revision = '7d30_apitoken_resourcescopes'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _has_column(bind, table, column):
|
||||
inspector = sa.inspect(bind)
|
||||
if table not in inspector.get_table_names():
|
||||
return False
|
||||
return column in {c['name'] for c in inspector.get_columns(table)}
|
||||
|
||||
|
||||
def _col_nullable(bind, table, column):
|
||||
inspector = sa.inspect(bind)
|
||||
for c in inspector.get_columns(table):
|
||||
if c['name'] == column:
|
||||
return c.get('nullable', True)
|
||||
return True
|
||||
|
||||
|
||||
def _has_index(bind, table, index):
|
||||
inspector = sa.inspect(bind)
|
||||
if table not in inspector.get_table_names():
|
||||
return False
|
||||
return index in {i['name'] for i in inspector.get_indexes(table)}
|
||||
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
if not _has_column(bind, 'dashboarddefaults', 'fqdn'):
|
||||
op.add_column('dashboarddefaults',
|
||||
sa.Column('fqdn', sa.String(191), nullable=True))
|
||||
if not _has_index(bind, 'dashboarddefaults', 'idx_dashboarddefaults_fqdn'):
|
||||
op.create_index('idx_dashboarddefaults_fqdn', 'dashboarddefaults',
|
||||
['fqdn'], unique=True)
|
||||
# IP is now optional (an FQDN-only mapping has no IP).
|
||||
if not _col_nullable(bind, 'dashboarddefaults', 'ipaddress'):
|
||||
op.alter_column('dashboarddefaults', 'ipaddress',
|
||||
existing_type=sa.String(50), nullable=True)
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
if _has_index(bind, 'dashboarddefaults', 'idx_dashboarddefaults_fqdn'):
|
||||
op.drop_index('idx_dashboarddefaults_fqdn',
|
||||
table_name='dashboarddefaults')
|
||||
if _has_column(bind, 'dashboarddefaults', 'fqdn'):
|
||||
op.drop_column('dashboarddefaults', 'fqdn')
|
||||
# ipaddress is left nullable: reverting to NOT NULL could fail on FQDN-only
|
||||
# rows that legitimately have no IP.
|
||||
Reference in New Issue
Block a user