#include <limits>
#include <iostream>
+#include <iomanip>
#include <netinet/in.h>
#include <vector>
#include <map>
// Let's check if all subnets have either the same interface
// or don't have the interface specified at all.
- string iface = (*net)->getIface();
bool authoritative = (*net)->getAuthoritative();
+ string iface = (*net)->getIface();
const Subnet4Collection* subnets = (*net)->getAllSubnets();
if (subnets) {
// For each subnet, add it to a list of regular subnets.
for (auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
+ if ((*subnet)->getAuthoritative() != authoritative) {
+ isc_throw(DhcpConfigError, "Subnet " << boolalpha
+ << (*subnet)->toText()
+ << " has different authoritative setting "
+ << (*subnet)->getAuthoritative()
+ << " than the shared-network itself: "
+ << authoritative);
+ }
+
if (iface.empty()) {
iface = (*subnet)->getIface();
continue;
<< " or the shared-network itself used " << iface);
}
- if ((*subnet)->getAuthoritative() != authoritative) {
- isc_throw(DhcpConfigError, "Subnet " << (*subnet)->toText()
- << " has different authoritative setting "
- << (*subnet)->getAuthoritative()
- << " than the shared-network itself: "
- << authoritative);
- }
-
// Let's collect the subnets in case we later find out the
// subnet doesn't have a mandatory name.
txt += (*subnet)->toText() + " ";
return (answer);
}
+void databaseConfigFetch(const SrvConfigPtr& srv_cfg) {
+
+ ConfigBackendDHCPv4Mgr& mgr = ConfigBackendDHCPv4Mgr::instance();
+
+ // Close any existing CB databasess, then open all in srv_cfg (if any)
+ if (!databaseConfigConnect(srv_cfg)) {
+ // There are no CB databases so we're done
+ return;
+ }
+
+ LOG_INFO(dhcp4_logger, DHCP4_CONFIG_FETCH);
+
+ // For now we find data based on first backend that has it.
+ BackendSelector backend_selector(BackendSelector::Type::UNSPEC);
+
+ // Use the server_tag if set, otherwise use ALL.
+ std::string server_tag = srv_cfg->getServerTag();
+ ServerSelector& server_selector = (server_tag.empty()? ServerSelector::ALL()
+ : ServerSelector::ONE(server_tag));
+ // Create the external config into which we'll fetch backend config data.
+ SrvConfigPtr external_cfg = CfgMgr::instance().createExternalCfg();
+
+ // First let's fetch the globals and add them to external config.
+ data::StampedValueCollection globals;
+ globals = mgr.getPool()->getAllGlobalParameters4(backend_selector, server_selector);
+ addGlobalsToConfig(external_cfg, globals);
+
+ // Now we fetch the option definitions and add them.
+ OptionDefContainer option_defs = mgr.getPool()->getAllOptionDefs4(backend_selector,
+ server_selector);
+ for (auto option_def = option_defs.begin(); option_def != option_defs.end(); ++option_def) {
+ external_cfg->getCfgOptionDef()->add((*option_def), (*option_def)->getOptionSpaceName());
+ }
+
+ // Next fetch the options. They are returned as a container of OptionDescriptors.
+ OptionContainer options = mgr.getPool()->getAllOptions4(backend_selector, server_selector);
+ for (auto option = options.begin(); option != options.end(); ++option) {
+ external_cfg->getCfgOption()->add((*option), (*option).space_name_);
+ }
+
+ // Now fetch the shared networks.
+ SharedNetwork4Collection networks = mgr.getPool()->getAllSharedNetworks4(backend_selector,
+ server_selector);
+ for (auto network = networks.begin(); network != networks.end(); ++network) {
+ external_cfg->getCfgSharedNetworks4()->add((*network));
+ }
+
+ // Next we fetch subnets.
+ Subnet4Collection subnets = mgr.getPool()->getAllSubnets4(backend_selector, server_selector);
+ for (auto subnet = subnets.begin(); subnet != subnets.end(); ++subnet) {
+ external_cfg->getCfgSubnets4()->add((*subnet));
+ }
+
+ // Now we merge the fecthed configuration into the staging configuration.
+ CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
+ LOG_INFO(dhcp4_logger, DHCP4_CONFIG_MERGED);
+}
+
+bool databaseConfigConnect(const SrvConfigPtr& srv_cfg) {
+ // We need to get rid of any existing backends. These would be any
+ // opened by previous configuration cycle.
+ ConfigBackendDHCPv4Mgr& mgr = ConfigBackendDHCPv4Mgr::instance();
+ mgr.delAllBackends();
+
+ // Fetch the config-control info.
+ ConstConfigControlInfoPtr config_ctl = srv_cfg->getConfigControlInfo();
+ if (!config_ctl || config_ctl->getConfigDatabases().empty()) {
+ // No config dbs, nothing to do.
+ return (false);
+ }
+
+ // Iterate over the configured DBs and instantiate them.
+ for (auto db : config_ctl->getConfigDatabases()) {
+ LOG_INFO(dhcp4_logger, DHCP4_OPEN_CONFIG_DB)
+ .arg(db.redactedAccessString());
+ mgr.addBackend(db.getAccessString());
+ }
+
+ // Let the caller know we have opened DBs.
+ return (true);
+}
+
+
+void addGlobalsToConfig(SrvConfigPtr external_cfg, data::StampedValueCollection& cb_globals) {
+ const auto& index = cb_globals.get<StampedValueNameIndexTag>();
+ for (auto cb_global = index.begin(); cb_global != index.end(); ++cb_global) {
+
+ if ((*cb_global)->amNull()) {
+ continue;
+ }
+
+ external_cfg->addConfiguredGlobal((*cb_global)->getName(),
+ (*cb_global)->getElementValue());
+ }
+}
+
}; // end of isc::dhcp namespace
}; // end of isc namespace