%PDF- %PDF-
Direktori : /backups/router/usr/local/share/kea/scripts/mysql/ |
Current File : //backups/router/usr/local/share/kea/scripts/mysql/upgrade_007.0_to_008.0.sh |
#!/bin/sh # Copyright (C) 2019-2024 Internet Systems Consortium, Inc. ("ISC") # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Exit with error if commands exit with non-zero and if undefined variables are # used. set -eu # shellcheck disable=SC2034 # SC2034: ... appears unused. Verify use (or export if used externally). prefix="/usr/local" # Include utilities based on location of this script. Check for sources first, # so that the unexpected situations with weird paths fall on the default # case of installed. script_path=$(cd "$(dirname "${0}")" && pwd) if test "${script_path}" = "/usr/obj/usr/ports/net/kea/work/kea-2.6.1/src/share/database/scripts/mysql"; then # shellcheck source=./src/bin/admin/admin-utils.sh.in . "/usr/obj/usr/ports/net/kea/work/kea-2.6.1/src/bin/admin/admin-utils.sh" else # shellcheck source=./src/bin/admin/admin-utils.sh.in . "${prefix}/share/kea/scripts/admin-utils.sh" fi VERSION=$(mysql_version "$@") if [ "$VERSION" != "7.0" ]; then printf 'This script upgrades 7.0 to 8.0. ' printf 'Reported version is %s. Skipping upgrade.\n' "${VERSION}" exit 0 fi mysql "$@" <<EOF -- This line starts the schema upgrade to version 8.0. ALTER TABLE dhcp4_options MODIFY COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; ALTER TABLE dhcp6_options MODIFY COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; ALTER TABLE dhcp4_subnet ADD COLUMN authoritative TINYINT(1) DEFAULT NULL, ADD COLUMN calculate_tee_times TINYINT(1) DEFAULT NULL, ADD COLUMN t1_percent FLOAT DEFAULT NULL, ADD COLUMN t2_percent FLOAT DEFAULT NULL; ALTER TABLE dhcp4_subnet MODIFY COLUMN reservation_mode TINYINT(3) DEFAULT NULL; ALTER TABLE dhcp4_subnet MODIFY COLUMN match_client_id TINYINT(1) DEFAULT NULL; ALTER TABLE dhcp4_shared_network ADD COLUMN authoritative TINYINT(1) DEFAULT NULL, ADD COLUMN calculate_tee_times TINYINT(1) DEFAULT NULL, ADD COLUMN t1_percent FLOAT DEFAULT NULL, ADD COLUMN t2_percent FLOAT DEFAULT NULL, ADD COLUMN boot_file_name VARCHAR(512) DEFAULT NULL, ADD COLUMN next_server INT(10) UNSIGNED DEFAULT NULL, ADD COLUMN server_hostname VARCHAR(512) DEFAULT NULL; ALTER TABLE dhcp4_shared_network MODIFY COLUMN reservation_mode TINYINT(3) DEFAULT NULL; ALTER TABLE dhcp4_shared_network MODIFY COLUMN match_client_id TINYINT(1) DEFAULT NULL; ALTER TABLE dhcp6_subnet ADD COLUMN calculate_tee_times TINYINT(1) DEFAULT NULL, ADD COLUMN t1_percent FLOAT DEFAULT NULL, ADD COLUMN t2_percent FLOAT DEFAULT NULL, ADD COLUMN interface_id VARCHAR(128) DEFAULT NULL; ALTER TABLE dhcp6_subnet MODIFY COLUMN reservation_mode TINYINT(3) DEFAULT NULL; ALTER TABLE dhcp6_subnet MODIFY COLUMN rapid_commit TINYINT(1) DEFAULT NULL; ALTER TABLE dhcp6_shared_network ADD COLUMN calculate_tee_times TINYINT(1) DEFAULT NULL, ADD COLUMN t1_percent FLOAT DEFAULT NULL, ADD COLUMN t2_percent FLOAT DEFAULT NULL, ADD COLUMN interface_id VARCHAR(128) DEFAULT NULL; ALTER TABLE dhcp6_shared_network MODIFY COLUMN reservation_mode TINYINT(3) DEFAULT NULL; ALTER TABLE dhcp6_shared_network MODIFY COLUMN rapid_commit TINYINT(1) DEFAULT NULL; -- ----------------------------------------------------- -- Make sure that constraints on the 7.0 schema tables -- have appropriate referential actions. All tables -- which join the configuration elements with the -- servers should perform cascade deletion. -- ----------------------------------------------------- ALTER TABLE dhcp4_global_parameter_server DROP FOREIGN KEY fk_dhcp4_global_parameter_server_server_id; ALTER TABLE dhcp4_global_parameter_server ADD CONSTRAINT fk_dhcp4_global_parameter_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp4_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp4_option_def_server DROP FOREIGN KEY fk_dhcp4_option_def_server_server_id; ALTER TABLE dhcp4_option_def_server ADD CONSTRAINT fk_dhcp4_option_def_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp4_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp4_shared_network_server DROP FOREIGN KEY fk_dhcp4_shared_network_server_server_id; ALTER TABLE dhcp4_shared_network_server ADD CONSTRAINT fk_dhcp4_shared_network_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp4_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp4_subnet_server DROP FOREIGN KEY fk_dhcp4_subnet_server_server_id; ALTER TABLE dhcp4_subnet_server ADD CONSTRAINT fk_dhcp4_subnet_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp4_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp4_options_server DROP FOREIGN KEY fk_dhcp4_options_server_server_id; ALTER TABLE dhcp4_options_server ADD CONSTRAINT fk_dhcp4_options_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp4_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp6_global_parameter_server DROP FOREIGN KEY fk_dhcp6_global_parameter_server_server_id; ALTER TABLE dhcp6_global_parameter_server ADD CONSTRAINT fk_dhcp6_global_parameter_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp6_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp6_option_def_server DROP FOREIGN KEY fk_dhcp6_option_def_server_server_id; ALTER TABLE dhcp6_option_def_server ADD CONSTRAINT fk_dhcp6_option_def_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp6_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp6_shared_network_server DROP FOREIGN KEY fk_dhcp6_shared_network_server_server_id; ALTER TABLE dhcp6_shared_network_server ADD CONSTRAINT fk_dhcp6_shared_network_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp6_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp6_subnet_server DROP FOREIGN KEY fk_dhcp6_subnet_server_server_id; ALTER TABLE dhcp6_subnet_server ADD CONSTRAINT fk_dhcp6_subnet_server_server_id FOREIGN KEY (server_id) REFERENCES dhcp6_server (id) ON DELETE CASCADE ON UPDATE NO ACTION; ALTER TABLE dhcp6_options_server DROP FOREIGN KEY fk_dhcp6_options_server_option_id; ALTER TABLE dhcp6_options_server ADD CONSTRAINT fk_dhcp6_options_server_option_id FOREIGN KEY (option_id) REFERENCES dhcp6_options (option_id) ON DELETE CASCADE ON UPDATE NO ACTION; -- ----------------------------------------------------- -- Table dhcp4_audit_revision -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS dhcp4_audit_revision ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, modification_ts TIMESTAMP NOT NULL, log_message TEXT, server_id BIGINT(10) UNSIGNED, PRIMARY KEY (id), KEY key_dhcp4_audit_revision_by_modification_ts (modification_ts) ) ENGINE=InnoDB; -- ----------------------------------------------------- -- Drop columns from the dhcp4_audit table which now -- belong to the dhcp4_audit_revision. -- ----------------------------------------------------- ALTER TABLE dhcp4_audit DROP COLUMN modification_ts, DROP COLUMN log_message; -- ----------------------------------------------------- -- Add column revision_id and the foreign key with a -- reference to the dhcp4_audit_revision table. -- ----------------------------------------------------- ALTER TABLE dhcp4_audit ADD COLUMN revision_id BIGINT(20) UNSIGNED NOT NULL; ALTER TABLE dhcp4_audit ADD CONSTRAINT fk_dhcp4_audit_revision FOREIGN KEY (revision_id) REFERENCES dhcp4_audit_revision (id) ON DELETE NO ACTION ON UPDATE CASCADE; -- ----------------------------------------------------- -- Stored procedure which creates a new entry in the -- dhcp4_audit_revision table and sets appropriate session -- variables to be used while creating the audit entries -- by triggers. This procedure should be called at the -- beginning of a transaction which modifies configuration -- data in the database, e.g. when new subnet is added. -- -- Parameters: -- - audit_ts timestamp to be associated with the audit -- revision. -- - server_tag is used to retrieve the server_id which -- associates the changes applied with the particular -- server or all servers. -- - audit_log_message is a log message associates with -- the audit revision. -- - cascade_transaction is assigned to a session -- variable which is used in some triggers to determine -- if the audit entry should be created for them or -- not. Specifically, this is used when DHCP options -- are inserted, updated or deleted. If such modification -- is a part of the larger change (e.g. change in the -- subnet the options belong to) the dedicated audit -- entry for options must not be created. On the other -- hand, if the global option is being added, the -- audit entry for the option must be created because -- it is the sole object modified in that case. -- Session variable disable_audit is used to disable -- the procedure when wiping the database during -- unit tests. This avoids issues with revision_id -- being null. -- ----------------------------------------------------- DROP PROCEDURE IF EXISTS createAuditRevisionDHCP4; DELIMITER $$ CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP, IN server_tag VARCHAR(256), IN audit_log_message TEXT, IN cascade_transaction TINYINT(1)) BEGIN DECLARE srv_id BIGINT(20); IF @disable_audit IS NULL OR @disable_audit = 0 THEN SELECT id INTO srv_id FROM dhcp4_server WHERE tag = server_tag; INSERT INTO dhcp4_audit_revision (modification_ts, server_id, log_message) VALUES (audit_ts, srv_id, audit_log_message); SET @audit_revision_id = LAST_INSERT_ID(); SET @cascade_transaction = cascade_transaction; END IF; END $$ DELIMITER ; -- ----------------------------------------------------- -- Stored procedure which creates a new entry in the -- dhcp4_audit table. It should be called from the -- triggers of the tables where the config modifications -- are applied. The @audit_revision_id variable contains -- the revision id to be placed in the audit entries. -- -- The following parameters are passed to this procedure: -- - object_type_val: name of the table to be associated -- with the applied changes. -- - object_id_val: identifier of the modified object in -- that table. -- - modification_type_val: string value indicating the -- type of the change, i.e. "create", "update" or -- "delete". -- Session variable disable_audit is used to disable -- the procedure when wiping the database during -- unit tests. This avoids issues with revision_id -- being null. -- ---------------------------------------------------- DROP PROCEDURE IF EXISTS createAuditEntryDHCP4; DELIMITER $$ CREATE PROCEDURE createAuditEntryDHCP4(IN object_type_val VARCHAR(256), IN object_id_val BIGINT(20) UNSIGNED, IN modification_type_val VARCHAR(32)) BEGIN IF @disable_audit IS NULL OR @disable_audit = 0 THEN INSERT INTO dhcp4_audit (object_type, object_id, modification_type, revision_id) VALUES (object_type_val, object_id_val, \ (SELECT id FROM modification WHERE modification_type = modification_type_val), \ @audit_revision_id); END IF; END $$ DELIMITER ; -- ----------------------------------------------------- -- Triggers used to create entries in the audit -- tables upon insertion, update or deletion of the -- configuration entries. -- ----------------------------------------------------- # Create dhcp4_global_parameter insert trigger DELIMITER $$ CREATE TRIGGER dhcp4_global_parameter_AINS AFTER INSERT ON dhcp4_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_global_parameter', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp4_global_parameter update trigger DELIMITER $$ CREATE TRIGGER dhcp4_global_parameter_AUPD AFTER UPDATE ON dhcp4_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_global_parameter', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp4_global_parameter delete trigger DELIMITER $$ CREATE TRIGGER dhcp4_global_parameter_ADEL AFTER DELETE ON dhcp4_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_global_parameter', OLD.id, "delete"); END $$ DELIMITER ; # Create dhcp4_subnet insert trigger DELIMITER $$ CREATE TRIGGER dhcp4_subnet_AINS AFTER INSERT ON dhcp4_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_subnet', NEW.subnet_id, "create"); END $$ DELIMITER ; # Create dhcp4_subnet update trigger DELIMITER $$ CREATE TRIGGER dhcp4_subnet_AUPD AFTER UPDATE ON dhcp4_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_subnet', NEW.subnet_id, "update"); END $$ DELIMITER ; # Create dhcp4_subnet delete trigger DELIMITER $$ CREATE TRIGGER dhcp4_subnet_ADEL AFTER DELETE ON dhcp4_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_subnet', OLD.subnet_id, "delete"); END $$ DELIMITER ; # Create dhcp4_shared_network insert trigger DELIMITER $$ CREATE TRIGGER dhcp4_shared_network_AINS AFTER INSERT ON dhcp4_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_shared_network', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp4_shared_network update trigger DELIMITER $$ CREATE TRIGGER dhcp4_shared_network_AUPD AFTER UPDATE ON dhcp4_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_shared_network', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp4_shared_network delete trigger DELIMITER $$ CREATE TRIGGER dhcp4_shared_network_ADEL AFTER DELETE ON dhcp4_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_shared_network', OLD.id, "delete"); END $$ DELIMITER ; # Create dhcp4_option_def insert trigger DELIMITER $$ CREATE TRIGGER dhcp4_option_def_AINS AFTER INSERT ON dhcp4_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_option_def', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp4_option_def update trigger DELIMITER $$ CREATE TRIGGER dhcp4_option_def_AUPD AFTER UPDATE ON dhcp4_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_option_def', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp4_option_def delete trigger DELIMITER $$ CREATE TRIGGER dhcp4_option_def_ADEL AFTER DELETE ON dhcp4_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP4('dhcp4_option_def', OLD.id, "delete"); END $$ DELIMITER ; -- ----------------------------------------------------- -- Stored procedure which creates an audit entry for a -- DHCPv4 option. Depending on the scope of the option -- the audit entry can be created for various levels -- of configuration hierarchy. If this is a global -- option the audit entry is created for this option -- for CREATE, UPDATE or DELETE. If the option is being -- added for an owning option, e.g. for a subnet, the -- audit entry is created as an UPDATE to this object. -- From the Kea perspective such option addition will -- be seen as a subnet update and the server will fetch -- the whole subnet and merge it into its configuration. -- The audit entry is not created if it was already -- created as part of the current transaction. -- -- The following parameters are passed to the procedure: -- - modification_type: "create", "update" or "delete" -- - scope_id: identifier of the option scope, e.g. -- global, subnet specific etc. -- - option_id: identifier of the option. -- - subnet_id: identifier of the subnet if the option -- belongs to the subnet. -- - host_id: identifier of the host if the option -- - belongs to the host. -- - network_name: shared network name if the option -- belongs to the shared network. -- - pool_id: identifier of the pool if the option -- belongs to the pool. -- ----------------------------------------------------- DROP PROCEDURE IF EXISTS createOptionAuditDHCP4; DELIMITER $$ CREATE PROCEDURE createOptionAuditDHCP4(IN modification_type VARCHAR(32), IN scope_id TINYINT(3) UNSIGNED, IN option_id BIGINT(20) UNSIGNED, IN subnet_id INT(10) UNSIGNED, IN host_id INT(10) UNSIGNED, IN network_name VARCHAR(128), IN pool_id BIGINT(20)) BEGIN # These variables will hold shared network id and subnet id that # we will select. DECLARE snid VARCHAR(128); DECLARE sid INT(10) UNSIGNED; # Cascade transaction flag is set to 1 to prevent creation of # the audit entries for the options when the options are # created as part of the parent object creation or update. # For example: when the option is added as part of the subnet # addition, the cascade transaction flag is equal to 1. If # the option is added into the existing subnet the cascade # transaction is equal to 0. Note that depending on the option # scope the audit entry will contain the object_type value # of the parent object to cause the server to replace the # entire subnet. The only case when the object_type will be # set to 'dhcp4_options' is when a global option is added. # Global options do not have the owner. IF @cascade_transaction IS NULL OR @cascade_transaction = 0 THEN # todo: host manager hasn't been updated to use audit # mechanisms so ignore host specific options for now. IF scope_id = 0 THEN # If a global option is added or modified, create audit # entry for the 'dhcp4_options' table. CALL createAuditEntryDHCP4('dhcp4_options', option_id, modification_type); ELSEIF scope_id = 1 THEN # If subnet specific option is added or modified, create # audit entry for the entire subnet, which indicates that # it should be treated as the subnet update. CALL createAuditEntryDHCP4('dhcp4_subnet', subnet_id, "update"); ELSEIF scope_id = 4 THEN # If shared network specific option is added or modified, # create audit entry for the shared network which # indicates that it should be treated as the shared # network update. SELECT id INTO snid FROM dhcp4_shared_network WHERE name = network_name LIMIT 1; CALL createAuditEntryDHCP4('dhcp4_shared_network', snid, "update"); ELSEIF scope_id = 5 THEN # If pool specific option is added or modified, create # audit entry for the subnet which this pool belongs to. SELECT dhcp4_pool.subnet_id INTO sid FROM dhcp4_pool WHERE id = pool_id; CALL createAuditEntryDHCP4('dhcp4_subnet', sid, "update"); END IF; END IF; END $$ DELIMITER ; # Create dhcp4_options insert trigger DELIMITER $$ CREATE TRIGGER dhcp4_options_AINS AFTER INSERT ON dhcp4_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP4("create", NEW.scope_id, NEW.option_id, NEW.dhcp4_subnet_id, NEW.host_id, NEW.shared_network_name, NEW.pool_id); END $$ DELIMITER ; # Create dhcp4_options update trigger DELIMITER $$ CREATE TRIGGER dhcp4_options_AUPD AFTER UPDATE ON dhcp4_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP4("update", NEW.scope_id, NEW.option_id, NEW.dhcp4_subnet_id, NEW.host_id, NEW.shared_network_name, NEW.pool_id); END $$ DELIMITER ; # Create dhcp4_options delete trigger DELIMITER $$ CREATE TRIGGER dhcp4_options_ADEL AFTER DELETE ON dhcp4_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP4("delete", OLD.scope_id, OLD.option_id, OLD.dhcp4_subnet_id, OLD.host_id, OLD.shared_network_name, OLD.pool_id); END $$ DELIMITER ; -- ----------------------------------------------------- -- Table parameter_data_type -- Reflects an enum used by Kea to define supported -- data types for the simple configuration parameters, -- e.g. global parameters used by DHCP servers. -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS parameter_data_type ( id TINYINT UNSIGNED NOT NULL PRIMARY KEY, name VARCHAR(32) NOT NULL ) ENGINE = InnoDB; START TRANSACTION; INSERT INTO parameter_data_type VALUES (0, 'integer'); INSERT INTO parameter_data_type VALUES (1, 'real'); INSERT INTO parameter_data_type VALUES (2, 'boolean'); INSERT INTO parameter_data_type VALUES (4, 'string'); COMMIT; ALTER TABLE dhcp4_global_parameter ADD COLUMN parameter_type TINYINT UNSIGNED NOT NULL; ALTER TABLE dhcp4_global_parameter ADD CONSTRAINT fk_dhcp4_global_parameter_type FOREIGN KEY (parameter_type) REFERENCES parameter_data_type (id); ALTER TABLE dhcp6_global_parameter ADD COLUMN parameter_type TINYINT UNSIGNED NOT NULL; ALTER TABLE dhcp6_global_parameter ADD CONSTRAINT fk_dhcp6_global_parameter_type FOREIGN KEY (parameter_type) REFERENCES parameter_data_type (id); -- Rename dhcp6_subnet_id column of dhcp6_pool and dhcp6_pd_pool ALTER TABLE dhcp6_pool DROP FOREIGN KEY fk_dhcp6_pool_subnet_id; DROP INDEX fk_dhcp6_pool_subnet_id ON dhcp6_pool; ALTER TABLE dhcp6_pd_pool DROP FOREIGN KEY fk_dhcp6_pd_pool_subnet_id; DROP INDEX fk_dhcp6_pd_pool_subnet_id ON dhcp6_pd_pool; ALTER TABLE dhcp6_pool CHANGE dhcp6_subnet_id subnet_id INT(10) UNSIGNED NOT NULL; ALTER TABLE dhcp6_pd_pool CHANGE dhcp6_subnet_id subnet_id INT(10) UNSIGNED NOT NULL; ALTER TABLE dhcp6_pool ADD CONSTRAINT fk_dhcp6_pool_subnet_id FOREIGN KEY (subnet_id) REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE dhcp6_pd_pool ADD CONSTRAINT fk_dhcp6_pd_pool_subnet_id FOREIGN KEY (subnet_id) REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE; -- align dhcp6_shared_network_server indexes on dhcp4_shared_network_server ALTER TABLE dhcp6_shared_network_server ADD PRIMARY KEY (shared_network_id, server_id); ALTER TABLE dhcp6_shared_network_server DROP FOREIGN KEY fk_dhcp6_shared_network_server_shared_network_id; DROP INDEX fk_dhcp6_shared_network_server_shared_network_id ON dhcp6_shared_network_server; ALTER TABLE dhcp6_shared_network_server ADD CONSTRAINT fk_dhcp6_shared_network_server_shared_network_id FOREIGN KEY (shared_network_id) REFERENCES dhcp6_shared_network (id) ON DELETE CASCADE ON UPDATE NO ACTION; -- Update dhcp4_subnet_server and dhcp6_subnet_server to allow update -- on the prefix too by setting the CASCADE action. ALTER TABLE dhcp4_subnet_server DROP FOREIGN KEY fk_dhcp4_subnet_server_subnet_id; ALTER TABLE dhcp4_subnet_server ADD CONSTRAINT fk_dhcp4_subnet_server_subnet_id FOREIGN KEY (subnet_id) REFERENCES dhcp4_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE dhcp6_subnet_server DROP FOREIGN KEY fk_dhcp6_subnet_server_subnet_id; ALTER TABLE dhcp6_subnet_server ADD CONSTRAINT fk_dhcp6_subnet_server_subnet_id FOREIGN KEY (subnet_id) REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE; -- ----------------------------------------------------- -- Table dhcp6_audit_revision -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS dhcp6_audit_revision ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, modification_ts TIMESTAMP NOT NULL, log_message TEXT, server_id BIGINT(10) UNSIGNED, PRIMARY KEY (id), KEY key_dhcp6_audit_revision_by_modification_ts (modification_ts) ) ENGINE=InnoDB; -- ----------------------------------------------------- -- Drop columns from the dhcp6_audit table which now -- belong to the dhcp6_audit_revision. -- ----------------------------------------------------- ALTER TABLE dhcp6_audit DROP COLUMN modification_ts, DROP COLUMN log_message; -- ----------------------------------------------------- -- Add column revision_id and the foreign key with a -- reference to the dhcp6_audit_revision table. -- ----------------------------------------------------- ALTER TABLE dhcp6_audit ADD COLUMN revision_id BIGINT(20) UNSIGNED NOT NULL; ALTER TABLE dhcp6_audit ADD CONSTRAINT fk_dhcp6_audit_revision FOREIGN KEY (revision_id) REFERENCES dhcp6_audit_revision (id) ON DELETE NO ACTION ON UPDATE CASCADE; -- ----------------------------------------------------- -- Stored procedure which creates a new entry in the -- dhcp6_audit_revision table and sets appropriate session -- variables to be used while creating the audit entries -- by triggers. This procedure should be called at the -- beginning of a transaction which modifies configuration -- data in the database, e.g. when new subnet is added. -- -- Parameters: -- - audit_ts timestamp to be associated with the audit -- revision. -- - server_tag is used to retrieve the server_id which -- associates the changes applied with the particular -- server or all servers. -- - audit_log_message is a log message associates with -- the audit revision. -- - cascade_transaction is assigned to a session -- variable which is used in some triggers to determine -- if the audit entry should be created for them or -- not. Specifically, this is used when DHCP options -- are inserted, updated or deleted. If such modification -- is a part of the larger change (e.g. change in the -- subnet the options belong to) the dedicated audit -- entry for options must not be created. On the other -- hand, if the global option is being added, the -- audit entry for the option must be created because -- it is the sole object modified in that case. -- Session variable disable_audit is used to disable -- the procedure when wiping the database during -- unit tests. This avoids issues with revision_id -- being null. -- ----------------------------------------------------- DROP PROCEDURE IF EXISTS createAuditRevisionDHCP6; DELIMITER $$ CREATE PROCEDURE createAuditRevisionDHCP6(IN audit_ts TIMESTAMP, IN server_tag VARCHAR(256), IN audit_log_message TEXT, IN cascade_transaction TINYINT(1)) BEGIN DECLARE srv_id BIGINT(20); IF @disable_audit IS NULL OR @disable_audit = 0 THEN SELECT id INTO srv_id FROM dhcp6_server WHERE tag = server_tag; INSERT INTO dhcp6_audit_revision (modification_ts, server_id, log_message) VALUES (audit_ts, srv_id, audit_log_message); SET @audit_revision_id = LAST_INSERT_ID(); SET @cascade_transaction = cascade_transaction; END IF; END $$ DELIMITER ; -- ----------------------------------------------------- -- Stored procedure which creates a new entry in the -- dhcp6_audit table. It should be called from the -- triggers of the tables where the config modifications -- are applied. The @audit_revision_id variable contains -- the revision id to be placed in the audit entries. -- -- The following parameters are passed to this procedure: -- - object_type_val: name of the table to be associated -- with the applied changes. -- - object_id_val: identifier of the modified object in -- that table. -- - modification_type_val: string value indicating the -- type of the change, i.e. "create", "update" or -- "delete". -- Session variable disable_audit is used to disable -- the procedure when wiping the database during -- unit tests. This avoids issues with revision_id -- being null. -- ---------------------------------------------------- DROP PROCEDURE IF EXISTS createAuditEntryDHCP6; DELIMITER $$ CREATE PROCEDURE createAuditEntryDHCP6(IN object_type_val VARCHAR(256), IN object_id_val BIGINT(20) UNSIGNED, IN modification_type_val VARCHAR(32)) BEGIN IF @disable_audit IS NULL OR @disable_audit = 0 THEN INSERT INTO dhcp6_audit (object_type, object_id, modification_type, revision_id) VALUES (object_type_val, object_id_val, \ (SELECT id FROM modification WHERE modification_type = modification_type_val), \ @audit_revision_id); END IF; END $$ DELIMITER ; -- ----------------------------------------------------- -- Triggers used to create entries in the audit -- tables upon insertion, update or deletion of the -- configuration entries. -- ----------------------------------------------------- # Create dhcp6_global_parameter insert trigger DELIMITER $$ CREATE TRIGGER dhcp6_global_parameter_AINS AFTER INSERT ON dhcp6_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_global_parameter', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp6_global_parameter update trigger DELIMITER $$ CREATE TRIGGER dhcp6_global_parameter_AUPD AFTER UPDATE ON dhcp6_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_global_parameter', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp6_global_parameter delete trigger DELIMITER $$ CREATE TRIGGER dhcp6_global_parameter_ADEL AFTER DELETE ON dhcp6_global_parameter FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_global_parameter', OLD.id, "delete"); END $$ DELIMITER ; # Create dhcp6_subnet insert trigger DELIMITER $$ CREATE TRIGGER dhcp6_subnet_AINS AFTER INSERT ON dhcp6_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_subnet', NEW.subnet_id, "create"); END $$ DELIMITER ; # Create dhcp6_subnet update trigger DELIMITER $$ CREATE TRIGGER dhcp6_subnet_AUPD AFTER UPDATE ON dhcp6_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_subnet', NEW.subnet_id, "update"); END $$ DELIMITER ; # Create dhcp6_subnet delete trigger DELIMITER $$ CREATE TRIGGER dhcp6_subnet_ADEL AFTER DELETE ON dhcp6_subnet FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_subnet', OLD.subnet_id, "delete"); END $$ DELIMITER ; # Create dhcp6_shared_network insert trigger DELIMITER $$ CREATE TRIGGER dhcp6_shared_network_AINS AFTER INSERT ON dhcp6_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_shared_network', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp6_shared_network update trigger DELIMITER $$ CREATE TRIGGER dhcp6_shared_network_AUPD AFTER UPDATE ON dhcp6_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_shared_network', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp6_shared_network delete trigger DELIMITER $$ CREATE TRIGGER dhcp6_shared_network_ADEL AFTER DELETE ON dhcp6_shared_network FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_shared_network', OLD.id, "delete"); END $$ DELIMITER ; # Create dhcp6_option_def insert trigger DELIMITER $$ CREATE TRIGGER dhcp6_option_def_AINS AFTER INSERT ON dhcp6_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_option_def', NEW.id, "create"); END $$ DELIMITER ; # Create dhcp6_option_def update trigger DELIMITER $$ CREATE TRIGGER dhcp6_option_def_AUPD AFTER UPDATE ON dhcp6_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_option_def', NEW.id, "update"); END $$ DELIMITER ; # Create dhcp6_option_def delete trigger DELIMITER $$ CREATE TRIGGER dhcp6_option_def_ADEL AFTER DELETE ON dhcp6_option_def FOR EACH ROW BEGIN CALL createAuditEntryDHCP6('dhcp6_option_def', OLD.id, "delete"); END $$ DELIMITER ; -- ----------------------------------------------------- -- Stored procedure which creates an audit entry for a -- DHCPv6 option. Depending on the scope of the option -- the audit entry can be created for various levels -- of configuration hierarchy. If this is a global -- option the audit entry is created for this option -- for CREATE, UPDATE or DELETE. If the option is being -- added for an owning option, e.g. for a subnet, the -- audit entry is created as an UPDATE to this object. -- From the Kea perspective such option addition will -- be seen as a subnet update and the server will fetch -- the whole subnet and merge it into its configuration. -- The audit entry is not created if it was already -- created as part of the current transaction. -- -- The following parameters are passed to the procedure: -- - modification_type: "create", "update" or "delete" -- - scope_id: identifier of the option scope, e.g. -- global, subnet specific etc. -- - option_id: identifier of the option. -- - subnet_id: identifier of the subnet if the option -- belongs to the subnet. -- - host_id: identifier of the host if the option -- - belongs to the host. -- - network_name: shared network name if the option -- belongs to the shared network. -- - pool_id: identifier of the pool if the option -- belongs to the pool. -- - pd_pool_id: identifier of the pool if the option -- belongs to the pd pool. -- ----------------------------------------------------- DROP PROCEDURE IF EXISTS createOptionAuditDHCP6; DELIMITER $$ CREATE PROCEDURE createOptionAuditDHCP6(IN modification_type VARCHAR(32), IN scope_id TINYINT(3) UNSIGNED, IN option_id BIGINT(20) UNSIGNED, IN subnet_id INT(10) UNSIGNED, IN host_id INT(10) UNSIGNED, IN network_name VARCHAR(128), IN pool_id BIGINT(20), IN pd_pool_id BIGINT(20)) BEGIN # These variables will hold shared network id and subnet id that # we will select. DECLARE snid VARCHAR(128); DECLARE sid INT(10) UNSIGNED; # Cascade transaction flag is set to 1 to prevent creation of # the audit entries for the options when the options are # created as part of the parent object creation or update. # For example: when the option is added as part of the subnet # addition, the cascade transaction flag is equal to 1. If # the option is added into the existing subnet the cascade # transaction is equal to 0. Note that depending on the option # scope the audit entry will contain the object_type value # of the parent object to cause the server to replace the # entire subnet. The only case when the object_type will be # set to 'dhcp6_options' is when a global option is added. # Global options do not have the owner. IF @cascade_transaction IS NULL OR @cascade_transaction = 0 THEN # todo: host manager hasn't been updated to use audit # mechanisms so ignore host specific options for now. IF scope_id = 0 THEN # If a global option is added or modified, create audit # entry for the 'dhcp6_options' table. CALL createAuditEntryDHCP6('dhcp6_options', option_id, modification_type); ELSEIF scope_id = 1 THEN # If subnet specific option is added or modified, create # audit entry for the entire subnet, which indicates that # it should be treated as the subnet update. CALL createAuditEntryDHCP6('dhcp6_subnet', subnet_id, "update"); ELSEIF scope_id = 4 THEN # If shared network specific option is added or modified, # create audit entry for the shared network which # indicates that it should be treated as the shared # network update. SELECT id INTO snid FROM dhcp6_shared_network WHERE name = network_name LIMIT 1; CALL createAuditEntryDHCP6('dhcp6_shared_network', snid, "update"); ELSEIF scope_id = 5 THEN # If pool specific option is added or modified, create # audit entry for the subnet which this pool belongs to. SELECT dhcp6_pool.subnet_id INTO sid FROM dhcp6_pool WHERE id = pool_id; CALL createAuditEntryDHCP6('dhcp6_subnet', sid, "update"); ELSEIF scope_id = 6 THEN # If pd pool specific option is added or modified, create # audit entry for the subnet which this pd pool belongs to. SELECT dhcp6_pd_pool.subnet_id INTO sid FROM dhcp6_pd_pool WHERE id = pd_pool_id; CALL createAuditEntryDHCP6('dhcp6_subnet', sid, "update"); END IF; END IF; END $$ DELIMITER ; # Create dhcp6_options insert trigger DELIMITER $$ CREATE TRIGGER dhcp6_options_AINS AFTER INSERT ON dhcp6_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP6("create", NEW.scope_id, NEW.option_id, NEW.dhcp6_subnet_id, NEW.host_id, NEW.shared_network_name, NEW.pool_id, NEW.pd_pool_id); END $$ DELIMITER ; # Create dhcp6_options update trigger DELIMITER $$ CREATE TRIGGER dhcp6_options_AUPD AFTER UPDATE ON dhcp6_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP6("update", NEW.scope_id, NEW.option_id, NEW.dhcp6_subnet_id, NEW.host_id, NEW.shared_network_name, NEW.pool_id, NEW.pd_pool_id); END $$ DELIMITER ; # Create dhcp6_options delete trigger DELIMITER $$ CREATE TRIGGER dhcp6_options_ADEL AFTER DELETE ON dhcp6_options FOR EACH ROW BEGIN CALL createOptionAuditDHCP6("delete", OLD.scope_id, OLD.option_id, OLD.dhcp6_subnet_id, OLD.host_id, OLD.shared_network_name, OLD.pool_id, OLD.pd_pool_id); END $$ DELIMITER ; # Update the schema version number. UPDATE schema_version SET version = '8', minor = '0'; # This line concludes the schema upgrade to version 8.0. EOF