2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-03 07:25:18 +00:00

[5039] SimpleParser is now split into cc/SimpleParser and SimpleParser{4,6}

This commit is contained in:
Tomek Mrugalski
2016-12-22 16:20:34 +01:00
parent d352a45e2b
commit 475b253194
15 changed files with 510 additions and 101 deletions

View File

@@ -3,7 +3,7 @@ SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src
AM_CPPFLAGS += $(BOOST_INCLUDES) AM_CPPFLAGS += $(BOOST_INCLUDES) -std=c++11
if HAVE_MYSQL if HAVE_MYSQL
AM_CPPFLAGS += $(MYSQL_CPPFLAGS) AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
endif endif
@@ -62,8 +62,8 @@ libdhcp4_la_SOURCES += json_config_parser.cc json_config_parser.h
libdhcp4_la_SOURCES += dhcp4_log.cc dhcp4_log.h libdhcp4_la_SOURCES += dhcp4_log.cc dhcp4_log.h
libdhcp4_la_SOURCES += dhcp4_srv.cc dhcp4_srv.h libdhcp4_la_SOURCES += dhcp4_srv.cc dhcp4_srv.h
libdhcp4_la_SOURCES += dhcp4to6_ipc.cc dhcp4to6_ipc.h libdhcp4_la_SOURCES += dhcp4to6_ipc.cc dhcp4to6_ipc.h
libdhcp4_la_SOURCES += kea_controller.cc libdhcp4_la_SOURCES += kea_controller.cc
libdhcp4_la_SOURCES += simple_parser4.cc simple_parser4.h
nodist_libdhcp4_la_SOURCES = dhcp4_messages.h dhcp4_messages.cc nodist_libdhcp4_la_SOURCES = dhcp4_messages.h dhcp4_messages.cc
EXTRA_DIST += dhcp4_messages.mes EXTRA_DIST += dhcp4_messages.mes

View File

@@ -8,6 +8,7 @@
#include <cc/command_interpreter.h> #include <cc/command_interpreter.h>
#include <dhcp4/dhcp4_log.h> #include <dhcp4/dhcp4_log.h>
#include <dhcp4/simple_parser4.h>
#include <dhcp/libdhcp++.h> #include <dhcp/libdhcp++.h>
#include <dhcp/option_definition.h> #include <dhcp/option_definition.h>
#include <dhcpsrv/cfg_option.h> #include <dhcpsrv/cfg_option.h>
@@ -20,7 +21,6 @@
#include <dhcpsrv/parsers/host_reservation_parser.h> #include <dhcpsrv/parsers/host_reservation_parser.h>
#include <dhcpsrv/parsers/host_reservations_list_parser.h> #include <dhcpsrv/parsers/host_reservations_list_parser.h>
#include <dhcpsrv/parsers/ifaces_config_parser.h> #include <dhcpsrv/parsers/ifaces_config_parser.h>
#include <dhcpsrv/parsers/simple_parser.h>
#include <dhcpsrv/timer_mgr.h> #include <dhcpsrv/timer_mgr.h>
#include <config/command_mgr.h> #include <config/command_mgr.h>
#include <util/encode/hex.h> #include <util/encode/hex.h>
@@ -573,7 +573,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
mutable_cfg->setValue(values); mutable_cfg->setValue(values);
// Set all default values if not specified by the user. // Set all default values if not specified by the user.
SimpleParser::setAllDefaults(mutable_cfg, false); SimpleParser4::setAllDefaults(mutable_cfg);
// We need definitions first // We need definitions first
ConstElementPtr option_defs = mutable_cfg->get("option-def"); ConstElementPtr option_defs = mutable_cfg->get("option-def");

View File

