]> granicus.if.org Git - icinga2/commitdiff
Cli: Refactor feature {enable,disable,list} code
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 21 Oct 2014 16:35:43 +0000 (18:35 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Tue, 21 Oct 2014 16:53:14 +0000 (18:53 +0200)
Required for agent setup.

refs #7423

lib/cli/featuredisablecommand.cpp
lib/cli/featureenablecommand.cpp
lib/cli/featurelistcommand.cpp
lib/cli/featureutility.cpp
lib/cli/featureutility.hpp

index 54af35aa866c7a4cd88071ff70ff616a650d098e..9c2253388fcfa98269bd30c39af94725e9afd109 100644 (file)
 #include "cli/featuredisablecommand.hpp"
 #include "cli/featureutility.hpp"
 #include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/convert.hpp"
-#include "base/console.hpp"
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string/join.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
 
 using namespace icinga;
 namespace po = boost::program_options;
@@ -46,7 +38,7 @@ String FeatureDisableCommand::GetShortDescription(void) const
 
 std::vector<String> FeatureDisableCommand::GetPositionalSuggestions(const String& word) const
 {
-       return FeatureUtility::GetFieldCompletionSuggestions(FeatureCommandDisable, word);
+       return FeatureUtility::GetFieldCompletionSuggestions(word, false);
 }
 
 /**
@@ -56,49 +48,10 @@ std::vector<String> FeatureDisableCommand::GetPositionalSuggestions(const String
  */
 int FeatureDisableCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       String features_enabled_dir = Application::GetSysconfDir() + "/icinga2/features-enabled";
-
        if (ap.empty()) {
                Log(LogCritical, "cli", "Cannot disable feature(s). Name(s) are missing!");
                return 0;
        }
 
-       if (!Utility::PathExists(features_enabled_dir) ) {
-               Log(LogCritical, "cli")
-                   << "Cannot disable features. Path '" << features_enabled_dir << "' does not exist.";
-               return 0;
-       }
-
-       std::vector<std::string> errors;
-
-       BOOST_FOREACH(const String& feature, ap) {
-               String target = features_enabled_dir + "/" + feature + ".conf";
-
-               if (!Utility::PathExists(target) ) {
-                       Log(LogCritical, "cli")
-                           << "Cannot disable feature '" << feature << "'. Target file '" << target << "' does not exist.";
-                       errors.push_back(feature);
-                       continue;
-               }
-
-               if (unlink(target.CStr()) < 0) {
-                       Log(LogCritical, "cli")
-                           << "Cannot disable feature '" << feature << "'. Unlinking target file '" << target
-                           << "' failed with error code " << errno << ", \"" + Utility::FormatErrorNumber(errno) << "\".";
-                       errors.push_back(feature);
-                       continue;
-               }
-
-               std::cout << "Disabling feature " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << feature
-                   << ConsoleColorTag(Console_Normal) << ". Make sure to restart Icinga 2 for these changes to take effect.\n";
-       }
-
-       if (!errors.empty()) {
-               Log(LogCritical, "cli")
-                   << "Cannot disable feature(s): " << boost::algorithm::join(errors, " ");
-               errors.clear();
-               return 1;
-       }
-
-       return 0;
+       return FeatureUtility::DisableFeatures(ap);
 }
index 36f80167a54767a2d98c93a9d9e01a85e95fddbd..131629bde1e5d3b6a6c39ffd4219d798d0ef5fe4 100644 (file)
 #include "cli/featureenablecommand.hpp"
 #include "cli/featureutility.hpp"
 #include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/convert.hpp"
-#include "base/console.hpp"
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string/join.hpp>
-#include <iostream>
-#include <fstream>
 
 using namespace icinga;
 namespace po = boost::program_options;
@@ -45,7 +38,7 @@ String FeatureEnableCommand::GetShortDescription(void) const
 
 std::vector<String> FeatureEnableCommand::GetPositionalSuggestions(const String& word) const
 {
-       return FeatureUtility::GetFieldCompletionSuggestions(FeatureCommandEnable, word);
+       return FeatureUtility::GetFieldCompletionSuggestions(word, true);
 }
 
 /**
@@ -55,78 +48,12 @@ std::vector<String> FeatureEnableCommand::GetPositionalSuggestions(const String&
  */
 int FeatureEnableCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       String features_available_dir = Application::GetSysconfDir() + "/icinga2/features-available";
-       String features_enabled_dir = Application::GetSysconfDir() + "/icinga2/features-enabled";
-
        if (ap.empty()) {
                Log(LogCritical, "cli", "Cannot enable feature(s). Name(s) are missing!");
                return 0;
        }
 
