]> granicus.if.org Git - icinga2/commitdiff
Unify setting the local and parent zone names for node wizard/setup
authorMichael Friedrich <michael.friedrich@icinga.com>
Fri, 6 Apr 2018 17:18:19 +0000 (19:18 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Fri, 6 Apr 2018 17:18:19 +0000 (19:18 +0200)
lib/cli/nodesetupcommand.cpp
lib/cli/nodeutility.cpp
lib/cli/nodeutility.hpp
lib/cli/nodewizardcommand.cpp

index dca96ff294bd61821a1ad9c1825bad2cbbd151db..128c2bdacc94622898a0e568ee0f8d6d9f1df412 100644 (file)
@@ -56,8 +56,9 @@ void NodeSetupCommand::InitParameters(boost::program_options::options_descriptio
 {
        visibleDesc.add_options()
                ("zone", po::value<std::string>(), "The name of the local zone")
-               ("master_host", po::value<std::string>(), "The name of the master host for auto-signing the csr; syntax: host[,port]")
                ("endpoint", po::value<std::vector<std::string> >(), "Connect to remote endpoint; syntax: cn[,host,port]")
+               ("parent_host", po::value<std::string>(), "The name of the parent host for auto-signing the csr; syntax: host[,port]")
+               ("parent_zone", po::value<std::string>(), "The name of the parent zone")
                ("listen", po::value<std::string>(), "Listen on host,port")
                ("ticket", po::value<std::string>(), "Generated ticket number for this request (optional)")
                ("trustedcert", po::value<std::string>(), "Trusted master certificate file")
@@ -68,7 +69,8 @@ void NodeSetupCommand::InitParameters(boost::program_options::options_descriptio
                ("global_zones", po::value<std::vector<std::string> >(), "The names of the additional global zones.");
 
        hiddenDesc.add_options()
-               ("master_zone", po::value<std::string>(), "The name of the master zone");
+               ("master_zone", po::value<std::string>(), "DEPRECATED: The name of the master zone")
+               ("master_host", po::value<std::string>(), "DEPRECATED: The name of the master host for auto-signing the csr; syntax: host[,port]");
 }
 
 std::vector<String> NodeSetupCommand::GetArgumentSuggestions(const String& argument, const String& word) const
@@ -262,6 +264,12 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
                return 1;
        }
 
+       /* Deprecation warnings. TODO: Remove in 2.10.0. */
+       if (vm.count("master_zone"))
+               Log(LogWarning, "cli", "The 'master_zone' parameter has been deprecated. Use 'parent_zone' instead.");
+       if (vm.count("master_host"))
+               Log(LogWarning, "cli", "The 'master_host' parameter has been deprecated. Use 'parent_host' instead.");
+
        String ticket;
 
        if (vm.count("ticket"))
@@ -277,31 +285,38 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
 
        /* require master host information for auto-signing requests */
 
-       if (!vm.count("master_host")) {
-               Log(LogCritical, "cli", "Please pass the master host connection information for auto-signing using '--master_host <host>'. This can also be a direct parent satellite since 2.8.");
-
+       /* TODO: master_host is deprecated, remove it in 2.10.0. */
+       if (!vm.count("master_host") && !vm.count("parent_host") ) {
+               Log(LogCritical, "cli", "Please pass the parent host connection information for auto-signing using '--parent_host <host>'.");
                return 1;
        }
 
-       std::vector<String> tokens = String(vm["master_host"].as<std::string>()).Split(",");
-       String master_host;
-       String master_port = "5665";
+       String parentHostInfo;
+
+       if (vm.count("parent_host"))
+               parentHostInfo = vm["parent_host"].as<std::string>();
+       else if (vm.count("master_host")) /* TODO: Remove in 2.10.0. */
+               parentHostInfo = vm["master_host"].as<std::string>();
+
+       std::vector<String> tokens = parentHostInfo.Split(",");
+       String parentHost;
+       String parentPort = "5665";
 
        if (tokens.size() == 1 || tokens.size() == 2)
-               master_host = tokens[0];
+               parentHost = tokens[0];
 
        if (tokens.size() == 2)
-               master_port = tokens[1];
+               parentPort = tokens[1];
 
        Log(LogInformation, "cli")
-               << "Verifying parent host connection information: host '" << master_host << "', port '" << master_port << "'.";
+               << "Verifying parent host connection information: host '" << parentHost << "', port '" << parentPort << "'.";
 
        /* trusted cert must be passed (retrieved by the user with 'pki save-cert' before) */
 
        if (!vm.count("trustedcert")) {
                Log(LogCritical, "cli")
                        << "Please pass the trusted cert retrieved from the parent node (master or satellite)\n"
-                       << "(Hint: 'icinga2 pki save-cert --host <masterhost> --port <5665> --key local.key --cert local.crt --trustedcert master.crt').";
+                       << "(Hint: 'icinga2 pki save-cert --host <parenthost> --port <5665> --key local.key --cert local.crt --trustedcert parent.crt').";
                return 1;
        }
 
@@ -320,21 +335,20 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
                << "Using the following CN (defaults to FQDN): '" << cn << "'.";
 
        /* pki request a signed certificate from the master */
-
-       String pki_path = ApiListener::GetCertsDir();
-       Utility::MkDirP(pki_path, 0700);
+       String certsDir = ApiListener::GetCertsDir();
+       Utility::MkDirP(certsDir, 0700);
 
        String user = ScriptGlobal::Get("RunAsUser");
        String group = ScriptGlobal::Get("RunAsGroup");
 
-       if (!Utility::SetFileOwnership(pki_path, user, group)) {
+       if (!Utility::SetFileOwnership(certsDir, user, group)) {
                Log(LogWarning, "cli")
-                       << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << pki_path << "'. Verify it yourself!";
+                       << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << certsDir << "'. Verify it yourself!";
        }
 
-       String key = pki_path + "/" + cn + ".key";
-       String cert = pki_path + "/" + cn + ".crt";
-       String ca = pki_path + "/ca.crt";
+       String key = certsDir + "/" + cn + ".key";
+       String cert = certsDir + "/" + cn + ".crt";
+       String ca = certsDir + "/ca.crt";
 
        if (Utility::PathExists(key))
                NodeUtility::CreateBackupFile(key, true);
@@ -354,11 +368,11 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
 
        Log(LogInformation, "cli", "Requesting a signed certificate from the parent Icinga node.");
 
-       if (PkiUtility::RequestCertificate(master_host, master_port, key, cert, ca, trustedcert, ticket) > 0) {
+       if (PkiUtility::RequestCertificate(parentHost, parentPort, key, cert, ca, trustedcert, ticket) > 0) {
                Log(LogCritical, "cli")
                        << "Failed to fetch signed certificate from parent Icinga node '"
-                       << master_host << ", "
-                       << master_port << "'. Please try again.";
+                       << parentHost << ", "
+                       << parentPort << "'. Please try again.";
                return 1;
        }
 
@@ -432,10 +446,22 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
                        << boost::errinfo_file_name(tempApiPath));
        }
 
-       /* generate local zones.conf with zone+endpoint */
 
+       /* Generate zones configuration. */
        Log(LogInformation, "cli", "Generating zone and object configuration.");
 
+       /* Setup command hardcodes this as FQDN */
+       String endpointName = cn;
+
+       /* Allow to specify zone name. */
+       String zoneName = vm["zone"].as<std::string>();
+
+       /* Allow to specify the parent zone name. */
+       String parentZoneName = "master";
+
+       if (vm.count("parent_zone"))
+               parentZoneName = vm["parent_zone"].as<std::string>();
+
        std::vector<String> globalZones { "global-templates", "director-global" };
        std::vector<std::string> setupGlobalZones;
 
@@ -452,7 +478,8 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
 
        globalZones.insert(globalZones.end(), setupGlobalZones.begin(), setupGlobalZones.end());
 
-       NodeUtility::GenerateNodeIcingaConfig(vm["endpoint"].as<std::vector<std::string> >(), globalZones);
+       /* Generate node configuration. */
+       NodeUtility::GenerateNodeIcingaConfig(endpointName, zoneName, parentZoneName, vm["endpoint"].as<std::vector<std::string> >(), globalZones);
 
        /* update constants.conf with NodeName = CN */
        if (cn != Utility::GetFQDN()) {
index 5d4c6c90aac87138d2337e4b10b78e6ac6ea6453..645e19d947d1d951d68b935f248a870ef15780b8 100644 (file)
@@ -46,80 +46,83 @@ String NodeUtility::GetConstantsConfPath()
        return Application::GetSysconfDir() + "/icinga2/constants.conf";
 }
 
+String NodeUtility::GetZonesConfPath()
+{
+       return Application::GetSysconfDir() + "/icinga2/zones.conf";
+}
+
 /*
  * Node Setup helpers
  */
 
-int NodeUtility::GenerateNodeIcingaConfig(const std::vector<std::string>& endpoints, const std::vector<String>& globalZones)
+int NodeUtility::GenerateNodeIcingaConfig(const String& endpointName, const String& zoneName,
+       const String& parentZoneName, const std::vector<std::string>& endpoints,
+       const std::vector<String>& globalZones)
 {
-       Array::Ptr my_config = new Array();
-
-       Array::Ptr my_master_zone_members = new Array();
+       Array::Ptr config = new Array();
 
-       String master_zone_name = "master"; //TODO: Find a better name.
+       Array::Ptr myParentZoneMembers = new Array();
 
        for (const String& endpoint : endpoints) {
                /* extract all --endpoint arguments and store host,port info */
                std::vector<String> tokens = endpoint.Split(",");
 
-               Dictionary::Ptr my_master_endpoint = new Dictionary();
+               Dictionary::Ptr myParentEndpoint = new Dictionary();
 
                if (tokens.size() > 1) {
                        String host = tokens[1].Trim();
 
                        if (!host.IsEmpty())
-                               my_master_endpoint->Set("host", host);
+                               myParentEndpoint->Set("host", host);
                }
 
                if (tokens.size() > 2) {
                        String port = tokens[2].Trim();
 
                        if (!port.IsEmpty())
-                               my_master_endpoint->Set("port", port);
+                               myParentEndpoint->Set("port", port);
                }
 
-               String cn = tokens[0].Trim();
-               my_master_endpoint->Set("__name", cn);
-               my_master_endpoint->Set("__type", "Endpoint");
+               String myEndpointName = tokens[0].Trim();
+               myParentEndpoint->Set("__name", myEndpointName);
+               myParentEndpoint->Set("__type", "Endpoint");
 
                /* save endpoint in master zone */
-               my_master_zone_members->Add(cn);
+               myParentZoneMembers->Add(myEndpointName);
 
-               my_config->Add(my_master_endpoint);
+               config->Add(myParentEndpoint);
        }
 
-       /* add the master zone to the config */
-       my_config->Add(new Dictionary({
-               { "__name", master_zone_name },
+       /* add the parent zone to the config */
+       config->Add(new Dictionary({
+               { "__name", parentZoneName },
                { "__type", "Zone" },
-               { "endpoints", my_master_zone_members }
+               { "endpoints", myParentZoneMembers }
        }));
 
        /* store the local generated node configuration */
-       my_config->Add(new Dictionary({
-               { "__name", new ConfigIdentifier("NodeName") },
+       config->Add(new Dictionary({
+               { "__name", endpointName },
                { "__type", "Endpoint" }
        }));
 
-       my_config->Add(new Dictionary({
-               { "__name", new ConfigIdentifier("ZoneName") },
+       config->Add(new Dictionary({
+               { "__name", zoneName },
                { "__type", "Zone" },
-               { "parent", master_zone_name }, //set the master zone as parent
-               { "endpoints", new Array({ new ConfigIdentifier("ZoneName") }) }
+               { "parent", parentZoneName },
+               { "endpoints", new Array({ endpointName }) }
        }));
 
        for (const String& globalzone : globalZones) {
-               my_config->Add(new Dictionary({
+               config->Add(new Dictionary({
                        { "__name", globalzone },
                        { "__type", "Zone" },
                        { "global", true }
                }));
        }
 
-       /* write the newly generated configuration */
-       String zones_path = Application::GetSysconfDir() + "/icinga2/zones.conf";
-
-       NodeUtility::WriteNodeConfigObjects(zones_path, my_config);
+       /* Write the newly generated configuration. */
+       NodeUtility::WriteNodeConfigObjects(GetZonesConfPath(), config);
 
        return 0;
 }
@@ -127,32 +130,30 @@ int NodeUtility::GenerateNodeIcingaConfig(const std::vector<std::string>& endpoi
 int NodeUtility::GenerateNodeMasterIcingaConfig(const String& endpointName, const String& zoneName,
        const std::vector<String>& globalZones)
 {
-       Array::Ptr my_config = new Array();
+       Array::Ptr config = new Array();
 
        /* store the local generated node master configuration */
-       my_config->Add(new Dictionary({
+       config->Add(new Dictionary({
                { "__name", endpointName },
                { "__type", "Endpoint" }
        }));
 
-       my_config->Add(new Dictionary({
+       config->Add(new Dictionary({
                { "__name", zoneName },
                { "__type", "Zone" },
                { "endpoints", new Array({ endpointName }) }
        }));
 
        for (const String& globalzone : globalZones) {
-               my_config->Add(new Dictionary({
+               config->Add(new Dictionary({
                        { "__name", globalzone },
                        { "__type", "Zone" },
                        { "global", true }
                }));
        }
 
-       /* write the newly generated configuration */
-       String zones_path = Application::GetSysconfDir() + "/icinga2/zones.conf";
-
-       NodeUtility::WriteNodeConfigObjects(zones_path, my_config);
+       /* Write the newly generated configuration. */
+       NodeUtility::WriteNodeConfigObjects(GetZonesConfPath(), config);
 
        return 0;
 }
@@ -215,7 +216,7 @@ bool NodeUtility::WriteNodeConfigObjects(const String& filename, const Array::Pt
 /*
  * We generally don't overwrite files without backup before
  */
-bool NodeUtility::CreateBackupFile(const String& target, bool is_private)
+bool NodeUtility::CreateBackupFile(const String& target, bool isPrivate)
 {
        if (!Utility::PathExists(target))
                return false;
@@ -231,7 +232,7 @@ bool NodeUtility::CreateBackupFile(const String& target, bool is_private)
        Utility::CopyFile(target, backup);
 
 #ifndef _WIN32
-       if (is_private)
+       if (isPrivate)
                chmod(backup.CStr(), 0600);
 #endif /* _WIN32 */
 
index b9c66ff64a14097a4e39915a4f041111077070a2..2ba33c2f366ef595a886635f3e5db529b36c85d0 100644 (file)
@@ -38,15 +38,18 @@ class NodeUtility
 {
 public:
        static String GetConstantsConfPath();
+       static String GetZonesConfPath();
 
-       static bool CreateBackupFile(const String& target, bool is_private = false);
+       static bool CreateBackupFile(const String& target, bool isPrivate = false);
 
        static bool WriteNodeConfigObjects(const String& filename, const Array::Ptr& objects);
 
        static void UpdateConstant(const String& name, const String& value);
 
        /* node setup helpers */
-       static int GenerateNodeIcingaConfig(const std::vector<std::string>& endpoints, const std::vector<String>& globalZones);
+       static int GenerateNodeIcingaConfig(const String& endpointName, const String& zoneName,
+               const String& parentZoneName, const std::vector<std::string>& endpoints,
+               const std::vector<String>& globalZones);
        static int GenerateNodeMasterIcingaConfig(const String& endpointName, const String& zoneName,
                const std::vector<String>& globalZones);
 
index 384d8e5f2f6f71118dcc43472469a1240fa5f5eb..31fdfe00fef54a3ad0912c0f3bd999bde9e346f1 100644 (file)
@@ -254,6 +254,7 @@ wizard_endpoint_loop_start:
        if (choice.Contains("y"))
                goto wizard_endpoint_loop_start;
 
+       /* Extract parent node information. */
        String parentHost, parentPort;
 
        for (const String& endpoint : endpoints) {
@@ -496,9 +497,33 @@ wizard_ticket:
                        << boost::errinfo_file_name(tempApiConfPath));
        }
 
-       /* apilistener config */
+       /* Zones configuration. */
        Log(LogInformation, "cli", "Generating local zones.conf.");
 
+       /* Setup command hardcodes this as FQDN */
+       String endpointName = cn;
+
+       /* Different local zone name. */
+       std::cout << "\nLocal zone name [" + endpointName + "]: ";
+       std::getline(std::cin, answer);
+
+       if (answer.empty())
+               answer = endpointName;
+
+       String zoneName = answer;
+       zoneName = zoneName.Trim();
+
+       /* Different parent zone name. */
+       std::cout << "Parent zone name [master]: ";
+       std::getline(std::cin, answer);
+
+       if (answer.empty())
+               answer = "master";
+
+       String parentZoneName = answer;
+       parentZoneName = parentZoneName.Trim();
+
+       /* Global zones. */
        std::vector<String> globalZones { "global-templates", "director-global" };
 
        std::cout << "\nDo you want to specify additional global zones? [y/N]: ";
@@ -540,7 +565,8 @@ wizard_global_zone_loop_start:
        } else
                Log(LogInformation, "cli", "No additional global Zones have been specified");
 
-       NodeUtility::GenerateNodeIcingaConfig(endpoints, globalZones);
+       /* Generate node configuration. */
+       NodeUtility::GenerateNodeIcingaConfig(endpointName, zoneName, parentZoneName, endpoints, globalZones);
 
        if (cn != Utility::GetFQDN()) {
                Log(LogWarning, "cli")