2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 21:45:37 +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/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/ncr_generator.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/sanity_checker.h>
#include <dhcp/duid.h>
@@ -34,6 +35,7 @@
using namespace isc::dhcp;
using namespace isc::data;
using namespace isc::dhcp_ddns;
using namespace isc::config;
using namespace isc::asiolink;
using namespace isc::hooks;
@@ -282,6 +284,24 @@ public:
int
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
///
/// See @ref Parameters class for detailed description of what is expected
@@ -329,6 +349,16 @@ public:
const DuidPtr& duid,
const int control_result,
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
@@ -1543,6 +1573,121 @@ LeaseCmdsImpl::getIPv6LeaseForDelete(const Parameters& parameters) const {
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
LeaseCmdsImpl::createFailedLeaseMap(const Lease::Type& lease_type,
const IOAddress& lease_address,
@@ -1651,6 +1796,16 @@ LeaseCmds::lease6WipeHandler(CalloutHandle& 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()
:impl_(new LeaseCmdsImpl()) {
}

View File

@@ -525,6 +525,56 @@ public:
int
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:
/// Pointer to the actual implementation
boost::shared_ptr<LeaseCmdsImpl> impl_;

View File

@@ -242,6 +242,28 @@ int lease6_wipe(CalloutHandle& 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.
///
/// @param handle library handle
@@ -271,6 +293,8 @@ int load(LibraryHandle& handle) {
handle.registerCommandCallout("lease6-update", lease6_update);
handle.registerCommandCallout("lease4-wipe", lease4_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);
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 <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_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_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 {
@@ -32,6 +36,10 @@ const char* values[] = {
"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_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
};

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
#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_INIT_FAILED;
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

View File

@@ -49,3 +49,19 @@ the log message.
% LEASE_CMDS_INIT_OK loading Lease Commands hooks library successful
This info message indicates that the Lease Commands hooks library has been
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.