]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[494-dhcp4configparser-sharednetworkssanitychecks-is-buggy] Fixed sharedNetworksSanit...
authorFrancis Dupont <fdupont@isc.org>
Sun, 10 Mar 2019 23:13:47 +0000 (00:13 +0100)
committerTomek Mrugalski <tomek@isc.org>
Fri, 19 Apr 2019 11:26:14 +0000 (07:26 -0400)
src/bin/dhcp4/json_config_parser.cc

index cbb6425e67f47e0539fd206642a2e5eee36595f8..2e62b2a59665e7d0647c45045972b3d65ab1abfa 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <limits>
 #include <iostream>
+#include <iomanip>
 #include <netinet/in.h>
 #include <vector>
 #include <map>
@@ -195,13 +196,22 @@ public:
 
             // 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;
@@ -218,14 +228,6 @@ public:
                                   << " 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() + " ";
@@ -667,5 +669,101 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
     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