@@ -0,0 +1,73 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <dhcp4/simple_parser4.h>
#include <cc/data.h>
#include <boost/foreach.hpp>
using namespace std;
using namespace isc::data;
namespace isc {
namespace dhcp {
/// This table defines default values for option definitions in DHCPv4
const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
{ "record-types", Element::string, ""},
{ "space", Element::string, "dhcp4"},
{ "array", Element::boolean, "false"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for options in DHCPv4
const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = {
{ "space", Element::string, "dhcp4"},
{ "csv-format", Element::boolean, "true"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for DHCPv4
const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
{ "renew-timer", Element::integer, "900" },
{ "rebind-timer", Element::integer, "1800" },
{ "valid-lifetime", Element::integer, "7200" }
};
/// This list defines parameters that can be inherited from the global
/// scope to subnet6 scope.
const ParamsList SimpleParser4::INHERIT_GLOBAL_TO_SUBNET4 = {
"renew-timer",
"rebind-timer",
"valid-lifetime"
};
size_t SimpleParser4::setAllDefaults(isc::data::ElementPtr global) {
size_t cnt = 0;
// Set global defaults first.
cnt = setDefaults(global, GLOBAL4_DEFAULTS);
// Now set option defintion defaults for each specified option definition
ConstElementPtr option_defs = global->get("option-def");
if (option_defs) {
BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
cnt += SimpleParser::setDefaults(option_def, OPTION4_DEF_DEFAULTS);
}
}
// Finally, set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
cnt += SimpleParser::setDefaults(single_option, OPTION4_DEFAULTS);
}
}
return (cnt);
}
};
};

View File

@@ -0,0 +1,33 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SIMPLE_PARSER4_H
#define SIMPLE_PARSER4_H
#include <cc/simple_parser.h>
namespace isc {
namespace dhcp {
class SimpleParser4 : public isc::data::SimpleParser {
public:
/// @brief Sets all defaults for DHCPv4 configuration
///
/// This method sets global, option data and option definitions defaults.
///
/// @param global scope to be filled in with defaults.
/// @return number of default values added
static size_t setAllDefaults(isc::data::ElementPtr global);
static const isc::data::SimpleDefaults OPTION4_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
};
};
};
#endif

View File

@@ -92,6 +92,7 @@ dhcp4_unittests_SOURCES += out_of_range_unittest.cc
dhcp4_unittests_SOURCES += decline_unittest.cc dhcp4_unittests_SOURCES += decline_unittest.cc
dhcp4_unittests_SOURCES += kea_controller_unittest.cc dhcp4_unittests_SOURCES += kea_controller_unittest.cc
dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc
dhcp4_unittests_SOURCES += simple_parser4_unittest.cc
nodist_dhcp4_unittests_SOURCES = marker_file.h test_libraries.h nodist_dhcp4_unittests_SOURCES = marker_file.h test_libraries.h

View File

@@ -0,0 +1,91 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <gtest/gtest.h>
#include <dhcp4/simple_parser4.h>
#include <cc/data.h>
using namespace isc::data;
namespace isc {
namespace dhcp {
namespace test {
/// @brief DHCP Parser test fixture class
class SimpleParser4Test : public ::testing::Test {
public:
/// @brief Checks if specified map has an integer parameter with expected value
///
/// @param map map to be checked
/// @param param_name name of the parameter to be checked
/// @param exp_value expected value of the parameter.
void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
int64_t exp_value) {
// First check if the passed element is a map.
ASSERT_EQ(Element::map, map->getType());
// Now try to get the element being checked
ConstElementPtr elem = map->get(param_name);
ASSERT_TRUE(elem);
// Now check if it's indeed integer
ASSERT_EQ(Element::integer, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
};
// This test checks if global defaults are properly set for DHCPv4.
TEST_F(SimpleParser4Test, globalDefaults4) {
ElementPtr empty = Element::fromJSON("{ }");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(empty));
// We expect at least 3 parameters to be inserted.
EXPECT_TRUE(num >= 3);
checkIntegerValue(empty, "valid-lifetime", 7200);
checkIntegerValue(empty, "rebind-timer", 1800);
checkIntegerValue(empty, "renew-timer", 900);
// Make sure that preferred-lifetime is not set for v4 (it's v6 only
// parameter)
EXPECT_FALSE(empty->get("preferred-lifetime"));
}
// This test checks if the parameters can be inherited from the global
// scope to the subnet scope.
TEST_F(SimpleParser4Test, inheritGlobalToSubnet4) {
ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4"
"}");
ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
// we should inherit 3 parameters. Renew-timer should remain intact,
// as it was already defined in the subnet scope.
size_t num;
EXPECT_NO_THROW(num = SimpleParser4::deriveParams(global, subnet,
SimpleParser4::INHERIT_GLOBAL_TO_SUBNET4));
EXPECT_EQ(2, num);
// Check the values. 2 of them are interited, while the third one
// was already defined in the subnet, so should not be inherited.
checkIntegerValue(subnet, "renew-timer", 100);
checkIntegerValue(subnet, "rebind-timer", 2);
checkIntegerValue(subnet, "valid-lifetime", 4);
}
};
};
};

