Browse Source

[master] Merge branch 'trac5102'

Marcin Siodelski 8 years ago
parent
commit
390d687d0f

+ 2 - 0
configure.ac

@@ -1811,9 +1811,11 @@ AC_CONFIG_FILES([Makefile
                  src/share/database/scripts/mysql/upgrade_3.0_to_4.0.sh
                  src/share/database/scripts/mysql/upgrade_4.0_to_4.1.sh
                  src/share/database/scripts/mysql/upgrade_4.1_to_5.0.sh
+                 src/share/database/scripts/mysql/upgrade_5.0_to_5.1.sh
                  src/share/database/scripts/pgsql/Makefile
                  src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
                  src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
+                 src/share/database/scripts/pgsql/upgrade_3.0_to_3.1.sh
                  tools/Makefile
                  tools/path_replacer.sh
 ])

+ 4 - 4
src/bin/admin/tests/mysql_tests.sh.in

@@ -193,7 +193,7 @@ mysql_upgrade_test() {
 
     assert_str_eq "1.0" ${version} "Expected kea-admin to return %s, returned value was %s"
 
-    # Ok, we have a 1.0 database. Let's upgrade it to 5.0
+    # Ok, we have a 1.0 database. Let's upgrade it to 5.1
     ${keaadmin} lease-upgrade mysql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir
     ERRCODE=$?
 
@@ -300,7 +300,7 @@ EOF
     count=`mysql_execute "${qry}"`
     ERRCODE=$?
     assert_eq 0 $ERRCODE "select from host_identifier_type failed. (expected status code %d, returned %d)"
-    assert_eq 3 "$count" "host_identifier_type does not contain correct number of entries. (expected count %d, returned %d)"
+    assert_eq 4 "$count" "host_identifier_type does not contain correct number of entries. (expected count %d, returned %d)"
 
     # verify that foreign key fk_host_identifier_type exists
     qry="show create table hosts";
@@ -351,9 +351,9 @@ EOF
     count=`echo $text | grep -ic unsigned`
     assert_eq 1 $count "dhcp6_subnet_id is not of unsigned type. (expected count %d, returned %d)"
 
-    # Verify upgraded schema reports version 5.0
+    # Verify upgraded schema reports version 5.1
     version=$(${keaadmin} lease-version mysql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
-    assert_str_eq "5.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "5.1" ${version} "Expected kea-admin to return %s, returned value was %s"
 
     # Let's wipe the whole database
     mysql_wipe

+ 8 - 3
src/bin/admin/tests/pgsql_tests.sh.in

@@ -89,7 +89,7 @@ pgsql_lease_version_test() {
 
     # Verify that kea-admin lease-version returns the correct version
     version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name)
-    assert_str_eq "3.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "3.1" ${version} "Expected kea-admin to return %s, returned value was %s"
 
     # Let's wipe the whole database
     pgsql_wipe
@@ -197,10 +197,12 @@ pgsql_upgrade_2_0_to_3_0() {
     ERRCODE=$?
     assert_eq 0 $ERRCODE "select from lease_hwaddr_source failed. (expected status code %d, returned %d)"
     assert_eq 1 "$output" "lease_hwaddr_source does not contain entry for HWADDR_SOURCE_UKNOWN. (record count %d, expected %d)"
+}
 
-    # Verify upgraded schemd reports version 3.0.
+pgsql_upgrade_3_0_to_3_1() {
+    # Verify upgraded schemd reports version 3.1.
     version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
-    assert_str_eq "3.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "3.1" ${version} "Expected kea-admin to return %s, returned value was %s"
 }
 
 pgsql_upgrade_test() {
@@ -222,6 +224,9 @@ pgsql_upgrade_test() {
     # Check 2.0 to 3.0 upgrade
     pgsql_upgrade_2_0_to_3_0
 
+    # Check 3.0 to 3.1 upgrade
+    pgsql_upgrade_3_0_to_3_1
+
     # Let's wipe the whole database
     pgsql_wipe
 

+ 29 - 2
src/bin/dhcp4/tests/dora_unittest.cc

@@ -69,10 +69,12 @@ namespace {
 ///     - IP address 10.0.0.7 for HW address aa:bb:cc:dd:ee:ff
 ///     - IP address 10.0.0.8 for DUID 01:02:03:04:05
 ///     - IP address 10.0.0.9 for circuit-id 'charter950'
+///     - IP address 10.0.0.1 for client-id
 ///
 /// - Configuration 5:
 ///   - The same as configuration 4, but using the following order of
-///     host-reservation-identifiers: duid, circuit-id, hw-address.
+///     host-reservation-identifiers: duid, circuit-id, hw-address,
+///     client-id.
 ///
 /// - Configuration 6:
 ///   - This configuration provides reservations for next-server,
@@ -890,7 +892,7 @@ TEST_F(DORATest, reservation) {
 // DUID carried in the Client Identifier option.
 TEST_F(DORATest, reservationByDUID) {
     Dhcp4Client client(Dhcp4Client::SELECTING);
-    // Use relay agent so as the circuit-id can be inserted.
+    // Use relay agent.
     client.useRelay(true, IOAddress("10.0.0.1"), IOAddress("10.0.0.2"));
     // Modify HW address so as the server doesn't assign reserved
     // address by HW address.
@@ -942,6 +944,31 @@ TEST_F(DORATest, reservationByCircuitId) {
     ASSERT_EQ("10.0.0.9", client.config_.lease_.addr_.toText());
 }
 
+// This test checks that it is possible to make a reservation by
+// client-id.
+TEST_F(DORATest, reservationByClientId) {
+    Dhcp4Client client(Dhcp4Client::SELECTING);
+    // Use relay agent to make sure that the desired subnet is
+    // selected for our client.
+    client.useRelay(true, IOAddress("10.0.0.20"), IOAddress("10.0.0.21"));
+    // Specify client identifier.
+    client.includeClientId("01:11:22:33:44:55:66");
+
+    // Configure DHCP server.
+    configure(DORA_CONFIGS[2], *client.getServer());
+    // Client A performs 4-way exchange and should obtain a reserved
+    // address.
+    ASSERT_NO_THROW(client.doDORA(boost::shared_ptr<
+                                  IOAddress>(new IOAddress("0.0.0.0"))));
+    // Make sure that the server responded.
+    ASSERT_TRUE(client.getContext().response_);
+    Pkt4Ptr resp = client.getContext().response_;
+    // Make sure that the server has responded with DHCPACK.
+    ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+    // Make sure that the client has got the lease for the reserved address.
+    ASSERT_EQ("10.0.0.1", client.config_.lease_.addr_.toText());
+}
+
 // This test verifies that order in which host identifiers are used to
 // retrieve host reservations can be controlled.
 TEST_F(DORATest, hostIdentifiersOrder) {

+ 55 - 55
src/bin/dhcp4/tests/get_config_unittest.cc

@@ -1515,7 +1515,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -1556,7 +1556,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -1622,7 +1622,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -1688,7 +1688,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -1754,7 +1754,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -1892,7 +1892,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2030,7 +2030,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2096,7 +2096,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2162,7 +2162,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2228,7 +2228,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2294,7 +2294,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2360,7 +2360,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2450,7 +2450,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2540,7 +2540,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2606,7 +2606,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2702,7 +2702,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -2768,7 +2768,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -2819,7 +2819,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -2870,7 +2870,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -2930,7 +2930,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -2981,7 +2981,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -3032,7 +3032,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -3083,7 +3083,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -3134,7 +3134,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3215,7 +3215,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3296,7 +3296,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3387,7 +3387,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3462,7 +3462,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3578,7 +3578,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3667,7 +3667,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3773,7 +3773,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3848,7 +3848,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -3955,7 +3955,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4034,7 +4034,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4118,7 +4118,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"eth0\", \"eth1\" ]\n"
 "        },\n"
@@ -4159,7 +4159,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ]\n"
 "        },\n"
@@ -4200,7 +4200,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4266,7 +4266,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4332,7 +4332,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4543,7 +4543,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4638,7 +4638,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ ]\n"
 "        },\n"
@@ -4776,7 +4776,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4817,7 +4817,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4858,7 +4858,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4899,7 +4899,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 10\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -4940,7 +4940,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5006,7 +5006,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5072,7 +5072,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5138,7 +5138,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5204,7 +5204,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5293,7 +5293,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5359,7 +5359,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5425,7 +5425,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5492,7 +5492,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"
@@ -5563,7 +5563,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\" ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ]\n"
 "        },\n"

+ 1 - 0
src/lib/dhcpsrv/cfg_host_operations.cc

@@ -26,6 +26,7 @@ CfgHostOperations::createConfig4() {
     cfg->addIdentifierType("hw-address");
     cfg->addIdentifierType("duid");
     cfg->addIdentifierType("circuit-id");
+    cfg->addIdentifierType("client-id");
     return (cfg);
 }
 

+ 2 - 2
src/lib/dhcpsrv/mysql_connection.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2017 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
@@ -41,7 +41,7 @@ extern const int MLM_MYSQL_FETCH_FAILURE;
 /// @name Current database schema version values.
 //@{
 const uint32_t MYSQL_SCHEMA_VERSION_MAJOR = 5;
-const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 0;
+const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 1;
 
 //@}
 

+ 1 - 1
src/lib/dhcpsrv/mysql_host_data_source.cc

@@ -73,7 +73,7 @@ const size_t BOOT_FILE_NAME_MAX_LEN = 128;
 ///
 /// This value is used to validate whether the identifier type stored in
 /// a database is within bounds. of supported identifiers.
-const uint8_t MAX_IDENTIFIER_TYPE = static_cast<uint8_t>(Host::IDENT_CIRCUIT_ID);
+const uint8_t MAX_IDENTIFIER_TYPE = static_cast<uint8_t>(Host::LAST_IDENTIFIER_TYPE);
 
 /// @brief This class provides mechanisms for sending and retrieving
 /// information from the 'hosts' table.

+ 1 - 1
src/lib/dhcpsrv/pgsql_connection.h

@@ -19,7 +19,7 @@ namespace dhcp {
 
 /// @brief Define PostgreSQL backend version: 3.0
 const uint32_t PG_SCHEMA_VERSION_MAJOR = 3;
-const uint32_t PG_SCHEMA_VERSION_MINOR = 0;
+const uint32_t PG_SCHEMA_VERSION_MINOR = 1;
 
 // Maximum number of parameters that can be used a statement
 // @todo This allows us to use an initializer list (since we can't

+ 1 - 1
src/lib/dhcpsrv/pgsql_host_data_source.cc

@@ -44,7 +44,7 @@ const size_t OPTION_VALUE_MAX_LEN = 4096;
 ///
 /// This value is used to validate whether the identifier type stored in
 /// a database is within bounds. of supported identifiers.
-const uint8_t MAX_IDENTIFIER_TYPE = static_cast<uint8_t>(Host::IDENT_CIRCUIT_ID);
+const uint8_t MAX_IDENTIFIER_TYPE = static_cast<uint8_t>(Host::LAST_IDENTIFIER_TYPE);
 
 /// @brief Maximum length of DHCP identifier value.
 const size_t DHCP_IDENTIFIER_MAX_LEN = 128;

+ 1 - 0
src/lib/dhcpsrv/tests/cfg_host_operations_unittest.cc

@@ -97,6 +97,7 @@ TEST(CfgHostOperationsTest, createConfig4) {
     EXPECT_TRUE(identifierAtPosition(*cfg, Host::IDENT_HWADDR, 0));
     EXPECT_TRUE(identifierAtPosition(*cfg, Host::IDENT_DUID, 1));
     EXPECT_TRUE(identifierAtPosition(*cfg, Host::IDENT_CIRCUIT_ID, 2));
+    EXPECT_TRUE(identifierAtPosition(*cfg, Host::IDENT_CLIENT_ID, 3));
 }
 
 // This test verifies that the default DHCPv6 configuration is created

+ 6 - 0
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc

@@ -264,6 +264,12 @@ TEST_F(MySqlHostDataSourceTest, get4ByCircuitId) {
     testGet4ByIdentifier(Host::IDENT_CIRCUIT_ID);
 }
 
+// Test verifies if a host reservation can be added and later retrieved by
+// client-id.
+TEST_F(MySqlHostDataSourceTest, get4ByClientId) {
+    testGet4ByIdentifier(Host::IDENT_CLIENT_ID);
+}
+
 // Test verifies if hardware address and client identifier are not confused.
 TEST_F(MySqlHostDataSourceTest, hwaddrNotClientId1) {
     testHWAddrNotClientId();

+ 6 - 0
src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc

@@ -221,6 +221,12 @@ TEST_F(PgSqlHostDataSourceTest, get4ByCircuitId) {
     testGet4ByIdentifier(Host::IDENT_CIRCUIT_ID);
 }
 
+// Test verifies if a host reservation can be added and later retrieved by
+// client-id.
+TEST_F(PgSqlHostDataSourceTest, get4ByClientId) {
+    testGet4ByIdentifier(Host::IDENT_CLIENT_ID);
+}
+
 // Test verifies if hardware address and client identifier are not confused.
 TEST_F(PgSqlHostDataSourceTest, hwaddrNotClientId1) {
     testHWAddrNotClientId();

+ 1 - 1
src/lib/dhcpsrv/tests/srv_config_unittest.cc

@@ -450,7 +450,7 @@ TEST_F(SrvConfigTest, unparse) {
     std::string defaults4 = "\"echo-client-id\": true,\n";
     defaults4 += "\"subnet4\": [ ],\n";
     defaults4 += "\"host-reservation-identifiers\": ";
-    defaults4 += "[ \"hw-address\", \"duid\", \"circuit-id\" ],\n";
+    defaults4 += "[ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n";
 
     std::string defaults6 = "\"relay-supplied-options\": [ \"65\" ],\n";
     defaults6 += "\"subnet6\": [ ],\n";

+ 1 - 0
src/share/database/scripts/mysql/.gitignore

@@ -3,3 +3,4 @@
 /upgrade_3.0_to_4.0.sh
 /upgrade_4.0_to_4.1.sh
 /upgrade_4.1_to_5.0.sh
+/upgrade_5.0_to_5.1.sh

+ 11 - 3
src/share/database/scripts/mysql/dhcpdb_create.mysql

@@ -420,9 +420,9 @@ CREATE TABLE IF NOT EXISTS host_identifier_type (
 ) ENGINE = INNODB;
 
 START TRANSACTION;
-INSERT INTO host_identifier_type VALUES (0, 'hw-address'); # Non-temporary v6 addresses
-INSERT INTO host_identifier_type VALUES (1, 'duid');       # Temporary v6 addresses
-INSERT INTO host_identifier_type VALUES (2, 'circuit-id'); # Prefix delegations
+INSERT INTO host_identifier_type VALUES (0, 'hw-address');
+INSERT INTO host_identifier_type VALUES (1, 'duid');
+INSERT INTO host_identifier_type VALUES (2, 'circuit-id');
 COMMIT;
 
 # Add a constraint that any identifier type value added to the hosts
@@ -480,6 +480,14 @@ UPDATE schema_version
 SET version = '5', minor = '0';
 # This line concludes database upgrade to version 5.0.
 
+# Add missing 'client-id' host identifier type.
+INSERT INTO host_identifier_type VALUES (3, 'client-id');
+
+# Update the schema version number
+UPDATE schema_version
+SET version = '5', minor = '1';
+# This line concludes database upgrade to version 5.1.
+
 # Notes:
 #
 # Indexes

+ 32 - 0
src/share/database/scripts/mysql/upgrade_5.0_to_5.1.sh.in

@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Include utilities. Use installed version if available and
+# use build version if it isn't.
+if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+VERSION=`mysql_version "$@"`
+
+if [ "$VERSION" != "5.0" ]; then
+    printf "This script upgrades 5.0 to 5.1. Reported version is $VERSION. Skipping upgrade.\n"
+    exit 0
+fi
+
+mysql "$@" <<EOF
+
+# Add missing 'client-id' host identifier type.
+INSERT INTO host_identifier_type VALUES (3, 'client-id');
+
+# Update the schema version number
+UPDATE schema_version
+SET version = '5', minor = '1';
+# This line concludes database upgrade to version 5.1.
+
+EOF
+
+RESULT=$?
+
+exit $?

+ 1 - 0
src/share/database/scripts/pgsql/.gitignore

@@ -1,2 +1,3 @@
 upgrade_1.0_to_2.0.sh
 upgrade_2.0_to_3.0.sh
+upgrade_3.0_to_3.1.sh

+ 11 - 0
src/share/database/scripts/pgsql/dhcpdb_create.pgsql

@@ -483,6 +483,17 @@ UPDATE schema_version
 
 -- Schema 3.0 specification ends here.
 
+-- This is a placeholder for the changes between 3.0 and 3.1. Even if there
+-- are no further changes the schema version should be set to 3.1, because
+-- we have added a missing 'client-id' host reservation type entry in the
+-- 3.0 -> 3.1 upgrade script. This entry had been accidentally omitted when
+-- the 2.0 -> 3.0 upgrade script was created.
+
+-- Set 3.1 schema version.
+UPDATE schema_version
+    SET version = '3', minor = '1';
+
+
 -- Commit the script transaction.
 COMMIT;
 

+ 47 - 0
src/share/database/scripts/pgsql/upgrade_3.0_to_3.1.sh.in

@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Include utilities. Use installed version if available and
+# use build version if it isn't.
+if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+VERSION=`pgsql_version "$@"`
+
+if [ "$VERSION" != "3.0" ]; then
+    printf "This script upgrades 3.0 to 3.1. Reported version is $VERSION. Skipping upgrade.\n"
+    exit 0
+fi
+
+psql "$@" >/dev/null <<EOF
+
+START TRANSACTION;
+
+-- Upgrade to schema 3.1 begins here:
+
+-- The 'client-id' host identifier type was missing in the
+-- 2.0 -> 3.0 upgrade script. However, it was present in the
+-- dhcpdb_create.pgsql file. This means that this entry may
+-- or may not be present. By the conditional insert below we
+-- will only insert it if it doesn't exist.
+INSERT INTO host_identifier_type (type, name)
+  SELECT 3, 'client-id'
+    WHERE NOT EXISTS (
+        SELECT type FROM host_identifier_type WHERE type = 3
+    );
+
+-- Set 3.1 schema version.
+UPDATE schema_version
+    SET version = '3', minor = '1';
+
+-- Schema 3.1 specification ends here.
+
+-- Commit the script transaction
+COMMIT;
+
+EOF
+
+exit $RESULT
+