]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[465-add-subnet4-update-and-subnet6-update-commands-to-subnet-cmds-hook] Added missin...
authorFrancis Dupont <fdupont@isc.org>
Fri, 8 Mar 2019 22:21:39 +0000 (23:21 +0100)
committerTomek Mrugalski <tomek@isc.org>
Fri, 19 Apr 2019 10:39:47 +0000 (06:39 -0400)
doc/Makefile.am
doc/api/subnet4-update.json [new file with mode: 0644]
doc/api/subnet6-update.json [new file with mode: 0644]
doc/guide/api.xml
doc/guide/hooks.xml
src/lib/dhcpsrv/cfg_subnets4.cc
src/lib/dhcpsrv/cfg_subnets6.cc
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc

index c884546ea5d886afcb009f32467316069ff94410..4a1067509116bbd987f5dc50276c59b784eb9417 100644 (file)
@@ -116,8 +116,10 @@ EXTRA_DIST += api/statistic-reset-all.json api/statistic-reset.json
 EXTRA_DIST += api/stat-lease4-get.json api/stat-lease6-get.json
 EXTRA_DIST += api/subnet4-add.json api/subnet4-del.json
 EXTRA_DIST += api/subnet4-get.json api/subnet4-list.json
+EXTRA_DIST += api/subnet4-update.json
 EXTRA_DIST += api/subnet6-add.json api/subnet6-del.json
 EXTRA_DIST += api/subnet6-get.json api/subnet6-list.json
+EXTRA_DIST += api/subnet6-update.json
 EXTRA_DIST += api/_template.json api/version-get.json
 
 devel:
diff --git a/doc/api/subnet4-update.json b/doc/api/subnet4-update.json
new file mode 100644 (file)
index 0000000..5926b47
--- /dev/null
@@ -0,0 +1,30 @@
+{
+    "name": "subnet4-update",
+    "brief": "This command is used to update a subnet in the existing server configuration.",
+    "description": "See <xref linkend=\"idp69\"/>",
+    "support": [ "kea-dhcp4"],
+    "avail": "1.6.0",
+    "hook": "subnet_cmds",
+    "cmd-syntax": "{
+    \"command\": \"subnet4-update\",
+    \"arguments\": {
+        \"subnets\": [ {
+            \"id\": 123,
+            \"subnet\": \"10.20.30.0/24\",
+            ...
+        } ]
+    }
+}",
+    "resp-syntax": "{
+    \"result\": 0,
+    \"text\": \"IPv4 subnet updated\",
+    \"arguments\": {
+        \"subnets\": [
+            {
+                \"id\": 123,
+                \"subnet\": \"10.20.30.0/24\"
+            }
+        ]
+    }
+}"
+}
diff --git a/doc/api/subnet6-update.json b/doc/api/subnet6-update.json
new file mode 100644 (file)
index 0000000..9360a37
--- /dev/null
@@ -0,0 +1,30 @@
+{
+    "name": "subnet6-update",
+    "brief": "This command is used to update a subnet in the existing server configuration. This operation has no impact on other subnets.",
+    "description": "See <xref linkend=\"idp70\"/>",
+    "support": [ "kea-dhcp6" ],
+    "avail": "1.6.0",
+    "hook": "subnet_cmds",
+    "cmd-syntax": "{
+    \"command\": \"subnet6-update\",
+    \"arguments\": {
+        \"subnet6\": [ {
+            \"id\": 234,
+            \"subnet\": \"2001:db8:1::/64\",
+            ...
+        } ]
+    }
+}",
+    "resp-syntax": "{
+    \"result\": 0,
+    \"text\": \"IPv6 subnet updated\",
+    \"arguments\": {
+        \"subnet6\": [
+            {
+                \"id\": 234,
+                \"subnet\": \"2001:db8:1::/64\"
+            }
+        ]
+    }
+}"
+}
index 660b3d0468d7261eae75390529c2a1351c53ad82..489250204deeea6ed2004244da30f57e558bc0c3 100644 (file)
 , <command><link linkend="ref-subnet4-del">subnet4-del</link></command>
 , <command><link linkend="ref-subnet4-get">subnet4-get</link></command>
 , <command><link linkend="ref-subnet4-list">subnet4-list</link></command>