View File

@@ -3,7 +3,7 @@ SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src
AM_CPPFLAGS += $(BOOST_INCLUDES) AM_CPPFLAGS += $(BOOST_INCLUDES) -std=c++11
if HAVE_MYSQL if HAVE_MYSQL
AM_CPPFLAGS += $(MYSQL_CPPFLAGS) AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
endif endif
@@ -31,8 +31,8 @@ if GENERATE_DOCS
kea-dhcp6.8: kea-dhcp6.xml kea-dhcp6.8: kea-dhcp6.xml
@XSLTPROC@ --novalid --xinclude --nonet -o $@ \ @XSLTPROC@ --novalid --xinclude --nonet -o $@ \
http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
$(srcdir)/kea-dhcp6.xml $(srcdir)/kea-dhcp6.xml
else else
@@ -63,8 +63,8 @@ libdhcp6_la_SOURCES += dhcp6_srv.cc dhcp6_srv.h
libdhcp6_la_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h libdhcp6_la_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
libdhcp6_la_SOURCES += json_config_parser.cc json_config_parser.h libdhcp6_la_SOURCES += json_config_parser.cc json_config_parser.h
libdhcp6_la_SOURCES += dhcp6to4_ipc.cc dhcp6to4_ipc.h libdhcp6_la_SOURCES += dhcp6to4_ipc.cc dhcp6to4_ipc.h
libdhcp6_la_SOURCES += kea_controller.cc libdhcp6_la_SOURCES += kea_controller.cc
libdhcp6_la_SOURCES += simple_parser6.cc simple_parser6.h
nodist_libdhcp6_la_SOURCES = dhcp6_messages.h dhcp6_messages.cc nodist_libdhcp6_la_SOURCES = dhcp6_messages.h dhcp6_messages.cc
EXTRA_DIST += dhcp6_messages.mes EXTRA_DIST += dhcp6_messages.mes

View File

@@ -13,6 +13,7 @@
#include <dhcp/libdhcp++.h> #include <dhcp/libdhcp++.h>
#include <dhcp6/json_config_parser.h> #include <dhcp6/json_config_parser.h>
#include <dhcp6/dhcp6_log.h> #include <dhcp6/dhcp6_log.h>
#include <dhcp6/simple_parser6.h>
#include <dhcp/iface_mgr.h> #include <dhcp/iface_mgr.h>
#include <dhcpsrv/cfg_option.h> #include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfgmgr.h> #include <dhcpsrv/cfgmgr.h>
@@ -29,7 +30,6 @@
#include <dhcpsrv/parsers/host_reservation_parser.h> #include <dhcpsrv/parsers/host_reservation_parser.h>
#include <dhcpsrv/parsers/host_reservations_list_parser.h> #include <dhcpsrv/parsers/host_reservations_list_parser.h>
#include <dhcpsrv/parsers/ifaces_config_parser.h> #include <dhcpsrv/parsers/ifaces_config_parser.h>
#include <dhcpsrv/parsers/simple_parser.h>
#include <log/logger_support.h> #include <log/logger_support.h>
#include <util/encode/hex.h> #include <util/encode/hex.h>
#include <util/strutil.h> #include <util/strutil.h>
@@ -845,7 +845,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
ElementPtr mutable_cfg(new MapElement()); ElementPtr mutable_cfg(new MapElement());
mutable_cfg->setValue(values); mutable_cfg->setValue(values);
SimpleParser::setAllDefaults(mutable_cfg, true); SimpleParser6::setAllDefaults(mutable_cfg);
// Make parsers grouping. // Make parsers grouping.
const std::map<std::string, ConstElementPtr>& values_map = const std::map<std::string, ConstElementPtr>& values_map =

View File

