diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll index 65184f61d4..c688dc76ed 100644 --- a/src/bin/dhcp4/dhcp4_lexer.ll +++ b/src/bin/dhcp4/dhcp4_lexer.ll @@ -135,6 +135,8 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} return isc::dhcp::Dhcp4Parser::make_SUB_HOOKS_LIBRARY(driver.loc_); case Parser4Context::PARSER_DHCP_DDNS: return isc::dhcp::Dhcp4Parser::make_SUB_DHCP_DDNS(driver.loc_); + case Parser4Context::PARSER_LOGGING: + return isc::dhcp::Dhcp4Parser::make_SUB_LOGGING(driver.loc_); } } %} @@ -580,8 +582,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} switch(driver.ctx_) { case isc::dhcp::Parser4Context::DHCP4: case isc::dhcp::Parser4Context::INTERFACES_CONFIG: - case isc::dhcp::Parser4Context::LEASE_DATABASE: - case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::SUBNET4: case isc::dhcp::Parser4Context::POOLS: case isc::dhcp::Parser4Context::SHARED_NETWORK: @@ -602,8 +602,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} switch(driver.ctx_) { case isc::dhcp::Parser4Context::DHCP4: case isc::dhcp::Parser4Context::INTERFACES_CONFIG: - case isc::dhcp::Parser4Context::LEASE_DATABASE: - case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::SUBNET4: case isc::dhcp::Parser4Context::POOLS: case isc::dhcp::Parser4Context::SHARED_NETWORK: diff --git a/src/bin/dhcp4/dhcp4_parser.yy b/src/bin/dhcp4/dhcp4_parser.yy index 3e52523137..a701979f08 100644 --- a/src/bin/dhcp4/dhcp4_parser.yy +++ b/src/bin/dhcp4/dhcp4_parser.yy @@ -206,6 +206,7 @@ using namespace std; SUB_OPTION_DATA SUB_HOOKS_LIBRARY SUB_DHCP_DDNS + SUB_LOGGING ; %token STRING "constant string" @@ -243,6 +244,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data | SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library | SUB_DHCP_DDNS { ctx.ctx_ = ctx.DHCP_DDNS; } sub_dhcp_ddns + | SUB_LOGGING { ctx.ctx_ = ctx.LOGGING; } sub_logging ; // ---- generic JSON parser --------------------------------- @@ -582,8 +584,6 @@ database_map_param: database_type | connect_timeout | contact_points | keyspace - | user_context - | comment | unknown_map_entry ; @@ -1861,6 +1861,14 @@ logging_object: LOGGING { ctx.leave(); }; +sub_logging: LCURLY_BRACKET { + // Parse the Logging map + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.push_back(m); +} logging_params RCURLY_BRACKET { + // parsing completed +}; + // This defines the list of allowed parameters that may appear // in the top-level Logging object. It can either be a single // parameter or several parameters separated by commas. diff --git a/src/bin/dhcp4/parser_context.h b/src/bin/dhcp4/parser_context.h index ee998e05f8..189d7512ae 100644 --- a/src/bin/dhcp4/parser_context.h +++ b/src/bin/dhcp4/parser_context.h @@ -86,7 +86,10 @@ public: PARSER_HOOKS_LIBRARY, /// This will parse the input as dhcp-ddns. - PARSER_DHCP_DDNS + PARSER_DHCP_DDNS, + + /// This will parse the content of Logging. + PARSER_LOGGING } ParserType; /// @brief Default constructor. diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 22f37795c4..09e84ce723 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -165,7 +166,7 @@ public: // Open port 0 means to not do anything at all. We don't want to // deal with sockets here, just check if configuration handling // is sane. - srv_.reset(new Dhcpv4Srv(0)); + srv_.reset(new ControlledDhcpv4Srv(0)); // Create fresh context. resetConfiguration(); } @@ -5612,58 +5613,84 @@ TEST_F(Dhcp4ParserTest, comments) { string config = "{\n" "\"comment\": \"A DHCPv4 server\",\n" + "\"interfaces-config\": {\n" + " \"comment\": \"Use wildcard\",\n" + " \"interfaces\": [ \"*\" ] },\n" "\"option-def\": [ {\n" + " \"comment\": \"An option definition\",\n" " \"name\": \"foo\",\n" " \"code\": 100,\n" - " \"comment\": \"An option definition\",\n" " \"type\": \"ipv4-address\",\n" " \"space\": \"isc\"\n" " } ],\n" "\"option-data\": [ {\n" - " \"name\": \"dhcp-message\",\n" " \"comment\": \"Set option value\",\n" + " \"name\": \"dhcp-message\",\n" " \"data\": \"ABCDEF0105\",\n" " \"csv-format\": false\n" " } ],\n" "\"client-classes\": [\n" " {\n" - " \"name\": \"all\",\n" " \"comment\": \"match all\",\n" + " \"name\": \"all\",\n" " \"test\": \"'' == ''\"\n" " },\n" " {\n" " \"name\": \"none\"\n" " },\n" " {\n" - " \"name\": \"two\",\n" " \"comment\": \"first comment\",\n" - " \"comment\": \"second comment\"\n" + " \"comment\": \"second comment\",\n" + " \"name\": \"two\"\n" " },\n" " {\n" - " \"name\": \"both\",\n" " \"comment\": \"a comment\",\n" + " \"name\": \"both\",\n" " \"user-context\": {\n" " \"version\": 1\n" " }\n" " }\n" " ],\n" + "\"control-socket\": {\n" + " \"comment\": \"REST API\",\n" + " \"socket-type\": \"unix\",\n" + " \"socket-name\": \"/tmp/kea4-ctrl-socket\",\n" + " \"user-context\": { \"comment\": \"Indirect comment\" }\n" + "},\n" "\"shared-networks\": [ {\n" - " \"name\": \"foo\"\n," " \"comment\": \"A shared network\"\n," + " \"name\": \"foo\"\n," " \"subnet4\": [\n" " { \n" - " \"subnet\": \"192.0.1.0/24\",\n" " \"comment\": \"A subnet\"\n," + " \"subnet\": \"192.0.1.0/24\",\n" + " \"id\": 100,\n" " \"pools\": [\n" " {\n" - " \"pool\": \"192.0.1.1-192.0.1.10\",\n" - " \"comment\": \"A pool\"\n" + " \"comment\": \"A pool\",\n" + " \"pool\": \"192.0.1.1-192.0.1.10\"\n" + " }\n" + " ],\n" + " \"reservations\": [\n" + " {\n" + " \"comment\": \"A host reservation\",\n" + " \"hw-address\": \"AA:BB:CC:DD:EE:FF\",\n" + " \"hostname\": \"foo.example.com\",\n" + " \"option-data\": [ {\n" + " \"comment\": \"An option in a reservation\",\n" + " \"name\": \"domain-name\",\n" + " \"data\": \"example.com\"\n" + " } ]\n" " }\n" " ]\n" " }\n" " ]\n" - " } ]\n" - "} \n"; + " } ],\n" + "\"dhcp-ddns\": {\n" + " \"comment\": \"No dynamic DNS\",\n" + " \"enable-updates\": false\n" + "}\n" + "}\n"; extractConfig(config); configure(config, CONTROL_RESULT_SUCCESS, ""); @@ -5675,8 +5702,20 @@ TEST_F(Dhcp4ParserTest, comments) { ASSERT_TRUE(ctx->get("comment")); EXPECT_EQ("\"A DHCPv4 server\"", ctx->get("comment")->str()); + // There is a network interface configuration. + ConstCfgIfacePtr iface = CfgMgr::instance().getStagingCfg()->getCfgIface(); + ASSERT_TRUE(iface); + + // Check network interface configuration user context. + ConstElementPtr ctx_iface = iface->getContext(); + ASSERT_TRUE(ctx_iface); + ASSERT_EQ(1, ctx_iface->size()); + ASSERT_TRUE(ctx_iface->get("comment")); + EXPECT_EQ("\"Use wildcard\"", ctx_iface->get("comment")->str()); + // There is a global option definition. - OptionDefinitionPtr opt_def = LibDHCP::getRuntimeOptionDef("isc", 100); + const OptionDefinitionPtr& opt_def = + LibDHCP::getRuntimeOptionDef("isc", 100); ASSERT_TRUE(opt_def); EXPECT_EQ("foo", opt_def->getName()); EXPECT_EQ(100, opt_def->getCode()); @@ -5692,7 +5731,7 @@ TEST_F(Dhcp4ParserTest, comments) { EXPECT_EQ("\"An option definition\"", ctx_opt_def->get("comment")->str()); // There is an option descriptor aka option data. - OptionDescriptor opt_desc = + const OptionDescriptor& opt_desc = CfgMgr::instance().getStagingCfg()->getCfgOption()-> get(DHCP4_OPTION_SPACE, DHO_DHCP_MESSAGE); ASSERT_TRUE(opt_desc.option_); @@ -5706,7 +5745,7 @@ TEST_F(Dhcp4ParserTest, comments) { EXPECT_EQ("\"Set option value\"", ctx_opt_desc->get("comment")->str()); // And there are some client classes. - ClientClassDictionaryPtr dict = + const ClientClassDictionaryPtr& dict = CfgMgr::instance().getStagingCfg()->getClientClassDictionary(); ASSERT_TRUE(dict); EXPECT_EQ(4, dict->getClasses()->size()); @@ -5752,15 +5791,34 @@ TEST_F(Dhcp4ParserTest, comments) { ASSERT_TRUE(ctx_class->get("version")); EXPECT_EQ("1", ctx_class->get("version")->str()); + // There is a control socket. + ConstElementPtr socket = + CfgMgr::instance().getStagingCfg()->getControlSocketInfo(); + ASSERT_TRUE(socket); + ASSERT_TRUE(socket->get("socket-type")); + EXPECT_EQ("\"unix\"", socket->get("socket-type")->str()); + ASSERT_TRUE(socket->get("socket-name")); + EXPECT_EQ("\"/tmp/kea4-ctrl-socket\"", socket->get("socket-name")->str()); + + // Check control socket comment and user context. + ConstElementPtr ctx_socket = socket->get("comment"); + ASSERT_TRUE(ctx_socket); + EXPECT_EQ("\"REST API\"", ctx_socket->str()); + ctx_socket = socket->get("user-context"); + ASSERT_EQ(1, ctx_socket->size()); + ASSERT_TRUE(ctx_socket->get("comment")); + EXPECT_EQ("\"Indirect comment\"", ctx_socket->get("comment")->str()); + // Now verify that the shared network was indeed configured. - CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg() - ->getCfgSharedNetworks4(); + const CfgSharedNetworks4Ptr& cfg_net = + CfgMgr::instance().getStagingCfg()->getCfgSharedNetworks4(); ASSERT_TRUE(cfg_net); const SharedNetwork4Collection* nets = cfg_net->getAll(); ASSERT_TRUE(nets); ASSERT_EQ(1, nets->size()); SharedNetwork4Ptr net = nets->at(0); ASSERT_TRUE(net); + EXPECT_EQ("foo", net->getName()); // Check shared network user context. ConstElementPtr ctx_net = net->getContext(); @@ -5770,11 +5828,13 @@ TEST_F(Dhcp4ParserTest, comments) { EXPECT_EQ("\"A shared network\"", ctx_net->get("comment")->str()); // The shared network has a subnet. - const Subnet4Collection * subs = net->getAllSubnets(); + const Subnet4Collection* subs = net->getAllSubnets(); ASSERT_TRUE(subs); ASSERT_EQ(1, subs->size()); Subnet4Ptr sub = subs->at(0); ASSERT_TRUE(sub); + EXPECT_EQ(100, sub->getID()); + EXPECT_EQ("192.0.1.0/24", sub->toText()); // Check subnet user context. ConstElementPtr ctx_sub = sub->getContext(); @@ -5795,6 +5855,66 @@ TEST_F(Dhcp4ParserTest, comments) { ASSERT_EQ(1, ctx_pool->size()); ASSERT_TRUE(ctx_pool->get("comment")); EXPECT_EQ("\"A pool\"", ctx_pool->get("comment")->str()); + + // The subnet has a host reservation. + uint8_t hw[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; + HWAddrPtr hwaddr(new HWAddr(hw, sizeof(hw), HTYPE_ETHER)); + ConstHostPtr host = + CfgMgr::instance().getStagingCfg()->getCfgHosts()->get4(100, hwaddr); + ASSERT_TRUE(host); + EXPECT_EQ(Host::IDENT_HWADDR, host->getIdentifierType()); + EXPECT_EQ("aa:bb:cc:dd:ee:ff", host->getHWAddress()->toText(false)); + EXPECT_FALSE(host->getDuid()); + EXPECT_EQ(100, host->getIPv4SubnetID()); + EXPECT_EQ(0, host->getIPv6SubnetID()); + EXPECT_EQ("foo.example.com", host->getHostname()); + + // Check host user context. + ConstElementPtr ctx_host = host->getContext(); + ASSERT_TRUE(ctx_host); + ASSERT_EQ(1, ctx_host->size()); + ASSERT_TRUE(ctx_host->get("comment")); + EXPECT_EQ("\"A host reservation\"", ctx_host->get("comment")->str()); + + // The host reservation has an option data. + ConstCfgOptionPtr opts = host->getCfgOption4(); + ASSERT_TRUE(opts); + EXPECT_FALSE(opts->empty()); + const OptionDescriptor& host_desc = + opts->get(DHCP4_OPTION_SPACE, DHO_DOMAIN_NAME); + ASSERT_TRUE(host_desc.option_); + EXPECT_EQ(DHO_DOMAIN_NAME, host_desc.option_->getType()); + + // Check embedded option data user context. + ConstElementPtr ctx_host_desc = host_desc.getContext(); + ASSERT_TRUE(ctx_host_desc); + ASSERT_EQ(1, ctx_host_desc->size()); + ASSERT_TRUE(ctx_host_desc->get("comment")); + EXPECT_EQ("\"An option in a reservation\"", + ctx_host_desc->get("comment")->str()); + + // Finally dynamic DNS update configuration. + const D2ClientConfigPtr& d2 = + CfgMgr::instance().getStagingCfg()->getD2ClientConfig(); + ASSERT_TRUE(d2); + EXPECT_FALSE(d2->getEnableUpdates()); + + // Check dynamic DNS update configuration user context. + ConstElementPtr ctx_d2 = d2->getContext(); + ASSERT_TRUE(ctx_d2); + ASSERT_EQ(1, ctx_d2->size()); + ASSERT_TRUE(ctx_d2->get("comment")); + EXPECT_EQ("\"No dynamic DNS\"", ctx_d2->get("comment")->str()); + +#if 0 + // Loggers section supports comments too. + + string logging = "{\n" + "\"loggers\": [ {\n" + " \"comment\": \"A logger\",\n" + " \"name\": \"kea-dhcp4\"\n" + "} ]\n"; +#endif } } diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc index 790fbc261e..40e7264caf 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc +++ b/src/bin/dhcp4/tests/get_config_unittest.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -1661,6 +1662,23 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " }\n" " ],\n" +" \"control-socket\": {\n" +" \"comment\": \"REST API\",\n" +" \"socket-name\": \"/tmp/kea4-ctrl-socket\",\n" +" \"socket-type\": \"unix\",\n" +" \"user-context\": {\n" +" \"comment\": \"Indirect comment\"\n" +" }\n" +" },\n" +" \"dhcp-ddns\": {\n" +" \"comment\": \"No dynamic DNS\",\n" +" \"enable-updates\": false\n" +" },\n" +" \"interfaces-config\": {\n" +" \"comment\": \"Use wildcard\",\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" " \"option-data\": [\n" " {\n" " \"comment\": \"Set option value\",\n" @@ -1685,12 +1703,27 @@ const char* EXTRACTED_CONFIGS[] = { " \"subnet4\": [\n" " {\n" " \"comment\": \"A subnet\",\n" +" \"id\": 100,\n" " \"pools\": [\n" " {\n" " \"comment\": \"A pool\",\n" " \"pool\": \"192.0.1.1-192.0.1.10\"\n" " }\n" " ],\n" +" \"reservations\": [\n" +" {\n" +" \"comment\": \"A host reservation\",\n" +" \"hostname\": \"foo.example.com\",\n" +" \"hw-address\": \"AA:BB:CC:DD:EE:FF\",\n" +" \"option-data\": [\n" +" {\n" +" \"comment\": \"An option in a reservation\",\n" +" \"data\": \"example.com\",\n" +" \"name\": \"domain-name\"\n" +" }\n" +" ]\n" +" }\n" +" ],\n" " \"subnet\": \"192.0.1.0/24\"\n" " }\n" " ]\n" @@ -6384,8 +6417,17 @@ const char* UNPARSED_CONFIGS[] = { " \"server-hostname\": \"\"\n" " }\n" " ],\n" +" \"control-socket\": {\n" +" \"comment\": \"REST API\",\n" +" \"socket-name\": \"/tmp/kea4-ctrl-socket\",\n" +" \"socket-type\": \"unix\",\n" +" \"user-context\": {\n" +" \"comment\": \"Indirect comment\"\n" +" }\n" +" },\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" +" \"comment\": \"No dynamic DNS\",\n" " \"always-include-fqdn\": false,\n" " \"enable-updates\": false,\n" " \"generated-prefix\": \"myhost\",\n" @@ -6414,7 +6456,8 @@ const char* UNPARSED_CONFIGS[] = { " \"hooks-libraries\": [ ],\n" " \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n" " \"interfaces-config\": {\n" -" \"interfaces\": [ ],\n" +" \"comment\": \"Use wildcard\",\n" +" \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" " },\n" " \"lease-database\": {\n" @@ -6462,7 +6505,7 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" " \"boot-file-name\": \"\",\n" -" \"id\": 1,\n" +" \"id\": 100,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" " \"option-data\": [ ],\n" @@ -6584,7 +6627,7 @@ public: // Open port 0 means to not do anything at all. We don't want to // deal with sockets here, just check if configuration handling // is sane. - srv_.reset(new Dhcpv4Srv(0)); + srv_.reset(new ControlledDhcpv4Srv(0)); // Create fresh context. resetConfiguration(); } @@ -6686,7 +6729,7 @@ public: CfgMgr::instance().setFamily(AF_INET); } - boost::scoped_ptr srv_; ///< DHCP4 server under test + boost::scoped_ptr srv_; ///< DHCP4 server under test int rcode_; ///< Return code from element parsing ConstElementPtr comment_; ///< Reason for parse fail }; diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc.skel b/src/bin/dhcp4/tests/get_config_unittest.cc.skel index f5bec0e103..4a0242c7d6 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc.skel +++ b/src/bin/dhcp4/tests/get_config_unittest.cc.skel @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -168,7 +169,7 @@ public: // Open port 0 means to not do anything at all. We don't want to // deal with sockets here, just check if configuration handling // is sane. - srv_.reset(new Dhcpv4Srv(0)); + srv_.reset(new ControlledDhcpv4Srv(0)); // Create fresh context. resetConfiguration(); } @@ -270,7 +271,7 @@ public: CfgMgr::instance().setFamily(AF_INET); } - boost::scoped_ptr srv_; ///< DHCP4 server under test + boost::scoped_ptr srv_; ///< DHCP4 server under test int rcode_; ///< Return code from element parsing ConstElementPtr comment_; ///< Reason for parse fail }; diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 38de3af809..ddfb8e39c2 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -137,6 +137,8 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} return isc::dhcp::Dhcp6Parser::make_SUB_HOOKS_LIBRARY(driver.loc_); case Parser6Context::PARSER_DHCP_DDNS: return isc::dhcp::Dhcp6Parser::make_SUB_DHCP_DDNS(driver.loc_); + case Parser6Context::PARSER_LOGGING: + return isc::dhcp::Dhcp6Parser::make_SUB_LOGGING(driver.loc_); } } %} @@ -810,8 +812,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: case isc::dhcp::Parser6Context::INTERFACES_CONFIG: - case isc::dhcp::Parser6Context::LEASE_DATABASE: - case isc::dhcp::Parser6Context::HOSTS_DATABASE: case isc::dhcp::Parser6Context::SUBNET6: case isc::dhcp::Parser6Context::SHARED_NETWORK: case isc::dhcp::Parser6Context::OPTION_DEF: @@ -834,8 +834,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} switch(driver.ctx_) { case isc::dhcp::Parser6Context::DHCP6: case isc::dhcp::Parser6Context::INTERFACES_CONFIG: - case isc::dhcp::Parser6Context::LEASE_DATABASE: - case isc::dhcp::Parser6Context::HOSTS_DATABASE: case isc::dhcp::Parser6Context::SUBNET6: case isc::dhcp::Parser6Context::SHARED_NETWORK: case isc::dhcp::Parser6Context::OPTION_DEF: diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index 687aa99ea4..f7bb059294 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -210,6 +210,7 @@ using namespace std; SUB_OPTION_DATA SUB_HOOKS_LIBRARY SUB_DHCP_DDNS + SUB_LOGGING ; %token STRING "constant string" @@ -247,6 +248,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data | SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library | SUB_DHCP_DDNS { ctx.ctx_ = ctx.DHCP_DDNS; } sub_dhcp_ddns + | SUB_LOGGING { ctx.ctx_ = ctx.LOGGING; } sub_logging ; // ---- generic JSON parser --------------------------------- @@ -552,8 +554,6 @@ database_map_param: database_type | connect_timeout | contact_points | keyspace - | user_context - | comment | unknown_map_entry ; @@ -1945,6 +1945,14 @@ logging_object: LOGGING { ctx.leave(); }; +sub_logging: LCURLY_BRACKET { + // Parse the Logging map + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.push_back(m); +} logging_params RCURLY_BRACKET { + // parsing completed +}; + // This defines the list of allowed parameters that may appear // in the top-level Logging object. It can either be a single // parameter or several parameters separated by commas. diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index 63f4b882c4..9cca5e630f 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -89,7 +89,11 @@ public: PARSER_HOOKS_LIBRARY, /// This will parse the input as dhcp-ddns. (D2 client config) - PARSER_DHCP_DDNS + PARSER_DHCP_DDNS, + + /// This will parse the content of Logging. + PARSER_LOGGING + } ParserType; /// @brief Default constructor. diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index ad0aab9de6..0d062321e9 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -812,8 +813,8 @@ public: EXPECT_TRUE(pool); } - int rcode_; ///< Return code (see @ref isc::config::parseAnswer) - Dhcpv6Srv srv_; ///< Instance of the Dhcp6Srv used during tests + int rcode_; ///< Return code (see @ref isc::config::parseAnswer) + ControlledDhcpv6Srv srv_; ///< Instance of the ControlledDhcp6Srv used during tests ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer) string valid_iface_; ///< Valid network interface name (present in system) string bogus_iface_; ///< invalid network interface name (not in system) @@ -6054,66 +6055,96 @@ TEST_F(Dhcp6ParserTest, comments) { string config = "{\n" "\"comment\": \"A DHCPv6 server\",\n" + "\"server-id\": {\n" + " \"comment\": \"DHCPv6 specific\",\n" + " \"type\": \"LL\"\n" + "},\n" + "\"interfaces-config\": {\n" + " \"comment\": \"Use wildcard\",\n" + " \"interfaces\": [ \"*\" ] },\n" "\"option-def\": [ {\n" + " \"comment\": \"An option definition\",\n" " \"name\": \"foo\",\n" " \"code\": 100,\n" - " \"comment\": \"An option definition\",\n" " \"type\": \"ipv6-address\",\n" " \"space\": \"isc\"\n" " } ],\n" "\"option-data\": [ {\n" - " \"name\": \"subscriber-id\",\n" " \"comment\": \"Set option value\",\n" + " \"name\": \"subscriber-id\",\n" " \"data\": \"ABCDEF0105\",\n" " \"csv-format\": false\n" " } ],\n" "\"client-classes\": [\n" " {\n" - " \"name\": \"all\",\n" " \"comment\": \"match all\",\n" + " \"name\": \"all\",\n" " \"test\": \"'' == ''\"\n" " },\n" " {\n" " \"name\": \"none\"\n" " },\n" " {\n" - " \"name\": \"two\",\n" " \"comment\": \"first comment\",\n" - " \"comment\": \"second comment\"\n" + " \"comment\": \"second comment\",\n" + " \"name\": \"two\"\n" " },\n" " {\n" - " \"name\": \"both\",\n" " \"comment\": \"a comment\",\n" + " \"name\": \"both\",\n" " \"user-context\": {\n" " \"version\": 1\n" " }\n" " }\n" " ],\n" + "\"control-socket\": {\n" + " \"comment\": \"REST API\",\n" + " \"socket-type\": \"unix\",\n" + " \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n" + " \"user-context\": { \"comment\": \"Indirect comment\" }\n" + "},\n" "\"shared-networks\": [ {\n" - " \"name\": \"foo\"\n," " \"comment\": \"A shared network\"\n," + " \"name\": \"foo\"\n," " \"subnet6\": [\n" " { \n" - " \"subnet\": \"2001:db1::/48\",\n" " \"comment\": \"A subnet\"\n," + " \"subnet\": \"2001:db1::/48\",\n" + " \"id\": 100,\n" " \"pools\": [\n" " {\n" - " \"pool\": \"2001:db1::/64\",\n" - " \"comment\": \"A pool\"\n" + " \"comment\": \"A pool\",\n" + " \"pool\": \"2001:db1::/64\"\n" " }\n" " ],\n" " \"pd-pools\": [\n" " {\n" + " \"comment\": \"A prefix pool\",\n" " \"prefix\": \"2001:db2::\",\n" " \"prefix-len\": 48,\n" - " \"delegated-len\": 64,\n" - " \"comment\": \"A prefix pool\"\n" + " \"delegated-len\": 64\n" + " }\n" + " ],\n" + " \"reservations\": [\n" + " {\n" + " \"comment\": \"A host reservation\",\n" + " \"hw-address\": \"AA:BB:CC:DD:EE:FF\",\n" + " \"hostname\": \"foo.example.com\",\n" + " \"option-data\": [ {\n" + " \"comment\": \"An option in a reservation\",\n" + " \"name\": \"domain-search\",\n" + " \"data\": \"example.com\"\n" + " } ]\n" " }\n" " ]\n" " }\n" " ]\n" - " } ]\n" - "} \n"; + " } ],\n" + "\"dhcp-ddns\": {\n" + " \"comment\": \"No dynamic DNS\",\n" + " \"enable-updates\": false\n" + "}\n" + "}\n"; extractConfig(config); configure(config, CONTROL_RESULT_SUCCESS, ""); @@ -6125,8 +6156,32 @@ TEST_F(Dhcp6ParserTest, comments) { ASSERT_TRUE(ctx->get("comment")); EXPECT_EQ("\"A DHCPv6 server\"", ctx->get("comment")->str()); + // There is a server id. + ConstCfgDUIDPtr duid = CfgMgr::instance().getStagingCfg()->getCfgDUID(); + ASSERT_TRUE(duid); + EXPECT_EQ(DUID::DUID_LL, duid->getType()); + + // Check server id user context. + ConstElementPtr ctx_duid = duid->getContext(); + ASSERT_TRUE(ctx_duid); + ASSERT_EQ(1, ctx_duid->size()); + ASSERT_TRUE(ctx_duid->get("comment")); + EXPECT_EQ("\"DHCPv6 specific\"", ctx_duid->get("comment")->str()); + + // There is a network interface configuration. + ConstCfgIfacePtr iface = CfgMgr::instance().getStagingCfg()->getCfgIface(); + ASSERT_TRUE(iface); + + // Check network interface configuration user context. + ConstElementPtr ctx_iface = iface->getContext(); + ASSERT_TRUE(ctx_iface); + ASSERT_EQ(1, ctx_iface->size()); + ASSERT_TRUE(ctx_iface->get("comment")); + EXPECT_EQ("\"Use wildcard\"", ctx_iface->get("comment")->str()); + // There is a global option definition. - OptionDefinitionPtr opt_def = LibDHCP::getRuntimeOptionDef("isc", 100); + const OptionDefinitionPtr& opt_def = + LibDHCP::getRuntimeOptionDef("isc", 100); ASSERT_TRUE(opt_def); EXPECT_EQ("foo", opt_def->getName()); EXPECT_EQ(100, opt_def->getCode()); @@ -6142,7 +6197,7 @@ TEST_F(Dhcp6ParserTest, comments) { EXPECT_EQ("\"An option definition\"", ctx_opt_def->get("comment")->str()); // There is an option descriptor aka option data. - OptionDescriptor opt_desc = + const OptionDescriptor& opt_desc = CfgMgr::instance().getStagingCfg()->getCfgOption()-> get(DHCP6_OPTION_SPACE, D6O_SUBSCRIBER_ID); ASSERT_TRUE(opt_desc.option_); @@ -6156,7 +6211,7 @@ TEST_F(Dhcp6ParserTest, comments) { EXPECT_EQ("\"Set option value\"", ctx_opt_desc->get("comment")->str()); // And there there are some client classes. - ClientClassDictionaryPtr dict = + const ClientClassDictionaryPtr& dict = CfgMgr::instance().getStagingCfg()->getClientClassDictionary(); ASSERT_TRUE(dict); EXPECT_EQ(4, dict->getClasses()->size()); @@ -6202,15 +6257,34 @@ TEST_F(Dhcp6ParserTest, comments) { ASSERT_TRUE(ctx_class->get("version")); EXPECT_EQ("1", ctx_class->get("version")->str()); + // There is a control socket. + ConstElementPtr socket = + CfgMgr::instance().getStagingCfg()->getControlSocketInfo(); + ASSERT_TRUE(socket); + ASSERT_TRUE(socket->get("socket-type")); + EXPECT_EQ("\"unix\"", socket->get("socket-type")->str()); + ASSERT_TRUE(socket->get("socket-name")); + EXPECT_EQ("\"/tmp/kea6-ctrl-socket\"", socket->get("socket-name")->str()); + + // Check control socket comment and user context. + ConstElementPtr ctx_socket = socket->get("comment"); + ASSERT_TRUE(ctx_socket); + EXPECT_EQ("\"REST API\"", ctx_socket->str()); + ctx_socket = socket->get("user-context"); + ASSERT_EQ(1, ctx_socket->size()); + ASSERT_TRUE(ctx_socket->get("comment")); + EXPECT_EQ("\"Indirect comment\"", ctx_socket->get("comment")->str()); + // Now verify that the shared network was indeed configured. - CfgSharedNetworks6Ptr cfg_net = CfgMgr::instance().getStagingCfg() - ->getCfgSharedNetworks6(); + const CfgSharedNetworks6Ptr& cfg_net = + CfgMgr::instance().getStagingCfg()->getCfgSharedNetworks6(); ASSERT_TRUE(cfg_net); const SharedNetwork6Collection* nets = cfg_net->getAll(); ASSERT_TRUE(nets); ASSERT_EQ(1, nets->size()); SharedNetwork6Ptr net = nets->at(0); ASSERT_TRUE(net); + EXPECT_EQ("foo", net->getName()); // Check shared network user context. ConstElementPtr ctx_net = net->getContext(); @@ -6220,7 +6294,7 @@ TEST_F(Dhcp6ParserTest, comments) { EXPECT_EQ("\"A shared network\"", ctx_net->get("comment")->str()); // The shared network has a subnet. - const Subnet6Collection * subs = net->getAllSubnets(); + const Subnet6Collection* subs = net->getAllSubnets(); ASSERT_TRUE(subs); ASSERT_EQ(1, subs->size()); Subnet6Ptr sub = subs->at(0); @@ -6232,6 +6306,8 @@ TEST_F(Dhcp6ParserTest, comments) { ASSERT_EQ(1, ctx_sub->size()); ASSERT_TRUE(ctx_sub->get("comment")); EXPECT_EQ("\"A subnet\"", ctx_sub->get("comment")->str()); + EXPECT_EQ(100, sub->getID()); + EXPECT_EQ("2001:db1::/48", sub->toText()); // The subnet has a pool. const PoolCollection& pools = sub->getPools(Lease::TYPE_NA); @@ -6258,6 +6334,66 @@ TEST_F(Dhcp6ParserTest, comments) { ASSERT_EQ(1, ctx_pdpool->size()); ASSERT_TRUE(ctx_pdpool->get("comment")); EXPECT_EQ("\"A prefix pool\"", ctx_pdpool->get("comment")->str()); + + // The subnet has a host reservation. + uint8_t hw[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; + HWAddrPtr hwaddr(new HWAddr(hw, sizeof(hw), HTYPE_ETHER)); + ConstHostPtr host = + CfgMgr::instance().getStagingCfg()->getCfgHosts()->get6(100, DuidPtr(), hwaddr); + ASSERT_TRUE(host); + EXPECT_EQ(Host::IDENT_HWADDR, host->getIdentifierType()); + EXPECT_EQ("aa:bb:cc:dd:ee:ff", host->getHWAddress()->toText(false)); + EXPECT_FALSE(host->getDuid()); + EXPECT_EQ(0, host->getIPv4SubnetID()); + EXPECT_EQ(100, host->getIPv6SubnetID()); + EXPECT_EQ("foo.example.com", host->getHostname()); + + // Check host user context. + ConstElementPtr ctx_host = host->getContext(); + ASSERT_TRUE(ctx_host); + ASSERT_EQ(1, ctx_host->size()); + ASSERT_TRUE(ctx_host->get("comment")); + EXPECT_EQ("\"A host reservation\"", ctx_host->get("comment")->str()); + + // The host reservation has an option data. + ConstCfgOptionPtr opts = host->getCfgOption6(); + ASSERT_TRUE(opts); + EXPECT_FALSE(opts->empty()); + const OptionDescriptor& host_desc = + opts->get(DHCP6_OPTION_SPACE, D6O_DOMAIN_SEARCH); + ASSERT_TRUE(host_desc.option_); + EXPECT_EQ(D6O_DOMAIN_SEARCH, host_desc.option_->getType()); + + // Check embedded option data user context. + ConstElementPtr ctx_host_desc = host_desc.getContext(); + ASSERT_TRUE(ctx_host_desc); + ASSERT_EQ(1, ctx_host_desc->size()); + ASSERT_TRUE(ctx_host_desc->get("comment")); + EXPECT_EQ("\"An option in a reservation\"", + ctx_host_desc->get("comment")->str()); + + // Finally dynamic DNS update configuration. + const D2ClientConfigPtr& d2 = + CfgMgr::instance().getStagingCfg()->getD2ClientConfig(); + ASSERT_TRUE(d2); + EXPECT_FALSE(d2->getEnableUpdates()); + + // Check dynamic DNS update configuration user context. + ConstElementPtr ctx_d2 = d2->getContext(); + ASSERT_TRUE(ctx_d2); + ASSERT_EQ(1, ctx_d2->size()); + ASSERT_TRUE(ctx_d2->get("comment")); + EXPECT_EQ("\"No dynamic DNS\"", ctx_d2->get("comment")->str()); + +#if 0 + // Loggers section supports comments too. + + string logging = "{\n" + "\"loggers\": [ {\n" + " \"comment\": \"A logger\",\n" + " \"name\": \"kea-dhcp6\"\n" + "} ]\n"; +#endif } }; diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc index 5087aaa73e..298e71647d 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc +++ b/src/bin/dhcp6/tests/get_config_unittest.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -1531,6 +1532,23 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " }\n" " ],\n" +" \"control-socket\": {\n" +" \"comment\": \"REST API\",\n" +" \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n" +" \"socket-type\": \"unix\",\n" +" \"user-context\": {\n" +" \"comment\": \"Indirect comment\"\n" +" }\n" +" },\n" +" \"dhcp-ddns\": {\n" +" \"comment\": \"No dynamic DNS\",\n" +" \"enable-updates\": false\n" +" },\n" +" \"interfaces-config\": {\n" +" \"comment\": \"Use wildcard\",\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" " \"option-data\": [\n" " {\n" " \"comment\": \"Set option value\",\n" @@ -1548,6 +1566,10 @@ const char* EXTRACTED_CONFIGS[] = { " \"type\": \"ipv6-address\"\n" " }\n" " ],\n" +" \"server-id\": {\n" +" \"comment\": \"DHCPv6 specific\",\n" +" \"type\": \"LL\"\n" +" },\n" " \"shared-networks\": [\n" " {\n" " \"comment\": \"A shared network\",\n" @@ -1555,6 +1577,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"subnet6\": [\n" " {\n" " \"comment\": \"A subnet\",\n" +" \"id\": 100,\n" " \"pd-pools\": [\n" " {\n" " \"comment\": \"A prefix pool\",\n" @@ -1569,6 +1592,20 @@ const char* EXTRACTED_CONFIGS[] = { " \"pool\": \"2001:db1::/64\"\n" " }\n" " ],\n" +" \"reservations\": [\n" +" {\n" +" \"comment\": \"A host reservation\",\n" +" \"hostname\": \"foo.example.com\",\n" +" \"hw-address\": \"AA:BB:CC:DD:EE:FF\",\n" +" \"option-data\": [\n" +" {\n" +" \"comment\": \"An option in a reservation\",\n" +" \"data\": \"example.com\",\n" +" \"name\": \"domain-search\"\n" +" }\n" +" ]\n" +" }\n" +" ],\n" " \"subnet\": \"2001:db1::/48\"\n" " }\n" " ]\n" @@ -5974,8 +6011,17 @@ const char* UNPARSED_CONFIGS[] = { " \"option-data\": [ ]\n" " }\n" " ],\n" +" \"control-socket\": {\n" +" \"comment\": \"REST API\",\n" +" \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n" +" \"socket-type\": \"unix\",\n" +" \"user-context\": {\n" +" \"comment\": \"Indirect comment\"\n" +" }\n" +" },\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" +" \"comment\": \"No dynamic DNS\",\n" " \"always-include-fqdn\": false,\n" " \"enable-updates\": false,\n" " \"generated-prefix\": \"myhost\",\n" @@ -6003,7 +6049,8 @@ const char* UNPARSED_CONFIGS[] = { " \"hooks-libraries\": [ ],\n" " \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n" " \"interfaces-config\": {\n" -" \"interfaces\": [ ],\n" +" \"comment\": \"Use wildcard\",\n" +" \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" " },\n" " \"lease-database\": {\n" @@ -6035,12 +6082,13 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"relay-supplied-options\": [ \"65\" ],\n" " \"server-id\": {\n" +" \"comment\": \"DHCPv6 specific\",\n" " \"enterprise-id\": 0,\n" " \"htype\": 0,\n" " \"identifier\": \"\",\n" " \"persist\": true,\n" " \"time\": 0,\n" -" \"type\": \"LLT\"\n" +" \"type\": \"LL\"\n" " },\n" " \"shared-networks\": [\n" " {\n" @@ -6058,7 +6106,7 @@ const char* UNPARSED_CONFIGS[] = { " \"subnet6\": [\n" " {\n" " \"comment\": \"A subnet\",\n" -" \"id\": 1,\n" +" \"id\": 100,\n" " \"option-data\": [ ],\n" " \"pd-pools\": [\n" " {\n" @@ -6293,8 +6341,8 @@ public: CfgMgr::instance().setFamily(AF_INET6); } - int rcode_; ///< Return code (see @ref isc::config::parseAnswer) - Dhcpv6Srv srv_; ///< Instance of the Dhcp6Srv used during tests + int rcode_; ///< Return code (see @ref isc::config::parseAnswer) + ControlledDhcpv6Srv srv_; ///< Instance of the ControlledDhcp6Srv used during tests ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer) }; diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc.skel b/src/bin/dhcp6/tests/get_config_unittest.cc.skel index efb2accc4e..50c71cd53d 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc.skel +++ b/src/bin/dhcp6/tests/get_config_unittest.cc.skel @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -274,8 +275,8 @@ public: CfgMgr::instance().setFamily(AF_INET6); } - int rcode_; ///< Return code (see @ref isc::config::parseAnswer) - Dhcpv6Srv srv_; ///< Instance of the Dhcp6Srv used during tests + int rcode_; ///< Return code (see @ref isc::config::parseAnswer) + ControlledDhcpv6Srv srv_; ///< Instance of the ControlledDhcp6Srv used during tests ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer) }; diff --git a/src/lib/dhcpsrv/cfg_db_access.cc b/src/lib/dhcpsrv/cfg_db_access.cc index 53ae5001c4..e93631dc7b 100644 --- a/src/lib/dhcpsrv/cfg_db_access.cc +++ b/src/lib/dhcpsrv/cfg_db_access.cc @@ -65,12 +65,12 @@ CfgDbAccess::getAccessString(const std::string& access_string) const { return (s.str()); } -void -CfgDbAccess::toElementDbAccessString(const std::string& dbaccess, - ElementPtr map) { +ElementPtr +CfgDbAccess::toElementDbAccessString(const std::string& dbaccess) { + ElementPtr result = Element::createMap(); // Code from DatabaseConnection::parse if (dbaccess.empty()) { - return; + return (result); } std::vector tokens; boost::split(tokens, dbaccess, boost::is_any_of(std::string("\t "))); @@ -86,7 +86,7 @@ CfgDbAccess::toElementDbAccessString(const std::string& dbaccess, int64_t int_value; try { int_value = boost::lexical_cast(value); - map->set(keyword, Element::create(int_value)); + result->set(keyword, Element::create(int_value)); } catch (...) { isc_throw(ToElementError, "invalid DB access " << "integer parameter: " @@ -95,9 +95,9 @@ CfgDbAccess::toElementDbAccessString(const std::string& dbaccess, } else if ((keyword == "persist") || (keyword == "readonly")) { if (value == "true") { - map->set(keyword, Element::create(true)); + result->set(keyword, Element::create(true)); } else if (value == "false") { - map->set(keyword, Element::create(false)); + result->set(keyword, Element::create(false)); } else { isc_throw(ToElementError, "invalid DB access " << "boolean parameter: " @@ -110,7 +110,7 @@ CfgDbAccess::toElementDbAccessString(const std::string& dbaccess, (keyword == "name") || (keyword == "contact_points") || (keyword == "keyspace")) { - map->set(keyword, Element::create(value)); + result->set(keyword, Element::create(value)); } else { isc_throw(ToElementError, "unknown DB access parameter: " << keyword << "=" << value); @@ -120,23 +120,6 @@ CfgDbAccess::toElementDbAccessString(const std::string& dbaccess, << ", expected format is name=value"); } } -} - -ElementPtr -CfgLeaseDbAccess::toElement() const { - ElementPtr result = Element::createMap(); - // Add user context - contextToElement(result); - CfgDbAccess::toElementDbAccessString(lease_db_access_, result); - return (result); -} - -ElementPtr -CfgHostDbAccess::toElement() const { - ElementPtr result = Element::createMap(); - // Add user context - contextToElement(result); - CfgDbAccess::toElementDbAccessString(host_db_access_, result); return (result); } diff --git a/src/lib/dhcpsrv/cfg_db_access.h b/src/lib/dhcpsrv/cfg_db_access.h index b74e94cc7f..2c87e4dafc 100644 --- a/src/lib/dhcpsrv/cfg_db_access.h +++ b/src/lib/dhcpsrv/cfg_db_access.h @@ -8,7 +8,6 @@ #define CFG_DBACCESS_H #include -#include #include #include @@ -20,7 +19,7 @@ namespace dhcp { /// /// The database access strings use the same format as the strings /// passed to the @ref isc::dhcp::LeaseMgrFactory::create function. -class CfgDbAccess : public UserContext { +class CfgDbAccess { public: /// @brief Constructor. @@ -68,10 +67,9 @@ public: /// @brief Unparse an access string /// /// @param dbaccess the database access string - /// @param map the element map where the access string is unparse - static void - toElementDbAccessString(const std::string& dbaccess, - isc::data::ElementPtr map); + /// @return a pointer to configuration + static + isc::data::ElementPtr toElementDbAccessString(const std::string& dbaccess); protected: @@ -108,7 +106,9 @@ struct CfgLeaseDbAccess : public CfgDbAccess, public isc::data::CfgToElement { /// @ref isc::data::CfgToElement::toElement /// /// @result a pointer to a configuration - virtual isc::data::ElementPtr toElement() const; + virtual isc::data::ElementPtr toElement() const { + return (CfgDbAccess::toElementDbAccessString(lease_db_access_)); + } }; struct CfgHostDbAccess : public CfgDbAccess, public isc::data::CfgToElement { @@ -120,9 +120,12 @@ struct CfgHostDbAccess : public CfgDbAccess, public isc::data::CfgToElement { /// @ref isc::data::CfgToElement::toElement /// /// @result a pointer to a configuration - virtual isc::data::ElementPtr toElement() const; + virtual isc::data::ElementPtr toElement() const { + return (CfgDbAccess::toElementDbAccessString(host_db_access_)); + } }; } } + #endif // CFG_DBACCESS_H diff --git a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc index db54bbd137..e4231dc1e2 100644 --- a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc +++ b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc @@ -56,7 +56,6 @@ DbAccessParser::parse(CfgDbAccessPtr& cfg_db, int64_t lfc_interval = 0; int64_t timeout = 0; int64_t port = 0; - ConstElementPtr user_context; // 2. Update the copy with the passed keywords. BOOST_FOREACH(ConfigPair param, database_config->mapValue()) { try { @@ -79,9 +78,6 @@ DbAccessParser::parse(CfgDbAccessPtr& cfg_db, values_copy[param.first] = boost::lexical_cast(port); - } else if (param.first == "user-context") { - user_context = param.second; - } else { values_copy[param.first] = param.second->stringValue(); } @@ -162,9 +158,6 @@ DbAccessParser::parse(CfgDbAccessPtr& cfg_db, cfg_db->setHostDbAccessString(getDbAccessString()); } - if (user_context) { - cfg_db->setContext(user_context); - } } // Create the database access string diff --git a/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc b/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc index 4b86a32fd4..cc8361ae50 100644 --- a/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc @@ -19,7 +19,6 @@ using namespace isc; using namespace isc::dhcp; using namespace isc::dhcp::test; using namespace isc::test; -using namespace isc::data; namespace { @@ -52,12 +51,6 @@ TEST(CfgDbAccessTest, setLeaseDbAccessString) { // Additional parameters are not in lease_db_access_ runToElementTest(expected, CfgLeaseDbAccess(cfg)); - // Add and check user context - std::string user_context = "{ \"foo\": \"bar\" }"; - cfg.setContext(Element::fromJSON(user_context)); - expected = "{ \"user-context\": { \"foo\": \"bar\" }, \"type\": \"mysql\" }"; - runToElementTest(expected, CfgLeaseDbAccess(cfg)); - // If access string is empty, no parameters will be appended. ASSERT_NO_THROW(cfg.setLeaseDbAccessString("")); EXPECT_TRUE(cfg.getLeaseDbAccessString().empty()); @@ -82,12 +75,6 @@ TEST(CfgDbAccessTest, setHostDbAccessString) { // Additional parameters are not in host_db_access_ runToElementTest(expected, CfgHostDbAccess(cfg)); - // Add and check user context - std::string user_context = "{ \"foo\": \"bar\" }"; - cfg.setContext(Element::fromJSON(user_context)); - expected = "{ \"user-context\": { \"foo\": \"bar\" }, \"type\": \"mysql\" }"; - runToElementTest(expected, CfgHostDbAccess(cfg)); - // If access string is empty, no parameters will be appended. ASSERT_NO_THROW(cfg.setHostDbAccessString("")); EXPECT_TRUE(cfg.getHostDbAccessString().empty()); diff --git a/src/lib/testutils/user_context_utils.cc b/src/lib/testutils/user_context_utils.cc index e6eb52b334..fc2e363276 100644 --- a/src/lib/testutils/user_context_utils.cc +++ b/src/lib/testutils/user_context_utils.cc @@ -78,6 +78,9 @@ EP moveComments1(EP element) { } else if (it->first == "user-context") { // Do not traverse user-context entries result->set("user-context", it->second); + } else if (it->first == "control-socket") { + // Do not traverse control-socke entries + result->set("control-socket", it->second); } else { // Not comment or user-context try { @@ -171,6 +174,9 @@ EP extractComments1(EP element) { if (it->first == "comment") { // Do not traverse comment entries result->set("comment", it->second); + } else if (it->first == "control-socket") { + // Do not traverse control-socke entries + result->set("control-socket", it->second); } else if (it->first == "user-context") { if (it->second->contains("comment")) { // Note there is a entry to move