+, <command><link linkend="ref-subnet4-update">subnet4-update</link></command>
 , <command><link linkend="ref-subnet6-add">subnet6-add</link></command>
 , <command><link linkend="ref-subnet6-del">subnet6-del</link></command>
 , <command><link linkend="ref-subnet6-get">subnet6-get</link></command>
 , <command><link linkend="ref-subnet6-list">subnet6-list</link></command>
+, <command><link linkend="ref-subnet6-update">subnet6-update</link></command>
 , <command><link linkend="ref-version-get">version-get</link></command>
 .</para>
 <para xml:id="commands-kea-ctrl-agent">Commands supported by kea-ctrl-agent daemon: <command><link linkend="ref-build-report">build-report</link></command>
 , <command><link linkend="ref-subnet4-del">subnet4-del</link></command>
 , <command><link linkend="ref-subnet4-get">subnet4-get</link></command>
 , <command><link linkend="ref-subnet4-list">subnet4-list</link></command>
+, <command><link linkend="ref-subnet4-update">subnet4-update</link></command>
 , <command><link linkend="ref-version-get">version-get</link></command>
 .</para>
 <para xml:id="commands-kea-dhcp6">Commands supported by kea-dhcp6 daemon: <command><link linkend="ref-build-report">build-report</link></command>
 , <command><link linkend="ref-subnet6-del">subnet6-del</link></command>
 , <command><link linkend="ref-subnet6-get">subnet6-get</link></command>
 , <command><link linkend="ref-subnet6-list">subnet6-list</link></command>
+, <command><link linkend="ref-subnet6-update">subnet6-update</link></command>
 , <command><link linkend="ref-version-get">version-get</link></command>
 .</para>
 <para xml:id="commands-class_cmds-lib">Commands supported by class_cmds hook library: <command><link linkend="ref-class-add">class-add</link></command>
 , <command><link linkend="ref-subnet4-del">subnet4-del</link></command>
 , <command><link linkend="ref-subnet4-get">subnet4-get</link></command>
 , <command><link linkend="ref-subnet4-list">subnet4-list</link></command>
+, <command><link linkend="ref-subnet4-update">subnet4-update</link></command>
 , <command><link linkend="ref-subnet6-add">subnet6-add</link></command>
 , <command><link linkend="ref-subnet6-del">subnet6-del</link></command>
 , <command><link linkend="ref-subnet6-get">subnet6-get</link></command>
 , <command><link linkend="ref-subnet6-list">subnet6-list</link></command>
+, <command><link linkend="ref-subnet6-update">subnet6-update</link></command>
 .</para>
 <!-- start of build-report -->
 <section xml:id="reference-build-report">
@@ -3175,6 +3181,54 @@ If no IPv4 subnets are found, an error code is returned along with the error des
 </section>
 <!-- end of subnet4-list -->
 
+<!-- start of subnet4-update -->
+<section xml:id="reference-subnet4-update">
+<title>subnet4-update reference</title>
+<para xml:id="ref-subnet4-update"><command>subnet4-update</command> - This command is used to  update a subnet in the existing server configuration.</para>
+
+<para>Supported by: <command><link linkend="commands-kea-dhcp4">kea-dhcp4</link></command></para>
+
+<para>Availability: 1.6.0 (<link linkend="commands-subnet_cmds-lib">subnet_cmds</link>  hook)</para>
+
+<para>Description and examples: See <xref linkend="command-subnet4-update"/></para>
+
+<para>Command syntax:
+  <screen>{
+    "command": "subnet4-update",
+    "arguments": {
+        "subnet4": [ {
+            "id": 123,
+            "subnet": "10.20.30.0/24",
+            ...
+        } ]
+    }
+}</screen>
+</para>
+
+<para>Response syntax:
+  <screen>{
+    "result": 0,
+    "text": "IPv4 subnet updated",
+    "arguments": {
+        "subnets": [
+            {
+                "id": 123,
+                "subnet": "10.20.30.0/24"
+            }
+        ]
+    }
+}</screen>
+Result is an integer representation of the status. Currently supported statuses are:
+<itemizedlist>
+  <listitem><para>0 - success</para></listitem>
+  <listitem><para>1 - error</para></listitem>
+  <listitem><para>2 - unsupported</para></listitem>
+</itemizedlist>
+</para>
+
+</section>
+<!-- end of subnet4-update -->
+
 <!-- start of subnet6-add -->
 <section xml:id="reference-subnet6-add">
 <title>subnet6-add reference</title>
