diff options
| author | Francis Dupont <fdupont@isc.org> | 2022-09-07 15:58:54 +0200 |
|---|---|---|
| committer | Francis Dupont <fdupont@isc.org> | 2022-09-23 15:06:06 +0200 |
| commit | f2e7a9968c504287db00f6a795c6b2420ebade11 (patch) | |
| tree | dae8094bea002b1d19556464bbcbdce06ee763b0 | |
| parent | 53d583895b725927184dd1f30732a5b907a79792 (diff) | |
[#1654] Checkpoint: did hook, doc to do
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/lease_cmds.cc | 58 | ||||
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/lease_cmds.dox | 2 | ||||
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/lease_cmds.h | 27 | ||||
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc | 24 | ||||
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc | 49 | ||||
| -rw-r--r-- | src/hooks/dhcp/lease_cmds/tests/lease_cmds6_unittest.cc | 49 |
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 |
