From: Otto Moerbeek Date: Wed, 27 Sep 2023 12:56:14 +0000 (+0200) Subject: First stab at converting api managed files X-Git-Tag: rec-5.0.0-alpha2~1^2~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=93522cd208e125ab5f13fa2487c55ded59d186ee;p=thirdparty%2Fpdns.git First stab at converting api managed files --- diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 25e6d7d74c..f61c819683 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1288,6 +1288,7 @@ void parseACLs() throw runtime_error("Error processing '" + configName + "': " + msg); break; case pdns::settings::rec::YamlSettingsStatus::OK: + pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, log); // Does *not* set include-dir pdns::settings::rec::setArgsForACLRelatedSettings(settings); break; @@ -3384,6 +3385,7 @@ int main(int argc, char** argv) g_yamlSettings = true; SLOG(g_log << Logger::Notice << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl, startupLog->info(Logr::Notice, "YAML config found and processed", "configname", Logging::Loggable(yamlconfigname))); + pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, startupLog); pdns::settings::rec::bridgeStructToOldStyleSettings(settings); break; } diff --git a/pdns/recursordist/settings/cxxsettings.hh b/pdns/recursordist/settings/cxxsettings.hh index 7577e86d32..ad21578da1 100644 --- a/pdns/recursordist/settings/cxxsettings.hh +++ b/pdns/recursordist/settings/cxxsettings.hh @@ -43,6 +43,7 @@ bool oldKVToBridgeStruct(string& key, const string& value, ::rust::String& secti std::string oldStyleSettingsFileToYaml(const string& fname, bool mainFile); std::string defaultsToYaml(); YamlSettingsStatus readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, rust::settings::rec::Recursorsettings& settings, std::string& msg, Logr::log_t log); +void processAPIDir(const string& includeDirOnCommandLine, pdns::rust::settings::rec::Recursorsettings& settings, Logr::log_t log); void bridgeStructToOldStyleSettings(const pdns::rust::settings::rec::Recursorsettings& settings); void readYamlForwardZonesFile(const std::string& filename, ::rust::Vec& vec, Logr::log_t log); void readYamlAllowFromFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log); diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index bde1a244a3..b6db21383c 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -22,6 +22,9 @@ #include #include +#include +#include +#include #include "namespaces.hh" #include "arguments.hh" @@ -131,6 +134,122 @@ static void mergeYamlSubFile(const std::string& configname, Recursorsettings& se pdns::rust::settings::rec::merge(settings, data); } +static void convertACLFile(const string& includeDir, const string& apiDir, const std::string& filename) +{ + auto path = includeDir; + path.append("/").append(filename).append(".conf"); + auto file = ifstream(path); + if (!file.is_open()) { + cerr << "Cannot open " << path << endl; + return; + } + rust::vec result; + std::string line; + while (getline(file, line)) { + auto pos = line.find('#'); + if (pos != string::npos) { + line.resize(pos); + } + boost::trim(line); + if (line.empty()) { + continue; + } + auto plusis = line.find("+="); + if (plusis != string::npos) { + auto val = line.substr(plusis + 2); + boost::trim(val); + result.emplace_back(val); + } + } + rust::string yaml; + if (filename == "allow-from") { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_from", "allow_from_file", result); + } + else { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", result); + } + string yamlfilename = apiDir; + yamlfilename.append("/").append(filename).append(".yml"); + ofstream ofconf(yamlfilename + ".tmp"); + if (!ofconf) { + throw runtime_error("Could not open config file '" + yamlfilename + "' for writing: " + stringerror()); + } + ofconf << "# Generated by pdns-recursor REST API, DO NOT EDIT" << endl; + ofconf << yaml << endl; + ofconf.close(); + cerr << "Converted " << path << " to " << yamlfilename < forwardFiles; + ::arg().gatherIncludes(includeDir, "..conf", forwardFiles); + pdns::rust::settings::rec::Recursorsettings settings; + for (const auto& file : forwardFiles) { + auto yaml = pdns::settings::rec::oldStyleSettingsFileToYaml(file, false); + cerr << "Converted YAML for " << file << endl; + cerr << yaml << endl; + pdns::rust::settings::rec::merge(settings, yaml); + } + const string yamlAPiZonesFile = apiDir + "/apizones"; + + for (auto& zone : settings.recursor.auth_zones) { + const std::string origName(zone.file); + std::string newName(zone.file); + newName.replace(0, includeDir.length(), apiDir); + cerr << "Rename " << origName << ' ' << newName << ' '; + auto ret = rename(origName.c_str(), newName.c_str()); + cerr << ret << ' ' << stringerror() << endl; + zone.file = ::rust::String(newName); + api_add_auth_zone(yamlAPiZonesFile, zone); + } + for (const auto& zone : settings.recursor.forward_zones) { + api_add_forward_zone(yamlAPiZonesFile, zone); + } + for (const auto& zone : settings.recursor.forward_zones_recurse) { + api_add_forward_zone(yamlAPiZonesFile, zone); + } + for (const auto& file : forwardFiles) { + rename(file.c_str(), (file + ".converted").c_str()); + } +} + +void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, pdns::rust::settings::rec::Recursorsettings& settings, Logr::log_t log) +{ + auto apiDir = std::string(settings.webservice.api_dir); + if (apiDir.empty()) { + return; + } + auto includeDir = std::string(settings.recursor.include_dir); + if (!includeDirOnCommandLine.empty()) { + includeDir = includeDirOnCommandLine; + } + if (includeDir == apiDir) { + throw runtime_error("Active YAML settings do not allow include_dir to be equal to api_dir"); + } + const std::array aclFiles = { + "allow-from", + "allow-notify-from" + }; + for (const auto& file : aclFiles) { + convertACLFile(includeDir, apiDir, file); + auto path = apiDir; + path.append("/").append(file).append(".yml"); + try { + mergeYamlSubFile(path, settings, log); + } + catch (const runtime_error& err) { + } + } + convertForwardsandAuths(includeDir, apiDir, log); +} + pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, Recursorsettings& settings, std::string& msg, Logr::log_t log) { auto file = ifstream(configname);