2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-02 06:55:16 +00:00

[5033] - kea-dhcp6 now uses new D2ClientConfigParser

src/bin/dhcp6/json_config_parser.cc
        createGlobalDhcp6ConfigParser()
        - added clause to invoke new D2ClientConfigParser to
        set staging config
        - added clause to apply staged D2ClientConfig (formerly done
        by parser commit

    src/bin/dhcp6/parser_context.h
    src/bin/dhcp6/parser_context.cc
        aded PARSER_DHCP_DDNS context

    src/bin/dhcp4/simple_parser6.h
    src/bin/dhcp4/simple_parser6.cc
        defined SimpleParser6::D2_CLIENT_CONFIG_DEFAULTS
        SimpleParser6::setAllDefaults() - now sets defaults
        for D2ClientConfig

    src/bin/dhcp6/tests/d2_unittest.cc
    src/bin/dhcp6/tests/fqdn_unittest.cc
        Updated replace-name-mode values and tests
        (true/false no longer supported)

    doc/guide/dhcp6-srv.xml
        Updated, replace-client-name no longer accepts booleans
This commit is contained in:
Thomas Markwalder
2017-01-11 15:22:30 -05:00
parent 85640c193b
commit 9b20235ebf
10 changed files with 96 additions and 59 deletions

View File

@@ -2372,9 +2372,10 @@ should include options from the isc option space:
<note> <note>
Note that formerly, this parameter was a boolean and permitted only values Note that formerly, this parameter was a boolean and permitted only values
of <command>true</command> and <command>false</command>. Boolean values of <command>true</command> and <command>false</command>. Boolean values
will still be accepted but may eventually be deprecated. A value of have been deprecated and are no longer accepted. If you are currently using
<command>true</command> equates to <command>when-present</command>, booleans, you must replace them with the desired mode name. A value of
<command>false</command> equates to <command>never</command>. <command>true</command> maps to <command>"when-present"</command>, while
<command>false</command> maps to <command>"never"</command>.
</note> </note>
For example, To instruct kea-dhcp6 to always generate the FQDN for a For example, To instruct kea-dhcp6 to always generate the FQDN for a

View File

@@ -742,12 +742,10 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
hooks_parser->commit(); hooks_parser->commit();
} }
{ // Apply the staged D2ClientConfig, used to be done by parser commit
// Used to be done by parser commit D2ClientConfigPtr cfg;
D2ClientConfigPtr cfg; cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig(); CfgMgr::instance().setD2ClientConfig(cfg);
CfgMgr::instance().setD2ClientConfig(cfg);
}
} }
catch (const isc::Exception& ex) { catch (const isc::Exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what()); LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());

View File

