%PDF- %PDF-
Direktori : /backups/router/usr/local/share/kea/scripts/pgsql/ |
Current File : //backups/router/usr/local/share/kea/scripts/pgsql/upgrade_016_to_017.sh |
#!/bin/sh # Copyright (C) 2023-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/pgsql"; 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=$(pgsql_version "$@") if [ "$VERSION" != "16.0" ]; then printf 'This script upgrades 16.0 to 17.0. ' printf 'Reported version is %s. Skipping upgrade.\n' "${VERSION}" exit 0 fi psql "$@" >/dev/null <<EOF START TRANSACTION; -- This line starts the schema upgrade to version 17.0. UPDATE lease6 SET duid = E'\\\\x000000' WHERE duid = E'\\\\x00'; -- Add pool_id column to the lease4 table. ALTER TABLE lease4 ADD COLUMN pool_id BIGINT NOT NULL DEFAULT 0; -- Add pool_id column to the lease6 table. ALTER TABLE lease6 ADD COLUMN pool_id BIGINT NOT NULL DEFAULT 0; -- Create v4 lease statistics table CREATE TABLE lease4_pool_stat ( subnet_id BIGINT NOT NULL, pool_id BIGINT NOT NULL, state INT8 NOT NULL, leases BIGINT, PRIMARY KEY (subnet_id, pool_id, state) ); -- Create v6 lease statistics table CREATE TABLE lease6_pool_stat ( subnet_id BIGINT NOT NULL, pool_id BIGINT NOT NULL, lease_type SMALLINT NOT NULL, state INT8 NOT NULL, leases BIGINT, PRIMARY KEY (subnet_id, pool_id, lease_type, state) ); CREATE OR REPLACE FUNCTION lease4_AINS_lease4_pool_stat(IN new_state BIGINT, IN new_subnet_id BIGINT, IN new_pool_id BIGINT) RETURNS VOID AS \$\$ BEGIN IF new_state = 0 OR new_state = 1 THEN -- Update the state count if it exists. UPDATE lease4_pool_stat SET leases = leases + 1 WHERE subnet_id = new_subnet_id AND pool_id = new_pool_id AND state = new_state; -- Insert the state count record if it does not exist. IF NOT FOUND THEN INSERT INTO lease4_pool_stat VALUES (new_subnet_id, new_pool_id, new_state, 1); END IF; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION lease4_AUPD_lease4_pool_stat(IN old_state BIGINT, IN old_subnet_id BIGINT, IN old_pool_id BIGINT, IN new_state BIGINT, IN new_subnet_id BIGINT, IN new_pool_id BIGINT) RETURNS VOID AS \$\$ BEGIN IF old_subnet_id != new_subnet_id OR old_pool_id != new_pool_id OR old_state != new_state THEN IF old_state = 0 OR old_state = 1 THEN -- Decrement the old state count if record exists. UPDATE lease4_pool_stat SET leases = GREATEST(leases - 1, 0) WHERE subnet_id = old_subnet_id AND pool_id = old_pool_id AND state = old_state; END IF; IF new_state = 0 OR new_state = 1 THEN -- Increment the new state count if record exists. UPDATE lease4_pool_stat SET leases = leases + 1 WHERE subnet_id = new_subnet_id AND pool_id = new_pool_id AND state = new_state; -- Insert new state record if it does not exist. IF NOT FOUND THEN INSERT INTO lease4_pool_stat VALUES (new_subnet_id, new_pool_id, new_state, 1); END IF; END IF; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION lease4_ADEL_lease4_pool_stat(IN old_state BIGINT, IN old_subnet_id BIGINT, IN old_pool_id BIGINT) RETURNS VOID AS \$\$ BEGIN IF old_state = 0 OR old_state = 1 THEN -- Decrement the state count if record exists. UPDATE lease4_pool_stat SET leases = GREATEST(leases - 1, 0) WHERE subnet_id = old_subnet_id AND pool_id = old_pool_id AND state = old_state; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION lease6_AINS_lease6_pool_stat(IN new_state BIGINT, IN new_subnet_id BIGINT, IN new_pool_id BIGINT, IN new_lease_type SMALLINT) RETURNS VOID AS \$\$ BEGIN IF new_state = 0 OR new_state = 1 THEN -- Update the state count if it exists. UPDATE lease6_pool_stat SET leases = leases + 1 WHERE subnet_id = new_subnet_id AND pool_id = new_pool_id AND lease_type = new_lease_type AND state = new_state; -- Insert the state count record if it does not exist. IF NOT FOUND THEN INSERT INTO lease6_pool_stat VALUES (new_subnet_id, new_pool_id, new_lease_type, new_state, 1); END IF; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION lease6_AUPD_lease6_pool_stat(IN old_state BIGINT, IN old_subnet_id BIGINT, IN old_pool_id BIGINT, IN old_lease_type SMALLINT, IN new_state BIGINT, IN new_subnet_id BIGINT, IN new_pool_id BIGINT, IN new_lease_type SMALLINT) RETURNS VOID AS \$\$ BEGIN IF old_subnet_id != new_subnet_id OR old_pool_id != new_pool_id OR old_lease_type != new_lease_type OR old_state != new_state THEN IF old_state = 0 OR old_state = 1 THEN -- Decrement the old state count if record exists. UPDATE lease6_pool_stat SET leases = GREATEST(leases - 1, 0) WHERE subnet_id = old_subnet_id AND pool_id = old_pool_id AND lease_type = old_lease_type AND state = old_state; END IF; IF new_state = 0 OR new_state = 1 THEN -- Increment the new state count if record exists UPDATE lease6_pool_stat SET leases = leases + 1 WHERE subnet_id = new_subnet_id AND pool_id = new_pool_id AND lease_type = new_lease_type AND state = new_state; -- Insert new state record if it does not exist IF NOT FOUND THEN INSERT INTO lease6_pool_stat VALUES (new_subnet_id, new_pool_id, new_lease_type, new_state, 1); END IF; END IF; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION lease6_ADEL_lease6_pool_stat(IN old_state BIGINT, IN old_subnet_id BIGINT, IN old_pool_id BIGINT, IN old_lease_type SMALLINT) RETURNS VOID AS \$\$ BEGIN IF old_state = 0 OR old_state = 1 THEN -- Decrement the state count if record exists UPDATE lease6_pool_stat SET leases = GREATEST(leases - 1, 0) WHERE subnet_id = old_subnet_id AND pool_id = old_pool_id AND lease_type = old_lease_type AND state = old_state; END IF; END; \$\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease4_AINS() RETURNS trigger AS \$lease4_AINS\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease4_AINS_lease4_stat_by_client_class(NEW.state, NEW.user_context); END IF; PERFORM lease4_AINS_lease4_stat(NEW.state, NEW.subnet_id); PERFORM lease4_AINS_lease4_pool_stat(NEW.state, NEW.subnet_id, NEW.pool_id); RETURN NULL; END; \$lease4_AINS\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease4_AUPD() RETURNS trigger AS \$lease4_AUPD\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease4_AUPD_lease4_stat_by_client_class(OLD.state, OLD.user_context, NEW.state, NEW.user_context); END IF; PERFORM lease4_AUPD_lease4_stat(OLD.state, OLD.subnet_id, NEW.state, NEW.subnet_id); PERFORM lease4_AUPD_lease4_pool_stat(OLD.state, OLD.subnet_id, OLD.pool_id, NEW.state, NEW.subnet_id, NEW.pool_id); RETURN NULL; END; \$lease4_AUPD\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease4_ADEL() RETURNS trigger AS \$lease4_ADEL\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease4_ADEL_lease4_stat_by_client_class(OLD.state, OLD.user_context); END IF; PERFORM lease4_ADEL_lease4_stat(OLD.state, OLD.subnet_id); PERFORM lease4_ADEL_lease4_pool_stat(OLD.state, OLD.subnet_id, OLD.pool_id); RETURN NULL; END; \$lease4_ADEL\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease6_AINS() RETURNS trigger AS \$lease6_AINS\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease6_AINS_lease6_stat_by_client_class(NEW.state, NEW.user_context, NEW.lease_type); END IF; PERFORM lease6_AINS_lease6_stat(NEW.state, NEW.subnet_id, NEW.lease_type); PERFORM lease6_AINS_lease6_pool_stat(NEW.state, NEW.subnet_id, NEW.pool_id, NEW.lease_type); RETURN NULL; END; \$lease6_AINS\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease6_AUPD() RETURNS trigger AS \$lease6_AUPD\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease6_AUPD_lease6_stat_by_client_class(OLD.state, OLD.user_context, OLD.lease_type, NEW.state, NEW.user_context, NEW.lease_type); END IF; PERFORM lease6_AUPD_lease6_stat(OLD.state, OLD.subnet_id, OLD.lease_type, NEW.state, NEW.subnet_id, NEW.lease_type); PERFORM lease6_AUPD_lease6_pool_stat(OLD.state, OLD.subnet_id, OLD.pool_id, OLD.lease_type, NEW.state, NEW.subnet_id, NEW.pool_id, NEW.lease_type); RETURN NULL; END; \$lease6_AUPD\$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION func_lease6_ADEL() RETURNS trigger AS \$lease6_ADEL\$ BEGIN IF isJsonSupported() = true THEN PERFORM lease6_ADEL_lease6_stat_by_client_class(OLD.state, OLD.user_context, OLD.lease_type); END IF; PERFORM lease6_ADEL_lease6_stat(OLD.state, OLD.subnet_id, OLD.lease_type); PERFORM lease6_ADEL_lease6_pool_stat(OLD.state, OLD.subnet_id, OLD.pool_id, OLD.lease_type); RETURN NULL; END; \$lease6_ADEL\$ LANGUAGE plpgsql; DROP FUNCTION IF EXISTS lease4DumpHeader(); CREATE OR REPLACE FUNCTION lease4DumpHeader() RETURNS text AS \$\$ select cast('address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context,pool_id' as text) as result; \$\$ LANGUAGE SQL; -- Adding support for pool ID in function to output a memfile-ready CSV file. -- Some columns that are SMALLINT in the lease4 table have their type promoted -- to INT in the declaration of this function for backwards compatibility with -- PostgreSQL versions. DROP FUNCTION IF EXISTS lease4DumpData(); CREATE OR REPLACE FUNCTION lease4DumpData() RETURNS TABLE ( address INET, hwaddr VARCHAR, client_id VARCHAR, valid_lifetime BIGINT, expire BIGINT, subnet_id BIGINT, fqdn_fwd INT, fqdn_rev INT, hostname VARCHAR, state INT8, user_context VARCHAR, pool_id BIGINT ) AS \$\$ SELECT ('0.0.0.0'::inet + address), colonSeparatedHex(encode(hwaddr, 'hex')), colonSeparatedHex(encode(client_id, 'hex')), valid_lifetime, extract(epoch from expire)::bigint, subnet_id, fqdn_fwd::int, fqdn_rev::int, replace(hostname, ',', ','), state, replace(user_context, ',', ','), pool_id FROM lease4 ORDER BY address; \$\$ LANGUAGE SQL; DROP FUNCTION IF EXISTS lease6DumpHeader(); CREATE OR REPLACE FUNCTION lease6DumpHeader() RETURNS TEXT AS \$\$ SELECT CAST('address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,state,user_context,hwtype,hwaddr_source,pool_id' AS TEXT) AS result; \$\$ LANGUAGE SQL; -- Adding support for pool ID in function to output a memfile-ready CSV file. -- Some columns that are SMALLINT in the lease6 table have their type promoted -- to INT in the declaration of this function for backwards compatibility with -- PostgreSQL versions. DROP FUNCTION IF EXISTS lease6DumpData(); CREATE OR REPLACE FUNCTION lease6DumpData() RETURNS TABLE ( address VARCHAR, duid VARCHAR, valid_lifetime BIGINT, expire BIGINT, subnet_id BIGINT, pref_lifetime BIGINT, lease_type SMALLINT, iaid INT, prefix_len SMALLINT, fqdn_fwd INT, fqdn_rev INT, hostname VARCHAR, hwaddr VARCHAR, state INT8, user_context VARCHAR, hwtype SMALLINT, hwaddr_source SMALLINT, pool_id BIGINT ) AS \$\$ SELECT address, colonSeparatedHex(encode(duid, 'hex')), valid_lifetime, extract(epoch from expire)::bigint, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd::int, fqdn_rev::int, replace(hostname, ',', ','), colonSeparatedHex(encode(hwaddr, 'hex')), state, replace(user_context, ',', ','), hwtype, hwaddr_source, pool_id FROM lease6 ORDER BY address; \$\$ LANGUAGE SQL; -- Adding support for pool id in function that inserts a v4 lease from memfile data. -- Some columns that are SMALLINT in the lease4 table have their type promoted -- to INT in the declaration of this function for backwards compatibility with -- PostgreSQL versions. CREATE OR REPLACE FUNCTION lease4Upload( IN address VARCHAR, IN hwaddr VARCHAR, IN client_id VARCHAR, IN valid_lifetime BIGINT, IN expire BIGINT, IN subnet_id BIGINT, IN fqdn_fwd INT, IN fqdn_rev INT, IN hostname VARCHAR, IN state INT8, IN user_context VARCHAR, IN pool_id BIGINT ) RETURNS VOID AS \$\$ BEGIN INSERT INTO lease4 ( address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state, user_context, pool_id ) VALUES ( address::inet - '0.0.0.0'::inet, decode(replace(hwaddr, ':', ''), 'hex'), decode(replace(client_id, ':', ''), 'hex'), valid_lifetime, to_timestamp(expire), subnet_id, fqdn_fwd::int::boolean, fqdn_rev::int::boolean, replace(hostname, ',', ','), state, replace(user_context, ',', ','), pool_id ); END \$\$ LANGUAGE plpgsql; -- Adding support for pool id in function that inserts a v6 lease from memfile data. -- Some columns that are SMALLINT in the lease6 table have their type promoted -- to INT in the declaration of this function for backwards compatibility with -- PostgreSQL versions. CREATE OR REPLACE FUNCTION lease6Upload( IN address VARCHAR, IN duid VARCHAR, IN valid_lifetime BIGINT, IN expire BIGINT, IN subnet_id BIGINT, IN pref_lifetime BIGINT, IN lease_type INT, IN iaid INT, IN prefix_len INT, IN fqdn_fwd INT, IN fqdn_rev INT, IN hostname VARCHAR, IN hwaddr VARCHAR, IN state INT8, IN user_context VARCHAR, IN hwtype INT, IN hwaddr_source INT, IN pool_id BIGINT ) RETURNS VOID AS \$\$ BEGIN INSERT INTO lease6 ( address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, state, user_context, hwtype, hwaddr_source, pool_id ) VALUES ( address, decode(replace(duid, ':', ''), 'hex'), valid_lifetime, to_timestamp(expire), subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd::int::boolean, fqdn_rev::int::boolean, replace(hostname, ',', ','), decode(replace(hwaddr, ':', ''), 'hex'), state, replace(user_context, ',', ','), hwtype, hwaddr_source, pool_id ); END \$\$ LANGUAGE plpgsql; INSERT INTO lease4_pool_stat (subnet_id, pool_id, state, leases) SELECT subnet_id, pool_id, state, count(*) FROM lease4 WHERE state = 0 OR state = 1 GROUP BY subnet_id, pool_id, state; INSERT INTO lease6_pool_stat (subnet_id, pool_id, lease_type, state, leases) SELECT subnet_id, pool_id, lease_type, state, count(*) FROM lease6 WHERE state = 0 OR state = 1 GROUP BY subnet_id, pool_id, lease_type, state; -- Add the binary version of the IPv6 address for v6 BLQ prefix filter. ALTER TABLE lease6 ADD COLUMN binaddr BYTEA DEFAULT NULL; CREATE INDEX lease6_by_binaddr ON lease6 (binaddr ASC); -- Create table for v6 BLQ by-relay-id. CREATE TABLE lease6_relay_id ( extended_info_id SERIAL PRIMARY KEY NOT NULL, relay_id BYTEA NOT NULL, lease_addr BYTEA NOT NULL); CREATE INDEX lease6_relay_id_by_id ON lease6_relay_id (relay_id, lease_addr ASC); CREATE INDEX lease6_relay_id_by_address ON lease6_relay_id (lease_addr); -- Create table for v6 BLQ by-remote-id. CREATE TABLE lease6_remote_id ( extended_info_id SERIAL PRIMARY KEY NOT NULL, remote_id BYTEA NOT NULL, lease_addr BYTEA NOT NULL); CREATE INDEX lease6_remote_id_by_id ON lease6_remote_id (remote_id, lease_addr ASC); CREATE INDEX lease6_remote_id_by_address ON lease6_remote_id (lease_addr); -- Update the schema version number. UPDATE schema_version SET version = '17', minor = '0'; -- This line concludes the schema upgrade to version 17.0. -- Commit the script transaction. COMMIT; EOF