mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[5468] Implemented lease4-get-all command.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2017-2018 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
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::data;
|
||||
@@ -129,6 +130,18 @@ public:
|
||||
int
|
||||
leaseGetHandler(CalloutHandle& handle);
|
||||
|
||||
/// @brief lease4-get-all command handler
|
||||
///
|
||||
/// This command attempts to retrieve all IPv4 leases or all IPv4 leases
|
||||
/// belonging to the particular subnets. If no subnet identifiers are
|
||||
/// provided, it returns all IPv4 leases from the database.
|
||||
///
|
||||
/// @param handle Callout context - which is expected to contain the
|
||||
/// get command JSON text in the "command" argument
|
||||
/// return 0 upon success, non-zero otherwise.
|
||||
int
|
||||
lease4GetAllHandler(CalloutHandle& handle);
|
||||
|
||||
/// @brief lease4-del command handler
|
||||
///
|
||||
/// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4DelHandler
|
||||
@@ -455,6 +468,65 @@ LeaseCmdsImpl::leaseGetHandler(CalloutHandle& handle) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
LeaseCmdsImpl::lease4GetAllHandler(CalloutHandle& handle) {
|
||||
try {
|
||||
extractCommand(handle);
|
||||
|
||||
ElementPtr leases_json = Element::createList();
|
||||
|
||||
// The argument may contain a list of subnets for which leases should
|
||||
// be returned.
|
||||
if (cmd_args_) {
|
||||
ConstElementPtr subnets = cmd_args_->get("subnets");
|
||||
if (subnets) {
|
||||
if (subnets->getType() != Element::list) {
|
||||
isc_throw(BadValue, "'subnets' parameter must be a list");
|
||||
}
|
||||
|
||||
const std::vector<ElementPtr>& subnet_ids = subnets->listValue();
|
||||
for (auto subnet_id = subnet_ids.begin(); subnet_id != subnet_ids.end();
|
||||
++subnet_id) {
|
||||
if ((*subnet_id)->getType() != Element::integer) {
|
||||
isc_throw(BadValue, "listed subnet identifiers must be numbers");
|
||||
}
|
||||
|
||||
Lease4Collection leases =
|
||||
LeaseMgrFactory::instance().getLeases4((*subnet_id)->intValue());
|
||||
for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
|
||||
ElementPtr lease_json = (*lease)->toElement();
|
||||
leases_json->add(lease_json);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
isc_throw(BadValue, "'subnets' parameter not specified");
|
||||
}
|
||||
|
||||
} else {
|
||||
// There is no 'subnets' argument so let's return all leases.
|
||||
Lease4Collection leases = LeaseMgrFactory::instance().getLeases4();
|
||||
for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
|
||||
ElementPtr lease_json = (*lease)->toElement();
|
||||
leases_json->add(lease_json);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream s;
|
||||
s << leases_json->size() << " IPv4 lease(s) found.";
|
||||
ConstElementPtr response = createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
s.str(), leases_json);
|
||||
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;
|
||||
@@ -707,6 +779,11 @@ LeaseCmds::leaseGetHandler(CalloutHandle& handle) {
|
||||
return(impl_->leaseGetHandler(handle));
|
||||
}
|
||||
|
||||
int
|
||||
LeaseCmds::lease4GetAllHandler(hooks::CalloutHandle& handle) {
|
||||
return (impl_->lease4GetAllHandler(handle));
|
||||
}
|
||||
|
||||
int
|
||||
LeaseCmds::lease4DelHandler(CalloutHandle& handle) {
|
||||
return(impl_->lease4DelHandler(handle));
|
||||
|
@@ -131,6 +131,31 @@ public:
|
||||
int
|
||||
leaseGetHandler(hooks::CalloutHandle& handle);
|
||||
|
||||
/// @brief lease4-get-all command handler
|
||||
///
|
||||
/// This command attempts to retrieve all IPv4 leases or all IPv4 leases
|
||||
/// belonging to the particular subnets. If no subnet identifiers are
|
||||
/// provided, it returns all IPv4 leases from the database.
|
||||
///
|
||||
/// Example command for query by (subnet-ids):
|
||||
/// {
|
||||
/// "command": "lease4-get-all",
|
||||
/// "arguments": {
|
||||
/// "subnets": [ 1, 2, 3, 4 ]
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// Example command for retrieving all leases:
|
||||
/// {
|
||||
/// "command": "lease4-get-all",
|
||||
/// }
|
||||
///
|
||||
/// @param handle Callout context - which is expected to contain the
|
||||
/// get command JSON text in the "command" argument
|
||||
/// @return result of the operation.
|
||||
int
|
||||
lease4GetAllHandler(hooks::CalloutHandle& handle);
|
||||
|
||||
/// @brief lease4-del command handler
|
||||
///
|
||||
/// This command attempts to delete an IPv4 lease that match selected
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the End User License
|
||||
// Agreement. See COPYING file in the premium/ directory.
|
||||
@@ -53,6 +53,17 @@ int lease4_get(CalloutHandle& handle) {
|
||||
return(lease_cmds.leaseGetHandler(handle));
|
||||
}
|
||||
|
||||
/// @brief This is a command callout for 'lease4-get-all' 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_get_all(CalloutHandle& handle) {
|
||||
LeaseCmds lease_cmds;
|
||||
return (lease_cmds.lease4GetAllHandler(handle));
|
||||
}
|
||||
|
||||
/// @brief This is a command callout for 'lease6-get' command.
|
||||
///
|
||||
/// @param handle Callout handle used to retrieve a command and
|
||||
@@ -138,6 +149,7 @@ int load(LibraryHandle& handle) {
|
||||
handle.registerCommandCallout("lease4-add", lease4_add);
|
||||
handle.registerCommandCallout("lease6-add", lease6_add);
|
||||
handle.registerCommandCallout("lease4-get", lease4_get);
|
||||
handle.registerCommandCallout("lease4-get-all", lease4_get_all);
|
||||
handle.registerCommandCallout("lease6-get", lease6_get);
|
||||
handle.registerCommandCallout("lease4-del", lease4_del);
|
||||
handle.registerCommandCallout("lease6-del", lease6_del);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2017-2018 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
|
||||
@@ -260,9 +260,11 @@ public:
|
||||
subnets->add(subnet6);
|
||||
cfg_mgr.commit();
|
||||
} else {
|
||||
Subnet4Ptr subnet4(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, 44));
|
||||
Subnet4Ptr subnet44(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, 44));
|
||||
Subnet4Ptr subnet88(new Subnet4(IOAddress("192.0.3.0"), 24, 1, 2, 3, 88));
|
||||
CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4();
|
||||
subnets->add(subnet4);
|
||||
subnets->add(subnet44);
|
||||
subnets->add(subnet88);
|
||||
cfg_mgr.commit();
|
||||
}
|
||||
|
||||
@@ -270,34 +272,43 @@ public:
|
||||
if (v6) {
|
||||
lmptr_->addLease(createLease6());
|
||||
} else {
|
||||
lmptr_->addLease(createLease4());
|
||||
lmptr_->addLease(createLease4("192.0.2.1", 44, 0x08, 0x42));
|
||||
lmptr_->addLease(createLease4("192.0.2.2", 44, 0x09, 0x56));
|
||||
lmptr_->addLease(createLease4("192.0.3.1", 88, 0x08, 0x42));
|
||||
lmptr_->addLease(createLease4("192.0.3.2", 88, 0x09, 0x56));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Creates an IPv4 lease
|
||||
///
|
||||
/// Lease parameters: ip-address = 192.0.2.1, hwaddr = 08:08:08:08:08:08,
|
||||
/// client-id = 42:42:42:42:42:42:42:42, valid lifetime = 3600,
|
||||
/// cltt = 12345678, subnet-id = 44, fqdn-fwd = false, fqdn-rev = true
|
||||
/// hostname = myhost.example.com
|
||||
/// Lease parameters: valid lifetime = 3600, cltt = 12345678, fqdn-fwd = false,
|
||||
/// fqdn-rev = true, hostname = myhost.example.com
|
||||
///
|
||||
/// @param ip_address IP address for the lease.
|
||||
/// @param subnet_id subnet identifier
|
||||
/// @param hw_address_pattern value to be used for generating HW address by repating
|
||||
/// it 6 times.
|
||||
/// @param client_id_pattern value to be used for generating client identifier by
|
||||
/// repeating it 8 times.
|
||||
/// @return Returns the lease created
|
||||
Lease4Ptr createLease4() {
|
||||
Lease4Ptr createLease4(const std::string& ip_address, const SubnetID& subnet_id,
|
||||
const uint8_t hw_address_pattern,
|
||||
const uint8_t client_id_pattern) {
|
||||
Lease4Ptr lease(new Lease4());
|
||||
|
||||
lease->addr_ = IOAddress("192.0.2.1");
|
||||
lease->addr_ = IOAddress(ip_address);
|
||||
|
||||
// Initialize unused fields.
|
||||
lease->t1_ = 0; // Not saved
|
||||
lease->t2_ = 0; // Not saved
|
||||
|
||||
// Set other parameters. For historical reasons, address 0 is not used.
|
||||
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x08), HTYPE_ETHER));
|
||||
lease->client_id_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, 0x42)));
|
||||
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, hw_address_pattern), HTYPE_ETHER));
|
||||
lease->client_id_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, client_id_pattern)));
|
||||
lease->valid_lft_ = 3600;
|
||||
lease->cltt_ = 12345678;
|
||||
lease->subnet_id_ = 44;
|
||||
lease->subnet_id_ = subnet_id;
|
||||
lease->fqdn_fwd_ = false;
|
||||
lease->fqdn_rev_ = true;
|
||||
lease->hostname_ = "myhost.example.com.";
|
||||
@@ -343,6 +354,20 @@ public:
|
||||
uint32_t subnet_id, std::string hwaddr,
|
||||
bool client_id_required) {
|
||||
ASSERT_TRUE(l);
|
||||
|
||||
// If the element is a list we need to retrieve the lease that
|
||||
// we're interested in.
|
||||
if (l->getType() == Element::list) {
|
||||
std::vector<ElementPtr> e = l->listValue();
|
||||
for (auto it = e.begin(); it != e.end(); ++it) {
|
||||
ConstElementPtr ip_address = (*it)->get("ip-address");
|
||||
if (ip_address && ip_address->stringValue() == ip) {
|
||||
l = (*it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_TRUE(l->get("ip-address"));
|
||||
EXPECT_EQ(ip, l->get("ip-address")->stringValue());
|
||||
|
||||
@@ -1099,6 +1124,132 @@ TEST_F(LeaseCmdsTest, Lease4GetByHWAddr) {
|
||||
checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
|
||||
}
|
||||
|
||||
// Checks that lease4-get-all returns all leases.
|
||||
TEST_F(LeaseCmdsTest, Lease4GetAll) {
|
||||
|
||||
// Initialize lease manager (false = v4, true = add a lease)
|
||||
initLeaseMgr(false, true);
|
||||
|
||||
// Query for all leases.
|
||||
string cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\"\n"
|
||||
"}";
|
||||
string exp_rsp = "4 IPv4 lease(s) found.";
|
||||
ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
|
||||
|
||||
// Now check that the lease parameters were indeed returned.
|
||||
ASSERT_TRUE(rsp);
|
||||
ConstElementPtr leases = rsp->get("arguments");
|
||||
ASSERT_TRUE(leases);
|
||||
ASSERT_EQ(Element::list, leases->getType());
|
||||
|
||||
// Let's check if the response contains desired leases.
|
||||
checkLease4(leases, "192.0.2.1", 44, "08:08:08:08:08:08", true);
|
||||
checkLease4(leases, "192.0.2.2", 44, "09:09:09:09:09:09", true);
|
||||
checkLease4(leases, "192.0.3.1", 88, "08:08:08:08:08:08", true);
|
||||
checkLease4(leases, "192.0.3.2", 88, "09:09:09:09:09:09", true);
|
||||
}
|
||||
|
||||
// Checks that lease4-get-all returns all leases for a subnet.
|
||||
TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetId) {
|
||||
|
||||
// Initialize lease manager (false = v4, true = add a lease)
|
||||
initLeaseMgr(false, true);
|
||||
|
||||
// Query for leases from subnet 44. Subnet 127 will be ignored because
|
||||
// it doesn't contain any leases.
|
||||
string cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\",\n"
|
||||
" \"arguments\": {\n"
|
||||
" \"subnets\": [ 44, 127 ]"
|
||||
" }\n"
|
||||
"}";
|
||||
string exp_rsp = "2 IPv4 lease(s) found.";
|
||||
ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
|
||||
|
||||
// Now check that the lease parameters were indeed returned.
|
||||
ASSERT_TRUE(rsp);
|
||||
ConstElementPtr leases = rsp->get("arguments");
|
||||
ASSERT_TRUE(leases);
|
||||
ASSERT_EQ(Element::list, leases->getType());
|
||||
|
||||
// Let's check if the response contains desired leases.
|
||||
checkLease4(leases, "192.0.2.1", 44, "08:08:08:08:08:08", true);
|
||||
checkLease4(leases, "192.0.2.2", 44, "09:09:09:09:09:09", true);
|
||||
}
|
||||
|
||||
// Checks that lease4-get-all returns leases from multiple subnets.
|
||||
TEST_F(LeaseCmdsTest, Lease4GetAllByMultipleSubnetIds) {
|
||||
|
||||
// Initialize lease manager (false = v4, true = add a lease)
|
||||
initLeaseMgr(false, true);
|
||||
|
||||
// Query for leases from subnet 44 and 88.
|
||||
string cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\",\n"
|
||||
" \"arguments\": {\n"
|
||||
" \"subnets\": [ 44, 88 ]"
|
||||
" }\n"
|
||||
"}";
|
||||
string exp_rsp = "4 IPv4 lease(s) found.";
|
||||
ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
|
||||
|
||||
// Now check that the lease parameters were indeed returned.
|
||||
ASSERT_TRUE(rsp);
|
||||
ConstElementPtr leases = rsp->get("arguments");
|
||||
ASSERT_TRUE(leases);
|
||||
ASSERT_EQ(Element::list, leases->getType());
|
||||
|
||||
// Let's check if the response contains desired leases.
|
||||
checkLease4(leases, "192.0.2.1", 44, "08:08:08:08:08:08", true);
|
||||
checkLease4(leases, "192.0.2.2", 44, "09:09:09:09:09:09", true);
|
||||
checkLease4(leases, "192.0.3.1", 88, "08:08:08:08:08:08", true);
|
||||
checkLease4(leases, "192.0.3.2", 88, "09:09:09:09:09:09", true);
|
||||
}
|
||||
|
||||
// Checks that lease4-get-all checks its input arguments.
|
||||
TEST_F(LeaseCmdsTest, Lease4GetBySubnetIdInvalidArguments) {
|
||||
|
||||
// Initialize lease manager (false = v4, true = add a lease)
|
||||
initLeaseMgr(false, true);
|
||||
|
||||
// Subnets not specified in arguments.
|
||||
string cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\",\n"
|
||||
" \"arguments\": {"
|
||||
" \"foo\": 1\n"
|
||||
" }\n"
|
||||
"}";
|
||||
string exp_rsp = "'subnets' parameter not specified";
|
||||
testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
|
||||
|
||||
// Subnets are not a list.
|
||||
cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\",\n"
|
||||
" \"arguments\": {"
|
||||
" \"subnets\": 1\n"
|
||||
" }\n"
|
||||
"}";
|
||||
exp_rsp = "'subnets' parameter must be a list";
|
||||
testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
|
||||
|
||||
// Subnets list must contain numbers.
|
||||
cmd =
|
||||
"{\n"
|
||||
" \"command\": \"lease4-get-all\",\n"
|
||||
" \"arguments\": {"
|
||||
" \"subnets\": [ \"x\", \"y\" ]\n"
|
||||
" }\n"
|
||||
"}";
|
||||
exp_rsp = "listed subnet identifiers must be numbers";
|
||||
testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
|
||||
}
|
||||
|
||||
// Checks that lease6-get(addr) can handle a situation when
|
||||
// the query is correctly formed, but the lease is not there.
|
||||
TEST_F(LeaseCmdsTest, Lease6GetByAddr6NotFound) {
|
||||
@@ -2098,7 +2249,7 @@ TEST_F(LeaseCmdsTest, Lease4Wipe) {
|
||||
" \"subnet-id\": 44"
|
||||
" }\n"
|
||||
"}";
|
||||
string exp_rsp = "Deleted 1 IPv4 lease(s).";
|
||||
string exp_rsp = "Deleted 2 IPv4 lease(s).";
|
||||
testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
|
||||
|
||||
// Make sure the lease is really gone.
|
||||
|
Reference in New Issue
Block a user