@@ -3354,6 +3408,54 @@ If no IPv6 subnets are found, an error code is returned along with the error des
 </section>
 <!-- end of subnet6-list -->
 
+<!-- start of subnet6-update -->
+<section xml:id="reference-subnet6-update">
+<title>subnet6-update reference</title>
+<para xml:id="ref-subnet6-update"><command>subnet6-update</command> - This command is used to update a subnet in the existing server configuration. This operation has no impact on other subnets.</para>
+
+<para>Supported by: <command><link linkend="commands-kea-dhcp6">kea-dhcp6</link></command></para>
+
+<para>Availability: 1.6.0 (<link linkend="commands-subnet_cmds-lib">subnet_cmds</link>  hook)</para>
+
+<para>Description and examples: See <xref linkend="command-subnet6-update"/></para>
+
+<para>Command syntax:
+  <screen>{
+    "command": "subnet6-update",
+    "arguments": {
+        "subnet6": [ {
+            "id": 234,
+            "subnet": "2001:db8:1::/64",
+            ...
+        } ]
+    }
+}</screen>
+</para>
+
+<para>Response syntax:
+  <screen>{
+    "result": 0,
+    "text": "IPv6 subnet updated",
+    "arguments": {
+        "subnet6": [
+            {
+                "id": 234,
+                "subnet": "2001:db8:1::/64"
+            }
+        ]
+    }
+}</screen>
+Result is an integer representation of the status. Currently supported statuses are:
+<itemizedlist>
+  <listitem><para>0 - success</para></listitem>
+  <listitem><para>1 - error</para></listitem>
+  <listitem><para>2 - unsupported</para></listitem>
+</itemizedlist>
+</para>
+
+</section>
+<!-- end of subnet6-update -->
+
 <!-- start of version-get -->
 <section xml:id="reference-version-get">
 <title>version-get reference</title>
index c8946447e4388de7d01a1034919330653e02d20e..a1823ee0e286de0f2e931259e61dd339019257f9 100644 (file)
@@ -1714,7 +1714,7 @@ An example result returned when the query was malformed:<screen>
           <command>reservation-get-page</command> instead (see <xref
           linkend="command-reservation-get-page"/>).
           </para>
-          
+
           <para>
           For a reference, see <xref linkend="ref-reservation-get-all"/>.
           </para>
@@ -1973,6 +1973,10 @@ An example deletion by (subnet-id, identifier-type, identifier) looks as follows
           </simpara>
           </listitem>
           <listitem>
+          <simpara> <command>subnet4-update/subnet6-update</command>: updates  subnet in server's configuration
+          </simpara>
+          </listitem>
+          <listitem>
           <simpara>
             <command>subnet4-del/subnet6-del</command>: removes a subnet from the server's configuration
           </simpara>
@@ -2336,6 +2340,105 @@ If the subnet exists the response will be similar to this:
 
       </section>
 
