// Parse Host Reservations for this subnet if any.
ConstElementPtr reservations = subnet->get("reservations");
if (reservations) {
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser4> parser;
- parser.parse(subnet_->getID(), reservations);
+ parser.parse(subnet_->getID(), reservations, hosts);
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
}
return (sn4ptr);
// Parse Host Reservations for this subnet if any.
ConstElementPtr reservations = subnet->get("reservations");
if (reservations) {
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser6> parser;
- parser.parse(subnet_->getID(), reservations);
+ parser.parse(subnet_->getID(), reservations, hosts);
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
}
return (sn6ptr);
namespace isc {
namespace dhcp {
-void
+HostPtr
HostReservationParser::parse(const SubnetID& subnet_id,
isc::data::ConstElementPtr reservation_data) {
- parseInternal(subnet_id, reservation_data);
+ return (parseInternal(subnet_id, reservation_data));
}
-void
+HostPtr
HostReservationParser::parseInternal(const SubnetID&,
isc::data::ConstElementPtr reservation_data) {
std::string identifier;
std::string identifier_name;
std::string hostname;
+ HostPtr host;
try {
// Gather those parameters that are common for both IPv4 and IPv6
}
// Create a host object from the basic parameters we already parsed.
- host_.reset(new Host(identifier, identifier_name, SubnetID(0),
+ host.reset(new Host(identifier, identifier_name, SubnetID(0),
SubnetID(0), IOAddress("0.0.0.0"), hostname));
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, ex.what() << " ("
<< reservation_data->getPosition() << ")");
}
-}
-
-void
-HostReservationParser::addHost(isc::data::ConstElementPtr reservation_data) {
- try {
- CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host_);
- } catch (const std::exception& ex) {
- // Append line number to the exception string.
- isc_throw(DhcpConfigError, ex.what() << " ("
- << reservation_data->getPosition() << ")");
- }
+ return (host);
}
bool
return (getSupportedParameters(false).count(param_name) > 0);
}
-void
+HostPtr
HostReservationParser4::parseInternal(const SubnetID& subnet_id,
isc::data::ConstElementPtr reservation_data) {
- HostReservationParser::parseInternal(subnet_id, reservation_data);
+ HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
- host_->setIPv4SubnetID(subnet_id);
+ host->setIPv4SubnetID(subnet_id);
BOOST_FOREACH(ConfigPair element, reservation_data->mapValue()) {
// For 'option-data' element we will use another parser which
// already returns errors with position appended, so don't
// surround it with try-catch.
if (element.first == "option-data") {
- CfgOptionPtr cfg_option = host_->getCfgOption4();
+ CfgOptionPtr cfg_option = host->getCfgOption4();
// This parser is converted to SimpleParser already. It
// parses the Element structure immediately, there's no need
} else {
try {
if (element.first == "ip-address") {
- host_->setIPv4Reservation(IOAddress(element.second->
+ host->setIPv4Reservation(IOAddress(element.second->
stringValue()));
} else if (element.first == "next-server") {
- host_->setNextServer(IOAddress(element.second->stringValue()));
+ host->setNextServer(IOAddress(element.second->stringValue()));
} else if (element.first == "server-hostname") {
- host_->setServerHostname(element.second->stringValue());
+ host->setServerHostname(element.second->stringValue());
} else if (element.first == "boot-file-name") {
- host_->setBootFileName(element.second->stringValue());
+ host->setBootFileName(element.second->stringValue());
} else if (element.first == "client-classes") {
BOOST_FOREACH(ConstElementPtr class_element,
element.second->listValue()) {
- host_->addClientClass4(class_element->stringValue());
+ host->addClientClass4(class_element->stringValue());
}
}
}
}
- addHost(reservation_data);
+ return (host);
}
const std::set<std::string>&
return (getSupportedParams4(identifiers_only));
}
-void
+HostPtr
HostReservationParser6::parseInternal(const SubnetID& subnet_id,
isc::data::ConstElementPtr reservation_data) {
- HostReservationParser::parseInternal(subnet_id, reservation_data);
+ HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
- host_->setIPv6SubnetID(subnet_id);
+ host->setIPv6SubnetID(subnet_id);
BOOST_FOREACH(ConfigPair element, reservation_data->mapValue()) {
// Parse option values. Note that the configuration option parser
// need to surround it with try-clause (and rethrow with position
// appended).
if (element.first == "option-data") {
- CfgOptionPtr cfg_option = host_->getCfgOption6();
+ CfgOptionPtr cfg_option = host->getCfgOption6();
// This parser is converted to SimpleParser already. It
// parses the Element structure immediately, there's no need
}
// Create a reservation for an address or prefix.
- host_->addReservation(IPv6Resrv(resrv_type,
+ host->addReservation(IPv6Resrv(resrv_type,
IOAddress(prefix),
prefix_len));
try {
BOOST_FOREACH(ConstElementPtr class_element,
element.second->listValue()) {
- host_->addClientClass6(class_element->stringValue());
+ host->addClientClass6(class_element->stringValue());
}
} catch (const std::exception& ex) {
// Append line number where the error occurred.
}
}
- // This may fail, but the addHost function will handle this on its own.
- addHost(reservation_data);
+ return (host);
}
const std::set<std::string>&
/// @param reservation_data Data element holding map with a host
/// reservation configuration.
///
+ /// @return Pointer to the object representing parsed host.
/// @throw DhcpConfigError If the configuration is invalid.
- void parse(const SubnetID& subnet_id,
- isc::data::ConstElementPtr reservation_data);
+ virtual HostPtr
+ parse(const SubnetID& subnet_id,
+ isc::data::ConstElementPtr reservation_data) final;
protected:
/// @param reservation_data Data element holding map with a host
/// reservation configuration.
///
+ /// @return Pointer to the object representing parsed host.
/// @throw DhcpConfigError If the configuration is invalid.
- virtual void parseInternal(const SubnetID& subnet_id,
- isc::data::ConstElementPtr reservation_data);
-
- /// @brief Inserts @c host_ object to the staging configuration.
- ///
- /// This method should be called by derived classes to insert the fully
- /// parsed host reservation configuration to the @c CfgMgr.
- ///
- /// @param reservation_data Data element holding host reservation. It
- /// used by this method to append the line number to the error string.
- ///
- /// @throw DhcpConfigError When operation to add a configured host fails.
- void addHost(isc::data::ConstElementPtr reservation_data);
+ virtual HostPtr parseInternal(const SubnetID& subnet_id,
+ isc::data::ConstElementPtr reservation_data);
/// @brief Checks if the specified parameter is a host identifier.
///
/// @return Set of supported parameter names.
virtual const std::set<std::string>&
getSupportedParameters(const bool identifiers_only) const = 0;
-
- /// @brief Holds a pointer to @c Host object representing a parsed
- /// host reservation configuration.
- HostPtr host_;
-
};
/// @brief Parser for a single host reservation for DHCPv4.
/// @param reservation_data Data element holding map with a host
/// reservation configuration.
///
+ /// @return Pointer to the object representing parsed host.
/// @throw DhcpConfigError If the configuration is invalid.
- virtual void parseInternal(const SubnetID& subnet_id,
- isc::data::ConstElementPtr reservation_data);
+ virtual HostPtr parseInternal(const SubnetID& subnet_id,
+ isc::data::ConstElementPtr reservation_data);
/// @brief Returns set of the supported parameters for DHCPv4.
///
/// @param reservation_data Data element holding map with a host
/// reservation configuration.
///
+ /// @return Pointer to the object representing parsed host.
/// @throw DhcpConfigError If the configuration is invalid.
- virtual void parseInternal(const SubnetID& subnet_id,
- isc::data::ConstElementPtr reservation_data);
+ virtual HostPtr parseInternal(const SubnetID& subnet_id,
+ isc::data::ConstElementPtr reservation_data);
/// @brief Returns set of the supported parameters for DHCPv6.
///
#include <cc/data.h>
#include <cc/simple_parser.h>
+#include <dhcpsrv/host.h>
#include <dhcpsrv/subnet_id.h>
#include <boost/foreach.hpp>
/// belong.
/// @param hr_list Data element holding a list of host reservations.
/// Each host reservation is described by a map object.
+ /// @param [out] hosts_list Hosts representing parsed reservations are stored
+ /// in this list.
///
/// @throw DhcpConfigError If the configuration if any of the reservations
/// is invalid.
- void parse(const SubnetID& subnet_id, isc::data::ConstElementPtr hr_list) {
+ void parse(const SubnetID& subnet_id, isc::data::ConstElementPtr hr_list,
+ HostCollection& hosts_list) {
+ HostCollection hosts;
BOOST_FOREACH(data::ConstElementPtr reservation, hr_list->listValue()) {
HostReservationParserType parser;
- parser.parse(subnet_id, reservation);
+ hosts.push_back(parser.parse(subnet_id, reservation));
}
+ hosts_list.swap(hosts);
}
};
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
ParserType parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
- // Retrieve a host.
- HostCollection hosts;
- CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
- ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
- ASSERT_EQ(1, hosts.size());
+ ASSERT_TRUE(host);
// There should be no options assigned to a host.
- EXPECT_TRUE(hosts[0]->getCfgOption4()->empty());
- EXPECT_TRUE(hosts[0]->getCfgOption6()->empty());
+ EXPECT_TRUE(host->getCfgOption4()->empty());
+ EXPECT_TRUE(host->getCfgOption6()->empty());
}
/// @brief This test verifies that the parser can parse a DHCPv4
ElementPtr config_element = Element::fromJSON(config.str());
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
- CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
- HostCollection hosts;
- ASSERT_NO_THROW(hosts = cfg_hosts->getAll(expected_identifier_type,
- &expected_identifier[0],
- expected_identifier.size()));
-
- ASSERT_EQ(1, hosts.size());
-
- EXPECT_EQ(10, hosts[0]->getIPv4SubnetID());
- EXPECT_EQ(0, hosts[0]->getIPv6SubnetID());
- EXPECT_EQ("192.0.2.112", hosts[0]->getIPv4Reservation().toText());
- EXPECT_TRUE(hosts[0]->getHostname().empty());
+ EXPECT_EQ(10, host->getIPv4SubnetID());
+ EXPECT_EQ(0, host->getIPv6SubnetID());
+ EXPECT_EQ("192.0.2.112", host->getIPv4Reservation().toText());
+ EXPECT_TRUE(host->getHostname().empty());
}
/// @brief This test verifies that the parser returns an error when
template<typename ParserType>
void testInvalidConfig(const std::string& config) const {
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
ParserType parser;
- EXPECT_THROW(parser.parse(SubnetID(10), config_element), DhcpConfigError);
+ EXPECT_THROW({
+ host = parser.parse(SubnetID(10), config_element);
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
+ }, isc::Exception);
}
/// @brief HW Address object used by tests.
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_HWADDR,
&hwaddr_->hwaddr_[0],
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser6 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_, DuidPtr()));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser6 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(12), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(12), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser6 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(12), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(12), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser6 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_DUID,
&duid_->getDuid()[0],
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser4 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
ASSERT_EQ(1, hosts.size());
ElementPtr config_element = Element::fromJSON(config);
+ HostPtr host;
HostReservationParser6 parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(10), config_element));
+ ASSERT_NO_THROW(host = parser.parse(SubnetID(10), config_element));
+ ASSERT_TRUE(host);
// One host should have been added to the configuration.
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ ASSERT_NO_THROW(cfg_hosts->add(host));
+
HostCollection hosts;
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(HWAddrPtr(), duid_));
ASSERT_EQ(1, hosts.size());
ElementPtr config_element = Element::fromJSON(config);
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser4> parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(1), config_element));
+ ASSERT_NO_THROW(parser.parse(SubnetID(1), config_element, hosts));
+
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
- HostCollection hosts;
// Get the first reservation for the host identified by the HW address.
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
ElementPtr config_element = Element::fromJSON(config.str());
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser4> parser;
- EXPECT_THROW(parser.parse(SubnetID(1), config_element), DhcpConfigError);
+ EXPECT_THROW({
+ parser.parse(SubnetID(1), config_element, hosts);
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
+ }, isc::Exception);
}
}
ElementPtr config_element = Element::fromJSON(config);
// Parse configuration.
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser6> parser;
- ASSERT_NO_THROW(parser.parse(SubnetID(2), config_element));
+ ASSERT_NO_THROW(parser.parse(SubnetID(2), config_element, hosts));
+
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
- HostCollection hosts;
// Get the reservation for the host identified by the HW address.
ASSERT_NO_THROW(hosts = cfg_hosts->getAll(hwaddr_));
ElementPtr config_element = Element::fromJSON(config.str());
+ HostCollection hosts;
HostReservationsListParser<HostReservationParser6> parser;
- EXPECT_THROW(parser.parse(SubnetID(1), config_element), DhcpConfigError);
+ EXPECT_THROW({
+ parser.parse(SubnetID(1), config_element, hosts);
+ for (auto h = hosts.begin(); h != hosts.end(); ++h) {
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
+ }
+ }, isc::Exception);
}
}