summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2022-09-07 15:58:54 +0200
committerFrancis Dupont <fdupont@isc.org>2022-09-23 15:06:06 +0200
commitf2e7a9968c504287db00f6a795c6b2420ebade11 (patch)
treedae8094bea002b1d19556464bbcbdce06ee763b0
parent53d583895b725927184dd1f30732a5b907a79792 (diff)
[#1654] Checkpoint: did hook, doc to do
-rw-r--r--src/hooks/dhcp/lease_cmds/lease_cmds.cc58
-rw-r--r--src/hooks/dhcp/lease_cmds/lease_cmds.dox2
-rw-r--r--src/hooks/dhcp/lease_cmds/lease_cmds.h27
-rw-r--r--src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc24
-rw-r--r--src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc49
-rw-r--r--src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc49
6 files changed, 207 insertions, 2 deletions
diff --git a/src/hooks/dhcp/lease_cmds/lease_cmds.cc b/src/hooks/dhcp/lease_cmds/lease_cmds.cc
index 4374118966..4bf4120385 100644
--- a/src/hooks/dhcp/lease_cmds/lease_cmds.cc
+++ b/src/hooks/dhcp/lease_cmds/lease_cmds.cc
@@ -327,6 +327,17 @@ public:
/// @return 0 upon success, non-zero otherwise
int lease6ResendDdnsHandler(CalloutHandle& handle);
+ /// @brief lease4-write handler, lease6-write handler
+ ///
+ /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseWriteHandler
+ ///
+ /// @param handle Callout context - which is expected to contain the
+ /// write command JSON text in the "command" argument
+ ///
+ /// @return 0 upon success, non-zero otherwise
+ int
+ leaseWriteHandler(CalloutHandle& handle);
+
/// @brief Extracts parameters required for reservation-get and reservation-del
///
/// See @ref Parameters class for detailed description of what is expected
@@ -2291,6 +2302,48 @@ LeaseCmdsImpl::createFailedLeaseMap(const Lease::Type& lease_type,
}
int
+LeaseCmdsImpl::leaseWriteHandler(CalloutHandle& handle) {
+ bool v4 = true;
+ try {
+ extractCommand(handle);
+ v4 = (cmd_name_ == "lease4-write");
+
+ if (!cmd_args_) {
+ isc_throw(isc::BadValue, "no parameters specified for the command");
+ }
+
+ ConstElementPtr file = cmd_args_->get("filename");
+ if (!file) {
+ isc_throw(BadValue, "'filename' parameter not specified");
+ }
+ if (file->getType() != Element::string) {
+ isc_throw(BadValue, "'filename' parameter must be a string");
+ }
+ string filename = file->stringValue();
+ if (filename.empty()) {
+ isc_throw(BadValue, "'filename' parameter is empty");
+ }
+
+ if (v4) {
+ LeaseMgrFactory::instance().writeLeases4(filename);
+ } else {
+ LeaseMgrFactory::instance().writeLeases6(filename);
+ }
+ ostringstream s;
+ s << (v4 ? "IPv4" : "IPv6")
+ << " lease database into '"
+ << filename << "'.";
+ ConstElementPtr response = createAnswer(CONTROL_RESULT_SUCCESS, s.str());
+ setResponse(handle, response);
+ } catch (const std::exception& ex) {
+ setErrorResponse(handle, ex.what());
+ return (CONTROL_RESULT_ERROR);
+ }
+
+ return (0);
+}
+
+int
LeaseCmds::leaseAddHandler(CalloutHandle& handle) {
return (impl_->leaseAddHandler(handle));
}
@@ -2377,6 +2430,11 @@ LeaseCmds::lease6ResendDdnsHandler(CalloutHandle& handle) {
return (impl_->lease6ResendDdnsHandler(handle));
}
+int
+LeaseCmds::leaseWriteHandler(CalloutHandle& handle) {
+ return (impl_->leaseWriteHandler(handle));
+}
+
LeaseCmds::LeaseCmds()
:impl_(new LeaseCmdsImpl()) {
}
diff --git a/src/hooks/dhcp/lease_cmds/lease_cmds.dox b/src/hooks/dhcp/lease_cmds/lease_cmds.dox
index 4b81c4a71d..96e2f862ce 100644
--- a/src/hooks/dhcp/lease_cmds/lease_cmds.dox
+++ b/src/hooks/dhcp/lease_cmds/lease_cmds.dox
@@ -67,6 +67,8 @@ For details see documentation and code of the following handlers:
- @ref isc::lease_cmds::LeaseCmdsImpl::lease6UpdateHandler (lease6-update)
- @ref isc::lease_cmds::LeaseCmdsImpl::lease4WipeHandler (lease4-wipe)
- @ref isc::lease_cmds::LeaseCmdsImpl::lease6WipeHandler (lease6-wipe)
+- @ref isc::lease_cmds::LeaseCmdsImpl::lease4WriteHandler (lease4-write)
+- @ref isc::lease_cmds::LeaseCmdsImpl::lease6WriteHandler (lease6-write)
@section lease_cmdsDesigns Lease Commands Design choices
diff --git a/src/hooks/dhcp/lease_cmds/lease_cmds.h b/src/hooks/dhcp/lease_cmds/lease_cmds.h
index 31dd8b6cd1..54ca5f74ab 100644
--- a/src/hooks/dhcp/lease_cmds/lease_cmds.h
+++ b/src/hooks/dhcp/lease_cmds/lease_cmds.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2022 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
@@ -520,7 +520,7 @@ public:
///
/// Example command:
/// {
- /// "command": "lease4-wipe",
+ /// "command": "lease6-wipe",
/// "arguments": {
/// "subnet-id": 44
/// }
@@ -582,6 +582,29 @@ public:
int
lease6ResendDdnsHandler(hooks::CalloutHandle& handle);
+ /// @brief lease4-write handler, lease6-write handler
+ ///
+ /// This commands attempts to write the lease database to a CSV file.
+ /// Currently it is supported only by the memfile database and
+ /// should be reserved to emergency situations.
+ /// It extracts the command name and arguments from the given Callouthandle,
+ /// attempts to process them, and then set's the handle's "response"
+ /// argument accordingly.
+ ///
+ /// Example command:
+ /// {
+ /// "command": "lease4-write",
+ /// "arguments": {
+ /// "filename": "leases.csv"
+ /// }
+ /// }";
+ ///
+ /// @param handle Callout context - which is expected to contain the
+ /// write command JSON text in the "command" argument
+ /// @return result of the operation
+ int
+ leaseWriteHandler(hooks::CalloutHandle& handle);
+
private:
/// Pointer to the actual implementation
boost::shared_ptr<LeaseCmdsImpl> impl_;
diff --git a/src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc b/src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc
index 25b257f76a..7d431b40dd 100644
--- a/src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc
+++ b/src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc
@@ -268,6 +268,28 @@ int lease6_resend_ddns(CalloutHandle& handle) {
return(lease_cmds.lease6ResendDdnsHandler(handle));
}
+/// @brief This is a command callout for 'lease4-write' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 otherwise.
+int lease4_write(CalloutHandle& handle) {
+ LeaseCmds lease_cmds;
+ return(lease_cmds.leaseWriteHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease6-write' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 otherwise.
+int lease6_write(CalloutHandle& handle) {
+ LeaseCmds lease_cmds;
+ return(lease_cmds.leaseWriteHandler(handle));
+}
+
/// @brief This function is called when the library is loaded.
///
/// @param handle library handle
@@ -314,6 +336,8 @@ int load(LibraryHandle& handle) {
handle.registerCommandCallout("lease6-wipe", lease6_wipe);
handle.registerCommandCallout("lease4-resend-ddns", lease4_resend_ddns);
handle.registerCommandCallout("lease6-resend-ddns", lease6_resend_ddns);
+ handle.registerCommandCallout("lease4-write", lease4_write);
+ handle.registerCommandCallout("lease6-write", lease6_write);
LOG_INFO(lease_cmds_logger, LEASE_CMDS_INIT_OK);
return (0);
diff --git a/src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc b/src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc
index 34cef073c8..a5e276f10a 100644
--- a/src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc
+++ b/src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc
@@ -422,6 +422,9 @@ public:
/// @brief Verify that v4 lease update handles conflict as expected.
void testLease4ConflictingUpdate();
+
+ /// @brief Check that lease4-write works as expected.
+ void testLease4Write();
};
void Lease4CmdsTest::testLease4AddMissingParams() {
@@ -3135,6 +3138,43 @@ void Lease4CmdsTest::testLease4ConflictingUpdate() {
EXPECT_EQ(original_lease, *lease);
}
+void Lease4CmdsTest::testLease4Write() {
+ // Initialize lease manager (false = v4, false = don't add leases)
+ initLeaseMgr(false, false);
+
+ // Parameter is missing.
+ string txt =
+ "{\n"
+ " \"command\": \"lease4-write\",\n"
+ " \"arguments\": {"
+ " }\n"
+ "}";
+ string exp_rsp = "'filename' parameter not specified";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // Filename must be a string.
+ txt =
+ "{\n"
+ " \"command\": \"lease4-write\",\n"
+ " \"arguments\": {"
+ " \"filename\": 0\n"
+ " }\n"
+ "}";
+ exp_rsp = "'filename' parameter must be a string";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // Filename must be not empty.
+ txt =
+ "{\n"
+ " \"command\": \"lease4-write\",\n"
+ " \"arguments\": {"
+ " \"filename\": \"\"\n"
+ " }\n"
+ "}";
+ exp_rsp = "'filename' parameter is empty";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
TEST_F(Lease4CmdsTest, lease4AddMissingParams) {
testLease4AddMissingParams();
}
@@ -3828,4 +3868,13 @@ TEST_F(Lease4CmdsTest, lease4ConflictingUpdateMultiThreading) {
testLease4ConflictingUpdate();
}
+TEST_F(Lease4CmdsTest, lease4Write) {
+ testLease4Write();
+}
+
+TEST_F(Lease4CmdsTest, lease4WriteMultiThreading) {
+ MultiThreadingTest mt(true);
+ testLease4Write();
+}
+
} // end of anonymous namespace
diff --git a/src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc b/src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc
index c585fd973e..462bc06e3f 100644
--- a/src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc
+++ b/src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc
@@ -452,6 +452,9 @@ public:
/// @brief Verify that v6 lease bulk update handles conflict as expected.
void testLease6ConflictingBulkApplyAdd();
+
+ /// @brief Check that lease6-write works as expected.
+ void testLease6Write();
};
void Lease6CmdsTest::testLease6AddMissingParams() {
@@ -3727,6 +3730,43 @@ void Lease6CmdsTest::testLease6ConflictingBulkApplyAdd() {
"ResourceBusy: IP address:2001:db8:2::77 could not be updated.");
}
+void Lease6CmdsTest::testLease6Write() {
+ // Initialize lease manager (true = v6, false = don't add leases)
+ initLeaseMgr(true, false);
+
+ // Parameter is missing.
+ string txt =
+ "{\n"
+ " \"command\": \"lease6-write\",\n"
+ " \"arguments\": {"
+ " }\n"
+ "}";
+ string exp_rsp = "'filename' parameter not specified";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // Filename must be a string.
+ txt =
+ "{\n"
+ " \"command\": \"lease6-write\",\n"
+ " \"arguments\": {"
+ " \"filename\": 0\n"
+ " }\n"
+ "}";
+ exp_rsp = "'filename' parameter must be a string";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+
+ // Filename must be not empty.
+ txt =
+ "{\n"
+ " \"command\": \"lease6-write\",\n"
+ " \"arguments\": {"
+ " \"filename\": \"\"\n"
+ " }\n"
+ "}";
+ exp_rsp = "'filename' parameter is empty";
+ testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
TEST_F(Lease6CmdsTest, lease6AddMissingParams) {
testLease6AddMissingParams();
}
@@ -4468,4 +4508,13 @@ TEST_F(Lease6CmdsTest, lease6ConflictingBulkApplyAddMultiThreading) {
testLease6ConflictingBulkApplyAdd();
}
+TEST_F(Lease6CmdsTest, lease6Write) {
+ testLease6Write();
+}
+
+TEST_F(Lease6CmdsTest, lease6WriteMultiThreading) {
+ MultiThreadingTest mt(true);
+ testLease6Write();
+}
+
} // end of anonymous namespace