-/* 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
}
}
+\"user-context\" {
+ switch(driver.ctx_) {
+ case ParserContext::AGENT:
+ case ParserContext::SERVER:
+ case ParserContext::LOGGERS:
+ return AgentParser::make_USER_CONTEXT(driver.loc_);
+ default:
+ return AgentParser::make_STRING("user-context", driver.loc_);
+ }
+}
+
+\"comment\" {
+ switch(driver.ctx_) {
+ case ParserContext::AGENT:
+ case ParserContext::SERVER:
+ case ParserContext::LOGGERS:
+ return AgentParser::make_COMMENT(driver.loc_);
+ default:
+ return AgentParser::make_STRING("comment", driver.loc_);
+ }
+}
+
\"control-sockets\" {
switch(driver.ctx_) {
case ParserContext::AGENT:
-/* 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
HTTP_HOST "http-host"
HTTP_PORT "http-port"
+ USER_CONTEXT "user-context"
+ COMMENT "comment"
+
CONTROL_SOCKETS "control-sockets"
DHCP4_SERVER "dhcp4"
DHCP6_SERVER "dhcp6"
// for it.
};
+map_value: map { $$ = ctx.stack_.back(); ctx.stack_.pop_back(); };
+
// Rule for map content. In some cases it is allowed to have an empty map,
// so we should say that explicitly. In most cases, though, there will
// be some actual content inside. That's defined by not_empty_map
| http_port
| control_sockets
| hooks_libraries
+ | user_context
+ | comment
| unknown_map_entry
;
ctx.stack_.back()->set("http-port", prf);
};
+user_context: USER_CONTEXT {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON map_value {
+ ElementPtr parent = ctx.stack_.back();
+ ElementPtr user_context = $4;
+ ConstElementPtr old = parent->get("user-context");
+
+ // Handle already existing user context
+ if (old) {
+ // Check if it was a comment or a duplicate
+ if ((old->size() != 1) || !old->contains("comment")) {
+ std::stringstream msg;
+ msg << "duplicate user-context entries (previous at "
+ << old->getPosition().str() << ")";
+ error(@1, msg.str());
+ }
+ // Merge the comment
+ user_context->set("comment", old->get("comment"));
+ }
+
+ // Set the user context
+ parent->set("user-context", user_context);
+ ctx.leave();
+};
+
+comment: COMMENT {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr parent = ctx.stack_.back();
+ ElementPtr user_context(new MapElement(ctx.loc2pos(@1)));
+ ElementPtr comment(new StringElement($4, ctx.loc2pos(@4)));
+ user_context->set("comment", comment);
+
+ // Handle already existing user context
+ ConstElementPtr old = parent->get("user-context");
+ if (old) {
+ // Check for duplicate comment
+ if (old->contains("comment")) {
+ std::stringstream msg;
+ msg << "duplicate user-context/comment entries (previous at "
+ << old->getPosition().str() << ")";
+ error(@1, msg.str());
+ }
+ // Merge the user context in the comment
+ merge(user_context, old);
+ }
+
+ // Set the user context
+ parent->set("user-context", user_context);
+ ctx.leave();
+};
+
// --- hooks-libraries ---------------------------------------------------------
hooks_libraries: HOOKS_LIBRARIES {
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
// We currently support two socket parameters: type and name.
control_socket_param: socket_name
| socket_type
+ | user_context
+ | comment
+ | unknown_map_entry
;
// This rule defines socket-name parameter.
| output_options_list
| debuglevel
| severity
+ | user_context
+ | comment
| unknown_map_entry
;
-// 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
ElementPtr
CtrlAgentCfgContext::toElement() const {
ElementPtr ca = Element::createMap();
+ // Set user-context
+ contextToElement(ca);
// Set http-host
ca->set("http-host", Element::create(http_host_));
// Set http-port
// Set control-sockets
ElementPtr control_sockets = Element::createMap();
for (auto si = ctrl_sockets_.cbegin(); si != ctrl_sockets_.cend(); ++si) {
- control_sockets->set(si->first, si->second);
+ ConstElementPtr socket = UserContext::toElement(si->second);
+ control_sockets->set(si->first, socket);
}
ca->set("control-sockets", control_sockets);
// Set Control-agent
-// 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
}
}
+ // User context can be done at anytime.
+ ConstElementPtr user_context = config->get("user-context");
+ if (user_context) {
+ ctx->setContext(user_context);
+ }
+
// Finally, let's get the hook libs!
using namespace isc::hooks;
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
ElementPtr
D2CfgContext::toElement() const {
ElementPtr d2 = Element::createMap();
+ // Set user-context
+ contextToElement(d2);
// Set ip-address
const IOAddress& ip_address = d2_params_->getIpAddress();
d2->set("ip-address", Element::create(ip_address.toText()));
namespace {
template <typename int_type> int_type
-getInt(const std::string& name, isc::data::ConstElementPtr value) {
+getInt(const std::string& name, ConstElementPtr value) {
int64_t val_int = value->intValue();
if ((val_int < std::numeric_limits<int_type>::min()) ||
(val_int > std::numeric_limits<int_type>::max())) {
}
isc::asiolink::IOAddress
-getIOAddress(const std::string& name, isc::data::ConstElementPtr value) {
+getIOAddress(const std::string& name, ConstElementPtr value) {
std::string str = value->stringValue();
try {
return (isc::asiolink::IOAddress(str));
}
dhcp_ddns::NameChangeProtocol
-getProtocol(const std::string& name, isc::data::ConstElementPtr value) {
+getProtocol(const std::string& name, ConstElementPtr value) {
std::string str = value->stringValue();
try {
return (dhcp_ddns::stringToNcrProtocol(str));
}
dhcp_ddns::NameChangeFormat
-getFormat(const std::string& name, isc::data::ConstElementPtr value) {
+getFormat(const std::string& name, ConstElementPtr value) {
std::string str = value->stringValue();
try {
return (dhcp_ddns::stringToNcrFormat(str));
void
D2CfgMgr::parseElement(const std::string& element_id,
- isc::data::ConstElementPtr element) {
+ ConstElementPtr element) {
try {
// Get D2 specific context.
D2CfgContextPtr context = getD2CfgContext();
(element_id == "port") ||
(element_id == "dns-server-timeout")) {
// global scalar params require nothing extra be done
+ } else if (element_id == "user-context") {
+ if (element->getType() == Element::map) {
+ context->setContext(element);
+ }
} else if (element_id == "tsig-keys") {
TSIGKeyInfoListParser parser;
context->setKeys(parser.parse(element));
};
void
-D2CfgMgr::setCfgDefaults(isc::data::ElementPtr mutable_config) {
+D2CfgMgr::setCfgDefaults(ElementPtr mutable_config) {
D2SimpleParser::setAllDefaults(mutable_config);
}
void
-D2CfgMgr::buildParams(isc::data::ConstElementPtr params_config) {
+D2CfgMgr::buildParams(ConstElementPtr params_config) {
// Base class build creates parses and invokes build on each parser.
// This populate the context scalar stores with all of the parameters.
// Assumes that params_config has had defaults added
BOOST_FOREACH(isc::dhcp::ConfigPair param, params_config->mapValue()) {
std::string entry(param.first);
- isc::data::ConstElementPtr value(param.second);
+ ConstElementPtr value(param.second);
try {
if (entry == "ip-address") {
ip_address = getIOAddress(entry, value);
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
/// it to be processed by SimpleParser derivations if they've been
/// implemented. The method should return true if it has processed the
/// element or false if the element should be passed onto the original
- /// DhcpConfigParer mechanisms. This method is invoked in both
+ /// DhcpConfigParser mechanisms. This method is invoked in both
/// @c DCfgMgrBase::buildParams() and DCfgMgrBase::buildAndCommit().
///
/// @param element_id name of the element as it is expected in the cfg
-// 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
ElementPtr
TSIGKeyInfo::toElement() const {
ElementPtr result = Element::createMap();
+ // Set user-context
+ contextToElement(result);
// Set name
result->set("name", Element::create(name_));
// Set algorithm
ElementPtr
DnsServerInfo::toElement() const {
ElementPtr result = Element::createMap();
+ // Set user-context
+ contextToElement(result);
// Set hostname
result->set("hostname", Element::create(hostname_));
// Set ip-address
ElementPtr
DdnsDomain::toElement() const {
ElementPtr result = Element::createMap();
+ // Set user-context
+ contextToElement(result);
// Set name
result->set("name", Element::create(name_));
// Set servers
// *********************** TSIGKeyInfoParser *************************
TSIGKeyInfoPtr
-TSIGKeyInfoParser::parse(data::ConstElementPtr key_config) {
+TSIGKeyInfoParser::parse(ConstElementPtr key_config) {
std::string name = getString(key_config, "name");
std::string algorithm = getString(key_config, "algorithm");
uint32_t digestbits = getInteger(key_config, "digest-bits");
std::string secret = getString(key_config, "secret");
+ ConstElementPtr user_context = key_config->get("user-context");
// Algorithm must be valid.
try {
<< key_config->getPosition() << ")");
}
+ // Add user-context
+ if (user_context) {
+ key_info->setContext(user_context);
+ }
+
return (key_info);
}
// *********************** TSIGKeyInfoListParser *************************
TSIGKeyInfoMapPtr
-TSIGKeyInfoListParser::parse(data::ConstElementPtr key_list) {
+TSIGKeyInfoListParser::parse(ConstElementPtr key_list) {
TSIGKeyInfoMapPtr keys(new TSIGKeyInfoMap());
- data::ConstElementPtr key_config;
+ ConstElementPtr key_config;
TSIGKeyInfoParser key_parser;
BOOST_FOREACH(key_config, key_list->listValue()) {
TSIGKeyInfoPtr key = key_parser.parse(key_config);
// *********************** DnsServerInfoParser *************************
DnsServerInfoPtr
-DnsServerInfoParser::parse(data::ConstElementPtr server_config) {
+DnsServerInfoParser::parse(ConstElementPtr server_config) {
std::string hostname = getString(server_config, "hostname");
std::string ip_address = getString(server_config, "ip-address");
uint32_t port = getInteger(server_config, "port");
+ ConstElementPtr user_context = server_config->get("user-context");
// The configuration must specify one or the other.
if (hostname.empty() == ip_address.empty()) {
}
}
- return(server_info);
+ // Add user-context
+ if (user_context) {
+ server_info->setContext(user_context);
+ }
+
+ return (server_info);
}
// *********************** DnsServerInfoListParser *************************
DnsServerInfoStoragePtr
-DnsServerInfoListParser::parse(data::ConstElementPtr server_list) {
+DnsServerInfoListParser::parse(ConstElementPtr server_list) {
DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
- data::ConstElementPtr server_config;
+ ConstElementPtr server_config;
DnsServerInfoParser parser;
BOOST_FOREACH(server_config, server_list->listValue()) {
DnsServerInfoPtr server = parser.parse(server_config);
// *********************** DdnsDomainParser *************************
-DdnsDomainPtr DdnsDomainParser::parse(data::ConstElementPtr domain_config,
+DdnsDomainPtr DdnsDomainParser::parse(ConstElementPtr domain_config,
const TSIGKeyInfoMapPtr keys) {
std::string name = getString(domain_config, "name");
std::string key_name = getString(domain_config, "key-name");
+ ConstElementPtr user_context = domain_config->get("user-context");
// Key name is optional. If it is not blank, then find the key in the
// list of defined keys.
}
// Parse the list of DNS servers
- data::ConstElementPtr servers_config;
+ ConstElementPtr servers_config;
try {
servers_config = domain_config->get("dns-servers");
} catch (const std::exception& ex) {
// Instantiate the new domain and add it to domain storage.
DdnsDomainPtr domain(new DdnsDomain(name, servers, tsig_key_info));
- return(domain);
+ // Add user-context
+ if (user_context) {
+ domain->setContext(user_context);
+ }
+
+ return (domain);
}
// *********************** DdnsDomainListParser *************************
-DdnsDomainMapPtr DdnsDomainListParser::parse(data::ConstElementPtr domain_list,
+DdnsDomainMapPtr DdnsDomainListParser::parse(ConstElementPtr domain_list,
const TSIGKeyInfoMapPtr keys) {
DdnsDomainMapPtr domains(new DdnsDomainMap());
DdnsDomainParser parser;
- data::ConstElementPtr domain_config;
+ ConstElementPtr domain_config;
BOOST_FOREACH(domain_config, domain_list->listValue()) {
DdnsDomainPtr domain = parser.parse(domain_config, keys);
// *********************** DdnsDomainListMgrParser *************************
DdnsDomainListMgrPtr
-DdnsDomainListMgrParser::parse(data::ConstElementPtr mgr_config,
+DdnsDomainListMgrParser::parse(ConstElementPtr mgr_config,
const std::string& mgr_name,
const TSIGKeyInfoMapPtr keys) {
DdnsDomainListMgrPtr mgr(new DdnsDomainListMgr(mgr_name));
// Parse the list of domains
- data::ConstElementPtr domains_config = mgr_config->get("ddns-domains");
+ ConstElementPtr domains_config = mgr_config->get("ddns-domains");
if (domains_config) {
DdnsDomainListParser domain_parser;
DdnsDomainMapPtr domains = domain_parser.parse(domains_config, keys);
-// 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
#include <cc/data.h>
#include <cc/simple_parser.h>
#include <cc/cfg_to_element.h>
+#include <cc/user_context.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
#include <dns/tsig.h>
#include <exceptions/exceptions.h>
/// instance of the actual key (@ref isc::dns::TSIGKey) that can be used
/// by the IO layer for signing and verifying messages.
///
-class TSIGKeyInfo : public isc::data::CfgToElement {
+class TSIGKeyInfo : public isc::dhcp::UserContext, public isc::data::CfgToElement {
public:
/// @brief Defines string values for the supported TSIG algorithms
//@{
/// belongs to a list of servers supporting DNS for a given domain. It will
/// be used to establish communications with the server to carry out DNS
/// updates.
-class DnsServerInfo : public isc::data::CfgToElement {
+class DnsServerInfo : public isc::dhcp::UserContext, public isc::data::CfgToElement {
public:
/// @brief defines DNS standard port value
static const uint32_t STANDARD_DNS_PORT = 53;
/// @todo Currently the name entry for a domain is just an std::string. It
/// may be worthwhile to change this to a dns::Name for purposes of better
/// validation and matching capabilities.
-class DdnsDomain : public isc::data::CfgToElement {
+class DdnsDomain : public isc::dhcp::UserContext, public isc::data::CfgToElement {
public:
/// @brief Constructor
///
///
/// This class parses the configuration element "tsig-key"
/// and creates an instance of a TSIGKeyInfo.
-class TSIGKeyInfoParser : public data::SimpleParser {
+class TSIGKeyInfoParser : public data::SimpleParser {
public:
/// @brief Performs the actual parsing of the given "tsig-key" element.
///
///
/// This class parses the configuration element "dns-server"
/// and creates an instance of a DnsServerInfo.
-class DnsServerInfoParser : public data::SimpleParser {
+class DnsServerInfoParser : public data::SimpleParser {
public:
/// @brief Performs the actual parsing of the given "dns-server" element.
///
-/* 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
return isc::d2::D2Parser::make_STRING(tmp, driver.loc_);
}
+\"user-context\" {
+ switch(driver.ctx_) {
+ case isc::d2::D2ParserContext::DHCPDDNS:
+ case isc::d2::D2ParserContext::DDNS_DOMAIN:
+ case isc::d2::D2ParserContext::DDNS_DOMAINS:
+ case isc::d2::D2ParserContext::DNS_SERVER:
+ case isc::d2::D2ParserContext::DNS_SERVERS:
+ case isc::d2::D2ParserContext::TSIG_KEY:
+ case isc::d2::D2ParserContext::TSIG_KEYS:
+ case isc::d2::D2ParserContext::LOGGERS:
+ return isc::d2::D2Parser::make_USER_CONTEXT(driver.loc_);
+ default:
+ return isc::d2::D2Parser::make_STRING("user-context", driver.loc_);
+ }
+}
+
+\"comment\" {
+ switch(driver.ctx_) {
+ case isc::d2::D2ParserContext::DHCPDDNS:
+ case isc::d2::D2ParserContext::DDNS_DOMAIN:
+ case isc::d2::D2ParserContext::DDNS_DOMAINS:
+ case isc::d2::D2ParserContext::DNS_SERVER:
+ case isc::d2::D2ParserContext::DNS_SERVERS:
+ case isc::d2::D2ParserContext::TSIG_KEY:
+ case isc::d2::D2ParserContext::TSIG_KEYS:
+ case isc::d2::D2ParserContext::LOGGERS:
+ return isc::d2::D2Parser::make_COMMENT(driver.loc_);
+ default:
+ return isc::d2::D2Parser::make_STRING("comment", driver.loc_);
+ }
+}
+
\"forward-ddns\" {
switch(driver.ctx_) {
case isc::d2::D2ParserContext::DHCPDDNS:
-/* 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
TCP "TCP"
NCR_FORMAT "ncr-format"
JSON "JSON"
+ USER_CONTEXT "user-context"
+ COMMENT "comment"
FORWARD_DDNS "forward-ddns"
REVERSE_DDNS "reverse-ddns"
DDNS_DOMAINS "ddns-domains"
// for it.
};
+map_value: map2 { $$ = ctx.stack_.back(); ctx.stack_.pop_back(); };
+
// Assignments rule
map_content: %empty // empty map
| not_empty_map
| forward_ddns
| reverse_ddns
| tsig_keys
+ | user_context
+ | comment
| unknown_map_entry
;
ctx.leave();
};
+user_context: USER_CONTEXT {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON map_value {
+ ElementPtr parent = ctx.stack_.back();
+ ElementPtr user_context = $4;
+ ConstElementPtr old = parent->get("user-context");
+
+ // Handle already existing user context
+ if (old) {
+ // Check if it was a comment or a duplicate
+ if ((old->size() != 1) || !old->contains("comment")) {
+ std::stringstream msg;
+ msg << "duplicate user-context entries (previous at "
+ << old->getPosition().str() << ")";
+ error(@1, msg.str());
+ }
+ // Merge the comment
+ user_context->set("comment", old->get("comment"));
+ }
+
+ // Set the user context
+ parent->set("user-context", user_context);
+ ctx.leave();
+};
+
+comment: COMMENT {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr parent = ctx.stack_.back();
+ ElementPtr user_context(new MapElement(ctx.loc2pos(@1)));
+ ElementPtr comment(new StringElement($4, ctx.loc2pos(@4)));
+ user_context->set("comment", comment);
+
+ // Handle already existing user context
+ ConstElementPtr old = parent->get("user-context");
+ if (old) {
+ // Check for duplicate comment
+ if (old->contains("comment")) {
+ std::stringstream msg;
+ msg << "duplicate user-context/comment entries (previous at "
+ << old->getPosition().str() << ")";
+ error(@1, msg.str());
+ }
+ // Merge the user context in the comment
+ merge(user_context, old);
+ }
+
+ // Set the user context
+ parent->set("user-context", user_context);
+ ctx.leave();
+};
+
forward_ddns : FORWARD_DDNS {
ElementPtr m(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("forward-ddns", m);
ddns_domain_param: ddns_domain_name
| ddns_domain_key_name
| dns_servers
+ | user_context
+ | comment
| unknown_map_entry
;
dns_server_param: dns_server_hostname
| dns_server_ip_address
| dns_server_port
+ | user_context
+ | comment
| unknown_map_entry
;
| tsig_key_algorithm
| tsig_key_digest_bits
| tsig_key_secret
+ | user_context
+ | comment
| unknown_map_entry
;
| output_options_list
| debuglevel
| severity
+ | user_context
+ | comment
| unknown_map_entry
;
TESTS =
if HAVE_GTEST
TESTS += run_unittests
-run_unittests_SOURCES = command_interpreter_unittests.cc data_unittests.cc
+run_unittests_SOURCES = command_interpreter_unittests.cc
+run_unittests_SOURCES += data_unittests.cc
run_unittests_SOURCES += data_file_unittests.cc
run_unittests_SOURCES += json_feed_unittests.cc
-run_unittests_SOURCES += run_unittests.cc
run_unittests_SOURCES += simple_parser_unittest.cc
+run_unittests_SOURCES += user_context_unittests.cc
+run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-// 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
namespace dhcp {
void
-UserContext::contextToElement(ElementPtr map) const{
+UserContext::contextToElement(ElementPtr map) const {
// Set user-context extracting comment
ConstElementPtr context = getContext();
if (!isNull(context)) {
}
}
+ElementPtr
+UserContext::toElement(ConstElementPtr map) {
+ ElementPtr result = isc::data::copy(map);
+ // Protect against argument not map
+ if (result->getType() != Element::map) {
+ return (result);
+ }
+ ConstElementPtr ctx = result->get("user-context");
+ // Protect against user context not map
+ if (!ctx || (ctx->getType() != Element::map)) {
+ return (result);
+ }
+ // Extract comment
+ if (ctx->contains("comment")) {
+ ElementPtr ctx_copy = isc::data::copy(ctx);
+ result->set("comment", ctx_copy->get("comment"));
+ ctx_copy->remove("comment");
+ result->remove("user-context");
+ if (ctx_copy->size() > 0) {
+ result->set("user-context", ctx_copy);
+ }
+ }
+ return (result);
+}
+
}; // end of isc::dhcp namespace
}; // end of isc 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
/// @param map A pointer to map where the user context will be unparsed.
void contextToElement(data::ElementPtr map) const;
+ /// @brief Copy extracting comments an Element map
+ ///
+ /// @param map A pointer to map.
+ /// @return a copy of map where comment is extracted.
+ static data::ElementPtr toElement(data::ConstElementPtr map);
+
protected:
/// @brief Pointer to the user context (may be NULL)
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
}
// Set control-socket (skip if null as empty is not legal)
if (!isNull(control_socket_)) {
- ElementPtr csocket = isc::data::copy(control_socket_);
- ConstElementPtr ctx = csocket->get("user-context");
- // Protect against not map
- if (ctx && (ctx->getType() != Element::map)) {
- ctx.reset();
- }
- // Extract comment
- if (ctx && ctx->contains("comment")) {
- ElementPtr ctx_copy = isc::data::copy(ctx);
- csocket->set("comment", ctx_copy->get("comment"));
- ctx_copy->remove("comment");
- csocket->remove("user-context");
- if (ctx_copy->size() > 0) {
- csocket->set("user-context", ctx_copy);
- }
- }
- dhcp->set("control-socket", csocket);
+ dhcp->set("control-socket", UserContext::toElement(control_socket_));
}
// Set client-classes
ConstElementPtr client_classes = class_dictionary_->toElement();
-// 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
}
}
+ // Handle user context here as it is really optional.
+ std::string user_context_id("user-context");
+ it = objects_map.find(user_context_id);
+ if (it != objects_map.end()) {
+ buildAndCommit(user_context_id, it->second);
+ // We parsed it, take it out of the list.
+ objects_map.erase(it);
+ }
+
// NOTE: When using ordered parsing, the parse order list MUST
// include every possible element id that the value_map may contain.
// Entries in the map that are not in the parse order, will not be
-// 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
#include <cc/data.h>
#include <cc/cfg_to_element.h>
+#include <cc/user_context.h>
#include <exceptions/exceptions.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
#include <functional>
/// // Restore from backup
/// context_ = backup_copy;
///
-class DCfgContextBase : public isc::data::CfgToElement {
+class DCfgContextBase : public isc::dhcp::UserContext, public isc::data::CfgToElement {
public:
/// @brief Indicator that a configuration parameter is optional.
static const bool OPTIONAL = true;