@@ -427,10 +427,7 @@ public:
// in a client request correctly, according to the replace-client-name // in a client request correctly, according to the replace-client-name
// mode configuration parameter. // mode configuration parameter.
// //
// @param mode - value to use client-name-replacment parameter - for // @param mode - value to use for replace-client-name
// mode labels such as NEVER and ALWAYS must incluce enclosing quotes:
// "\"NEVER\"". This allows us to also pass in boolean literals which
// are unquoted.
// @param client_name_flag - specifies whether or not the client request // @param client_name_flag - specifies whether or not the client request
// should contain a hostname option // should contain a hostname option
// @param exp_replacement_flag - specifies whether or not the server is // @param exp_replacement_flag - specifies whether or not the server is
@@ -452,7 +449,7 @@ public:
"\"dhcp-ddns\": {" "\"dhcp-ddns\": {"
"\"enable-updates\": true," "\"enable-updates\": true,"
"\"qualifying-suffix\": \"fake-suffix.isc.org.\"," "\"qualifying-suffix\": \"fake-suffix.isc.org.\","
"\"replace-client-name\": %s" "\"replace-client-name\": \"%s\""
"}}"; "}}";
// Create the configuration and configure the server // Create the configuration and configure the server
@@ -1551,24 +1548,24 @@ TEST_F(NameDhcpv4SrvTest, emptyFqdn) {
// the supported modes. // the supported modes.
TEST_F(NameDhcpv4SrvTest, replaceClientNameModeTest) { TEST_F(NameDhcpv4SrvTest, replaceClientNameModeTest) {
testReplaceClientNameMode("\"never\"", testReplaceClientNameMode("never",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"never\"", testReplaceClientNameMode("never",
CLIENT_NAME_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"always\"", testReplaceClientNameMode("always",
CLIENT_NAME_NOT_PRESENT, NAME_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"always\"", testReplaceClientNameMode("always",
CLIENT_NAME_PRESENT, NAME_REPLACED); CLIENT_NAME_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-present\"", testReplaceClientNameMode("when-present",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"when-present\"", testReplaceClientNameMode("when-present",
CLIENT_NAME_PRESENT, NAME_REPLACED); CLIENT_NAME_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-not-present\"", testReplaceClientNameMode("when-not-present",
CLIENT_NAME_NOT_PRESENT, NAME_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-not-present\"", testReplaceClientNameMode("when-not-present",
CLIENT_NAME_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_PRESENT, NAME_NOT_REPLACED);
} }

View File

@@ -716,8 +716,7 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB); parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB);
} else if (config_id.compare("hooks-libraries") == 0) { } else if (config_id.compare("hooks-libraries") == 0) {
parser = new HooksLibrariesParser(config_id); parser = new HooksLibrariesParser(config_id);
} else if (config_id.compare("dhcp-ddns") == 0) { // dhcp-ddns has been converted to SimpleParser
parser = new D2ClientConfigParser(config_id);
} else if (config_id.compare("mac-sources") == 0) { } else if (config_id.compare("mac-sources") == 0) {
parser = new MACSourcesListConfigParser(config_id, parser = new MACSourcesListConfigParser(config_id,
globalContext()); globalContext());
@@ -911,6 +910,13 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
continue; continue;
} }
if (config_pair.first == "dhcp-ddns") {
D2ClientConfigParser parser;
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
continue;
}
ParserPtr parser(createGlobal6DhcpConfigParser(config_pair.first, ParserPtr parser(createGlobal6DhcpConfigParser(config_pair.first,
config_pair.second)); config_pair.second));
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PARSER_CREATED) LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PARSER_CREATED)
@@ -1012,6 +1018,11 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
if (hooks_parser) { if (hooks_parser) {
hooks_parser->commit(); hooks_parser->commit();
} }
// Apply staged D2ClientConfig, used to be done by parser commit
D2ClientConfigPtr cfg;
cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
CfgMgr::instance().setD2ClientConfig(cfg);
} }
catch (const isc::Exception& ex) { catch (const isc::Exception& ex) {
LOG_ERROR(dhcp6_logger, DHCP6_PARSER_COMMIT_FAIL).arg(ex.what()); LOG_ERROR(dhcp6_logger, DHCP6_PARSER_COMMIT_FAIL).arg(ex.what());

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -163,6 +163,8 @@ Parser6Context::contextName()
return ("loggers"); return ("loggers");
case OUTPUT_OPTIONS: case OUTPUT_OPTIONS:
return ("output-options"); return ("output-options");
case DHCP_DDNS:
return ("dhcp-ddns");
default: default:
return ("__unknown__"); return ("__unknown__");
} }

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -83,7 +83,10 @@ public:
PARSER_OPTION_DATA, PARSER_OPTION_DATA,
/// This will parse the input as hooks-library. /// This will parse the input as hooks-library.
PARSER_HOOKS_LIBRARY PARSER_HOOKS_LIBRARY,
/// This will parse the input as dhcp-ddns. (D2 client config)
PARSER_DHCP_DDNS
} ParserType; } ParserType;
/// @brief Default constructor. /// @brief Default constructor.
@@ -250,7 +253,10 @@ public:
LOGGERS, LOGGERS,
/// Used while parsing Logging/loggers/output_options structures. /// Used while parsing Logging/loggers/output_options structures.
OUTPUT_OPTIONS OUTPUT_OPTIONS,
/// Used while parsing Dhcp6/dhcp-ddns
DHCP_DDNS
} ParserContext; } ParserContext;
/// @brief File name /// @brief File name

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -73,6 +73,27 @@ const ParamsList SimpleParser6::INHERIT_GLOBAL_TO_SUBNET6 = {
"preferred-lifetime", "preferred-lifetime",
"valid-lifetime" "valid-lifetime"
}; };
/// @brief This table defines default values for D2 client configuration
///
const SimpleDefaults SimpleParser6::D2_CLIENT_CONFIG_DEFAULTS = {
{ "server-ip", Element::string, "127.0.0.1" },
{ "server-port", Element::integer, "53001" },
// default sender-ip depends on server-ip family, so we leave default blank
// parser knows to use the appropriate ZERO address based on server-ip
{ "sender-ip", Element::string, "" },
{ "sender-port", Element::integer, "0" },
{ "max-queue-size", Element::integer, "1024" },
{ "ncr-protocol", Element::string, "UDP" },
{ "ncr-format", Element::string, "JSON" },
{ "always-include-fqdn", Element::boolean, "false" },
{ "override-no-update", Element::boolean, "false" },
{ "override-client-update", Element::boolean, "false" },
{ "replace-client-name", Element::string, "NEVER" },
{ "generated-prefix", Element::string, "myhost" },
{ "qualifying-suffix", Element::string, "" }
};
/// @} /// @}
/// --------------------------------------------------------------------------- /// ---------------------------------------------------------------------------
@@ -101,6 +122,22 @@ size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
} }
} }
ConstElementPtr d2_client = global->get("dhcp-ddns");
/// @todo - what if it's not in global? should we add it?
if (d2_client) {
// Because "dhcp-ddns" is a MapElement and global->get()
// returns a ConstElementPtr, then we get a map we can't
// change. So go thru gyrations to create a non-const
// map, update it with default values and then replace
// the one in global with the new one. Ick.
std::map<std::string, ConstElementPtr> d2_map;
d2_client->getValue(d2_map);
ElementPtr new_map(new MapElement());
new_map->setValue(d2_map);
cnt += SimpleParser::setDefaults(new_map, D2_CLIENT_CONFIG_DEFAULTS);
global->set("dhcp-ddns", new_map);
}
return (cnt); return (cnt);
} }