+      <section id="command-subnet4-update">
+        <title>subnet4-update</title>
+        <para>
+          This command is used to update a subnet in the existing
+          server configuration. This operation has no impact on other
+          subnets. The subnet identifier is used to identify the
+          subnet to replace, it must be specified and must be unique
+          among all subnets. The subnet prefix should not be updated.
+        </para>
+        <para>
+          The subnet information within this command has the same structure
+          as the subnet information in the server configuration file with the
+          exception that static host reservations must not be specified
+          within <command>subnet4-update</command>. The commands described in
+          <xref linkend="host-cmds"/> should be used to update, remove and
+          modify static reservations.
+<screen>
+{
+    "command": "subnet4-update",
+    "arguments": {
+        "subnet4": [ {
+            "id": 123,
+            "subnet": "10.20.30.0/24",
+            ...
+        } ]
+    }
+}
+</screen>
+        </para>
+
+        <para>
+          The response to this command has the following structure:
+<screen>
+{
+    "result": 0,
+    "text": "IPv4 subnet updated",
+    "arguments": {
+        "subnet4": [
+            {
+                "id": 123,
+                "subnet": "10.20.30.0/24"
+            }
+        ]
+    }
+}
+</screen>
+        </para>
+      </section>
+
+      <section id="command-subnet6-update">
+        <title>subnet6-update</title>
+        <para>
+          This command is used to update a subnet in the existing
+          server configuration. This operation has no impact on other
+          subnets. The subnet identifier is used to identify the
+          subnet to replace, it must be specified and must be unique
+          among all subnets. The subnet prefix should not be updated.
+        </para>
+        <para>
+          The subnet information within this command has the same structure
+          as the subnet information in the server configuration file with the
+          exception that static host reservations must not be specified
+          within <command>subnet6-update</command>. The commands described in
+          <xref linkend="host-cmds"/> should be used to update, remove and
+          modify static reservations.
+<screen>
+{
+    "command": "subnet6-update",
+    "arguments": {
+        "subnet6": [ {
+            "id": 234,
+            "subnet": "2001:db8:1::/64",
+            ...
+        } ]
+    }
+}
+</screen>
+        </para>
+
+        <para>
+          The response to this command has the following structure:
+<screen>
+{
+    "result": 0,
+    "text": "IPv6 subnet updated",
+    "arguments": {
+        "subnet6": [
+            {
+                "id": 234,
+                "subnet": "2001:db8:1::/64"
+            }
+        ]
+    }
+}
+</screen>
+        </para>
+
+      </section>
+
       <section id="command-subnet4-del">
         <title>subnet4-del command</title>
         <para>
@@ -2354,7 +2457,7 @@ If the subnet exists the response will be similar to this:
           loose track of leases assigned to the clients from this subnet.
           However, removal of the subnet may still cause configuration
           errors and conflicts. For example: after removal of the subnet,
-          the server administrator may add a new subnet with the ID used
+          the server administrator may update a new subnet with the ID used
           previously for the removed subnet. This means that the existing
           leases and static reservations will be in conflict with this
           new subnet. Thus, we recommend that this command is used with extreme
index 244b39f29045a55148de4ef18e24c85eb6094edc..ffb323502fe445159dcf7c51d921978a16cabd16 100644 (file)
@@ -51,12 +51,13 @@ CfgSubnets4::replace(const Subnet4Ptr& subnet) {
         isc_throw(BadValue, "ID of the IPv4 subnet '" << subnet_id
                   << "' is not in use");
     }
+    Subnet4Ptr old = *subnet_it;
     bool ret = index.replace(subnet_it, subnet);
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_UPDATE_SUBNET4)
         .arg(subnet_id).arg(ret);
     if (ret) {
-        return (*subnet_it);
+        return (old);
     } else {
         return (Subnet4Ptr());
     }
index 210ad8a9b6e50fdd2f8fa4d03a76b35ece25c93e..2405594736b38c0f6a7063ea05c4d7848e323a1c 100644 (file)
@@ -51,12 +51,13 @@ CfgSubnets6::replace(const Subnet6Ptr& subnet) {
         isc_throw(BadValue, "ID of the IPv6 subnet '" << subnet_id
                   << "' is not in use");
     }
+    Subnet6Ptr old = *subnet_it;
     bool ret = index.replace(subnet_it, subnet);
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_UPDATE_SUBNET6)
         .arg(subnet_id).arg(ret);
     if (ret) {
-        return (*subnet_it);
+        return (old);
     } else {
         return (Subnet6Ptr());
     }
index 600adce08bbaab3a601546a55969deaf4945d82d..64f436ec5351023323133de899a432d25ed8129a 100644 (file)
@@ -150,6 +150,68 @@ TEST(CfgSubnets4Test, deleteSubnet) {
     EXPECT_FALSE(cfg.getByPrefix("192.0.2.0/26"));
 }
 