-       if (!Utility::PathExists(features_available_dir) ) {
-               Log(LogCritical, "cli")
-                   << "Cannot parse available features. Path '" << features_available_dir << "' does not exist.";
-               return 0;
-       }
-
-       if (!Utility::PathExists(features_enabled_dir) ) {
-               Log(LogCritical, "cli")
-                   << "Cannot enable features. Path '" << features_enabled_dir << "' does not exist.";
-               return 0;
-       }
-
-       std::vector<std::string> errors;
-
-       BOOST_FOREACH(const String& feature, ap) {
-               String source = features_available_dir + "/" + feature + ".conf";
-
-               if (!Utility::PathExists(source) ) {
-                       Log(LogCritical, "cli")
-                           << "Cannot enable feature '" << feature << "'. Source file '" << source + "' does not exist.";
-                       errors.push_back(feature);
-                       continue;
-               }
-
-               String target = features_enabled_dir + "/" + feature + ".conf";
-
-               if (Utility::PathExists(target) ) {
-                       Log(LogWarning, "cli")
-                           << "Feature '" << feature << "' already enabled.";
-                       continue;
-               }
-
-               std::cout << "Enabling feature " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << feature
-                   << ConsoleColorTag(Console_Normal) << ". Make sure to restart Icinga 2 for these changes to take effect.\n";
-
-#ifndef _WIN32
-               if (symlink(source.CStr(), target.CStr()) < 0) {
-                       Log(LogCritical, "cli")
-                           << "Cannot enable feature '" << feature << "'. Linking source '" << source << "' to target file '" << target
-                           << "' failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\".";
-                       errors.push_back(feature);
-                       continue;
-               }
-#else /* _WIN32 */
-               std::ofstream fp;
-               fp.open(target.CStr());
-               fp << "include \"../features-available/" << feature << ".conf\"" << std::endl;
-               fp.close();
-
-               if (fp.fail()) {
-                       Log(LogCritical, "cli")
-                           << "Cannot enable feature '" << feature << "'. Failed to open file '" << target << "'.";
-                       errors.push_back(feature);
-                       continue;
-               }
-#endif /* _WIN32 */
-       }
-
-       if (!errors.empty()) {
-               Log(LogCritical, "cli")
-                   << "Cannot enable feature(s): " << boost::algorithm::join(errors, " ");
-               errors.clear();
-               return 1;
-       }
+       return FeatureUtility::EnableFeatures(ap);
 
        return 0;
 }
index 76a25b870c4e40af9d85263a101372bed02a7ecd..7e0347fd6a03589d5fe8aaae9b1bf9ee3c16b3f0 100644 (file)
@@ -53,18 +53,5 @@ int FeatureListCommand::Run(const boost::program_options::variables_map& vm, con
                    << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
        }
 
-       std::vector<String> disabled_features;
-       std::vector<String> enabled_features;
-
-       if (!FeatureUtility::GetFeatures(FeaturesDisabled, disabled_features))
-               return 1;
-       if (!FeatureUtility::GetFeatures(FeaturesEnabled, enabled_features))
-               return 1;
-
-       std::cout << ConsoleColorTag(Console_ForegroundRed | Console_Bold) << "Disabled features: " << ConsoleColorTag(Console_Normal)
-           << boost::algorithm::join(disabled_features, " ") << "\n";
-       std::cout << ConsoleColorTag(Console_ForegroundGreen | Console_Bold) << "Enabled features: " << ConsoleColorTag(Console_Normal)
-           << boost::algorithm::join(enabled_features, " ") << "\n";
-
-       return 0;
+       return FeatureUtility::ListFeatures();
 }
index d3be2466830ca45640ef47e52f6e1c143093f1bd..a094459714b5f655fe76a2fb16d0ac27eb453de6 100644 (file)
 
 #include "cli/featureutility.hpp"
 #include "base/logger.hpp"
+#include "base/console.hpp"
 #include "base/application.hpp"
 #include <boost/foreach.hpp>
+#include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/replace.hpp>
 
 using namespace icinga;
@@ -35,19 +37,12 @@ String FeatureUtility::GetFeaturesEnabledPath(void)
        return Application::GetSysconfDir() + "/icinga2/features-enabled";
 }
 
