2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[5584] Checkpoint: more updates

This commit is contained in:
Francis Dupont
2018-06-22 11:37:22 +02:00
parent 66f4a42a9b
commit b14d388e54
7 changed files with 182 additions and 45 deletions

View File

@@ -475,6 +475,8 @@ $ <userinput>ls -l /usr/local/lib/hooks/*.so</userinput>
errors, like adding a lease with subnet-id that does not exist in
the configuration or configuring a lease to use an address that is
outside of the subnet to which it is supposed to belong.
It provides a not programmatic way to manage user contexts
associated to leases.
</entry>
</row>
@@ -720,7 +722,7 @@ path/base-name.CCYYMMDD.txt
An entry is a single string with no embedded end-of-line markers,
a prepended timestamp and has the following sections:
<screen>
timestamp address duration device-id {client-info} {relay-info}
timestamp address duration device-id {client-info} {relay-info} {user-context}
</screen>
</para>
<para>
@@ -754,6 +756,9 @@ timestamp address duration device-id {client-info} {relay-info}
options: 1, 2 and 6) if present.
The circuit id and remote id are presented as hex strings
</para></listitem>
<listitem><para>
user-context - the optional user context associated to the lease.
</para></listitem>
</itemizedlist>
</para>
<para>
@@ -835,7 +840,7 @@ with hardware address: 1a:1b:1c:1d:1e:1f, client-id: 1234567890
An entry is a single string with no embedded end-of-line markers,
a prepended timestamp and has the following sections:
<screen>
timestamp address duration device-id {relay-info}*
timestamp address duration device-id {relay-info}* {user-context}
</screen>
</para>
<para>
@@ -868,6 +873,9 @@ timestamp address duration device-id {relay-info}*
topology. Nevertheless, this is useful information to better scope
down the location of the device, so it is being recorded, if present.
</para></listitem>
<listitem><para>
user-context - the optional user context associated to the lease.
</para></listitem>
</itemizedlist>
</para>
<para>
@@ -1063,20 +1071,7 @@ Examples:
Please refer to <xref linkend="mysql-database"/> for MySQL,
to <xref linkend="pgsql-database"/> for PostgreSQL or
to <xref linkend="cql-database"/> for Cassandra CQL.
Scripts are in
<filename><replaceable>path-to-kea</replaceable>/share/kea/legal_log/scripts</filename> directory, for instance the PostgreSQL create schema
command is:
<screen>
$ <userinput>psql -d <replaceable>database-name</replaceable> -U <replaceable>user-name</replaceable> -f <replaceable>path-to-kea</replaceable>/share/kea/legal_log/scripts/pgsql/legldb_create.pgsql</userinput>
Password for user <replaceable>user-name</replaceable>:
START TRANSACTION
CREATE TABLE
CREATE INDEX
CREATE TABLE
INSERT 0 1
COMMIT
$
</screen>
The logs table is part of the Kea database schemas.
</para>
<para>
Configuration parameters are extended by standard lease database
@@ -1671,6 +1666,8 @@ An example deletion by (subnet-id, identifier-type, identifier) looks as follows
errors, like adding a lease with subnet-id that does not exist in the
configuration or configuring a lease to use an address that is outside
of the subnet to which it is supposed to belong.
It provides a not programmatic way to manage user contexts
associated to leases.
<note>
<para>This library may only be loaded by <command>kea-dhcp4</command>
@@ -1875,6 +1872,11 @@ The commands can take a number of additional optional parameters:
configured for the subnet corresponding to the specified subnet-id
is used. This parameter is not used in IPv4.</para>
</listitem>
<listitem>
<para><command>user-context</command> - specifies the user
context to be associated with this lease. It must be a
JSON map.</para>
</listitem>
</itemizedlist>
</para>
@@ -1894,7 +1896,8 @@ The commands can take a number of additional optional parameters:
"expire": 12345678,
"fqdn-fwd": true,
"fqdn-rev": true,
"hostname": "urania.example.org"
"hostname": "urania.example.org",
"user-context": { "version": 1 }
}
}
</screen>
@@ -3136,6 +3139,7 @@ both the command and the response.
host reservations, control socket, dhcp ddns, loggers and server id.
These are supported in both DHCPv4 and DHCPv6 at the exception
of server id which is DHCPv6 only.
Kea 1.5 added user contexts assocated with leases.
</para>
</section>

View File

@@ -84,11 +84,11 @@ protected:
cstr_ = base_dir + "/" + "config_file"; // config
v4_hdr_ = "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
"fqdn_fwd,fqdn_rev,hostname,state\n";
"fqdn_fwd,fqdn_rev,hostname,state,user_context\n";
v6_hdr_ = "address,duid,valid_lifetime,expire,subnet_id,"
"pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
"fqdn_rev,hostname,hwaddr,state\n";
"fqdn_rev,hostname,hwaddr,state,user_context\n";
// and remove any outstanding test files
removeTestFile();
@@ -398,27 +398,27 @@ TEST_F(LFCControllerTest, launch4) {
// We have several entries for different leases, the naming is:
// <lease letter>_<version#>
string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
"200,200,8,1,1,host.example.com,1\n";
"200,200,8,1,1,host.example.com,1,\n";
string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
"200,500,8,1,1,host.example.com,1\n";
"200,500,8,1,1,host.example.com,1,\n";
string a_3 = "192.0.2.1,06:07:08:09:0a:bc,,"
"200,800,8,1,1,host.example.com,1\n";
"200,800,8,1,1,host.example.com,1,{ \"foo\": true }\n";
string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
"100,100,7,0,0,,1\n";
"100,100,7,0,0,,1,{ \"bar\": false }\n";
string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
"100,135,7,0,0,,1\n";
"100,135,7,0,0,,1,\n";
string b_3 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
"100,150,7,0,0,,1\n";
"100,150,7,0,0,,1,\n";
// This one should be invalid, no hardware address and state is not declined
string c_1 = "192.0.2.3,,a:11:01:04,"
"200,200,8,1,1,host.example.com,0\n";
"200,200,8,1,1,host.example.com,0,\n";
string d_1 = "192.0.2.5,16:17:18:19:1a:bc,,"
"200,200,8,1,1,host.example.com,1\n";
"200,200,8,1,1,host.example.com,1,\n";
string d_2 = "192.0.2.5,16:17:18:19:1a:bc,,"
"0,200,8,1,1,host.example.com,1\n";
"0,200,8,1,1,host.example.com,1,\n";
// Subtest 1: both previous and copy available.
// Create the test previous file
@@ -553,27 +553,29 @@ TEST_F(LFCControllerTest, launch6) {
// We have several entries for different leases, the naming is:
// <lease letter>_<version#>.
string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
string a_2 = "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
"200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
string a_2 = "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,"
"host.example.com,,1,\n";
string a_3 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"200,400,8,100,0,7,0,1,1,host.example.com,,1\n";
"200,400,8,100,0,7,0,1,1,host.example.com,,1,\n";
string a_4 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"0,200,8,100,0,7,0,1,1,host.example.com,,1\n";
"0,200,8,100,0,7,0,1,1,host.example.com,,1,"
"{ \"foo\": true }\n";
string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
"300,300,6,150,0,8,0,0,0,,,1\n";
"300,300,6,150,0,8,0,0,0,,,1,{ \"bar\": false }\n";
string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
"300,800,6,150,0,8,0,0,0,,,1\n";
"300,800,6,150,0,8,0,0,0,,,1,\n";
string b_3 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
"300,1000,6,150,0,8,0,0,0,,,1\n";
"300,1000,6,150,0,8,0,0,0,,,1,\n";
string c_1 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"100,200,8,0,2,16,64,0,0,,,1\n";
"100,200,8,0,2,16,64,0,0,,,1,\n";
string c_2 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"100,400,8,0,2,16,64,0,0,,,1\n";
"100,400,8,0,2,16,64,0,0,,,1,\n";
string d_1 = "2001:db8:1::3,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
"200,600,8,100,0,7,0,1,1,host.example.com,,1\n";
"200,600,8,100,0,7,0,1,1,host.example.com,,1,\n";
// Subtest 1: bot previous and copy available
// Create the test previous file

View File

@@ -110,6 +110,13 @@ Lease4Parser::parse(ConstSrvConfigPtr& cfg,
"values are: 0 (default), 1 (declined) and 2 (expired-reclaimed)");
}
// Handle user context.
ConstElementPtr ctx = lease_info->get("user-context");
if (ctx && (ctx->getType() != Element::map)) {
isc_throw(BadValue, "Invalid user context '" << ctx->str()
<< "' is not a JSON map.");
}
// Let's fabricate some data and we're ready to go.
uint32_t t1 = subnet->getT1();
uint32_t t2 = subnet->getT2();
@@ -118,6 +125,7 @@ Lease4Parser::parse(ConstSrvConfigPtr& cfg,
cltt, subnet_id,
fqdn_fwd, fqdn_rev, hostname));
l->state_ = state;
l->setContext(ctx);
// Retrieve the optional flag indicating if the lease must be created when it
// doesn't exist during the update.
@@ -251,6 +259,13 @@ Lease6Parser::parse(ConstSrvConfigPtr& cfg,
"values are: 0 (default), 1 (declined) and 2 (expired-reclaimed)");
}
// Handle user context.
ConstElementPtr ctx = lease_info->get("user-context");
if (ctx && (ctx->getType() != Element::map)) {
isc_throw(BadValue, "Invalid user context '" << ctx->str()
<< "' is not a JSON map.");
}
// Let's fabricate some data and we're ready to go.
uint32_t t1 = subnet->getT1();
uint32_t t2 = subnet->getT2();
@@ -260,6 +275,7 @@ Lease6Parser::parse(ConstSrvConfigPtr& cfg,
hwaddr_ptr, prefix_len));
l->cltt_ = cltt;
l->state_ = state;
l->setContext(ctx);
// Retrieve the optional flag indicating if the lease must be created when it
// doesn't exist during the update.

View File

@@ -29,7 +29,8 @@ namespace lease_cmds {
/// "fqdn-fwd": true,
/// "fqdn-rev": true,
/// "hostname": "myhost.example.org",
/// "state": 0
/// "state": 0,
/// "user-context": { \"version\": 1 }
/// }
class Lease4Parser : public isc::data::SimpleParser {
public:
@@ -67,7 +68,8 @@ public:
/// "fqdn-fwd": true,
/// "fqdn-rev": true,
/// "hostname": "myhost.example.org",
/// "state": 0
/// "state": 0,
/// "user-context": { \"version\": 1 }
/// }
/// It expects the input data to use the following format:

View File

@@ -14,8 +14,8 @@
#include <dhcpsrv/cfgmgr.h>
#include <cc/command_interpreter.h>
#include <cc/data.h>
#include <testutils/user_context_utils.h>
#include <gtest/gtest.h>
#include <cc/data.h>
#include <errno.h>
using namespace std;
@@ -25,6 +25,7 @@ using namespace isc::config;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::asiolink;
using namespace isc::test;
namespace {
@@ -472,6 +473,22 @@ public:
// Check that there are no v4 specific fields.
EXPECT_FALSE(l->contains("client-id"));
}
/// @brief Checks if specified response contains user context
///
/// @param lease Element tree that represents a lease
/// @param expected expected user context in textual form
void checkContext(ConstElementPtr lease, std::string expected) {
ASSERT_TRUE(lease);
ConstElementPtr moved = moveComments(lease);
ConstElementPtr ctx = moved->get("user-context");
if (!expected.empty()) {
ASSERT_TRUE(ctx);
EXPECT_EQ(expected, ctx->str());
} else {
EXPECT_FALSE(ctx);
}
}
};
// Simple test that checks the library really registers the commands.
@@ -611,6 +628,20 @@ TEST_F(LeaseCmdsTest, Lease4AddBadParams) {
exp_rsp = "Invalid state value: 123, supported values are: 0 (default), 1 "
"(declined) and 2 (expired-reclaimed)";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
// Bad user context: not a map.
txt =
"{\n"
" \"command\": \"lease4-add\",\n"
" \"arguments\": {"
" \"subnet-id\": 44,\n"
" \"ip-address\": \"192.0.2.1\",\n"
" \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
" \"user-context\": \"bad value\"\n"
" }\n"
"}";
exp_rsp = "Invalid user context '\"bad value\"' is not a JSON map.";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that a simple, well formed lease4 can be added.
@@ -646,6 +677,7 @@ TEST_F(LeaseCmdsTest, Lease4Add) {
EXPECT_FALSE(l->fqdn_fwd_);
EXPECT_FALSE(l->fqdn_rev_);
EXPECT_EQ("", l->hostname_);
EXPECT_FALSE(l->getContext());
// Test execution is fast. The cltt should be set to now. In some rare
// cases we could have the seconds counter to tick, so having a value off
@@ -677,7 +709,8 @@ TEST_F(LeaseCmdsTest, Lease4AddFull) {
" \"expire\": 12345678,\n"
" \"fqdn-fwd\": true,\n"
" \"fqdn-rev\": true,\n"
" \"hostname\": \"urania.example.org\""
" \"hostname\": \"urania.example.org\",\n"
" \"user-context\": { \"foobar\": true }\n"
" }\n"
"}";
string exp_rsp = "Lease added.";
@@ -695,6 +728,8 @@ TEST_F(LeaseCmdsTest, Lease4AddFull) {
EXPECT_EQ(true, l->fqdn_fwd_);
EXPECT_EQ(true, l->fqdn_rev_);
EXPECT_EQ("urania.example.org", l->hostname_);
ASSERT_TRUE(l->getContext());
EXPECT_EQ("{ \"foobar\": true }", l->getContext()->str());
}
// Check that lease6-add with missing parameters will fail.
@@ -845,6 +880,21 @@ TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
exp_rsp = "Invalid state value: 123, supported values are: 0 (default), 1 "
"(declined) and 2 (expired-reclaimed)";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
// Bad user context: not a map.
txt =
"{\n"
" \"command\": \"lease6-add\",\n"
" \"arguments\": {"
" \"subnet-id\": 66,\n"
" \"ip-address\": \"2001:db8:1::1\",\n"
" \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
" \"iaid\": 1234\n,"
" \"user-context\": \"bad value\"\n"
" }\n"
"}";
exp_rsp = "Invalid user context '\"bad value\"' is not a JSON map.";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that a simple, well formed lease6 can be added.
@@ -871,7 +921,10 @@ TEST_F(LeaseCmdsTest, Lease6Add) {
testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
// Now check that the lease is really there.
EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3")));
Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
ASSERT_TRUE(l);
EXPECT_EQ("", l->hostname_);
EXPECT_FALSE(l->getContext());
}
// Check that a simple, well formed prefix lease can be added.
@@ -904,6 +957,8 @@ TEST_F(LeaseCmdsTest, Lease6AddPrefix) {
ASSERT_TRUE(l);
EXPECT_EQ(Lease::TYPE_PD, l->type_);
EXPECT_EQ(48, l->prefixlen_);
EXPECT_EQ("", l->hostname_);
EXPECT_FALSE(l->getContext());
}
// Check that a well formed lease6 with tons of parameters can be added.
@@ -930,7 +985,8 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
" \"expire\": 12345678,\n"
" \"fqdn-fwd\": true,\n"
" \"fqdn-rev\": true,\n"
" \"hostname\": \"urania.example.org\""
" \"hostname\": \"urania.example.org\",\n"
" \"user-context\": { \"foobar\": true }\n"
" }\n"
"}";
string exp_rsp = "Lease added.";
@@ -949,6 +1005,8 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
EXPECT_EQ(true, l->fqdn_fwd_);
EXPECT_EQ(true, l->fqdn_rev_);
EXPECT_EQ("urania.example.org", l->hostname_);
ASSERT_TRUE(l->getContext());
EXPECT_EQ("{ \"foobar\": true }", l->getContext()->str());
}
// Checks that lease6-get can handle a situation when the query is
@@ -1894,6 +1952,20 @@ TEST_F(LeaseCmdsTest, Lease4UpdateBadParams) {
"}";
exp_rsp = "Non-IPv4 address specified: 2001:db8:1::1";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
// Bad user context: not a map.
txt =
"{\n"
" \"command\": \"lease4-update\",\n"
" \"arguments\": {"
" \"subnet-id\": 44,\n"
" \"ip-address\": \"192.0.2.1\",\n"
" \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
" \"user-context\": \"bad value\"\n"
" }\n"
"}";
exp_rsp = "Invalid user context '\"bad value\"' is not a JSON map.";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that lease4-update correctly handles case when there is
@@ -1953,6 +2025,7 @@ TEST_F(LeaseCmdsTest, Lease4Update) {
ASSERT_TRUE(l->hwaddr_);
EXPECT_EQ("1a:1b:1c:1d:1e:1f", l->hwaddr_->toText(false));
EXPECT_EQ("newhostname.example.org", l->hostname_);
EXPECT_FALSE(l->getContext());
}
// Check that a lease4 is created if it doesn't exist during the update.
@@ -1988,6 +2061,7 @@ TEST_F(LeaseCmdsTest, Lease4UpdateForceCreate) {
ASSERT_TRUE(l->hwaddr_);
EXPECT_EQ("1a:1b:1c:1d:1e:1f", l->hwaddr_->toText(false));
EXPECT_EQ("newhostname.example.org", l->hostname_);
EXPECT_FALSE(l->getContext());
}
// Check that lease4-update correctly handles case when the 'force-create'
@@ -2119,6 +2193,21 @@ TEST_F(LeaseCmdsTest, Lease6UpdateBadParams) {
"}";
exp_rsp = "Non-IPv6 address specified: 192.0.2.1";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
// Bad user context: not a map.
txt =
"{\n"
" \"command\": \"lease6-update\",\n"
" \"arguments\": {"
" \"subnet-id\": 66,\n"
" \"ip-address\": \"2001:db8:1::1\",\n"
" \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
" \"iaid\": 1234\n,"
" \"user-context\": \"bad value\"\n"
" }\n"
"}";
exp_rsp = "Invalid user context '\"bad value\"' is not a JSON map.";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
// Check that a lease6 can be updated. We're changing hw-address
@@ -2155,6 +2244,7 @@ TEST_F(LeaseCmdsTest, Lease6Update) {
EXPECT_EQ("88:88:88:88:88:88:88:88", l->duid_->toText());
EXPECT_EQ("newhostname.example.org", l->hostname_);
EXPECT_EQ(7654321, l->iaid_);
EXPECT_FALSE(l->getContext());
}
@@ -2220,6 +2310,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateForceCreate) {
EXPECT_EQ("88:88:88:88:88:88:88:88", l->duid_->toText());
EXPECT_EQ("newhostname.example.org", l->hostname_);
EXPECT_EQ(7654321, l->iaid_);
EXPECT_FALSE(l->getContext());
}
// Check that lease6-update correctly handles case when the 'force-create'

View File

@@ -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
@@ -128,6 +128,11 @@ ElementPtr moveComments(ElementPtr element) {
return (result.get());
}
ConstElementPtr moveComments(ConstElementPtr element) {
Value<ConstElementPtr> result = moveComments1(element);
return (result.get());
}
}; // end of isc::test namespace
}; // end of isc namespace
@@ -231,5 +236,10 @@ ElementPtr extractComments(ElementPtr element) {
return (result.get());
}
ConstElementPtr extractComments(ConstElementPtr element) {
Value<ConstElementPtr> result = extractComments1(element);
return (result.get());
}
}; // end of isc::test namespace
}; // end of isc namespace

View File

@@ -23,6 +23,12 @@ namespace test {
/// @return a processed copy of element or unmodified element
isc::data::ElementPtr moveComments(isc::data::ElementPtr element);
/// @brief Move comment entries to user-context (const variant)
///
/// @param element
/// @return a processed copy of element or unmodified element
isc::data::ConstElementPtr moveComments(isc::data::ConstElementPtr element);
/// @brief Extract comment entries from user-context
///
/// Process an element looking for user-context entries carrying
@@ -35,6 +41,12 @@ isc::data::ElementPtr moveComments(isc::data::ElementPtr element);
/// @return a processed copy of element or unmodified element
isc::data::ElementPtr extractComments(isc::data::ElementPtr element);
/// @brief Extract comment entries from user-context (const variant)
///
/// @param element
/// @return a processed copy of element or unmodified element
isc::data::ConstElementPtr extractComments(isc::data::ConstElementPtr element);
}; // end of isc::test namespace
}; // end of isc namespace