@@ -0,0 +1,76 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <dhcp6/simple_parser6.h>
#include <cc/data.h>
#include <boost/foreach.hpp>
using namespace std;
using namespace isc::data;
namespace isc {
namespace dhcp {
/// This table defines default values for option definitions in DHCPv6
const SimpleDefaults SimpleParser6::OPTION6_DEF_DEFAULTS = {
{ "record-types", Element::string, ""},
{ "space", Element::string, "dhcp6"},
{ "array", Element::boolean, "false"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for options in DHCPv6
const SimpleDefaults SimpleParser6::OPTION6_DEFAULTS = {
{ "space", Element::string, "dhcp6"},
{ "csv-format", Element::boolean, "true"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for both DHCPv4 and DHCPv6
const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = {
{ "renew-timer", Element::integer, "900" },
{ "rebind-timer", Element::integer, "1800" },
{ "preferred-lifetime", Element::integer, "3600" },
{ "valid-lifetime", Element::integer, "7200" }
};
/// This list defines parameters that can be inherited from the global
/// scope to subnet6 scope.
const ParamsList SimpleParser6::INHERIT_GLOBAL_TO_SUBNET6 = {
"renew-timer",
"rebind-timer",
"preferred-lifetime",
"valid-lifetime"
};
size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
size_t cnt = 0;
// Set global defaults first.
cnt = setDefaults(global, GLOBAL6_DEFAULTS);
// Now set the defaults for each specified option definition
ConstElementPtr option_defs = global->get("option-def");
if (option_defs) {
BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
cnt += SimpleParser::setDefaults(option_def, OPTION6_DEF_DEFAULTS);
}
}
// Finally, set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
cnt += SimpleParser::setDefaults(single_option, OPTION6_DEFAULTS);
}
}
return (cnt);
}
};
};

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SIMPLE_PARSER6_H
#define SIMPLE_PARSER6_H
#include <cc/simple_parser.h>
namespace isc {
namespace dhcp {
class SimpleParser6 : public isc::data::SimpleParser {
public:
/// @brief Sets all defaults for DHCPv6 configuration
///
/// This method sets global, option data and option definitions defaults.
///
/// @param global scope to be filled in with defaults.
/// @return number of default values added
static size_t setAllDefaults(isc::data::ElementPtr global);
static const isc::data::SimpleDefaults OPTION6_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
};
};
};
#endif

View File

@@ -93,6 +93,7 @@ dhcp6_unittests_SOURCES += dhcp6_message_test.cc dhcp6_message_test.h
dhcp6_unittests_SOURCES += kea_controller_unittest.cc dhcp6_unittests_SOURCES += kea_controller_unittest.cc
dhcp6_unittests_SOURCES += dhcp6to4_ipc_unittest.cc dhcp6_unittests_SOURCES += dhcp6to4_ipc_unittest.cc
dhcp6_unittests_SOURCES += classify_unittests.cc dhcp6_unittests_SOURCES += classify_unittests.cc
dhcp6_unittests_SOURCES += simple_parser6_unittest.cc
nodist_dhcp6_unittests_SOURCES = marker_file.h test_libraries.h nodist_dhcp6_unittests_SOURCES = marker_file.h test_libraries.h

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2016 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <cc/data.h>
#include <dhcp6/simple_parser6.h>
#include <gtest/gtest.h>
using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
namespace {
/// @brief DHCP Parser test fixture class
class SimpleParser6Test : public ::testing::Test {
public:
/// @brief Checks if specified map has an integer parameter with expected value
///
/// @param map map to be checked
/// @param param_name name of the parameter to be checked
/// @param exp_value expected value of the parameter.
void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
int64_t exp_value) {
// First check if the passed element is a map.
ASSERT_EQ(Element::map, map->getType());
// Now try to get the element being checked
ConstElementPtr elem = map->get(param_name);
ASSERT_TRUE(elem);
// Now check if it's indeed integer
ASSERT_EQ(Element::integer, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
};
// This test checks if global defaults are properly set for DHCPv6.
TEST_F(SimpleParser6Test, globalDefaults6) {
ElementPtr empty = Element::fromJSON("{ }");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(empty));
// We expect at least 4 parameters to be inserted.
EXPECT_TRUE(num >= 4);
checkIntegerValue(empty, "valid-lifetime", 7200);
checkIntegerValue(empty, "preferred-lifetime", 3600);
checkIntegerValue(empty, "rebind-timer", 1800);
checkIntegerValue(empty, "renew-timer", 900);
}
// This test checks if the parameters can be inherited from the global
// scope to the subnet scope.
TEST_F(SimpleParser6Test, inheritGlobalToSubnet6) {
ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4"
"}");
ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
// we should inherit 3 parameters. Renew-timer should remain intact,
// as it was already defined in the subnet scope.
size_t num;
EXPECT_NO_THROW(num = SimpleParser::deriveParams(global, subnet,
SimpleParser6::INHERIT_GLOBAL_TO_SUBNET6));
EXPECT_EQ(3, num);
// Check the values. 3 of them are interited, while the fourth one
// was already defined in the subnet, so should not be inherited.
checkIntegerValue(subnet, "renew-timer", 100);
checkIntegerValue(subnet, "rebind-timer", 2);
checkIntegerValue(subnet, "preferred-lifetime", 3);
checkIntegerValue(subnet, "valid-lifetime", 4);
}
};

