]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[393-global-search-through-leases-by-mac-or-hostname-w-o-specifying-a-subnet-id]...
authorFrancis Dupont <fdupont@isc.org>
Wed, 16 Oct 2019 20:08:34 +0000 (22:08 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 25 Oct 2019 15:26:23 +0000 (17:26 +0200)
src/hooks/dhcp/lease_cmds/lease_cmds.cc
src/hooks/dhcp/lease_cmds/lease_cmds.h
src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc

index 5ec7bce1f18b7b7ab309d535960b3fa2e32c60a5..7ded5be594c973daf2a348e83a19cfcb3719ac92 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <boost/bind.hpp>
 #include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
 #include <string>
 #include <sstream>
 
@@ -174,6 +175,51 @@ public:
     int
     leaseGetPageHandler(hooks::CalloutHandle& handle);
 
+    /// @brief lease4-get-by-hw-address command handler
+    ///
+    /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseGetByHwAddressHandler
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByHwAddressHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease4-get-by-client-id command handler
+    ///
+    /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseGetByClientIdHandler
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByClientIdHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease6-get-by-duid command handler
+    ///
+    /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseGetByDuidHandler
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByDuidHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease4-get-by-hostname and lease6-get-by-hostname commands
+    /// handler
+    ///
+    /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseGetByHostnameHandler
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByHostnameHandler(hooks::CalloutHandle& handle);
+
     /// @brief lease4-del command handler
     ///
     /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4DelHandler
@@ -748,6 +794,230 @@ LeaseCmdsImpl::leaseGetPageHandler(CalloutHandle& handle) {
     return (CONTROL_RESULT_SUCCESS);
 }
 
+int
+LeaseCmdsImpl::leaseGetByHwAddressHandler(CalloutHandle& handle) {
+    try {
+        extractCommand(handle);
+
+        // arguments must always be present
+        if (!cmd_args_) {
+            isc_throw(BadValue, "no parameters specified for the " << cmd_name_
+                      << " command");
+        }
+
+        // the hw-address parameter is mandatory.
+        ConstElementPtr hw_address = cmd_args_->get("hw-address");
+        if (!hw_address) {
+            isc_throw(BadValue, "'hw-address' parameter not specified");
+        }
+
+        // The 'hw-address' argument is a string.
+        if (hw_address->getType() != Element::string) {
+            isc_throw(BadValue, "'hw-address'parameter must be a string");
+        }
+
+        HWAddr hwaddr = HWAddr::fromText(hw_address->stringValue());
+
+        Lease4Collection leases =
+            LeaseMgrFactory::instance().getLease4(hwaddr);
+        ElementPtr leases_json = Element::createList();
+        for (auto lease : leases) {
+            ElementPtr lease_json = lease->toElement();
+            leases_json->add(lease_json);
+        }
+
+        std::ostringstream s;
+        s << leases_json->size() << " IPv4 lease(s) found.";
+        ElementPtr args = Element::createMap();
+        args->set("leases", leases_json);
+        ConstElementPtr response =
+            createAnswer(leases_json->size() > 0 ?
+                         CONTROL_RESULT_SUCCESS :
+                         CONTROL_RESULT_EMPTY,
+                         s.str(), args);
+        setResponse(handle, response);
+
+    } catch (const std::exception& ex) {
+        setErrorResponse(handle, ex.what());
+        return (CONTROL_RESULT_ERROR);
+    }
+
+    return (0);
+}
+
+int
+LeaseCmdsImpl::leaseGetByClientIdHandler(CalloutHandle& handle) {
+    try {
+        extractCommand(handle);
+
+        // arguments must always be present
+        if (!cmd_args_) {
+            isc_throw(BadValue, "no parameters specified for the " << cmd_name_
+                      << " command");
+        }
+
+        // the client-id parameter is mandatory.
+        ConstElementPtr client_id = cmd_args_->get("client-id");
+        if (!client_id) {
+            isc_throw(BadValue, "'client-id' parameter not specified");
+        }
+
+        // The 'client-id' argument is a string.
+        if (client_id->getType() != Element::string) {
+            isc_throw(BadValue, "'client-id'parameter must be a string");
+        }
+
+        ClientIdPtr clientid = ClientId::fromText(client_id->stringValue());
+
+        Lease4Collection leases =
+            LeaseMgrFactory::instance().getLease4(*clientid);
+        ElementPtr leases_json = Element::createList();
+        for (auto lease : leases) {
+            ElementPtr lease_json = lease->toElement();
+            leases_json->add(lease_json);
+        }
+
+        std::ostringstream s;
+        s << leases_json->size() << " IPv4 lease(s) found.";
+        ElementPtr args = Element::createMap();
+        args->set("leases", leases_json);
+        ConstElementPtr response =
+            createAnswer(leases_json->size() > 0 ?
+                         CONTROL_RESULT_SUCCESS :
+                         CONTROL_RESULT_EMPTY,
+                         s.str(), args);
+        setResponse(handle, response);
+
+    } catch (const std::exception& ex) {
+        setErrorResponse(handle, ex.what());
+        return (CONTROL_RESULT_ERROR);
+    }
+
+    return (0);
+}
+
+int
+LeaseCmdsImpl::leaseGetByDuidHandler(CalloutHandle& handle) {
+    try {
+        extractCommand(handle);
+
+        // arguments must always be present
+        if (!cmd_args_) {
+            isc_throw(BadValue, "no parameters specified for the " << cmd_name_
+                      << " command");
+        }
+
+        // the duid parameter is mandatory.
+        ConstElementPtr duid = cmd_args_->get("duid");
+        if (!duid) {
+            isc_throw(BadValue, "'duid' parameter not specified");
+        }
+
+        // The 'duid' argument is a string.
+        if (duid->getType() != Element::string) {
+            isc_throw(BadValue, "'duid'parameter must be a string");
+        }
+
+        DUID duid_ = DUID::fromText(duid->stringValue());
+
+        Lease6Collection leases =
+            LeaseMgrFactory::instance().getLeases6(duid_);
+        ElementPtr leases_json = Element::createList();
+        for (auto lease : leases) {
+            ElementPtr lease_json = lease->toElement();
+            leases_json->add(lease_json);
+        }
+
+        std::ostringstream s;
+        s << leases_json->size() << " IPv4 lease(s) found.";
+        ElementPtr args = Element::createMap();
+        args->set("leases", leases_json);
+        ConstElementPtr response =
+            createAnswer(leases_json->size() > 0 ?
+                         CONTROL_RESULT_SUCCESS :
+                         CONTROL_RESULT_EMPTY,
+                         s.str(), args);
+        setResponse(handle, response);
+
+    } catch (const std::exception& ex) {
+        setErrorResponse(handle, ex.what());
+        return (CONTROL_RESULT_ERROR);
+    }
+
+    return (0);
+}
+
+int
+LeaseCmdsImpl::leaseGetByHostnameHandler(CalloutHandle& handle) {
+    bool v4;
+    try {
+        extractCommand(handle);
+        v4 = (cmd_name_ == "lease4-get-by-hostname");
+
+        // arguments must always be present
+        if (!cmd_args_) {
+            isc_throw(BadValue, "no parameters specified for the " << cmd_name_
+                      << " command");
+        }
+
+        // the hostname parameter is mandatory.
+        ConstElementPtr hostname = cmd_args_->get("hostname");
+        if (!hostname) {
+            isc_throw(BadValue, "'hostname' parameter not specified");
+        }
+
+        // The 'hostname' argument is a string.
+        if (hostname->getType() != Element::string) {
+            isc_throw(BadValue, "'hostname'parameter must be a string");
+        }
+
+        std::string hostname_ = hostname->stringValue();
+        /// The 'hostname' argument should not be empty.
+        if (hostname_.empty()) {
+            isc_throw(BadValue, "'hostname' parameter  is empty");
+        }
+        boost::algorithm::to_lower(hostname_);
+
+        ElementPtr leases_json = Element::createList();
+        if (v4) {
+            Lease4Collection leases =
+                LeaseMgrFactory::instance().getLeases4(hostname_);
+
+            for (auto lease : leases) {
+                ElementPtr lease_json = lease->toElement();
+                leases_json->add(lease_json);
+            }
+        } else {
+            Lease6Collection leases =
+                LeaseMgrFactory::instance().getLeases6(hostname_);
+
+            for (auto lease : leases) {
+                ElementPtr lease_json = lease->toElement();
+                leases_json->add(lease_json);
+            }
+        }
+
+        std::ostringstream s;
+        s << leases_json->size()
+          << " IPv" << (v4 ? "4" : "6")
+          << " lease(s) found.";
+        ElementPtr args = Element::createMap();
+        args->set("leases", leases_json);
+        ConstElementPtr response =
+            createAnswer(leases_json->size() > 0 ?
+                         CONTROL_RESULT_SUCCESS :
+                         CONTROL_RESULT_EMPTY,
+                         s.str(), args);
+        setResponse(handle, response);
+
+    } catch (const std::exception& ex) {
+        setErrorResponse(handle, ex.what());
+        return (CONTROL_RESULT_ERROR);
+    }
+
+    return (0);
+}
+
 int
 LeaseCmdsImpl::lease4DelHandler(CalloutHandle& handle) {
     Parameters p;
@@ -1264,7 +1534,7 @@ LeaseCmdsImpl::getIPv6AddressForDelete(const Parameters& parameters) const {
         if (lease6) {
             addr = lease6->addr_;
         }
+
        break;
 
     default:
@@ -1323,6 +1593,26 @@ LeaseCmds::leaseGetPageHandler(hooks::CalloutHandle& handle) {
     return (impl_->leaseGetPageHandler(handle));
 }
 
+int
+LeaseCmds::leaseGetByHwAddressHandler(hooks::CalloutHandle& handle) {
+    return (impl_->leaseGetByHwAddressHandler(handle));
+}
+
+int
+LeaseCmds::leaseGetByClientIdHandler(hooks::CalloutHandle& handle) {
+    return (impl_->leaseGetByClientIdHandler(handle));
+}
+
+int
+LeaseCmds::leaseGetByDuidHandler(hooks::CalloutHandle& handle) {
+    return (impl_->leaseGetByDuidHandler(handle));
+}
+
+int
+LeaseCmds::leaseGetByHostnameHandler(hooks::CalloutHandle& handle) {
+    return (impl_->leaseGetByHostnameHandler(handle));
+}
+
 int
 LeaseCmds::lease4DelHandler(CalloutHandle& handle) {
     return(impl_->lease4DelHandler(handle));
index 66c2851a9c0536c35248e6d86cfca85ee9023867..1f8e8481df9f12a40a86b6760a4b2315d9b97c8e 100644 (file)
@@ -258,6 +258,87 @@ public:
     int
     leaseGetPageHandler(hooks::CalloutHandle& handle);
 
+    /// @brief lease4-get-by-hw-address command handler
+    ///
+    /// This command attempts to retrieve all IPv4 leases with a particular
+    /// hardware address.
+    ///
+    /// Example command:
+    /// {
+    ///     "command": "lease4-get-by-hw-address",
+    ///     "arguments": {
+    ///         "hwaddr": "00:01:02:03:04:05"
+    ///     }
+    /// }
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByHwAddressHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease4-get-by-client-id command handler
+    ///
+    /// This command attempts to retrieve all IPv4 leases with a particular
+    /// Client Id.
+    ///
+    /// Example command:
+    /// {
+    ///     "command": "lease4-get-by-client-id",
+    ///     "arguments": {
+    ///         "client-id": "this-is-a-client"
+    ///     }
+    /// }
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByClientIdHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease6-get-by-duid command handler
+    ///
+    /// This command attempts to retrieve all IPv6 leases with a particular
+    /// DUID.
+    ///
+    /// Example command:
+    /// {
+    ///     "command": "lease6-get-by-duid",
+    ///     "arguments": {
+    ///         "duid": "01:02:03:04:05:06:07:08"
+    ///     }
+    /// }
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByDuidHandler(hooks::CalloutHandle& handle);
+
+    /// @brief lease4-get-by-hostname and lease6-get-by-hostname commands
+    /// handler
+    ///
+    /// Thesecommands attempt to retrieve all IPv4 or Ipv6 leases with
+    /// a particular hostname.
+    ///
+    /// Example command for v4:
+    /// {
+    ///     "command": "lease4-get-by-hostname",
+    ///     "arguments": {
+    ///         "hostname": "urania.example.org"
+    ///     }
+    /// }
+    ///
+    /// @param handle Callout context - which is expected to contain the
+    /// get command JSON text in the "command" argument
+    /// @return 0 if the handler has been invoked successfully, 1 if an
+    /// error occurs, 3 if no leases are returned.
+    int
+    leaseGetByHostnameHandler(hooks::CalloutHandle& handle);
+
     /// @brief lease4-del command handler
     ///
     /// This command attempts to delete an IPv4 lease that match selected
index b610af68fe03b923ef471c51513da65254ab14cf..1b28e4615e1d4aa269c0537d15988511e545565a 100644 (file)
@@ -121,6 +121,61 @@ int lease6_get_page(CalloutHandle& handle) {
     return (lease_cmds.leaseGetPageHandler(handle));
 }
 
+/// @brief This is a command callout for 'lease4-get-by-hw-address' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 3 if no leases are returned.
+int lease4_get_by_hw_address(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return (lease_cmds.leaseGetByHwAddressHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease4-get-by-client-id' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 3 if no leases are returned.
+int lease4_get_by_client_id(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return (lease_cmds.leaseGetByClientIdHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease6-get-by-duid' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 3 if no leases are returned.
+int lease6_get_by_duid(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return (lease_cmds.leaseGetByDuidHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease4-get-by-hostname' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 3 if no leases are returned.
+int lease4_get_by_hostname(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return (lease_cmds.leaseGetByHostnameHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease6-get-by-hostname' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 3 if no leases are returned.
+int lease6_get_by_hostname(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return (lease_cmds.leaseGetByHostnameHandler(handle));
+}
+
 /// @brief This is a command callout for 'lease4-del' command.
 ///
 /// @param handle Callout handle used to retrieve a command and
@@ -201,6 +256,15 @@ int load(LibraryHandle& handle) {
     handle.registerCommandCallout("lease6-get-all", lease6_get_all);
     handle.registerCommandCallout("lease4-get-page", lease4_get_page);
     handle.registerCommandCallout("lease6-get-page", lease6_get_page);
+    handle.registerCommandCallout("lease4-get-by-hw-address",
+                                  lease4_get_by_hw_address);
+    handle.registerCommandCallout("lease4-get-by-client-id",
+                                  lease4_get_by_client_id);
+    handle.registerCommandCallout("lease6-get-by-duid", lease6_get_by_duid);
+    handle.registerCommandCallout("lease4-get-by-hostname",
+                                  lease4_get_by_hostname);
+    handle.registerCommandCallout("lease6-get-by-hostname",
+                                  lease6_get_by_hostname);
     handle.registerCommandCallout("lease4-del", lease4_del);
     handle.registerCommandCallout("lease6-del", lease6_del);
     handle.registerCommandCallout("lease4-update", lease4_update);