/// @brief Wrapper class around reservation command handlers.
class LeaseCmdsImpl : private CmdsImpl {
public:
- /// @brief Parameters specified for reservation-get and reservation-del
- ///
- /// As both call types (get and delete) need specify which reservation to
- /// act on, they have the same set of parameters. In particular, those
- /// two call types support the following sets of parameters:
- /// - address
- /// - subnet-id, identifier-type, identifier-value (v4)
- /// - subnet-id, lease-type, iaid, identifier-type, identifier-value (v6)
- ///
- /// This class stores those parameters and is used to pass them around.
+
+ /// @brief Parameters specified for lease commands.
class Parameters {
public:
/// @brief specifies type of query (by IP addr, by hwaddr, by DUID)
typedef enum {
- TYPE_ADDR, ///< query by IP address (either v4 or v6)
- TYPE_HWADDR, ///< query by hardware address (v4 only)
- TYPE_DUID ///< query by DUID (v6 only)
+ TYPE_ADDR, ///< query by IP address (either v4 or v6)
+ TYPE_HWADDR, ///< query by hardware address (v4 only)
+ TYPE_DUID, ///< query by DUID (v6 only)
+ TYPE_CLIENT_ID ///< query by client identifier (v4 only).
} Type;
/// @brief Specifies subnet-id (always used)
/// @brief Specifies identifier value (used when query_type is TYPE_DUID)
isc::dhcp::DuidPtr duid;
+ /// @brief Specifies identifier value (used when query_type is TYPE_CLIENT_ID)
+ isc::dhcp::ClientIdPtr client_id;
+
/// @brief Attempts to covert text to one of specified types
///
/// Supported values are: "address", hw-address and duid.
return (Parameters::TYPE_HWADDR);
} else if (txt == "duid") {
return (Parameters::TYPE_DUID);
+ } else if (txt == "client-id") {
+ return (Parameters::TYPE_CLIENT_ID);
} else {
isc_throw(BadValue, "Incorrect identifier type: "
<< txt << ", the only supported values are: "
x.hwaddr = HWAddrPtr(new HWAddr(hw));
break;
}
+ case Parameters::TYPE_CLIENT_ID: {
+ x.client_id = ClientId::fromText(ident->stringValue());
+ break;
+ }
case Parameters::TYPE_DUID: {
DUID duid = DUID::fromText(ident->stringValue());
x.duid = DuidPtr(new DUID(duid));
}
break;
+ case Parameters::TYPE_CLIENT_ID:
+ if (v4) {
+ if (!p.client_id) {
+ isc_throw(InvalidParameter, "Program error: Query by client-id "
+ "requires client-id to be specified");
+ }
+
+ lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
+ } else {
+ isc_throw(isc::InvalidParameter, "Query by client-id is not allowed in v6.");
+ }
+ break;
+
default: {
isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
break;
addr = lease4->addr_;
break;
+ case Parameters::TYPE_CLIENT_ID:
+ if (!p.client_id) {
+ isc_throw(InvalidParameter, "Program error: Query by client-id "
+ "requires client-id to be specified");
+ }
+
+ // Let's see if there's such a lease at all.
+ lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
+ if (!lease4) {
+ setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
+ return (0);
+ }
+
+ // Found it, can use it as is.
+ addr = lease4->addr_;
+ break;
+
case Parameters::TYPE_DUID:
isc_throw(InvalidParameter, "Delete by duid is not allowed in v4.");
break;
ASSERT_TRUE(lease);
// Let's check if the response makes any sense.
- checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
+ checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", true);
}
// Checks that lease4-get can handle a situation when the query is
testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
}
+// Checks that lease4-get can handle a situation when the query is
+// well formed, but the lease is not there.
+TEST_F(LeaseCmdsTest, Lease4GetByClientIdNotFound) {
+
+ // Initialize lease manager (false = v4, false = don't add a lease)
+ initLeaseMgr(false, false);
+
+ // No such lease.
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-get\",\n"
+ " \"arguments\": {"
+ " \"identifier-type\": \"client-id\","
+ " \"identifier\": \"01:02:03:04\","
+ " \"subnet-id\": 44"
+ " }\n"
+ "}";
+ string exp_rsp = "Lease not found.";
+ ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+}
+
+// Check that lease4-get can find a lease by client identifier.
+TEST_F(LeaseCmdsTest, Lease4GetByClientId) {
+ // Initialize lease manager (false = v4, true = add a lease)
+ initLeaseMgr(false, true);
+
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-get\",\n"
+ " \"arguments\": {"
+ " \"identifier-type\": \"client-id\","
+ " \"identifier\": \"42:42:42:42:42:42:42:42\","
+ " \"subnet-id\": 44"
+ " }\n"
+ "}";
+ string exp_rsp = "IPv4 lease found.";
+ ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+ // Now check that the lease parameters were indeed returned.
+ ASSERT_TRUE(rsp);
+ ConstElementPtr lease = rsp->get("arguments");
+ ASSERT_TRUE(lease);
+
+ // Let's check if the response makes any sense.
+ checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
+}
+
// Checks that lease6-get(subnet-id, addr) can handle a situation when
// the query is correctly formed, but the lease is not there.
TEST_F(LeaseCmdsTest, Lease6GetByDuidNotFound) {
EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
}
+// Checks that lease4-del can handle a situation when the query is
+// well formed, but the lease is not there.
+TEST_F(LeaseCmdsTest, Lease4DelByClientIdNotFound) {
+
+ // Initialize lease manager (false = v4, true = add a lease)
+ initLeaseMgr(false, true);
+
+ // No such lease.
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-del\",\n"
+ " \"arguments\": {"
+ " \"identifier-type\": \"client-id\","
+ " \"identifier\": \"01:02:03:04\","
+ " \"subnet-id\": 44"
+ " }\n"
+ "}";
+ string exp_rsp = "IPv4 lease not found.";
+ ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+
+ // Make sure the lease is still there.
+ EXPECT_TRUE(lmptr_->getLease4(IOAddress("192.0.2.1")));
+}
+
+// Checks that lease4-del can find and delete a lease by client identifier.
+TEST_F(LeaseCmdsTest, Lease4DelByClientId) {
+ // Initialize lease manager (false = v4, true = add a lease)
+ initLeaseMgr(false, true);
+
+ // Invalid
+ string cmd =
+ "{\n"
+ " \"command\": \"lease4-del\",\n"
+ " \"arguments\": {"
+ " \"identifier-type\": \"client-id\","
+ " \"identifier\": \"42:42:42:42:42:42:42:42\","
+ " \"subnet-id\": 44"
+ " }\n"
+ "}";
+ string exp_rsp = "IPv4 lease deleted.";
+ ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+ // Make sure the lease is really gone.
+ EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
+}
+
// Checks that lease6-del(addr) can handle a situation when
// the query is correctly formed, but the lease is not there.
TEST_F(LeaseCmdsTest, Lease6DelByAddr6NotFound) {