// servers. At this time the only supported socket type is "unix".
// Make sure that the Agent and respective servers configuration
// matches exactly, otherwise they won't be able to communicate.
+ // One extra feature that requires some explanation is
+ // user-context. This is a structure that you can define at
+ // global scope, in control sockets and others. It is parsed by
+ // Kea, but not used directly. It is intended to keep anything
+ // you may want to put there - comments, extra designations,
+ // floor or department names etc. These structures will be made
+ // available to Kea hooks. A comment entry is translated into a
+ // user-context with a "comment" property so you can include
+ // comments inside the configuration itself.
"control-sockets":
{
// This is how the Agent can communicate with the DHCPv4 server.
"dhcp4":
{
+ "comment": "socket to DHCP4 server",
"socket-type": "unix",
"socket-name": "/path/to/the/unix/socket-v4"
},
"d2":
{
"socket-type": "unix",
- "socket-name": "/path/to/the/unix/socket-d2"
+ "socket-name": "/path/to/the/unix/socket-d2",
+ "user-context": { "in-use": false }
}
},
"port": 53001,
"dns-server-timeout" : 1000,
+// One extra feature that requires some explanation is
+// user-context. This is a structure that you can define at global scope,
+// in ddns domain, dns server, tsig key and others. It is parsed by
+// Kea, but not used directly. It is intended to keep anything you
+// may want to put there - comments, extra designations, floor or
+// department names etc.
+// A comment entry is translated into a user-context with a "comment"
+// property so you can include comments inside the configuration itself.
+
+ "user-context": { "version": 1 },
+
+
//
// ----------------- Forward DDNS ------------------
//
[
// DdnsDomain for zone "four.example.com."
{
+ "comment": "DdnsDomain example",
"name": "four.example.com.",
"key-name": "d2.md5.key",
"dns-servers":
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
" \"socket-name\": \"/tmp/socket-v6\"\n"
" }\n"
" }\n"
+ "}",
+
+ // Configuration 7: http and 2 sockets with user contexts and comments
+ "{\n"
+ " \"user-context\": { \"comment\": \"Indirect comment\" },\n"
+ " \"http-host\": \"betelgeuse\",\n"
+ " \"http-port\": 8001,\n"
+ " \"control-sockets\": {\n"
+ " \"dhcp4\": {\n"
+ " \"comment\": \"dhcp4 socket\",\n"
+ " \"socket-name\": \"/tmp/socket-v4\"\n"
+ " },\n"
+ " \"dhcp6\": {\n"
+ " \"socket-name\": \"/tmp/socket-v6\",\n"
+ " \"user-context\": { \"version\": 1 }\n"
+ " }\n"
+ " }\n"
"}"
};
EXPECT_EQ("{ \"param1\": \"foo\" }", libs[0].second->str());
}
+// This test checks comments.
+TEST_F(AgentParserTest, comments) {
+ configParse(AGENT_CONFIGS[7], 0);
+ CtrlAgentCfgContextPtr agent_ctx = cfg_mgr_.getCtrlAgentCfgContext();
+ ASSERT_TRUE(agent_ctx);
+
+ // Check global user context.
+ ConstElementPtr ctx = agent_ctx->getContext();
+ ASSERT_TRUE(ctx);
+ ASSERT_EQ(1, ctx->size());
+ ASSERT_TRUE(ctx->get("comment"));
+ EXPECT_EQ("\"Indirect comment\"", ctx->get("comment")->str());
+
+ // There is a DHCP4 control socket.
+ ConstElementPtr socket4 = agent_ctx->getControlSocketInfo("dhcp4");
+ ASSERT_TRUE(socket4);
+
+ // Check DHCP4 control socket user context.
+ ConstElementPtr ctx4 = socket4->get("user-context");
+ ASSERT_TRUE(ctx4);
+ ASSERT_EQ(1, ctx4->size());
+ ASSERT_TRUE(ctx4->get("comment"));
+ EXPECT_EQ("\"dhcp4 socket\"", ctx4->get("comment")->str());
+
+ // There is a DHCP6 control socket.
+ ConstElementPtr socket6 = agent_ctx->getControlSocketInfo("dhcp6");
+ ASSERT_TRUE(socket6);
+
+ // Check DHCP6 control socket user context.
+ ConstElementPtr ctx6 = socket6->get("user-context");
+ ASSERT_TRUE(ctx6);
+ ASSERT_EQ(1, ctx6->size());
+ ASSERT_TRUE(ctx6->get("version"));
+ EXPECT_EQ("1", ctx6->get("version")->str());
+}
}; // end of anonymous namespace
-// 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
#include <cc/data.h>
#include <cc/command_interpreter.h>
+#include <testutils/user_context_utils.h>
#include <process/testutils/d_test_stubs.h>
#include <agent/ca_cfg_mgr.h>
#include <agent/parser_context.h>
using namespace isc::config;
using namespace isc::data;
using namespace isc::process;
+using namespace isc::test;
namespace {
prettyPrint(unparsed, std::cerr, 0, 4);
std::cerr << "\n";
} else {
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseAGENT(expected, true));
+ ElementPtr jsond;
+ ASSERT_NO_THROW(jsond = parseAGENT(expected, true));
+ ElementPtr jsonj;
+ ASSERT_NO_THROW(jsonj = parseJSON(expected));
+ EXPECT_TRUE(isEquivalent(jsond, moveComments(jsonj)));
ConstElementPtr ca;
- ASSERT_NO_THROW(ca = json->get("Control-agent"));
+ ASSERT_NO_THROW(ca = jsonj->get("Control-agent"));
ASSERT_TRUE(ca);
pathReplacer(ca);
- EXPECT_TRUE(isEquivalent(unparsed, json));
+ EXPECT_TRUE(isEquivalent(unparsed, jsonj));
std::string current = prettyPrint(unparsed, 0, 4);
- std::string expected2 = prettyPrint(json, 0, 4);
+ std::string expected2 = prettyPrint(jsonj, 0, 4);
EXPECT_EQ(expected2, current);
if (expected2 != current) {
expected = current + "\n";
"control-sockets": {
"d2": {
"socket-name": "/path/to/the/unix/socket-d2",
- "socket-type": "unix"
+ "socket-type": "unix",
+ "user-context": {
+ "in-use": false
+ }
},
"dhcp4": {
+ "comment": "socket to DHCP4 server",
"socket-name": "/path/to/the/unix/socket-v4",
"socket-type": "unix"
},
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-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
}
}
+/// @brief Tests comments.
+TEST_F(D2CfgMgrTest, comments) {
+ std::string config = "{ "
+ "\"comment\": \"D2 config\" , "
+ "\"ip-address\" : \"192.168.1.33\" , "
+ "\"port\" : 88 , "
+ "\"tsig-keys\": ["
+ "{"
+ " \"user-context\": { "
+ " \"comment\": \"Indirect comment\" } , "
+ " \"name\": \"d2_key.example.com\" , "
+ " \"algorithm\": \"hmac-md5\" , "
+ " \"secret\": \"LSWXnfkKZjdPJI5QxlpnfQ==\" "
+ "}"
+ "],"
+ "\"forward-ddns\" : {"
+ "\"ddns-domains\": [ "
+ "{ \"comment\": \"A DDNS domain\" , "
+ " \"name\": \"example.com\" , "
+ " \"key-name\": \"d2_key.example.com\" , "
+ " \"dns-servers\" : [ "
+ " { \"ip-address\": \"127.0.0.1\" , "
+ " \"user-context\": { \"version\": 1 } } "
+ " ] } "
+ "] } }";
+
+ // Should parse without error.
+ RUN_CONFIG_OK(config);
+
+ // Check the D2 context.
+ D2CfgContextPtr d2_context;
+ ASSERT_NO_THROW(d2_context = cfg_mgr_->getD2CfgContext());
+ ASSERT_TRUE(d2_context);
+
+ // Check global user context.
+ ConstElementPtr ctx = d2_context->getContext();
+ ASSERT_TRUE(ctx);
+ ASSERT_EQ(1, ctx->size());
+ ASSERT_TRUE(ctx->get("comment"));
+ EXPECT_EQ("\"D2 config\"", ctx->get("comment")->str());
+
+ // Check TSIG keys.
+ TSIGKeyInfoMapPtr keys = d2_context->getKeys();
+ ASSERT_TRUE(keys);
+ ASSERT_EQ(1, keys->size());
+
+ // Check the TSIG key.
+ TSIGKeyInfoMap::iterator gotkey = keys->find("d2_key.example.com");
+ ASSERT_TRUE(gotkey != keys->end());
+ TSIGKeyInfoPtr key = gotkey->second;
+ ASSERT_TRUE(key);
+
+ // Check the TSIG key user context.
+ ConstElementPtr key_ctx = key->getContext();
+ ASSERT_TRUE(key_ctx);
+ ASSERT_EQ(1, key_ctx->size());
+ ASSERT_TRUE(key_ctx->get("comment"));
+ EXPECT_EQ("\"Indirect comment\"", key_ctx->get("comment")->str());
+
+ // Check the forward manager.
+ DdnsDomainListMgrPtr mgr = d2_context->getForwardMgr();
+ ASSERT_TRUE(mgr);
+ EXPECT_EQ("forward-ddns", mgr->getName());
+ DdnsDomainMapPtr domains = mgr->getDomains();
+ ASSERT_TRUE(domains);
+ ASSERT_EQ(1, domains->size());
+
+ // Check the DDNS domain.
+ DdnsDomainMap::iterator gotdns = domains->find("example.com");
+ ASSERT_TRUE(gotdns != domains->end());
+ DdnsDomainPtr domain = gotdns->second;
+ ASSERT_TRUE(domain);
+
+ // Check the DNS server.
+ DnsServerInfoStoragePtr servers = domain->getServers();
+ ASSERT_TRUE(servers);
+ ASSERT_EQ(1, servers->size());
+ DnsServerInfoPtr server = (*servers)[0];
+ ASSERT_TRUE(server);
+
+ // Check the DNS server user context.
+ ConstElementPtr srv_ctx = server->getContext();
+ ASSERT_TRUE(srv_ctx);
+ ASSERT_EQ(1, srv_ctx->size());
+ ASSERT_TRUE(srv_ctx->get("version"));
+ EXPECT_EQ("1", srv_ctx->get("version")->str());
+}
} // end of anonymous namespace
-// 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
#include <cc/data.h>
#include <cc/command_interpreter.h>
+#include <testutils/user_context_utils.h>
#include <process/testutils/d_test_stubs.h>
#include <d2/d2_config.h>
#include <d2/d2_cfg_mgr.h>
using namespace isc::d2;
using namespace isc::data;
using namespace isc::process;
+using namespace isc::test;
namespace {
prettyPrint(unparsed, std::cerr, 0, 4);
std::cerr << "\n";
} else {
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCPDDNS(expected, true));
- EXPECT_TRUE(isEquivalent(unparsed, json));
+ ElementPtr jsond;
+ ASSERT_NO_THROW(jsond = parseDHCPDDNS(expected, true));
+ ElementPtr jsonj;
+ ASSERT_NO_THROW(jsonj = parseJSON(expected));
+ EXPECT_TRUE(isEquivalent(jsond, moveComments(jsonj)));
+ EXPECT_TRUE(isEquivalent(unparsed, jsonj));
std::string current = prettyPrint(unparsed, 0, 4) + "\n";
EXPECT_EQ(expected, current);
if (expected != current) {
"forward-ddns": {
"ddns-domains": [
{
+ "comment": "DdnsDomain example",
"dns-servers": [
{
"hostname": "",
"name": "d2.sha512.key",
"secret": "/4wklkm04jeH4anx2MKGJLcya+ZLHldL5d6mK+4q6UXQP7KJ9mS2QG29hh0SJR4LA0ikxNJTUMvir42gLx6fGQ=="
}
- ]
+ ],
+ "user-context": {
+ "version": 1
+ }
}
}