]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5472] Added 'force-create' parameter to leaseX-update commands.
authorMarcin Siodelski <marcin@isc.org>
Mon, 8 Jan 2018 16:50:56 +0000 (17:50 +0100)
committerMarcin Siodelski <marcin@isc.org>
Mon, 8 Jan 2018 16:50:56 +0000 (17:50 +0100)
src/hooks/dhcp/lease_cmds/lease_cmds.cc
src/hooks/dhcp/lease_cmds/lease_cmds.h
src/hooks/dhcp/lease_cmds/lease_parser.cc
src/hooks/dhcp/lease_cmds/lease_parser.h
src/hooks/dhcp/lease_cmds/tests/lease_cmds_unittest.cc

index a5d3f25fb7416dbb6894a4a1451f9a63d919f15f..626771485542bdd9141bd6e4f6d3211e860584ee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 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
@@ -222,9 +222,11 @@ LeaseCmdsImpl::leaseAddHandler(CalloutHandle& handle) {
 
         Lease4Ptr lease4;
         Lease6Ptr lease6;
+        // This parameter is ignored for the commands adding the lease.
+        bool force_create = false;
         if (v4) {
             Lease4Parser parser;
-            lease4 = parser.parse(config, cmd_args_);
+            lease4 = parser.parse(config, cmd_args_, force_create);
 
             // checkLeaseIntegrity(config, lease4);
 
@@ -234,7 +236,7 @@ LeaseCmdsImpl::leaseAddHandler(CalloutHandle& handle) {
 
         } else {
             Lease6Parser parser;
-            lease6 = parser.parse(config, cmd_args_);
+            lease6 = parser.parse(config, cmd_args_, force_create);
 
             // checkLeaseIntegrity(config, lease6);
 
@@ -599,12 +601,19 @@ LeaseCmdsImpl::lease4UpdateHandler(CalloutHandle& handle) {
         ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
         Lease4Ptr lease4;
         Lease4Parser parser;
+        bool force_create = false;
+
         // The parser does sanity checks (if the address is in scope, if
         // subnet-id is valid, etc)
-        lease4 = parser.parse(config, cmd_args_);
+        lease4 = parser.parse(config, cmd_args_, force_create);
+        if (force_create && !LeaseMgrFactory::instance().getLease4(lease4->addr_)) {
+            LeaseMgrFactory::instance().addLease(lease4);
+            setSuccessResponse(handle, "IPv4 lease created.");
 
-        LeaseMgrFactory::instance().updateLease4(lease4);
-        setSuccessResponse(handle, "IPv4 lease updated.");
+        } else {
+            LeaseMgrFactory::instance().updateLease4(lease4);
+            setSuccessResponse(handle, "IPv4 lease updated.");
+        }
     } catch (const std::exception& ex) {
         setErrorResponse(handle, ex.what());
         return (1);
@@ -627,12 +636,19 @@ LeaseCmdsImpl::lease6UpdateHandler(CalloutHandle& handle) {
         ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
         Lease6Ptr lease6;
         Lease6Parser parser;
+        bool force_create = false;
+
         // The parser does sanity checks (if the address is in scope, if
         // subnet-id is valid, etc)
-        lease6 = parser.parse(config, cmd_args_);
-
-        LeaseMgrFactory::instance().updateLease6(lease6);
-        setSuccessResponse(handle, "IPv6 lease updated.");
+        lease6 = parser.parse(config, cmd_args_, force_create);
+        if (force_create && !LeaseMgrFactory::instance().getLease6(lease6->type_,
+                                                                   lease6->addr_)) {
+            LeaseMgrFactory::instance().addLease(lease6);
+            setSuccessResponse(handle, "IPv6 lease created.");
+        } else {
+            LeaseMgrFactory::instance().updateLease6(lease6);
+            setSuccessResponse(handle, "IPv6 lease updated.");
+        }
     } catch (const std::exception& ex) {
         setErrorResponse(handle, ex.what());
         return (1);
index 03e2cdcaf1dfe6e1405f948d094e2c83c5096d36..b31328fc07839e186bda03e224b5becc33c377e2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 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
@@ -227,6 +227,10 @@ public:
     ///     }
     /// };
     ///
+    /// The optional 'force-create' boolean parameter may be specified to force
+    /// the lease to be created if it doesn't exist. By default, this parameter
+    /// is set to false, which means that the lease is not created.
+    ///
     /// @param handle Callout context - which is expected to contain the
     /// update command JSON text in the "command" argument
     /// @return result of the operation
@@ -255,6 +259,10 @@ public:
     ///     }
     /// }";
     ///
+    /// The optional 'force-create' boolean parameter may be specified to force
+    /// the lease to be created if it doesn't exist. By default, this parameter
+    /// is set to false, which means that the lease is not created.
+    ///
     /// @param handle Callout context - which is expected to contain the
     /// update command JSON text in the "command" argument
     /// @return result of the operation
index b0288002d2ab8e6635307c46df1b6ab863e944a4..4a457d8a775d6646ed2e7f8a2a7004067ebe07ba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 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
@@ -22,7 +22,8 @@ namespace lease_cmds {
 
 Lease4Ptr
 Lease4Parser::parse(ConstSrvConfigPtr& cfg,
-                    const ConstElementPtr& lease_info) {
+                    const ConstElementPtr& lease_info,
+                    bool& force_create) {
     if (!lease_info) {
         isc_throw(BadValue, "lease information missing");
     }
@@ -117,12 +118,21 @@ Lease4Parser::parse(ConstSrvConfigPtr& cfg,
                            cltt, subnet_id,
                            fqdn_fwd, fqdn_rev, hostname));
     l->state_ = state;
+
+    // Retrieve the optional flag indicating if the lease must be created when it
+    // doesn't exist during the update.
+    force_create = false;
+    if (lease_info->contains("force-create")) {
+        force_create = getBoolean(lease_info, "force-create");
+    }
+
     return (l);
 }
 
 Lease6Ptr
 Lease6Parser::parse(ConstSrvConfigPtr& cfg,
-                    const ConstElementPtr& lease_info) {
+                    const ConstElementPtr& lease_info,
+                    bool& force_create) {
     if (!lease_info) {
         isc_throw(BadValue, "lease information missing");
     }
@@ -250,6 +260,14 @@ Lease6Parser::parse(ConstSrvConfigPtr& cfg,
                            hwaddr_ptr, prefix_len));
     l->cltt_ = cltt;
     l->state_ = state;
+
+    // Retrieve the optional flag indicating if the lease must be created when it
+    // doesn't exist during the update.
+    force_create = false;
+    if (lease_info->contains("force-create")) {
+        force_create = getBoolean(lease_info, "force-create");
+    }
+
     return (l);
 }
 
index 40400bd94a7888d2fb4350382466f5e2c1a128f6..8b72c0018aa0d9d9f44630577886fc83b06ff1bb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 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
@@ -40,11 +40,14 @@ public:
     ///
     /// @param cfg Currently running config (used for sanity checks and defaults)
     /// @param lease_info structure to be parsed
+    /// @param [out] force_create indicates if the lease should be created when it
+    /// doesn't exist.
     /// @return A pointer to Lease4
     /// @throw BadValue if any of the parameters is invalid
     /// @throw DhcpConfigError if mandatory parameter is missing
     virtual isc::dhcp::Lease4Ptr parse(isc::dhcp::ConstSrvConfigPtr& cfg,
-                                       const isc::data::ConstElementPtr& lease_info);
+                                       const isc::data::ConstElementPtr& lease_info,
+                                       bool& force_create);
 
     /// @brief virtual dtor (does nothing)
     virtual ~Lease4Parser() {}
@@ -76,11 +79,14 @@ public:
     ///
     /// @param cfg Currently running config (used for sanity checks and defaults)
     /// @param lease_info structure to be parsed
+    /// @param [out] force_create indicates if the lease should be created when it
+    /// doesn't exist.
     /// @return A pointer to Lease4
     /// @throw BadValue if any of the parameters is invalid
     /// @throw DhcpConfigError if mandatory parameter is missing
     virtual isc::dhcp::Lease6Ptr parse(isc::dhcp::ConstSrvConfigPtr& cfg,
-                                       const isc::data::ConstElementPtr& lease_info);
+                                       const isc::data::ConstElementPtr& lease_info,
+                                       bool& force_create);
 
     /// @brief virtual dtor (does nothing)
     virtual ~Lease6Parser() {}
index ff0d3b9a4468b5b6aa04e159fa3e1dfb37702e74..9a41749efc5e9113905de65ab83af3a2404154ff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 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
@@ -1498,6 +1498,67 @@ TEST_F(LeaseCmdsTest, Lease4Update) {
     EXPECT_EQ("newhostname.example.org", l->hostname_);
 }
 
+// Check that a lease4 is created if it doesn't exist during the update.
+// To trigger this behavior 'force-create' boolean parameter must be
+// included in the command.
+TEST_F(LeaseCmdsTest, Lease4UpdateForceCreate) {
+    // Initialize lease manager (false = v4, true = add a lease)
+    initLeaseMgr(false, false);
+
+    // Check that the lease manager pointer is there.
+    ASSERT_TRUE(lmptr_);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease4-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 44,\n"
+        "        \"ip-address\": \"192.0.2.1\",\n"
+        "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"hostname\": \"newhostname.example.org\","
+        "        \"force-create\": true"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv4 lease created.";
+    testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    // Now check that the lease is still there.
+    Lease4Ptr l = lmptr_->getLease4(IOAddress("192.0.2.1"));
+    ASSERT_TRUE(l);
+
+    // Make sure it contains expected values..
+    ASSERT_TRUE(l->hwaddr_);
+    EXPECT_EQ("1a:1b:1c:1d:1e:1f", l->hwaddr_->toText(false));
+    EXPECT_EQ("newhostname.example.org", l->hostname_);
+}
+
+// Check that lease4-update correctly handles case when the 'force-create'
+// parameter is explicitly set to false.
+TEST_F(LeaseCmdsTest, Lease4UpdateDoNotForceCreate) {
+
+    // Initialize lease manager (false = v4, false = don't add any lease)
+    initLeaseMgr(false, false);
+
+    // Check that the lease manager pointer is there.
+    ASSERT_TRUE(lmptr_);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease4-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 44,\n"
+        "        \"ip-address\": \"192.0.2.1\",\n"
+        "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
+        "        \"hostname\": \"newhostname.example.org\","
+        "        \"force-create\": false"
+        "    }\n"
+        "}";
+    string exp_rsp = "failed to update the lease with address 192.0.2.1 - no such lease";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
 // Test checks if lease6-update handler refuses calls with missing parameters.
 TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
     // Initialize lease manager (true = v6, true = add a lease)
@@ -1666,6 +1727,71 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
+// Check that a lease6 is created if it doesn't exist during the update.
+// To trigger this behavior 'force-create' boolean parameter must be
+// included in the command.
+TEST_F(LeaseCmdsTest, Lease6UpdateForceCreate) {
+
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, false);
+
+    // Check that the lease manager pointer is there.
+    ASSERT_TRUE(lmptr_);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease6-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"iaid\": 7654321,\n"
+        "        \"duid\": \"88:88:88:88:88:88:88:88\",\n"
+        "        \"hostname\": \"newhostname.example.org\","
+        "        \"force-create\": true"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv6 lease created.";
+    testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    // Now check that the lease is really there.
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1"));
+    ASSERT_TRUE(l);
+
+    // Make sure the lease is correct.
+    ASSERT_TRUE(l->duid_);
+    EXPECT_EQ("88:88:88:88:88:88:88:88", l->duid_->toText());
+    EXPECT_EQ("newhostname.example.org", l->hostname_);
+    EXPECT_EQ(7654321, l->iaid_);
+}
+
+// Check that lease6-update correctly handles case when the 'force-create'
+// parameter is explicitly set to false.
+TEST_F(LeaseCmdsTest, Lease6UpdateDoNotForceCreate) {
+
+    // Initialize lease manager (true = v6, false = don't add any lease)
+    initLeaseMgr(true, false);
+
+    // Check that the lease manager pointer is there.
+    ASSERT_TRUE(lmptr_);
+
+    // Now send the command.
+    string txt =
+        "{\n"
+        "    \"command\": \"lease6-update\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"iaid\": 7654321,\n"
+        "        \"duid\": \"88:88:88:88:88:88:88:88\",\n"
+        "        \"hostname\": \"newhostname.example.org\","
+        "        \"force-create\": false"
+        "    }\n"
+        "}";
+    string exp_rsp = "failed to update the lease with address 2001:db8::1 - no such lease";
+    testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
 // Checks that lease6-del can handle a situation when the query is
 // broken (some required parameters are missing).
 TEST_F(LeaseCmdsTest, Lease4DelMissingParams) {