Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dim-testsuite/t/container-create-1.t
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ $ ndcli create container ::/0 layer3domain default
ERROR - ::/0 already exists in layer3domain default with status Container

$ ndcli list containers layer3domain default
layer3domain: default
0.0.0.0/0 (Container)
0.0.0.0/0 (Available)
::/0 (Container)
Expand Down
1 change: 1 addition & 0 deletions dim/CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
to be released
------
* add ip version to the ipblock uniqueness key so 0.0.0.0/0 and ::/0 can coexist in one layer3domain (schema 13 -> 14, see sql/migrate_13_to_14.sql)
* added ldap pseudo user sync to manage_dim (introduces is_pseudo column, LDAP_PSEUDO_USER_BASE, LDAP_BIND_DN, and LDAP_BIND_PASSWORD configurations)
* added automated database schema mismatch verification check on application startup
* reject attribute names containing colons during deletion to prevent silent failure from incorrect key-value input
Expand Down
6 changes: 5 additions & 1 deletion dim/dim/models/ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,11 @@ def collect_data():


class Ipblock(db.Model, WithAttr, TrackChanges):
__table_constraints__ = (UniqueConstraint('address', 'prefix', 'layer3domain_id'), )
# 'version' is part of a block's identity: 0.0.0.0/0 and ::/0 both have
# address 0 and prefix 0, so without it they collide inside one layer3domain.
# It is appended so that the (address, prefix, layer3domain_id) index prefix
# stays intact -- ip.py hints this index by name in _set_parent().
__table_constraints__ = (UniqueConstraint('address', 'prefix', 'layer3domain_id', 'version'), )

id = Column(BigInteger, primary_key=True, nullable=False)
version = Column(Integer, index=True, nullable=False)
Expand Down
2 changes: 1 addition & 1 deletion dim/dim/models/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
__all__ = ['SCHEMA_VERSION', 'SchemaInfo']


SCHEMA_VERSION = "13"
SCHEMA_VERSION = "14"


class SchemaInfo(db.Model):
Expand Down
30 changes: 30 additions & 0 deletions dim/dim/sql/migrate_13_to_14.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- Add `version` to the ipblock uniqueness key.
--
-- 0.0.0.0/0 and ::/0 both have address 0 and prefix 0, so the old key
-- (address, prefix, layer3domain_id) could not hold both in one layer3domain:
-- creating the second one failed with a duplicate key error.
--
-- `version` is appended rather than inserted so that the existing
-- (address, prefix, layer3domain_id) index prefix stays usable, and the index
-- keeps its name -- Ipblock._set_parent() references it via USE INDEX (address).
--
-- DROP and ADD stay in one statement, otherwise the table is briefly without
-- the index DIM expects by name.
--
-- ALGORITHM=INPLACE, LOCK=NONE is an assertion, not a request: if the server
-- cannot do the change in place and without locking, the statement aborts with
-- ER_ALTER_OPERATION_NOT_SUPPORTED (1846) instead of silently falling back to a
-- copying, locking ALTER. Measured on MariaDB 10.6: ~0.6 s per million rows,
-- concurrent INSERTs keep working.
--
-- This only relaxes the constraint, so no existing row can violate it and no
-- data cleanup is needed. Databases where the index was already widened by hand
-- (ITOUDP-7795) are fine: the index is simply rebuilt with the same columns.

ALTER TABLE `ipblock`
DROP INDEX `address`,
ADD UNIQUE KEY `address` (`address`,`prefix`,`layer3domain_id`,`version`),
ALGORITHM=INPLACE, LOCK=NONE;

UPDATE schemainfo SET version=14;
COMMIT;
17 changes: 17 additions & 0 deletions dim/dim/sql/rollback_14_to_13.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Drop `version` from the ipblock uniqueness key.
--
-- This tightens the constraint, so it fails if any two blocks share
-- (address, prefix, layer3domain_id) and differ only in `version` -- the
-- 0.0.0.0/0 plus ::/0 pair being the case migrate_13_to_14.sql allowed.
-- Remove one of each such pair before rolling back:
--
-- SELECT address, prefix, layer3domain_id, COUNT(*) FROM ipblock
-- GROUP BY address, prefix, layer3domain_id HAVING COUNT(*) > 1;

ALTER TABLE `ipblock`
DROP INDEX `address`,
ADD UNIQUE KEY `address` (`address`,`prefix`,`layer3domain_id`),
ALGORITHM=INPLACE, LOCK=NONE;

UPDATE schemainfo SET version=13;
COMMIT;
Loading