Commit 62d94947 authored by Marcin Siodelski's avatar Marcin Siodelski

[5314] Subnet to Element conversion moved to SubnetX classes.

parent 137cf556
......@@ -284,106 +284,7 @@ CfgSubnets4::toElement() const {
// Iterate subnets
for (Subnet4Collection::const_iterator subnet = subnets_.cbegin();
subnet != subnets_.cend(); ++subnet) {
// Prepare the map
ElementPtr map = Element::createMap();
// Set subnet id
SubnetID id = (*subnet)->getID();
map->set("id", Element::create(static_cast<long long>(id)));
// Set relay info
const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
ElementPtr relay = Element::createMap();
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
map->set("relay", relay);
// Set subnet
map->set("subnet", Element::create((*subnet)->toText()));
// Set interface
const std::string& iface = (*subnet)->getIface();
map->set("interface", Element::create(iface));
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
((*subnet)->getT1().get())));
// Set rebind-timer
map->set("rebind-timer",
Element::create(static_cast<long long>
((*subnet)->getT2().get())));
// Set valid-lifetime
map->set("valid-lifetime",
Element::create(static_cast<long long>
((*subnet)->getValid().get())));
// Set pools
const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_V4);
ElementPtr pool_list = Element::createList();
for (PoolCollection::const_iterator pool = pools.cbegin();
pool != pools.cend(); ++pool) {
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr pool_map = Element::createMap();
// Set pool
const IOAddress& first = (*pool)->getFirstAddress();
const IOAddress& last = (*pool)->getLastAddress();
std::string range = first.toText() + "-" + last.toText();
// Try to output a prefix (vs a range)
int prefix_len = prefixLengthFromRange(first, last);
if (prefix_len >= 0) {
std::ostringstream oss;
oss << first.toText() << "/" << prefix_len;
range = oss.str();
}
pool_map->set("pool", Element::create(range));
// Set user-context
ConstElementPtr context = (*pool)->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pool_list->add(pool_map);
}
map->set("pools", pool_list);
// Set host reservation-mode
Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
std::string mode;
switch (hrmode) {
case Subnet::HR_DISABLED:
mode = "disabled";
break;
case Subnet::HR_OUT_OF_POOL:
mode = "out-of-pool";
break;
case Subnet::HR_ALL:
mode = "all";
break;
default:
isc_throw(ToElementError,
"invalid host reservation mode: " << hrmode);
}
map->set("reservation-mode", Element::create(mode));
// Set match-client-id
map->set("match-client-id",
Element::create((*subnet)->getMatchClientId()));
// Set next-server
map->set("next-server",
Element::create((*subnet)->getSiaddr().toText()));
// Set DHCP4o6
const Cfg4o6& d4o6 = (*subnet)->get4o6();
isc::data::merge(map, d4o6.toElement());
// Set client-class
const ClientClasses& cclasses = (*subnet)->getClientClasses();
if (cclasses.size() > 1) {
isc_throw(ToElementError, "client-class has too many items: "
<< cclasses.size());
} else if (!cclasses.empty()) {
map->set("client-class", Element::create(*cclasses.cbegin()));
}
// Set options
ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
map->set("option-data", opts->toElement());
// Not supported: interface-id
// Not supported: rapid-commit
// Push on the list
result->add(map);
result->add((*subnet)->toElement());
}
return (result);
}
......
......@@ -240,171 +240,7 @@ CfgSubnets6::toElement() const {
// Iterate subnets
for (Subnet6Collection::const_iterator subnet = subnets_.cbegin();
subnet != subnets_.cend(); ++subnet) {
// Prepare the map
ElementPtr map = Element::createMap();
// Set subnet id
SubnetID id = (*subnet)->getID();
map->set("id", Element::create(static_cast<long long>(id)));
// Set relay info
const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
ElementPtr relay = Element::createMap();
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
map->set("relay", relay);
// Set subnet
map->set("subnet", Element::create((*subnet)->toText()));
// Set interface
const std::string& iface = (*subnet)->getIface();
map->set("interface", Element::create(iface));
// Set interface-id
const OptionPtr& ifaceid = (*subnet)->getInterfaceId();
if (ifaceid) {
std::vector<uint8_t> bin = ifaceid->getData();
std::string ifid;
ifid.resize(bin.size());
if (!bin.empty()) {
std::memcpy(&ifid[0], &bin[0], bin.size());
}
map->set("interface-id", Element::create(ifid));
} else {
map->set("interface-id", Element::create(std::string()));
}
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
((*subnet)->getT1().get())));
// Set rebind-timer
map->set("rebind-timer",
Element::create(static_cast<long long>
((*subnet)->getT2().get())));
// Set preferred-lifetime
map->set("preferred-lifetime",
Element::create(static_cast<long long>
((*subnet)->getPreferred().get())));
// Set valid-lifetime
map->set("valid-lifetime",
Element::create(static_cast<long long>
((*subnet)->getValid().get())));
// Set rapid-commit
bool rapid_commit = (*subnet)->getRapidCommit();
map->set("rapid-commit", Element::create(rapid_commit));
// Set pools
const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_NA);
ElementPtr pool_list = Element::createList();
for (PoolCollection::const_iterator pool = pools.cbegin();
pool != pools.cend(); ++pool) {
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr pool_map = Element::createMap();
// Set pool
const IOAddress& first = (*pool)->getFirstAddress();
const IOAddress& last = (*pool)->getLastAddress();
std::string range = first.toText() + "-" + last.toText();
// Try to output a prefix (vs a range)
int prefix_len = prefixLengthFromRange(first, last);
if (prefix_len >= 0) {
std::ostringstream oss;
oss << first.toText() << "/" << prefix_len;
range = oss.str();
}
pool_map->set("pool", Element::create(range));
// Set user-context
ConstElementPtr context = (*pool)->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pool_list->add(pool_map);
}
map->set("pools", pool_list);
// Set pd-pools
const PoolCollection& pdpools = (*subnet)->getPools(Lease::TYPE_PD);
ElementPtr pdpool_list = Element::createList();
for (PoolCollection::const_iterator pool = pdpools.cbegin();
pool != pdpools.cend(); ++pool) {
// Get it as a Pool6 (@todo move this code to pool.cc)
const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
if (!pdpool) {
isc_throw(ToElementError, "invalid pd-pool pointer");
}
// Prepare the map for a pd-pool
ElementPtr pool_map = Element::createMap();
// Set prefix
const IOAddress& prefix = pdpool->getFirstAddress();
pool_map->set("prefix", Element::create(prefix.toText()));
// Set prefix-len (get it from min - max)
const IOAddress& last = pdpool->getLastAddress();
int prefix_len = prefixLengthFromRange(prefix, last);
if (prefix_len < 0) {
// The pool is bad: give up
isc_throw(ToElementError, "invalid prefix range "
<< prefix.toText() << "-" << last.toText());
}
pool_map->set("prefix-len", Element::create(prefix_len));
// Set delegated-len
uint8_t len = pdpool->getLength();
pool_map->set("delegated-len",
Element::create(static_cast<int>(len)));
// Set excluded prefix
const Option6PDExcludePtr& xopt =
pdpool->getPrefixExcludeOption();
if (xopt) {
const IOAddress& xprefix =
xopt->getExcludedPrefix(prefix, len);
pool_map->set("excluded-prefix",
Element::create(xprefix.toText()));
uint8_t xlen = xopt->getExcludedPrefixLength();
pool_map->set("excluded-prefix-len",
Element::create(static_cast<int>(xlen)));
} else {
pool_map->set("excluded-prefix",
Element::create(std::string("::")));
pool_map->set("excluded-prefix-len", Element::create(0));
}
// Set user-context
ConstElementPtr context = pdpool->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = pdpool->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pdpool_list->add(pool_map);
}
map->set("pd-pools", pdpool_list);
// Set host reservation-mode
Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
std::string mode;
switch (hrmode) {
case Subnet::HR_DISABLED:
mode = "disabled";
break;
case Subnet::HR_OUT_OF_POOL:
mode = "out-of-pool";
break;
case Subnet::HR_ALL:
mode = "all";
break;
default:
isc_throw(ToElementError,
"invalid host reservation mode: " << hrmode);
}
map->set("reservation-mode", Element::create(mode));
// Set client-class
const ClientClasses& cclasses = (*subnet)->getClientClasses();
if (cclasses.size() > 1) {
isc_throw(ToElementError, "client-class has too many items: "
<< cclasses.size());
} else if (!cclasses.empty()) {
map->set("client-class", Element::create(*cclasses.cbegin()));
}
// Set options
ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
map->set("option-data", opts->toElement());
// Push on the list
result->add(map);
result->add((*subnet)->toElement());
}
return (result);
}
......
......@@ -14,6 +14,7 @@
#include <sstream>
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::dhcp;
namespace {
......@@ -472,5 +473,279 @@ void Subnet6::checkType(Lease::Type type) const {
}
}
data::ElementPtr
Subnet4::toElement() const {
// Prepare the map
ElementPtr map = Element::createMap();
// Set subnet id
SubnetID id = getID();
map->set("id", Element::create(static_cast<long long>(id)));
// Set relay info
const Subnet::RelayInfo& relay_info = getRelayInfo();
ElementPtr relay = Element::createMap();
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
map->set("relay", relay);
// Set subnet
map->set("subnet", Element::create(toText()));
// Set interface
const std::string& iface = getIface();
map->set("interface", Element::create(iface));
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
(getT1().get())));
// Set rebind-timer
map->set("rebind-timer",
Element::create(static_cast<long long>
(getT2().get())));
// Set valid-lifetime
map->set("valid-lifetime",
Element::create(static_cast<long long>
(getValid().get())));
// Set pools
const PoolCollection& pools = getPools(Lease::TYPE_V4);
ElementPtr pool_list = Element::createList();
for (PoolCollection::const_iterator pool = pools.cbegin();
pool != pools.cend(); ++pool) {
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr pool_map = Element::createMap();
// Set pool
const IOAddress& first = (*pool)->getFirstAddress();
const IOAddress& last = (*pool)->getLastAddress();
std::string range = first.toText() + "-" + last.toText();
// Try to output a prefix (vs a range)
int prefix_len = prefixLengthFromRange(first, last);
if (prefix_len >= 0) {
std::ostringstream oss;
oss << first.toText() << "/" << prefix_len;
range = oss.str();
}
pool_map->set("pool", Element::create(range));
// Set user-context
ConstElementPtr context = (*pool)->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pool_list->add(pool_map);
}
map->set("pools", pool_list);
// Set host reservation-mode
Subnet::HRMode hrmode = getHostReservationMode();
std::string mode;
switch (hrmode) {
case Subnet::HR_DISABLED:
mode = "disabled";
break;
case Subnet::HR_OUT_OF_POOL:
mode = "out-of-pool";
break;
case Subnet::HR_ALL:
mode = "all";
break;
default:
isc_throw(ToElementError,
"invalid host reservation mode: " << hrmode);
}
map->set("reservation-mode", Element::create(mode));
// Set match-client-id
map->set("match-client-id",
Element::create(getMatchClientId()));
// Set next-server
map->set("next-server",
Element::create(getSiaddr().toText()));
// Set DHCP4o6
const Cfg4o6& d4o6 = get4o6();
isc::data::merge(map, d4o6.toElement());
// Set client-class
const ClientClasses& cclasses = getClientClasses();
if (cclasses.size() > 1) {
isc_throw(ToElementError, "client-class has too many items: "
<< cclasses.size());
} else if (!cclasses.empty()) {
map->set("client-class", Element::create(*cclasses.cbegin()));
}
// Set options
ConstCfgOptionPtr opts = getCfgOption();
map->set("option-data", opts->toElement());
// Not supported: interface-id
// Not supported: rapid-commit
return (map);
}
data::ElementPtr
Subnet6::toElement() const {
// Prepare the map
ElementPtr map = Element::createMap();
// Set subnet id
SubnetID id = getID();
map->set("id", Element::create(static_cast<long long>(id)));
// Set relay info
const Subnet::RelayInfo& relay_info = getRelayInfo();
ElementPtr relay = Element::createMap();
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
map->set("relay", relay);
// Set subnet
map->set("subnet", Element::create(toText()));
// Set interface
const std::string& iface = getIface();
map->set("interface", Element::create(iface));
// Set interface-id
const OptionPtr& ifaceid = getInterfaceId();
if (ifaceid) {
std::vector<uint8_t> bin = ifaceid->getData();
std::string ifid;
ifid.resize(bin.size());
if (!bin.empty()) {
std::memcpy(&ifid[0], &bin[0], bin.size());
}
map->set("interface-id", Element::create(ifid));
} else {
map->set("interface-id", Element::create(std::string()));
}
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
(getT1().get())));
// Set rebind-timer
map->set("rebind-timer",
Element::create(static_cast<long long>
(getT2().get())));
// Set preferred-lifetime
map->set("preferred-lifetime",
Element::create(static_cast<long long>
(getPreferred().get())));
// Set valid-lifetime
map->set("valid-lifetime",
Element::create(static_cast<long long>
(getValid().get())));
// Set rapid-commit
bool rapid_commit = getRapidCommit();
map->set("rapid-commit", Element::create(rapid_commit));
// Set pools
const PoolCollection& pools = getPools(Lease::TYPE_NA);
ElementPtr pool_list = Element::createList();
for (PoolCollection::const_iterator pool = pools.cbegin();
pool != pools.cend(); ++pool) {
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr pool_map = Element::createMap();
// Set pool
const IOAddress& first = (*pool)->getFirstAddress();
const IOAddress& last = (*pool)->getLastAddress();
std::string range = first.toText() + "-" + last.toText();
// Try to output a prefix (vs a range)
int prefix_len = prefixLengthFromRange(first, last);
if (prefix_len >= 0) {
std::ostringstream oss;
oss << first.toText() << "/" << prefix_len;
range = oss.str();
}
pool_map->set("pool", Element::create(range));
// Set user-context
ConstElementPtr context = (*pool)->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pool_list->add(pool_map);
}
map->set("pools", pool_list);
// Set pd-pools
const PoolCollection& pdpools = getPools(Lease::TYPE_PD);
ElementPtr pdpool_list = Element::createList();
for (PoolCollection::const_iterator pool = pdpools.cbegin();
pool != pdpools.cend(); ++pool) {
// Get it as a Pool6 (@todo move this code to pool.cc)
const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
if (!pdpool) {
isc_throw(ToElementError, "invalid pd-pool pointer");
}
// Prepare the map for a pd-pool
ElementPtr pool_map = Element::createMap();
// Set prefix
const IOAddress& prefix = pdpool->getFirstAddress();
pool_map->set("prefix", Element::create(prefix.toText()));
// Set prefix-len (get it from min - max)
const IOAddress& last = pdpool->getLastAddress();
int prefix_len = prefixLengthFromRange(prefix, last);
if (prefix_len < 0) {
// The pool is bad: give up
isc_throw(ToElementError, "invalid prefix range "
<< prefix.toText() << "-" << last.toText());
}
pool_map->set("prefix-len", Element::create(prefix_len));
// Set delegated-len
uint8_t len = pdpool->getLength();
pool_map->set("delegated-len",
Element::create(static_cast<int>(len)));
// Set excluded prefix
const Option6PDExcludePtr& xopt =
pdpool->getPrefixExcludeOption();
if (xopt) {
const IOAddress& xprefix =
xopt->getExcludedPrefix(prefix, len);
pool_map->set("excluded-prefix",
Element::create(xprefix.toText()));
uint8_t xlen = xopt->getExcludedPrefixLength();
pool_map->set("excluded-prefix-len",
Element::create(static_cast<int>(xlen)));
} else {
pool_map->set("excluded-prefix",
Element::create(std::string("::")));
pool_map->set("excluded-prefix-len", Element::create(0));
}
// Set user-context
ConstElementPtr context = pdpool->getContext();
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options
ConstCfgOptionPtr opts = pdpool->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pdpool_list->add(pool_map);
}
map->set("pd-pools", pdpool_list);
// Set host reservation-mode
Subnet::HRMode hrmode = getHostReservationMode();
std::string mode;
switch (hrmode) {
case Subnet::HR_DISABLED:
mode = "disabled";
break;
case Subnet::HR_OUT_OF_POOL:
mode = "out-of-pool";
break;
case Subnet::HR_ALL:
mode = "all";
break;
default:
isc_throw(ToElementError,
"invalid host reservation mode: " << hrmode);
}
map->set("reservation-mode", Element::create(mode));
// Set client-class
const ClientClasses& cclasses = getClientClasses();
if (cclasses.size() > 1) {
isc_throw(ToElementError, "client-class has too many items: "
<< cclasses.size());
} else if (!cclasses.empty()) {
map->set("client-class", Element::create(*cclasses.cbegin()));
}
// Set options
ConstCfgOptionPtr opts = getCfgOption();
map->set("option-data", opts->toElement());
return (map);
}
} // end of isc::dhcp namespace
} // end of isc namespace
......@@ -8,6 +8,7 @@
#define SUBNET_H
#include <asiolink/io_address.h>
#include <cc/data.h>
#include <dhcp/option.h>
#include <dhcp/classify.h>
#include <dhcp/option_space_container.h>
......@@ -280,7 +281,7 @@ public:
/// returned it is valid.
///
/// @return const reference to the relay information
const isc::dhcp::Subnet::RelayInfo& getRelayInfo() {
const isc::dhcp::Subnet::RelayInfo& getRelayInfo() const {
return (relay_);
}
......@@ -429,6 +430,11 @@ protected:
/// type.
bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
/// @brief Unparse a subnet object.
///
/// @return A pointer to unparsed subnet configuration.
virtual data::ElementPtr toElement() const = 0;
/// @brief subnet-id
///
/// Subnet-id is a unique value that can be used to find or identify
......@@ -577,6 +583,19 @@ public:
return (dhcp4o6_);
}
/// @brief Returns const DHCP4o6 configuration parameters.
///
/// This structure is always available. If the 4o6 is not enabled, its
/// enabled_ field will be set to false.
const Cfg4o6& get4o6() const {
return (dhcp4o6_);
}
/// @brief Unparse a subnet object.
///
/// @return A pointer to unparsed subnet configuration.
virtual data::ElementPtr toElement() const;
private:
/// @brief Returns default address for pool selection
......@@ -676,6 +695,11 @@ public:
return (rapid_commit_);
}
/// @brief Unparse a subnet object.
///