-
-std::vector<String> FeatureUtility::GetFieldCompletionSuggestions(FeatureCommandType fctype, const String& word)
+std::vector<String> FeatureUtility::GetFieldCompletionSuggestions(const String& word, bool enable)
 {
        std::vector<String> cache;
        std::vector<String> suggestions;
 
-       if (fctype == FeatureCommandEnable) {
-               /* only suggest features not already enabled */
-               GetFeatures(FeaturesDisabled, cache);
-       } else if (fctype == FeatureCommandDisable) {
-               /* suggest all enabled features */
-               GetFeatures(FeaturesEnabled, cache);
-       }
+       GetFeatures(cache, enable);
 
        std::sort(cache.begin(), cache.end());
 
@@ -59,16 +54,169 @@ std::vector<String> FeatureUtility::GetFieldCompletionSuggestions(FeatureCommand
        return suggestions;
 }
 
-bool FeatureUtility::GetFeatures(FeatureType ftype, std::vector<String>& features)
+int FeatureUtility::EnableFeatures(const std::vector<std::string>& features)
 {
-       String path = Application::GetSysconfDir() + "/icinga2/";
+       String features_available_dir = GetFeaturesAvailablePath();
+       String features_enabled_dir = GetFeaturesEnabledPath();
 
-       /* disabled = available-enabled */
-       if (ftype == FeaturesDisabled) {
-               std::vector<String> enabled;
+       if (!Utility::PathExists(features_available_dir) ) {
+               Log(LogCritical, "cli")
+                   << "Cannot parse available features. Path '" << features_available_dir << "' does not exist.";
+               return 1;
+       }
+
+       if (!Utility::PathExists(features_enabled_dir) ) {
+               Log(LogCritical, "cli")
+                   << "Cannot enable features. Path '" << features_enabled_dir << "' does not exist.";
+               return 1;
+       }
+
+       std::vector<std::string> errors;
+
+       BOOST_FOREACH(const String& feature, features) {
+               String source = features_available_dir + "/" + feature + ".conf";
+
+               if (!Utility::PathExists(source) ) {
+                       Log(LogCritical, "cli")
+                           << "Cannot enable feature '" << feature << "'. Source file '" << source + "' does not exist.";
+                       errors.push_back(feature);
+                       continue;
+               }
+
+               String target = features_enabled_dir + "/" + feature + ".conf";
+
+               if (Utility::PathExists(target) ) {
+                       Log(LogWarning, "cli")
+                           << "Feature '" << feature << "' already enabled.";
+                       continue;
+               }
+
+               std::cout << "Enabling feature " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << feature
+                   << ConsoleColorTag(Console_Normal) << ". Make sure to restart Icinga 2 for these changes to take effect.\n";
+
+#ifndef _WIN32
+               if (symlink(source.CStr(), target.CStr()) < 0) {
+                       Log(LogCritical, "cli")
+                           << "Cannot enable feature '" << feature << "'. Linking source '" << source << "' to target file '" << target
+                           << "' failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\".";
+                       errors.push_back(feature);
+                       continue;
+               }
+#else /* _WIN32 */
+               std::ofstream fp;
+               fp.open(target.CStr());
+               fp << "include \"../features-available/" << feature << ".conf\"" << std::endl;
+               fp.close();
+
+               if (fp.fail()) {
+                       Log(LogCritical, "cli")
+                           << "Cannot enable feature '" << feature << "'. Failed to open file '" << target << "'.";
+                       errors.push_back(feature);
+                       continue;
+               }
+#endif /* _WIN32 */
+       }
+
+       if (!errors.empty()) {
+               Log(LogCritical, "cli")
+                   << "Cannot enable feature(s): " << boost::algorithm::join(errors, " ");
+               errors.clear();
+               return 1;
+       }
+
+       return 0;
+}
+
+int FeatureUtility::DisableFeatures(const std::vector<std::string>& features)
+{
+       String features_enabled_dir = GetFeaturesEnabledPath();
+
+       if (!Utility::PathExists(features_enabled_dir) ) {
+               Log(LogCritical, "cli")
+                   << "Cannot disable features. Path '" << features_enabled_dir << "' does not exist.";
+               return 0;
+       }
+
+       std::vector<std::string> errors;
+
+       BOOST_FOREACH(const String& feature, features) {
+               String target = features_enabled_dir + "/" + feature + ".conf";
+
+               if (!Utility::PathExists(target) ) {
+                       Log(LogCritical, "cli")
+                           << "Cannot disable feature '" << feature << "'. Target file '" << target << "' does not exist.";
+                       errors.push_back(feature);
+                       continue;
+               }
+
+               if (unlink(target.CStr()) < 0) {
+                       Log(LogCritical, "cli")
+                           << "Cannot disable feature '" << feature << "'. Unlinking target file '" << target
+                           << "' failed with error code " << errno << ", \"" + Utility::FormatErrorNumber(errno) << "\".";
+                       errors.push_back(feature);
+                       continue;
+               }
+
+               std::cout << "Disabling feature " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << feature
+                   << ConsoleColorTag(Console_Normal) << ". Make sure to restart Icinga 2 for these changes to take effect.\n";
+       }
+
+       if (!errors.empty()) {
+               Log(LogCritical, "cli")
+                   << "Cannot disable feature(s): " << boost::algorithm::join(errors, " ");
+               errors.clear();
+               return 1;
+       }
+
+       return 0;
+}
+
+int FeatureUtility::ListFeatures(void)
+{
+       std::vector<String> disabled_features;
+       std::vector<String> enabled_features;
+
+       if (!FeatureUtility::GetFeatures(disabled_features, true))
+               return 1;
+
+       std::cout << ConsoleColorTag(Console_ForegroundRed | Console_Bold) << "Disabled features: " << ConsoleColorTag(Console_Normal)
+           << boost::algorithm::join(disabled_features, " ") << "\n";
+
+       if (!FeatureUtility::GetFeatures(enabled_features, false))
+               return 1;
+
+       std::cout << ConsoleColorTag(Console_ForegroundGreen | Console_Bold) << "Enabled features: " << ConsoleColorTag(Console_Normal)
+           << boost::algorithm::join(enabled_features, " ") << "\n";
+
+       return 0;
+}
+
+bool FeatureUtility::GetFeatures(std::vector<String>& features, bool get_disabled)
+{
+       String path;
+
+       /* request all disabled features */
+       if (get_disabled) {
+               /* disable = available-enabled */
+               String available_pattern = GetFeaturesAvailablePath() + "/*.conf";
                std::vector<String> available;
-               GetFeatures(FeaturesAvailable, available);
-               GetFeatures(FeaturesEnabled, enabled);
+
+               if (!Utility::Glob(available_pattern,
+                   boost::bind(&FeatureUtility::CollectFeatures, _1, boost::ref(available)), GlobFile)) {
+                       Log(LogCritical, "cli")
+                           << "Cannot access path '" << path << "'.";
+                       return false;
+               }
+
+               String enabled_pattern = GetFeaturesEnabledPath() + "/*.conf";
+               std::vector<String> enabled;
+
+               if (!Utility::Glob(enabled_pattern,
+                   boost::bind(&FeatureUtility::CollectFeatures, _1, boost::ref(enabled)), GlobFile)) {
+                       Log(LogCritical, "cli")
+                           << "Cannot access path '" << path << "'.";
+                       return false;
+               }
 
                std::sort(available.begin(), available.end());
                std::sort(enabled.begin(), enabled.end());
@@ -77,19 +225,11 @@ bool FeatureUtility::GetFeatures(FeatureType ftype, std::vector<String>& feature
                        enabled.begin(), enabled.end(),
                        std::back_inserter(features)
                );
-
-               return true;
        } else {
-               if (ftype == FeaturesAvailable)
-                       path += "features-available/";
-               else if (ftype == FeaturesEnabled)
-                       path += "features-enabled/";
-               else {
-                       Log(LogCritical, "cli", "Unknown feature type passed. Bailing out.");
-                       return false;
-               }
+               /* all enabled features */
+               String enabled_pattern = GetFeaturesEnabledPath() + "/*.conf";
 
-               if (!Utility::Glob(path + "/*.conf",
+               if (!Utility::Glob(enabled_pattern,
                    boost::bind(&FeatureUtility::CollectFeatures, _1, boost::ref(features)), GlobFile)) {
                        Log(LogCritical, "cli")
                            << "Cannot access path '" << path << "'.";
index 11b06d5980f92af9da739fb90b754cb31e8f6dab..05b9a3c0e7360143908cb4206039388a3075b131 100644 (file)
 namespace icinga
 {
 
-enum FeatureType
-{
-       FeaturesAvailable,
-       FeaturesEnabled,
-       FeaturesDisabled
-};
-
-enum FeatureCommandType
-{
-       FeatureCommandEnable,
-       FeatureCommandDisable
-};
-
 /**
  * @ingroup cli
  */
 class FeatureUtility
 {
 public:
-       static std::vector<String> GetFieldCompletionSuggestions(FeatureCommandType fctype, const String& word);
-       static bool GetFeatures(FeatureType ftype, std::vector<String>& features);
        static String GetFeaturesAvailablePath(void);
        static String GetFeaturesEnabledPath(void);
 
+       static std::vector<String> GetFieldCompletionSuggestions(const String& word, bool enable);
+
+       static int EnableFeatures(const std::vector<std::string>& features);
+       static int DisableFeatures(const std::vector<std::string>& features);
+       static int ListFeatures(void);
+
+       static bool GetFeatures(std::vector<String>& features, bool enable);
+
 private:
        FeatureUtility(void);
        static void CollectFeatures(const String& feature_file, std::vector<String>& features);