+// This test verifies that replace a subnet works as expected.
+TEST(CfgSubnets4Test, replaceSubnet) {
+    CfgSubnets4 cfg;
+
+    // Create 3 subnets.
+    Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.1.0"),
+                                   26, 1, 2, 100, SubnetID(10)));
+    Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"),
+                                   26, 1, 2, 100, SubnetID(2)));
+    Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.3.0"),
+                                   26, 1, 2, 100, SubnetID(13)));
+
+    ASSERT_NO_THROW(cfg.add(subnet1));
+    ASSERT_NO_THROW(cfg.add(subnet2));
+    ASSERT_NO_THROW(cfg.add(subnet3));
+
+    // There should be three subnets.
+    ASSERT_EQ(3, cfg.getAll()->size());
+    // We're going to replace  the subnet #2. Let's make sure it exists before
+    // we replace it.
+    ASSERT_TRUE(cfg.getByPrefix("192.0.3.0/26"));
+
+    // Replace the subnet and make sure it was updated.
+    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"),
+                                  26, 10, 20, 1000,  SubnetID(2)));
+    Subnet4Ptr replaced = cfg.replace(subnet);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet2);
+    ASSERT_EQ(3, cfg.getAll()->size());
+    Subnet4Ptr returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet);
+
+    // Rollback.
+    replaced = cfg.replace(replaced);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet);
+    ASSERT_EQ(3, cfg.getAll()->size());
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet2);
+
+    // Prefix conflict returns null.
+    subnet.reset(new Subnet4(IOAddress("192.0.3.0"),
+                             26, 10, 20, 1000,  SubnetID(2)));
+    replaced = cfg.replace(subnet);
+    EXPECT_FALSE(replaced);
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet2);
+
+    // Changing prefix works even it is highly not recommended.
+    subnet.reset(new Subnet4(IOAddress("192.0.10.0"),
+                             26, 10, 20, 1000,  SubnetID(2)));
+    replaced = cfg.replace(subnet);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet2);
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet);
+}
+
 // This test verifies that subnets configuration is properly merged.
 TEST(CfgSubnets4Test, mergeSubnets) {
     // Create custom options dictionary for testing merge. We're keeping it
index 9d631039daf3df8c297b08d3dd5256b0217e63bd..53124bf5ba267b6622d4a7f07f6a541e59c539d2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2019 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
@@ -148,6 +148,68 @@ TEST(CfgSubnets6Test, deleteSubnet) {
     EXPECT_FALSE(cfg.getByPrefix("2001:db8:1::/48"));
 }
 
+// This test verifies that replace a subnet works as expected.
+TEST(CfgSubnets6Test, replaceSubnet) {
+    CfgSubnets6 cfg;
+
+    // Create 3 subnets.
+    Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"),
+                                   48, 1, 2, 3, 100, SubnetID(10)));
+    Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"),
+                                   48, 1, 2, 3, 100, SubnetID(2)));
+    Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"),
+                                   48, 1, 2, 3, 100, SubnetID(13)));
+
+    ASSERT_NO_THROW(cfg.add(subnet1));
+    ASSERT_NO_THROW(cfg.add(subnet2));
+    ASSERT_NO_THROW(cfg.add(subnet3));
+
+    // There should be three subnets.
+    ASSERT_EQ(3, cfg.getAll()->size());
+    // We're going to replace  the subnet #2. Let's make sure it exists before
+    // we replace it.
+    ASSERT_TRUE(cfg.getByPrefix("2001:db8:2::/48"));
+
+    // Replace the subnet and make sure it was updated.
+    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:2::"),
+                                  48, 10, 20, 30, 1000,  SubnetID(2)));
+    Subnet6Ptr replaced = cfg.replace(subnet);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet2);
+    ASSERT_EQ(3, cfg.getAll()->size());
+    Subnet6Ptr returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet);
+
+    // Rollback.
+    replaced = cfg.replace(replaced);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet);
+    ASSERT_EQ(3, cfg.getAll()->size());
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet2);
+
+    // Prefix conflict returns null.
+    subnet.reset(new Subnet6(IOAddress("2001:db8:3::"),
+                             48, 10, 20, 30, 1000,  SubnetID(2)));
+    replaced = cfg.replace(subnet);
+    EXPECT_FALSE(replaced);
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet2);
+
+    // Changing prefix works even it is highly not recommended.
+    subnet.reset(new Subnet6(IOAddress("2001:db8:10::"),
+                             48, 10, 20, 30, 1000,  SubnetID(2)));
+    replaced = cfg.replace(subnet);
+    ASSERT_TRUE(replaced);
+    EXPECT_TRUE(replaced == subnet2);
+    returned = cfg.getAll()->at(1);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(returned == subnet);
+}
+
 // This test checks that the subnet can be selected using a relay agent's
 // link address.
 TEST(CfgSubnets6Test, selectSubnetByRelayAddress) {