View File

@@ -17,7 +17,7 @@
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfg_option_def.h> #include <dhcpsrv/cfg_option_def.h>
#include <dhcpsrv/parsers/dhcp_config_parser.h> #include <dhcpsrv/parsers/dhcp_config_parser.h>
#include <dhcpsrv/parsers/simple_parser.h> #include <cc/simple_parser.h>
#include <hooks/libinfo.h> #include <hooks/libinfo.h>
#include <exceptions/exceptions.h> #include <exceptions/exceptions.h>
#include <util/optional_value.h> #include <util/optional_value.h>
@@ -536,7 +536,7 @@ private:
/// an option the configuration will not be accepted. If parsing /// an option the configuration will not be accepted. If parsing
/// is successful then an instance of an option is created and /// is successful then an instance of an option is created and
/// added to the storage provided by the calling class. /// added to the storage provided by the calling class.
class OptionDataParser : public SimpleParser { class OptionDataParser : public isc::data::SimpleParser {
public: public:
/// @brief Constructor. /// @brief Constructor.
/// ///
@@ -652,7 +652,7 @@ typedef OptionDataParser *OptionDataParserFactory(const std::string&,
/// data for a particular subnet and creates a collection of options. /// data for a particular subnet and creates a collection of options.
/// If parsing is successful, all these options are added to the Subnet /// If parsing is successful, all these options are added to the Subnet
/// object. /// object.
class OptionDataListParser : public SimpleParser { class OptionDataListParser : public isc::data::SimpleParser {
public: public:
/// @brief Constructor. /// @brief Constructor.
/// ///
@@ -679,7 +679,7 @@ typedef std::pair<isc::dhcp::OptionDefinitionPtr, std::string> OptionDefinitionT
/// @brief Parser for a single option definition. /// @brief Parser for a single option definition.
/// ///
/// This parser creates an instance of a single option definition. /// This parser creates an instance of a single option definition.
class OptionDefParser : public SimpleParser { class OptionDefParser : public isc::data::SimpleParser {
public: public:
/// @brief Constructor. /// @brief Constructor.
/// ///
@@ -706,7 +706,7 @@ private:
/// option definitions and creates instances of these definitions. /// option definitions and creates instances of these definitions.
/// If the parsing is successful, the collection of created definitions /// If the parsing is successful, the collection of created definitions
/// is put into the provided storage. /// is put into the provided storage.
class OptionDefListParser : public SimpleParser { class OptionDefListParser : public isc::data::SimpleParser {
public: public:
/// @brief Constructor. /// @brief Constructor.
/// ///

View File

@@ -8,7 +8,7 @@ AM_CPPFLAGS += -DKEA_LFC_BUILD_DIR=\"$(abs_top_builddir)/src/bin/lfc\"
AM_CPPFLAGS += -DLOGGING_SPEC_FILE=\"$(abs_top_srcdir)/src/lib/dhcpsrv/logging.spec\" AM_CPPFLAGS += -DLOGGING_SPEC_FILE=\"$(abs_top_srcdir)/src/lib/dhcpsrv/logging.spec\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS) AM_CXXFLAGS = $(KEA_CXXFLAGS) -std=c++11
if USE_STATIC_LINK if USE_STATIC_LINK
AM_LDFLAGS = -static AM_LDFLAGS = -static

View File

@@ -7,6 +7,7 @@
#include <config.h> #include <config.h>
#include <cc/command_interpreter.h> #include <cc/command_interpreter.h>
#include <cc/data.h> #include <cc/data.h>
#include <cc/simple_parser.h>
#include <dhcp/option.h> #include <dhcp/option.h>
#include <dhcp/option_custom.h> #include <dhcp/option_custom.h>
#include <dhcp/option_int.h> #include <dhcp/option_int.h>
@@ -16,7 +17,6 @@
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfg_mac_source.h> #include <dhcpsrv/cfg_mac_source.h>
#include <dhcpsrv/parsers/dhcp_parsers.h> #include <dhcpsrv/parsers/dhcp_parsers.h>
#include <dhcpsrv/parsers/simple_parser.h>
#include <dhcpsrv/tests/test_libraries.h> #include <dhcpsrv/tests/test_libraries.h>
#include <dhcpsrv/testutils/config_result_check.h> #include <dhcpsrv/testutils/config_result_check.h>
#include <exceptions/exceptions.h> #include <exceptions/exceptions.h>
@@ -412,6 +412,101 @@ public:
return (parser); return (parser);
} }
/// @brief DHCP-specific method that sets global, and option specific defaults
///
/// This method sets the defaults in the global scope, in option definitions,
/// and in option data.
///
/// @param global pointer to the Element tree that holds configuration
/// @param global_defaults array with global default values
/// @param option_defaults array with option-data default values
/// @param option_def_defaults array with default values for option definitions
/// @return number of default values inserted.
size_t setAllDefaults(isc::data::ElementPtr global,
const SimpleDefaults& global_defaults,
const SimpleDefaults& option_defaults,
const SimpleDefaults& option_def_defaults) {
size_t cnt = 0;
// Set global defaults first.
/// @todo: Uncomment as part of the ticket 5019 work.
cnt = SimpleParser::setDefaults(global, global_defaults);
// Now set option defintion defaults for each specified option definition
ConstElementPtr option_defs = global->get("option-def");
if (option_defs) {
BOOST_FOREACH(ElementPtr single_def, option_defs->listValue()) {
cnt += SimpleParser::setDefaults(single_def, option_def_defaults);
}
}
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
cnt += SimpleParser::setDefaults(single_option, option_defaults);
}
}
return (cnt);
}
/// @brief sets all default values for DHCPv4 and DHCPv6
///
/// This function largely duplicates what SimpleParser4 and SimpleParser6 classes
/// provide. However, since there are tons of unit-tests in dhcpsrv that need
/// this functionality and there are good reasons to keep those classes in
/// src/bin/dhcp{4,6}, the most straightforward way is to simply copy the
/// minimum code here. Hence this method.
///
/// @param config configuration structure to be filled with default values
/// @param v6 true = DHCPv6, false = DHCPv4
void setAllDefaults(ElementPtr config, bool v6) {
/// This table defines default values for option definitions in DHCPv6
const SimpleDefaults OPTION6_DEF_DEFAULTS = {
{ "record-types", Element::string, ""},
{ "space", Element::string, "dhcp6"},
{ "array", Element::boolean, "false"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for option definitions in DHCPv4
const SimpleDefaults OPTION4_DEF_DEFAULTS = {
{ "record-types", Element::string, ""},
{ "space", Element::string, "dhcp4"},
{ "array", Element::boolean, "false"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for options in DHCPv6
const SimpleDefaults OPTION6_DEFAULTS = {
{ "space", Element::string, "dhcp6"},
{ "csv-format", Element::boolean, "true"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for options in DHCPv4
const SimpleDefaults OPTION4_DEFAULTS = {
{ "space", Element::string, "dhcp4"},
{ "csv-format", Element::boolean, "true"},
{ "encapsulate", Element::string, "" }
};
/// This table defines default values for both DHCPv4 and DHCPv6
const SimpleDefaults GLOBAL6_DEFAULTS = {
{ "renew-timer", Element::integer, "900" },
{ "rebind-timer", Element::integer, "1800" },
{ "preferred-lifetime", Element::integer, "3600" },
{ "valid-lifetime", Element::integer, "7200" }
};
if (v6) {
setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION6_DEFAULTS,
OPTION6_DEF_DEFAULTS);
} else {
setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION4_DEFAULTS,
OPTION4_DEF_DEFAULTS);
}
}
/// @brief Convenience method for parsing a configuration /// @brief Convenience method for parsing a configuration
/// ///
/// Given a configuration string, convert it into Elements /// Given a configuration string, convert it into Elements
@@ -427,7 +522,7 @@ public:
ElementPtr json = Element::fromJSON(config); ElementPtr json = Element::fromJSON(config);
EXPECT_TRUE(json); EXPECT_TRUE(json);
if (json) { if (json) {
SimpleParser::setAllDefaults(json, v6); setAllDefaults(json, v6);
ConstElementPtr status = parseElementSet(json); ConstElementPtr status = parseElementSet(json);
ConstElementPtr comment = parseAnswer(rcode_, status); ConstElementPtr comment = parseAnswer(rcode_, status);
@@ -487,28 +582,6 @@ public:
CfgMgr::instance().setD2ClientConfig(tmp); CfgMgr::instance().setD2ClientConfig(tmp);
} }
/// @brief Checks if specified map has an integer parameter with expected value
///
/// @param map map to be checked
/// @param param_name name of the parameter to be checked
/// @param exp_value expected value of the parameter.
void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
int64_t exp_value) {
// First check if the passed element is a map.
ASSERT_EQ(Element::map, map->getType());
// Now try to get the element being checked
ConstElementPtr elem = map->get(param_name);
ASSERT_TRUE(elem);
// Now check if it's indeed integer
ASSERT_EQ(Element::integer, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
/// @brief Parsers used in the parsing of the configuration /// @brief Parsers used in the parsing of the configuration
/// ///
/// Allows the tests to interrogate the state of the parsers (if required). /// Allows the tests to interrogate the state of the parsers (if required).
@@ -2425,65 +2498,4 @@ TEST_F(ParseConfigTest, validRelayInfo6) {
// (see CtrlDhcpv4SrvTest.commandSocketBasic in // (see CtrlDhcpv4SrvTest.commandSocketBasic in
// src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc). // src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc).
// This test checks if global defaults are properly set for DHCPv6.
TEST_F(ParseConfigTest, globalDefaults6) {
ElementPtr empty = Element::fromJSON("{ }");
size_t num;
EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, true));
// We expect at least 4 parameters to be inserted.
EXPECT_TRUE(num >= 4);
checkIntegerValue(empty, "valid-lifetime", 7200);
checkIntegerValue(empty, "preferred-lifetime", 3600);
checkIntegerValue(empty, "rebind-timer", 1800);
checkIntegerValue(empty, "renew-timer", 900);
}
// This test checks if global defaults are properly set for DHCPv4.
TEST_F(ParseConfigTest, DISABLED_globalDefaults4) {
ElementPtr empty = Element::fromJSON("{ }");
size_t num;
EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, false));
// We expect at least 3 parameters to be inserted.
EXPECT_TRUE(num >= 3);
checkIntegerValue(empty, "valid-lifetime", 7200);
checkIntegerValue(empty, "rebind-timer", 1800);
checkIntegerValue(empty, "renew-timer", 900);
// Make sure that preferred-lifetime is not set for v4 (it's v6 only
// parameter)
EXPECT_FALSE(empty->get("preferred-lifetime"));
}
// This test checks if the parameters can be inherited from the global
// scope to the subnet scope.
TEST_F(ParseConfigTest, inheritGlobalToSubnet) {
ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4"
"}");
ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
// we should inherit 3 parameters. Renew-timer should remain intact,
// as it was already defined in the subnet scope.
size_t num;
EXPECT_NO_THROW(num = SimpleParser::inheritGlobalToSubnet(global, subnet));
EXPECT_EQ(3, num);
// Check the values. 3 of them are interited, while the fourth one
// was already defined in the subnet, so should not be inherited.
checkIntegerValue(subnet, "renew-timer", 100);
checkIntegerValue(subnet, "rebind-timer", 2);
checkIntegerValue(subnet, "preferred-lifetime", 3);
checkIntegerValue(subnet, "valid-lifetime", 4);
}
}; // Anonymous namespace }; // Anonymous namespace