From: Francis Dupont Date: Wed, 16 Oct 2019 14:54:16 +0000 (+0200) Subject: [393-global-search-through-leases-by-mac-or-hostname-w-o-specifying-a-subnet-id]... X-Git-Tag: Kea-1.7.1~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=465cfbd9201df7be83e944a3e26e8897589abc04;p=thirdparty%2Fkea.git [393-global-search-through-leases-by-mac-or-hostname-w-o-specifying-a-subnet-id] Moves lease hostnames to lower case --- diff --git a/src/lib/dhcpsrv/lease.cc b/src/lib/dhcpsrv/lease.cc index 4b1f0bd6b5..d504a95eef 100644 --- a/src/lib/dhcpsrv/lease.cc +++ b/src/lib/dhcpsrv/lease.cc @@ -29,9 +29,9 @@ Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t valid_lft, SubnetID subnet_id, time_t cltt, const bool fqdn_fwd, const bool fqdn_rev, const std::string& hostname, const HWAddrPtr& hwaddr) - :addr_(addr), valid_lft_(valid_lft), cltt_(cltt), - subnet_id_(subnet_id), hostname_(hostname), fqdn_fwd_(fqdn_fwd), - fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) { + :addr_(addr), valid_lft_(valid_lft), cltt_(cltt), subnet_id_(subnet_id), + hostname_(boost::algorithm::to_lower_copy(hostname)), fqdn_fwd_(fqdn_fwd), + fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) { } @@ -237,6 +237,7 @@ Lease::fromElementCommon(const LeasePtr& lease, const data::ConstElementPtr& ele } lease->hostname_ = hostname->stringValue(); + boost::algorithm::to_lower(lease->hostname_); // state ConstElementPtr state = element->get("state"); diff --git a/src/lib/dhcpsrv/lease.h b/src/lib/dhcpsrv/lease.h index 2f661daa5b..1e3086354b 100644 --- a/src/lib/dhcpsrv/lease.h +++ b/src/lib/dhcpsrv/lease.h @@ -117,7 +117,7 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement { /// @brief Client hostname /// - /// This field may be empty + /// This field is in lower case and may be empty. std::string hostname_; /// @brief Forward zone updated? diff --git a/src/lib/dhcpsrv/tests/lease_unittest.cc b/src/lib/dhcpsrv/tests/lease_unittest.cc index 0763c0ce78..015f7becb9 100644 --- a/src/lib/dhcpsrv/tests/lease_unittest.cc +++ b/src/lib/dhcpsrv/tests/lease_unittest.cc @@ -126,7 +126,7 @@ TEST_F(Lease4Test, constructor) { // Create the lease Lease4 lease(ADDRESS[i], hwaddr_, clientid_, VALID_LIFETIME, current_time, SUBNET_ID, true, true, - "hostname.example.com."); + "Hostname.Example.Com."); EXPECT_EQ(ADDRESS[i], lease.addr_.toUint32()); EXPECT_TRUE(util::equalValues(hwaddr_, lease.hwaddr_)); @@ -370,7 +370,7 @@ TEST_F(Lease4Test, operatorEquals) { EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the EXPECT_FALSE(lease1 != lease2); // ... leases equal - lease1.hostname_ += std::string("Something random"); + lease1.hostname_ += std::string("something random"); EXPECT_FALSE(lease1 == lease2); EXPECT_TRUE(lease1 != lease2); lease1.hostname_ = lease2.hostname_; @@ -493,7 +493,7 @@ TEST_F(Lease4Test, toElement) { const time_t current_time = 12345678; Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, - current_time, 789, true, true, "urania.example.org"); + current_time, 789, true, true, "URANIA.example.org"); lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }")); std::string expected = "{" @@ -556,7 +556,7 @@ TEST_F(Lease4Test, fromElement) { "\"cltt\": 12345678," "\"fqdn-fwd\": true," "\"fqdn-rev\": true," - "\"hostname\": \"urania.example.org\"," + "\"hostname\": \"urania.example.ORG\"," "\"hw-address\": \"08:00:2b:02:3f:4e\"," "\"ip-address\": \"192.0.2.3\"," "\"state\": 0," @@ -634,7 +634,7 @@ TEST_F(Lease4Test, decline) { const time_t current_time = 12345678; Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, current_time, 789); - lease.hostname_="foo.example.org"; + lease.hostname_ = "foo.example.org"; lease.fqdn_fwd_ = true; lease.fqdn_rev_ = true; @@ -746,7 +746,7 @@ TEST(Lease6Test, Lease6ConstructorWithFQDN) { IOAddress addr(ADDRESS[i]); Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid, iaid, 100, 200, subnet_id, - true, true, "host.example.com.")); + true, true, "Host.Example.Com.")); EXPECT_TRUE(lease->addr_ == addr); EXPECT_TRUE(*lease->duid_ == *duid); @@ -862,7 +862,7 @@ TEST(Lease6Test, operatorEquals) { EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the EXPECT_FALSE(lease1 != lease2); // ... leases equal - lease1.hostname_ += std::string("Something random"); + lease1.hostname_ += std::string("something random"); EXPECT_FALSE(lease1 == lease2); EXPECT_TRUE(lease1 != lease2); lease1.hostname_ = lease2.hostname_; @@ -1220,7 +1220,7 @@ TEST(Lease6Test, fromElementNA) { "\"duid\": \"00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\"," "\"fqdn-fwd\": false," "\"fqdn-rev\": false," - "\"hostname\": \"urania.example.org\"," + "\"hostname\": \"urania.EXAMPLE.org\"," "\"hw-address\": \"08:00:2b:02:3f:4e\"," "\"iaid\": 123456," "\"ip-address\": \"2001:db8::1\"," @@ -1266,7 +1266,7 @@ TEST(Lease6Test, fromElementPD) { "\"duid\": \"00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\"," "\"fqdn-fwd\": false," "\"fqdn-rev\": false," - "\"hostname\": \"urania.example.org\"," + "\"hostname\": \"uraniA.exaMple.orG\"," "\"hw-address\": \"08:00:2b:02:3f:4e\"," "\"iaid\": 123456," "\"ip-address\": \"3000::\"," diff --git a/src/share/database/scripts/cql/dhcpdb_create.cql b/src/share/database/scripts/cql/dhcpdb_create.cql index 34d5cc7e12..903e039b08 100644 --- a/src/share/database/scripts/cql/dhcpdb_create.cql +++ b/src/share/database/scripts/cql/dhcpdb_create.cql @@ -374,6 +374,12 @@ ALTER TABLE hosts ADD lower_case_hostname VARCHAR; -- Make the lower case hostname an index. CREATE INDEX IF NOT EXISTS hostsindex8 ON hosts (lower_case_hostname); +-- Create a new hostname index on lease4. +CREATE INDEX IF NOT EXISTS lease4index6 ON lease4 (hostname); + +-- Create a new hostname index on lease6. +CREATE INDEX IF NOT EXISTS lease6index7 ON lease6 (hostname); + DELETE FROM schema_version WHERE version=4; INSERT INTO schema_version (version, minor) VALUES(5, 0); diff --git a/src/share/database/scripts/cql/dhcpdb_drop.cql b/src/share/database/scripts/cql/dhcpdb_drop.cql index 96c6ecc3d3..b70d8e7168 100644 --- a/src/share/database/scripts/cql/dhcpdb_drop.cql +++ b/src/share/database/scripts/cql/dhcpdb_drop.cql @@ -33,6 +33,7 @@ DROP INDEX IF EXISTS lease4index2; DROP INDEX IF EXISTS lease4index3; DROP INDEX IF EXISTS lease4index4; DROP INDEX IF EXISTS lease4index5; +DROP INDEX IF EXISTS lease4index6; DROP INDEX IF EXISTS lease6index1; DROP INDEX IF EXISTS lease6index2; @@ -40,6 +41,7 @@ DROP INDEX IF EXISTS lease6index3; DROP INDEX IF EXISTS lease6index4; DROP INDEX IF EXISTS lease6index5; DROP INDEX IF EXISTS lease6index6; +DROP INDEX IF EXISTS lease6index7; DROP INDEX IF EXISTS hostsindex1; DROP INDEX IF EXISTS hostsindex2; diff --git a/src/share/database/scripts/cql/upgrade_4.0_to_5.0.sh.in b/src/share/database/scripts/cql/upgrade_4.0_to_5.0.sh.in index 3d504513bd..36fc008004 100644 --- a/src/share/database/scripts/cql/upgrade_4.0_to_5.0.sh.in +++ b/src/share/database/scripts/cql/upgrade_4.0_to_5.0.sh.in @@ -41,6 +41,12 @@ ALTER TABLE hosts ADD lower_case_hostname VARCHAR; -- Make the lower case hostname an index. CREATE INDEX IF NOT EXISTS hostsindex8 ON hosts (lower_case_hostname); +-- Create a new hostname index on lease4. +CREATE INDEX IF NOT EXISTS lease4index6 ON lease4 (hostname); + +-- Create a new hostname index on lease6. +CREATE INDEX IF NOT EXISTS lease6index7 ON lease6 (hostname); + DELETE FROM schema_version WHERE version=4; INSERT INTO schema_version (version, minor) VALUES(5, 0); @@ -54,17 +60,37 @@ EOF fi } -# Function to delete temporary update files +# Functions to delete temporary update files clean_up() { # clean up the files - if [ -e "$export_file" ] + if [ -e "$host_export_file" ] + then + rm $host_export_file + fi + + if [ -e "$host_update_file" ] + then + rm $host_update_file + fi + + if [ -e "$lease4_export_file" ] + then + rm $lease4_export_file + fi + + if [ -e "$lease4_update_file" ] then - rm $export_file + rm $lease4_update_file fi - if [ -e "$update_file" ] + if [ -e "$lease6_export_file" ] then - rm $update_file + rm $lease6_export_file + fi + + if [ -e "$lease6_update_file" ] + then + rm $lease6_update_file fi } @@ -97,29 +123,26 @@ exit_now() { # # No parameters. update_host_data() { - export_file="$temp_file_dir/cql_export.csv" - update_file="$temp_file_dir/cql_update.cql" - clean_up # Fetch hosts data so we have primary key components and hostname. - echo "Exporting hostnames to $export_file ..." - query="COPY hosts (key, id, hostname) TO '$export_file'" + echo "Exporting hostnames to $host_export_file ..." + query="COPY hosts (key, id, hostname) TO '$host_export_file'" cqlsh $cqlargs -e "$query" if [ "$?" -ne 0 ] then - exit_now 1 "Cassandra get hostname failed! Could not update data!" + exit_now 1 "Cassandra get hostname failed! Could not update host!" fi # Strip the carriage returns that CQL insists on adding. - if [ -e "$export_file" ] + if [ -e "$host_export_file" ] then - cat $export_file | tr -d '\015' > $export_file.2 - mv $export_file.2 $export_file + cat $host_export_file | tr -d '\015' > $host_export_file.2 + mv $host_export_file.2 $host_export_file else # Shouldn't happen but then again we're talking about CQL here - exit_now 1 "Cassandra export file $export_file is missing?" + exit_now 1 "Cassandra export file $host_export_file is missing?" fi # Iterate through the exported data, accumulating update statements, @@ -167,31 +190,232 @@ update_host_data() { if [ "$hostname" != "" ] then lower=$(echo $hostname | tr '[:upper:]' '[:lower:]') - echo "update hosts set lower_case_hostname = '$lower' where key = $key and id = $host_id;" >> $update_file + echo "update hosts set lower_case_hostname = '$lower' where key = $key and id = $host_id;" >> $host_update_file + update_cnt=$((update_cnt + 1)) + fi + + IFS="$xIFS" + done < $host_export_file + + # If we didn't record any updates, then hey, we're good to go! + if [ "$update_cnt" -eq 0 ] + then + exit_now 0 "Completed successfully: No host updates were needed" + fi + + # We have at least one update in the update file, so submit it # to cqlsh. + echo "$update_cnt host update statements written to $host_update_file" + echo "Running the updates..." + cqlsh $cqlargs -f "$host_update_file" + if [ "$?" -ne 0 ] + then + exit_now 1 "Cassandra host updates failed" + fi + + exit_now 0 "Updated $update_cnt of $line_cnt host records" +} + +# This function moves lease4 hostnames to lower case. +# +# After exhausting the export file, the update file is submitted to +# cqlsh for execution. +# +# No parameters. +update_lease4_data() { + clean_up + + # Fetch lease4 data so we have primary address and hostname. + echo "Exporting hostnames to $lease4_export_file ..." + query="COPY lease4 (address, hostname) TO '$lease4_export_file'" + + cqlsh $cqlargs -e "$query" + if [ "$?" -ne 0 ] + then + exit_now 1 "Cassandra get hostname failed! Could not update lease4!" + fi + + # Strip the carriage returns that CQL insists on adding. + if [ -e "$lease4_export_file" ] + then + cat $lease4_export_file | tr -d '\015' > $lease4_export_file.2 + mv $lease4_export_file.2 $lease4_export_file + else + # Shouldn't happen but then again we're talking about CQL here + exit_now 1 "Cassandra export file $lease4_export_file is missing?" + fi + + # Iterate through the exported data, accumulating update statements, + # one for each lease that needs updating. We should have one lease4 + # per line. + line_cnt=0; + update_cnt=0; + + while read -r line + do + line_cnt=$((line_cnt + 1)); + xIFS="$IFS" + IFS=$',' + + i=1 + hostname= + # Parse the column values + for val in $line + do + case $i in + 1) + address="$val" + ;; + 2) + hostname="$val" + ;; + *) + # We're going to assume that since any error is fatal + exit_now 1 "Line# $line_cnt, too many values, wrong or corrupt file" + ;; + esac + i=$((i + 1)) + done + + if [ "$i" -lt 2 ] + then + # We're going to assume that since any error is fatal + exit_now 1 "Line# $line_cnt, too few values, wrong or corrupt file" + fi + + # If the hostname was not null set the lower case value + if [ "$hostname" != "" ] + then + lower=$(echo $hostname | tr '[:upper:]' '[:lower:]') + echo "update lease4 set hostname = '$lower' where address = $address;" >> $lease4_update_file update_cnt=$((update_cnt + 1)) fi IFS="$xIFS" - done < $export_file + done < $lease4_export_file # If we didn't record any updates, then hey, we're good to go! if [ "$update_cnt" -eq 0 ] then - exit_now 0 "Completed successfully: No updates were needed" + exit_now 0 "Completed successfully: No lease4 updates were needed" fi # We have at least one update in the update file, so submit it # to cqlsh. - echo "$update_cnt update statements written to $update_file" + echo "$update_cnt lease4 update statements written to $lease4_update_file" echo "Running the updates..." - cqlsh $cqlargs -f "$update_file" + cqlsh $cqlargs -f "$lease4_update_file" if [ "$?" -ne 0 ] then - exit_now 1 "Cassandra updates failed" + exit_now 1 "Cassandra lease4 updates failed" fi - exit_now 0 "Updated $update_cnt of $line_cnt records" + exit_now 0 "Updated $update_cnt of $line_cnt lease4 records" } +# This function moves lease6 hostnames to lower case. +# +# After exhausting the export file, the update file is submitted to +# cqlsh for execution. +# +# No parameters. +update_lease6_data() { + clean_up + + # Fetch lease6 data so we have primary address and hostname. + echo "Exporting hostnames to $lease6_export_file ..." + query="COPY lease6 (address, hostname) TO '$lease6_export_file'" + + cqlsh $cqlargs -e "$query" + if [ "$?" -ne 0 ] + then + exit_now 1 "Cassandra get hostname failed! Could not update lease6!" + fi + + # Strip the carriage returns that CQL insists on adding. + if [ -e "$lease6_export_file" ] + then + cat $lease6_export_file | tr -d '\015' > $lease6_export_file.2 + mv $lease6_export_file.2 $lease6_export_file + else + # Shouldn't happen but then again we're talking about CQL here + exit_now 1 "Cassandra export file $lease6_export_file is missing?" + fi + + # Iterate through the exported data, accumulating update statements, + # one for each lease that needs updating. We should have one lease6 + # per line. + line_cnt=0; + update_cnt=0; + + while read -r line + do + line_cnt=$((line_cnt + 1)); + xIFS="$IFS" + IFS=$',' + + i=1 + hostname= + # Parse the column values + for val in $line + do + case $i in + 1) + address="$val" + ;; + 2) + hostname="$val" + ;; + *) + # We're going to assume that since any error is fatal + exit_now 1 "Line# $line_cnt, too many values, wrong or corrupt file" + ;; + esac + i=$((i + 1)) + done + + if [ "$i" -lt 2 ] + then + # We're going to assume that since any error is fatal + exit_now 1 "Line# $line_cnt, too few values, wrong or corrupt file" + fi + + # If the hostname was not null set the lower case value + if [ "$hostname" != "" ] + then + lower=$(echo $hostname | tr '[:upper:]' '[:lower:]') + echo "update lease6 set hostname = '$lower' where address = $address;" >> $lease6_update_file + update_cnt=$((update_cnt + 1)) + fi + + IFS="$xIFS" + done < $lease6_export_file + + # If we didn't record any updates, then hey, we're good to go! + if [ "$update_cnt" -eq 0 ] + then + exit_now 0 "Completed successfully: No lease6 updates were needed" + fi + + # We have at least one update in the update file, so submit it # to cqlsh. + echo "$update_cnt lease6 update statements written to $lease6_update_file" + echo "Running the updates..." + cqlsh $cqlargs -f "$lease6_update_file" + if [ "$?" -ne 0 ] + then + exit_now 1 "Cassandra lease6 updates failed" + fi + + exit_now 0 "Updated $update_cnt of $line_cnt lease6 records" +} + +host_export_file="$temp_file_dir/cql_host_export.csv" +host_update_file="$temp_file_dir/cql_host_update.cql" +lease4_export_file="$temp_file_dir/cql_lease4_export.csv" +lease4_update_file="$temp_file_dir/cql_lease4_update.cql" +lease6_export_file="$temp_file_dir/cql_lease6_export.csv" +lease6_update_file="$temp_file_dir/cql_lease6_update.cql" + check_version update_schema update_host_data +update_lease4_data +update_lease6_data diff --git a/src/share/database/scripts/mysql/dhcpdb_create.mysql b/src/share/database/scripts/mysql/dhcpdb_create.mysql index f451757223..bc9a278041 100644 --- a/src/share/database/scripts/mysql/dhcpdb_create.mysql +++ b/src/share/database/scripts/mysql/dhcpdb_create.mysql @@ -2785,6 +2785,12 @@ SET version = '8', minor = '2'; # Create hostname index for host reservations CREATE INDEX hosts_by_hostname ON hosts (hostname); +# Create hostname index for lease4 +CREATE INDEX lease4_by_hostname ON lease4 (hostname); + +# Create hostname index for lease6 +CREATE INDEX lease6_by_hostname ON lease6 (hostname); + # Update the schema version number UPDATE schema_version SET version = '9', minor = '0'; diff --git a/src/share/database/scripts/mysql/upgrade_8.2_to_9.0.sh.in b/src/share/database/scripts/mysql/upgrade_8.2_to_9.0.sh.in index 1bdf048913..90732559d1 100644 --- a/src/share/database/scripts/mysql/upgrade_8.2_to_9.0.sh.in +++ b/src/share/database/scripts/mysql/upgrade_8.2_to_9.0.sh.in @@ -21,6 +21,20 @@ mysql "$@" </dev/null <