2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-02 06:55:16 +00:00

[#1106] Added leaseX-resend-ddns command to Lease Commands hook lib

src/hooks/dhcp/lease_cmds/lease_cmds.*
    LeaseCmds::
        lease4ResendDdnsHandler()
        lease6ResendDdnsHandler()
    LeaseCmdsImpl::
        lease4ResendDdnsHandler()
        lease6ResendDdnsHandler()
        getAddressParam()

src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc
    lease4_resend_ddns()
    lease6_resend_ddns()

src/hooks/dhcp/lease_cmds/lease_cmds_messages.*
    New log messages
This commit is contained in:
Thomas Markwalder
2020-03-16 08:28:30 -04:00
parent 2229ae696f
commit 04e89a7ec3
6 changed files with 259 additions and 2 deletions

View File

@@ -14,6 +14,7 @@
#include <dhcpsrv/dhcpsrv_exceptions.h> #include <dhcpsrv/dhcpsrv_exceptions.h>
#include <dhcpsrv/lease_mgr.h> #include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h> #include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/ncr_generator.h>
#include <dhcpsrv/subnet_id.h> #include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/sanity_checker.h> #include <dhcpsrv/sanity_checker.h>
#include <dhcp/duid.h> #include <dhcp/duid.h>
@@ -34,6 +35,7 @@
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::data; using namespace isc::data;
using namespace isc::dhcp_ddns;
using namespace isc::config; using namespace isc::config;
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::hooks; using namespace isc::hooks;
@@ -282,6 +284,24 @@ public:
int int
lease6WipeHandler(CalloutHandle& handle); lease6WipeHandler(CalloutHandle& handle);
/// @brief lease4-resend-ddns handler
///
/// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4ResendDdnsHandler
///
/// @param handle Callout context - which is expected to contain the
/// wipe command JSON text in the "command" argument
/// @return 0 upon success, non-zero otherwise
int lease4ResendDdnsHandler(CalloutHandle& handle);
/// @brief lease6-resend-ddns handler
///
/// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease6ResendDdnsHandler
///
/// @param handle Callout context - which is expected to contain the
/// wipe command JSON text in the "command" argument
/// @return 0 upon success, non-zero otherwise
int lease6ResendDdnsHandler(CalloutHandle& handle);
/// @brief Extracts parameters required for reservation-get and reservation-del /// @brief Extracts parameters required for reservation-get and reservation-del
/// ///
/// See @ref Parameters class for detailed description of what is expected /// See @ref Parameters class for detailed description of what is expected
@@ -329,6 +349,16 @@ public:
const DuidPtr& duid, const DuidPtr& duid,
const int control_result, const int control_result,
const std::string& error_message) const; const std::string& error_message) const;
/// @brief Fetches an IP address parameter from a map of parameters
/// @param map of parameters in which to look
/// @name name of the parameter desired
/// @family expected protocol family of the address parameter, AF_INET
/// or AF_INET6
/// @return IOAddress containing the value of the parameter.
/// @throw BadValue if the parameter is missing or invalid
IOAddress getAddressParam(ConstElementPtr params, const std::string name,
short family = AF_INET) const;
}; };
int int
@@ -1543,6 +1573,121 @@ LeaseCmdsImpl::getIPv6LeaseForDelete(const Parameters& parameters) const {
return (lease6); return (lease6);
} }
IOAddress
LeaseCmdsImpl::getAddressParam(ConstElementPtr params, const std::string name,
short family) const {
ConstElementPtr param = params->get(name);
if (!param) {
isc_throw(BadValue, "'" << name << "' parameter is missing.");
}
if (param->getType() != Element::string) {
isc_throw(BadValue, "'" << name << "' is not a string.");
}
IOAddress addr(0);
try {
addr = IOAddress(param->stringValue());
} catch (const std::exception& ex) {
isc_throw(BadValue, "'" << param->stringValue()
<< "' is not a valid IP address.");
}
if (addr.getFamily() != family) {
isc_throw(BadValue, "Invalid "
<< (family == AF_INET6 ? "IPv6" : "IPv4")
<< " address specified: " << param->stringValue());
}
return (addr);
}
int
LeaseCmdsImpl::lease4ResendDdnsHandler(CalloutHandle& handle) {
Lease4Ptr lease;
std::stringstream ss;
try {
extractCommand(handle);
// Get the target lease address. Invalid value will throw.
IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET);
// Find the lease.
lease = LeaseMgrFactory::instance().getLease4(addr);
if (!lease) {
ss << "No lease found for: " << addr.toText();
} else if (lease->hostname_.empty()) {
ss << "Lease for: " << addr.toText()
<< ", has no hostname, nothing to update";
} else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
ss << "Neither forward nor reverse updates enabled for lease for: "
<< addr.toText();
} else if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
ss << "DDNS updating is not enabled";
} else {
// We have a lease with a hostname and updates in at least
// one direction enabled. Queue an NCR for it.
queueNCR(CHG_ADD, lease);
ss << "NCR generated for: " << addr.toText()
<< ", hostname: " << lease->hostname_;
setSuccessResponse(handle, ss.str());
LOG_INFO(lease_cmds_logger, LEASE_CMDS_RESEND_DDNS4).arg(ss.str());
return (CONTROL_RESULT_SUCCESS);
}
} catch (const std::exception& ex) {
ss << ex.what();
}
LOG_ERROR(lease_cmds_logger, LEASE_CMDS_RESEND_DDNS4_FAILED).arg(ss.str());
setErrorResponse(handle, ss.str());
return (CONTROL_RESULT_ERROR);
}
int
LeaseCmdsImpl::lease6ResendDdnsHandler(CalloutHandle& handle) {
Lease6Ptr lease;
std::stringstream ss;
try {
extractCommand(handle);
// Get the target lease address. Invalid value will throw.
IOAddress addr = getAddressParam(cmd_args_, "ip-address", AF_INET6);
// Find the lease.
lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, addr);
if (!lease) {
ss << "No lease found for: " << addr.toText();
} else if (lease->hostname_.empty()) {
ss << "Lease for: " << addr.toText()
<< ", has no hostname, nothing to update";
} else if (!lease->fqdn_fwd_ && !lease->fqdn_rev_) {
ss << "Neither forward nor reverse updates enabled for lease for: "
<< addr.toText();
} else if (!CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
ss << "DDNS updating is not enabled";
} else {
// We have a lease with a hostname and updates in at least
// one direction enabled. Queue an NCR for it.
queueNCR(CHG_ADD, lease);
ss << "NCR generated for: " << addr.toText()
<< ", hostname: " << lease->hostname_;
setSuccessResponse(handle, ss.str());
LOG_INFO(lease_cmds_logger, LEASE_CMDS_RESEND_DDNS6).arg(ss.str());
return (CONTROL_RESULT_SUCCESS);
}
} catch (const std::exception& ex) {
ss << ex.what();
}
LOG_ERROR(lease_cmds_logger, LEASE_CMDS_RESEND_DDNS6_FAILED).arg(ss.str());
setErrorResponse(handle, ss.str());
return (CONTROL_RESULT_ERROR);
}
ElementPtr ElementPtr
LeaseCmdsImpl::createFailedLeaseMap(const Lease::Type& lease_type, LeaseCmdsImpl::createFailedLeaseMap(const Lease::Type& lease_type,
const IOAddress& lease_address, const IOAddress& lease_address,
@@ -1651,6 +1796,16 @@ LeaseCmds::lease6WipeHandler(CalloutHandle& handle) {
return (impl_->lease6WipeHandler(handle)); return (impl_->lease6WipeHandler(handle));
} }
int
LeaseCmds::lease4ResendDdnsHandler(CalloutHandle& handle) {
return (impl_->lease4ResendDdnsHandler(handle));
}
int
LeaseCmds::lease6ResendDdnsHandler(CalloutHandle& handle) {
return (impl_->lease6ResendDdnsHandler(handle));
}
LeaseCmds::LeaseCmds() LeaseCmds::LeaseCmds()
:impl_(new LeaseCmdsImpl()) { :impl_(new LeaseCmdsImpl()) {
} }

View File

@@ -525,6 +525,56 @@ public:
int int
lease6WipeHandler(hooks::CalloutHandle& handle); lease6WipeHandler(hooks::CalloutHandle& handle);
/// @brief lease4-resend-ddns command handler
///
/// This command attempts to resend the DDNS updates for the IPv4 lease that
/// matches the selection criteria.
///
/// 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.
///
/// A single parameter is supported: ip-address:
///
/// Example command to resend DDNS based on existing FDQN and flags
/// {
/// "command": "lease4-resend-ddns",
/// "arguments": {
/// "ip-address": "192.0.2.202"
/// }
/// }
///
/// @param handle Callout context - which is expected to contain the
/// delete command JSON text in the "command" argument
/// @return result of the operation
int
lease4ResendDdnsHandler(hooks::CalloutHandle& handle);
/// @brief lease6-resend-ddns command handler
///
/// This command attempts to resend the DDNS updates for the IPv6 lease that
/// matches the selection criteria.
///
/// 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.
///
/// A single parameter is supported: ip-address:
///
/// Example command to resend DDNS based on existing FDQN and flags
/// {
/// "command": "lease6-resend-ddns",
/// "arguments": {
/// "ip-address": "2001:db8:abcd::",
/// }
/// }
///
/// @param handle Callout context - which is expected to contain the
/// delete command JSON text in the "command" argument
/// @return result of the operation
int
lease6ResendDdnsHandler(hooks::CalloutHandle& handle);
private: private:
/// Pointer to the actual implementation /// Pointer to the actual implementation
boost::shared_ptr<LeaseCmdsImpl> impl_; boost::shared_ptr<LeaseCmdsImpl> impl_;

View File

@@ -242,6 +242,28 @@ int lease6_wipe(CalloutHandle& handle) {
return(lease_cmds.lease6WipeHandler(handle)); return(lease_cmds.lease6WipeHandler(handle));
} }
/// @brief This is a command callout for 'lease4-resend-ddns' 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_resend_ddns(CalloutHandle& handle) {
LeaseCmds lease_cmds;
return(lease_cmds.lease4ResendDdnsHandler(handle));
}
/// @brief This is a command callout for 'lease6-resend-ddns' 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_resend_ddns(CalloutHandle& handle) {
LeaseCmds lease_cmds;
return(lease_cmds.lease6ResendDdnsHandler(handle));
}
/// @brief This function is called when the library is loaded. /// @brief This function is called when the library is loaded.
/// ///
/// @param handle library handle /// @param handle library handle
@@ -271,6 +293,8 @@ int load(LibraryHandle& handle) {
handle.registerCommandCallout("lease6-update", lease6_update); handle.registerCommandCallout("lease6-update", lease6_update);
handle.registerCommandCallout("lease4-wipe", lease4_wipe); handle.registerCommandCallout("lease4-wipe", lease4_wipe);
handle.registerCommandCallout("lease6-wipe", lease6_wipe); handle.registerCommandCallout("lease6-wipe", lease6_wipe);
handle.registerCommandCallout("lease4-resend-ddns", lease4_resend_ddns);
handle.registerCommandCallout("lease6-resend-ddns", lease6_resend_ddns);
LOG_INFO(lease_cmds_logger, LEASE_CMDS_INIT_OK); LOG_INFO(lease_cmds_logger, LEASE_CMDS_INIT_OK);
return (0); return (0);

View File

@@ -1,4 +1,4 @@
// File created from ../../../../src/hooks/dhcp/lease_cmds/lease_cmds_messages.mes on Fri Feb 08 2019 20:34 // File created from ../../../../src/hooks/dhcp/lease_cmds/lease_cmds_messages.mes on Fri Mar 13 2020 14:35
#include <cstddef> #include <cstddef>
#include <log/message_types.h> #include <log/message_types.h>
@@ -16,6 +16,10 @@ extern const isc::log::MessageID LEASE_CMDS_DEL6 = "LEASE_CMDS_DEL6";
extern const isc::log::MessageID LEASE_CMDS_DEL6_FAILED = "LEASE_CMDS_DEL6_FAILED"; extern const isc::log::MessageID LEASE_CMDS_DEL6_FAILED = "LEASE_CMDS_DEL6_FAILED";
extern const isc::log::MessageID LEASE_CMDS_INIT_FAILED = "LEASE_CMDS_INIT_FAILED"; extern const isc::log::MessageID LEASE_CMDS_INIT_FAILED = "LEASE_CMDS_INIT_FAILED";
extern const isc::log::MessageID LEASE_CMDS_INIT_OK = "LEASE_CMDS_INIT_OK"; extern const isc::log::MessageID LEASE_CMDS_INIT_OK = "LEASE_CMDS_INIT_OK";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4 = "LEASE_CMDS_RESEND_DDNS4";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED = "LEASE_CMDS_RESEND_DDNS4_FAILED";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6 = "LEASE_CMDS_RESEND_DDNS6";
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED = "LEASE_CMDS_RESEND_DDNS6_FAILED";
namespace { namespace {
@@ -32,6 +36,10 @@ const char* values[] = {
"LEASE_CMDS_DEL6_FAILED", "lease6-del command failed (parameters: %1, reason: %2)", "LEASE_CMDS_DEL6_FAILED", "lease6-del command failed (parameters: %1, reason: %2)",
"LEASE_CMDS_INIT_FAILED", "loading Lease Commands hooks library failed: %1", "LEASE_CMDS_INIT_FAILED", "loading Lease Commands hooks library failed: %1",
"LEASE_CMDS_INIT_OK", "loading Lease Commands hooks library successful", "LEASE_CMDS_INIT_OK", "loading Lease Commands hooks library successful",
"LEASE_CMDS_RESEND_DDNS4", "lease6-resend-ddns command successful: %1",
"LEASE_CMDS_RESEND_DDNS4_FAILED", "lease6-resend-ddns command failed: %1",
"LEASE_CMDS_RESEND_DDNS6", "lease6-resend-ddns command successful: %1",
"LEASE_CMDS_RESEND_DDNS6_FAILED", "lease6-resend-ddns command failed: %1",
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
// File created from ../../../../src/hooks/dhcp/lease_cmds/lease_cmds_messages.mes on Fri Feb 08 2019 20:34 // File created from ../../../../src/hooks/dhcp/lease_cmds/lease_cmds_messages.mes on Fri Mar 13 2020 14:35
#ifndef LEASE_CMDS_MESSAGES_H #ifndef LEASE_CMDS_MESSAGES_H
#define LEASE_CMDS_MESSAGES_H #define LEASE_CMDS_MESSAGES_H
@@ -17,5 +17,9 @@ extern const isc::log::MessageID LEASE_CMDS_DEL6;
extern const isc::log::MessageID LEASE_CMDS_DEL6_FAILED; extern const isc::log::MessageID LEASE_CMDS_DEL6_FAILED;
extern const isc::log::MessageID LEASE_CMDS_INIT_FAILED; extern const isc::log::MessageID LEASE_CMDS_INIT_FAILED;
extern const isc::log::MessageID LEASE_CMDS_INIT_OK; extern const isc::log::MessageID LEASE_CMDS_INIT_OK;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS4_FAILED;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6;
extern const isc::log::MessageID LEASE_CMDS_RESEND_DDNS6_FAILED;
#endif // LEASE_CMDS_MESSAGES_H #endif // LEASE_CMDS_MESSAGES_H

View File

@@ -49,3 +49,19 @@ the log message.
% LEASE_CMDS_INIT_OK loading Lease Commands hooks library successful % LEASE_CMDS_INIT_OK loading Lease Commands hooks library successful
This info message indicates that the Lease Commands hooks library has been This info message indicates that the Lease Commands hooks library has been
loaded successfully. Enjoy! loaded successfully. Enjoy!
% LEASE_CMDS_RESEND_DDNS4 lease6-resend-ddns command successful: %1
A request to update DNS for the requested IPv4 lease address has been
successfully queued for transmission to kea-dhcp-ddns.
% LEASE_CMDS_RESEND_DDNS4_FAILED lease6-resend-ddns command failed: %1
A request to update DNS for the requested IPv4 lease has failed. The
reason for the failure is logged.
% LEASE_CMDS_RESEND_DDNS6 lease6-resend-ddns command successful: %1
A request to update DNS for the requested IPv6 lease address has been
successfully queued for transmission to kea-dhcp-ddns.
% LEASE_CMDS_RESEND_DDNS6_FAILED lease6-resend-ddns command failed: %1
A request to update DNS for the requested IPv6 lease has failed. The
reason for the failure is logged.