View File

@@ -34,6 +34,7 @@ public:
static const isc::data::SimpleDefaults OPTION6_DEFAULTS; static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS; static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6; static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS;
}; };
}; };

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -117,7 +117,7 @@ Dhcp6SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
" \"allow-client-update\" : true, " " \"allow-client-update\" : true, "
" \"override-no-update\" : true, " " \"override-no-update\" : true, "
" \"override-client-update\" : true, " " \"override-client-update\" : true, "
" \"replace-client-name\" : true, " " \"replace-client-name\" : \"when-present\", "
" \"generated-prefix\" : \"test.prefix\", " " \"generated-prefix\" : \"test.prefix\", "
" \"qualifying-suffix\" : \"test.suffix.\" }," " \"qualifying-suffix\" : \"test.suffix.\" },"
"\"valid-lifetime\": 4000 }"; "\"valid-lifetime\": 4000 }";

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2013-2016 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -391,10 +391,8 @@ public:
// in a client request correctly, according to the replace-client-name // in a client request correctly, according to the replace-client-name
// mode configuration parameter. // mode configuration parameter.
// //
// @param mode - value to use client-name-replacment parameter - for // @param mode - value to use for replace-client-name mode
// mode labels such as NEVER and ALWAYS must incluce enclosing quotes: //
// "\"NEVER\"". This allows us to also pass in boolean literals which
// are unquoted.
// @param client_name_flag - specifies whether or not the client request // @param client_name_flag - specifies whether or not the client request
// should contain a hostname option // should contain a hostname option
// @param exp_replacement_flag - specifies whether or not the server is // @param exp_replacement_flag - specifies whether or not the server is
@@ -420,7 +418,7 @@ public:
"\"dhcp-ddns\": { \n" "\"dhcp-ddns\": { \n"
"\"enable-updates\": true, \n" "\"enable-updates\": true, \n"
"\"qualifying-suffix\": \"fake-suffix.isc.org.\", \n" "\"qualifying-suffix\": \"fake-suffix.isc.org.\", \n"
"\"replace-client-name\": %s \n" "\"replace-client-name\": \"%s\" \n"
"}} \n"; "}} \n";
// Create the configuration and configure the server // Create the configuration and configure the server
@@ -1494,39 +1492,25 @@ TEST_F(FqdnDhcpv6SrvTest, hostnameReservationDdnsDisabled) {
TEST_F(FqdnDhcpv6SrvTest, replaceClientNameModeTest) { TEST_F(FqdnDhcpv6SrvTest, replaceClientNameModeTest) {
isc::dhcp::test::IfaceMgrTestConfig test_config(true); isc::dhcp::test::IfaceMgrTestConfig test_config(true);
// We pass mode labels in with enclosing quotes so we can also test testReplaceClientNameMode("never",
// unquoted boolean literals true/false
testReplaceClientNameMode("\"never\"",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"never\"", testReplaceClientNameMode("never",
CLIENT_NAME_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"always\"", testReplaceClientNameMode("always",
CLIENT_NAME_NOT_PRESENT, NAME_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"always\"", testReplaceClientNameMode("always",
CLIENT_NAME_PRESENT, NAME_REPLACED); CLIENT_NAME_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-present\"", testReplaceClientNameMode("when-present",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("\"when-present\"", testReplaceClientNameMode("when-present",
CLIENT_NAME_PRESENT, NAME_REPLACED); CLIENT_NAME_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-not-present\"", testReplaceClientNameMode("when-not-present",
CLIENT_NAME_NOT_PRESENT, NAME_REPLACED); CLIENT_NAME_NOT_PRESENT, NAME_REPLACED);
testReplaceClientNameMode("\"when-not-present\"", testReplaceClientNameMode("when-not-present",
CLIENT_NAME_PRESENT, NAME_NOT_REPLACED); CLIENT_NAME_PRESENT, NAME_NOT_REPLACED);
// Verify that boolean false produces the same result as RCM_NEVER
testReplaceClientNameMode("false",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("false",
CLIENT_NAME_PRESENT, NAME_NOT_REPLACED);
// Verify that boolean true produces the same result as RCM_WHEN_PRESENT
testReplaceClientNameMode("true",
CLIENT_NAME_NOT_PRESENT, NAME_NOT_REPLACED);
testReplaceClientNameMode("true",
CLIENT_NAME_PRESENT, NAME_REPLACED);
} }
} // end of anonymous namespace } // end of anonymous namespace