-// 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
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);
} else {
Lease6Parser parser;
- lease6 = parser.parse(config, cmd_args_);
+ lease6 = parser.parse(config, cmd_args_, force_create);
// checkLeaseIntegrity(config, lease6);
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);
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);
-// 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
/// }
/// };
///
+ /// 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
/// }
/// }";
///
+ /// 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
-// 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
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");
}
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");
}
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);
}
-// 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
///
/// @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() {}
///
/// @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() {}
-// 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
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)
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) {