\"hostname-char-set\" {
switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::DHCP_DDNS:
return isc::dhcp::Dhcp4Parser::make_HOSTNAME_CHAR_SET(driver.loc_);
default:
\"hostname-char-replacement\" {
switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::DHCP_DDNS:
return isc::dhcp::Dhcp4Parser::make_HOSTNAME_CHAR_REPLACEMENT(driver.loc_);
default:
| t1_percent
| t2_percent
| loggers
+ | hostname_char_set
+ | hostname_char_replacement
| unknown_map_entry
;
EXPECT_EQ(D2ClientConfig::RCM_WHEN_PRESENT, d2_client_config->getReplaceClientNameMode());
EXPECT_EQ("test.prefix", d2_client_config->getGeneratedPrefix());
EXPECT_EQ("test.suffix.", d2_client_config->getQualifyingSuffix());
- EXPECT_EQ("[^A-Za-z0-9_-]", d2_client_config->getHostnameCharSet());
- EXPECT_EQ("x", d2_client_config->getHostnameCharReplacement());
+ EXPECT_EQ("[^A-Za-z0-9_-]", d2_client_config->getHostnameCharSet().get());
+ EXPECT_EQ("x", d2_client_config->getHostnameCharReplacement().get());
}
// This test checks the ability of the server to handle a configuration
-// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2019 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
using namespace std;
using namespace isc::asiolink;
using namespace isc::data;
+using namespace isc::util;
namespace isc {
namespace dhcp {
const ReplaceClientNameMode replace_client_name_mode,
const std::string& generated_prefix,
const std::string& qualifying_suffix,
- const std::string& hostname_char_set,
- const std::string& hostname_char_replacement)
+ Optional<std::string> hostname_char_set,
+ Optional<std::string> hostname_char_replacement)
: enable_updates_(enable_updates),
server_ip_(server_ip),
server_port_(server_port),
qualifying_suffix_(qualifying_suffix),
hostname_char_set_(hostname_char_set),
hostname_char_replacement_(hostname_char_replacement),
- hostname_sanitizer_(0) {
+ hostname_sanitizer_(0),
+ fetch_globals_fn_(0) {
validateContents();
}
replace_client_name_mode_(stringToReplaceClientNameMode(DFT_REPLACE_CLIENT_NAME_MODE)),
generated_prefix_(DFT_GENERATED_PREFIX),
qualifying_suffix_(""),
- hostname_char_set_(DFT_HOSTNAME_CHAR_SET),
- hostname_char_replacement_(DFT_HOSTNAME_CHAR_SET),
- hostname_sanitizer_(0) {
+ hostname_char_set_(DFT_HOSTNAME_CHAR_SET, true),
+ hostname_char_replacement_(DFT_HOSTNAME_CHAR_SET, true),
+ hostname_sanitizer_(0),
+ fetch_globals_fn_(0) {
validateContents();
}
<< server_ip_.toText() << "/" << server_port_);
}
- if (!hostname_char_set_.empty()) {
+ if (!getHostnameCharSet().unspecified() && !getHostnameCharSet().empty()) {
try {
- hostname_sanitizer_.reset(new isc::util::str::StringSanitizer(hostname_char_set_,
- hostname_char_replacement_));
+ hostname_sanitizer_.reset(new isc::util::str::StringSanitizer(getHostnameCharSet(),
+ getHostnameCharReplacement()));
} catch (const std::exception& ex) {
isc_throw(D2ClientError, "D2ClientConfig: hostname-char-set"
" is not a valid regular expression");
<< replaceClientNameModeToString(replace_client_name_mode_)
<< ", generated-prefix: [" << generated_prefix_ << "]"
<< ", qualifying-suffix: [" << qualifying_suffix_ << "]"
- << ", hostname-char-set: [" << hostname_char_set_ << "]"
- << ", hostname-char-replacement: [" << hostname_char_replacement_ << "]";
+ << ", hostname-char-set: [" << getHostnameCharSet() << "]"
+ << ", hostname-char-replacement: [" << getHostnameCharReplacement() << "]";
}
return (stream.str());
// Set generated-prefix
result->set("generated-prefix", Element::create(generated_prefix_));
// Set hostname-char-set
- result->set("hostname-char-set", Element::create(hostname_char_set_));
+ if (!hostname_char_set_.unspecified()) {
+ result->set("hostname-char-set", Element::create(hostname_char_set_));
+ }
// Set hostname-char-replacement
- result->set("hostname-char-replacement", Element::create(hostname_char_replacement_));
+ if (!hostname_char_replacement_.unspecified()) {
+ result->set("hostname-char-replacement", Element::create(hostname_char_replacement_));
+ }
return (result);
}
-// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2019 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 <dhcp_ddns/ncr_io.h>
#include <exceptions/exceptions.h>
#include <util/strutil.h>
+#include <util/optional.h>
#include <boost/shared_ptr.hpp>
namespace isc {
namespace dhcp {
-
/// An exception that is thrown if an error occurs while configuring
/// the D2 DHCP DDNS client.
class D2ClientError : public isc::Exception {
: isc::Exception(file, line, what) {}
};
+/// @brief Callback function for @c D2ClientConfig that retrieves globally
+/// configured parameters.
+typedef std::function<data::ConstElementPtr()> FetchNetworkGlobalsFn;
+
/// @brief Acts as a storage vault for D2 client configuration
///
/// @param generated_prefix Prefix to use when generating domain-names.
/// @param qualifying_suffix Suffix to use to qualify partial domain-names.
/// @param hostname_char_set regular expression string which describes invalid
- /// characters to be scrubbed from client host names
+ /// characters to be scrubbed from client host names
/// @param hostname_char_replacement string of zero or more characters to
/// replace invalid chars when sanitizing client host names
///
const ReplaceClientNameMode replace_client_name_mode,
const std::string& generated_prefix,
const std::string& qualifying_suffix,
- const std::string& hostname_char_set,
- const std::string& hostname_char_replacement);
+ util::Optional<std::string> hostname_char_set,
+ util::Optional<std::string> hostname_char_replacement);
/// @brief Default constructor
}
/// @brief Return the char set regexp used to sanitize client hostnames.
- const std::string& getHostnameCharSet() const {
- return(hostname_char_set_);
- }
+ util::Optional<std::string> getHostnameCharSet() const {
+ if (hostname_char_set_.unspecified() && fetch_globals_fn_) {
+ data::ConstElementPtr globals = fetch_globals_fn_();
+ if (globals && (globals->getType() == data::Element::map)) {
+ data::ConstElementPtr global_param =
+ globals->get("hostname-char-set");
+ if (global_param) {
+ return (global_param->stringValue());
+ }
+ }
+ }
+
+ return (hostname_char_set_);
+ }
/// @brief Return the invalid char replacement used to sanitize client hostnames.
- const std::string& getHostnameCharReplacement() const {
- return(hostname_char_replacement_);
+ util::Optional<std::string> getHostnameCharReplacement() const {
+ if (hostname_char_replacement_.unspecified() && fetch_globals_fn_) {
+ data::ConstElementPtr globals = fetch_globals_fn_();
+ if (globals && (globals->getType() == data::Element::map)) {
+ data::ConstElementPtr global_param =
+ globals->get("hostname-char-replacement");
+ if (global_param) {
+ return (global_param->stringValue());
+ }
+ }
+ }
+
+ return (hostname_char_replacement_);
}
/// @brief Return pointer to compiled regular expression string sanitizer
return(hostname_sanitizer_);
}
+ /// @brief Sets the optional callback function used to fetch globally
+ /// configured parameters.
+ ///
+ /// @param fetch_globals_fn Pointer to the function.
+ void setFetchGlobalsFn(FetchNetworkGlobalsFn fetch_globals_fn) {
+ fetch_globals_fn_ = fetch_globals_fn;
+ }
+
+ /// @brief Checks if the D2 client config is associated with a function
+ /// used to fetch globally configured parameters.
+ ///
+ /// @return true if it is associated, false otherwise.
+ bool hasFetchGlobalsFn() const {
+ return (static_cast<bool>(fetch_globals_fn_));
+ }
+
/// @brief Compares two D2ClientConfigs for equality
bool operator == (const D2ClientConfig& other) const;
/// @brief Regular expression describing invalid characters for client hostnames.
/// If empty, host name scrubbing is not done.
- std::string hostname_char_set_;
+ util::Optional<std::string> hostname_char_set_;
/// @brief A string to replace invalid characters when scrubbing hostnames.
/// Meaningful only if hostname_char_set_ is not empty.
- std::string hostname_char_replacement_;
+ util::Optional<std::string> hostname_char_replacement_;
/// @brief Pointer to compiled regular expression string sanitizer
util::str::StringSanitizerPtr hostname_sanitizer_;
+
+ /// @brief Pointer to the optional callback used to fetch globally
+ /// configured parameters inherited to the @c D2ClientConfig object.
+ FetchNetworkGlobalsFn fetch_globals_fn_;
};
std::ostream&
// In order to take advantage of the dynamic inheritance of global
// parameters to a subnet we need to set a callback function for each
// subnet to allow for fetching global parameters.
- subnet_->setFetchGlobalsFn([]() -> ConstElementPtr {
+ subnet_->setFetchGlobalsFn([]() -> ConstElementPtr {
return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
});
std::string generated_prefix =
getString(client_config, "generated-prefix");
- std::string hostname_char_set =
- getString(client_config, "hostname-char-set");
+ Optional<std::string> hostname_char_set(D2ClientConfig::DFT_HOSTNAME_CHAR_SET, true);
+ if (client_config->contains("hostname-char-set")) {
+ hostname_char_set = getString(client_config, "hostname-char-set");
+ }
- std::string hostname_char_replacement =
- getString(client_config, "hostname-char-replacement");
+ Optional<std::string> hostname_char_replacement(D2ClientConfig::DFT_HOSTNAME_CHAR_REPLACEMENT, true);
+ if (client_config->contains("hostname-char-replacement")) {
+ hostname_char_replacement =
+ getString(client_config, "hostname-char-replacement");
+ }
// qualifying-suffix is the only parameter which has no default
std::string qualifying_suffix = "";
new_config->setContext(user_context);
}
+ // In order to take advantage of the dynamic inheritance of global
+ // parameters to a subnet we need to set a callback function for
+ // the d2 client config to allow for fetching global parameters.
+ new_config->setFetchGlobalsFn([]() -> ConstElementPtr {
+ return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
+ });
+
return(new_config);
}
{ "override-no-update", Element::boolean, "false" },
{ "override-client-update", Element::boolean, "false" },
{ "replace-client-name", Element::string, "never" },
- { "generated-prefix", Element::string, "myhost" },
- { "hostname-char-set", Element::string, "" },
- { "hostname-char-replacement", Element::string, "" }
+ { "generated-prefix", Element::string, "myhost" }
+ // hostname-char-set and hostname-char-replacement moved to global
// qualifying-suffix has no default
};
{ "calculate-tee-times", Element::boolean },
{ "t1-percent", Element::real },
{ "t2-percent", Element::real },
- { "loggers", Element::list }
+ { "loggers", Element::list },
+ { "hostname-char-set", Element::string },
+ { "hostname-char-replacement", Element::string }
};
/// @brief This table defines default values for option definitions in DHCPv4.
/// in Dhcp4) are optional. If not defined, the following values will be
/// used.
const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
- { "valid-lifetime", Element::integer, "7200" },
- { "decline-probation-period", Element::integer, "86400" }, // 24h
- { "dhcp4o6-port", Element::integer, "0" },
- { "echo-client-id", Element::boolean, "true" },
- { "match-client-id", Element::boolean, "true" },
- { "authoritative", Element::boolean, "false" },
- { "next-server", Element::string, "0.0.0.0" },
- { "server-hostname", Element::string, "" },
- { "boot-file-name", Element::string, "" },
- { "server-tag", Element::string, "" },
- { "reservation-mode", Element::string, "all" },
- { "calculate-tee-times", Element::boolean, "false" },
- { "t1-percent", Element::real, ".50" },
- { "t2-percent", Element::real, ".875" }
+ { "valid-lifetime", Element::integer, "7200" },
+ { "decline-probation-period", Element::integer, "86400" }, // 24h
+ { "dhcp4o6-port", Element::integer, "0" },
+ { "echo-client-id", Element::boolean, "true" },
+ { "match-client-id", Element::boolean, "true" },
+ { "authoritative", Element::boolean, "false" },
+ { "next-server", Element::string, "0.0.0.0" },
+ { "server-hostname", Element::string, "" },
+ { "boot-file-name", Element::string, "" },
+ { "server-tag", Element::string, "" },
+ { "reservation-mode", Element::string, "all" },
+ { "calculate-tee-times", Element::boolean, "false" },
+ { "t1-percent", Element::real, ".50" },
+ { "t2-percent", Element::real, ".875" }
};
/// @brief This table defines default values for each IPv4 subnet.