set(cli_SOURCES
apisetupcommand.cpp apisetuputility.cpp
calistcommand.cpp casigncommand.cpp
- nodeaddcommand.cpp nodeblackandwhitelistcommand.cpp nodelistcommand.cpp noderemovecommand.cpp
- nodesetcommand.cpp nodesetupcommand.cpp nodeupdateconfigcommand.cpp nodewizardcommand.cpp nodeutility.cpp
+ nodesetupcommand.cpp nodewizardcommand.cpp nodeutility.cpp
clicommand.cpp
consolecommand.cpp
daemoncommand.cpp daemonutility.cpp
featureenablecommand.cpp featuredisablecommand.cpp featurelistcommand.cpp featureutility.cpp
objectlistcommand.cpp objectlistutility.cpp
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp pkirequestcommand.cpp pkisavecertcommand.cpp pkiticketcommand.cpp
- repositoryclearchangescommand.cpp repositorycommitcommand.cpp repositoryobjectcommand.cpp repositoryutility.cpp
variablegetcommand.cpp variablelistcommand.cpp variableutility.cpp
troubleshootcommand.cpp
)
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/nodeaddcommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("node/add", NodeAddCommand);
-
-String NodeAddCommand::GetDescription(void) const
-{
- return "Add Icinga 2 node.";
-}
-
-String NodeAddCommand::GetShortDescription(void) const
-{
- return "add node";
-}
-
-int NodeAddCommand::GetMinArguments(void) const
-{
- return 1;
-}
-
-bool NodeAddCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "node add" CLI command.
- *
- * @returns An exit status.
- */
-int NodeAddCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- NodeUtility::AddNode(ap[0]);
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef NODEADDCOMMAND_H
-#define NODEADDCOMMAND_H
-
-#include "cli/clicommand.hpp"
-
-namespace icinga
-{
-
-/**
- * The "node add" command.
- *
- * @ingroup cli
- */
-class NodeAddCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(NodeAddCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual int GetMinArguments(void) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* NODEADDCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/nodeblackandwhitelistcommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/objectlock.hpp"
-#include "base/json.hpp"
-#include <iostream>
-#include <fstream>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_BLACKANDWHITELIST_CLICOMMAND(whitelist);
-REGISTER_BLACKANDWHITELIST_CLICOMMAND(blacklist);
-
-BlackAndWhitelistCommand::BlackAndWhitelistCommand(const String& type, BlackAndWhitelistCommandType command)
- : m_Type(type), m_Command(command)
-{ }
-
-String BlackAndWhitelistCommand::GetDescription(void) const
-{
- String description;
-
- switch (m_Command) {
- case BlackAndWhitelistCommandAdd:
- description = "Adds a new";
- break;
- case BlackAndWhitelistCommandRemove:
- description = "Removes a";
- break;
- case BlackAndWhitelistCommandList:
- description = "Lists all";
- break;
- }
-
- description += " " + m_Type + " filter";
-
- if (m_Command == BlackAndWhitelistCommandList)
- description += "s";
-
- return description;
-}
-
-String BlackAndWhitelistCommand::GetShortDescription(void) const
-{
- String description;
-
- switch (m_Command) {
- case BlackAndWhitelistCommandAdd:
- description = "adds a new";
- break;
- case BlackAndWhitelistCommandRemove:
- description = "removes a";
- break;
- case BlackAndWhitelistCommandList:
- description = "lists all";
- break;
- }
-
- description += " " + m_Type + " filter";
-
- if (m_Command == BlackAndWhitelistCommandList)
- description += "s";
-
- return description;
-}
-
-bool BlackAndWhitelistCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-void BlackAndWhitelistCommand::InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const
-{
- if (m_Command == BlackAndWhitelistCommandAdd || m_Command == BlackAndWhitelistCommandRemove) {
- visibleDesc.add_options()
- ("zone", po::value<std::string>(), "The name of the zone")
- ("host", po::value<std::string>(), "The name of the host")
- ("service", po::value<std::string>(), "The name of the service");
- }
-}
-
-/**
- * The entry point for the "node <whitelist/blacklist> <add/remove/list>" CLI command.
- *
- * @returns An exit status.
- */
-int BlackAndWhitelistCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- if (m_Command == BlackAndWhitelistCommandAdd) {
- if (!vm.count("zone")) {
- Log(LogCritical, "cli", "At least the zone name filter is required!");
- return 1;
- }
-
- if (!vm.count("host")) {
- Log(LogCritical, "cli", "At least the host name filter is required!");
- return 1;
- }
-
- String service_filter;
-
- if (vm.count("service"))
- service_filter = vm["service"].as<std::string>();
-
- return NodeUtility::UpdateBlackAndWhiteList(m_Type, vm["zone"].as<std::string>(), vm["host"].as<std::string>(), service_filter);
- } else if (m_Command == BlackAndWhitelistCommandList) {
- return NodeUtility::PrintBlackAndWhiteList(std::cout, m_Type);
- } else if (m_Command == BlackAndWhitelistCommandRemove) {
- if (!vm.count("zone")) {
- Log(LogCritical, "cli", "The zone name filter is required!");
- return 1;
- }
-
- if (!vm.count("host")) {
- Log(LogCritical, "cli", "The host name filter is required!");
- return 1;
- }
-
- String zone_filter = vm["zone"].as<std::string>();
- String host_filter = vm["host"].as<std::string>();
- String service_filter;
-
- if (vm.count("service")) {
- service_filter = vm["service"].as<std::string>();
- }
-
- return NodeUtility::RemoveBlackAndWhiteList(m_Type, vm["zone"].as<std::string>(), vm["host"].as<std::string>(), service_filter);
- }
-
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef BLACKANDWHITELISTCOMMAND_H
-#define BLACKANDWHITELISTCOMMAND_H
-
-#include "cli/clicommand.hpp"
-#include <boost/algorithm/string/case_conv.hpp>
-
-namespace icinga
-{
-
-enum BlackAndWhitelistCommandType
-{
- BlackAndWhitelistCommandAdd,
- BlackAndWhitelistCommandRemove,
- BlackAndWhitelistCommandList
-};
-
-/**
- * The "repository <type> <add/remove/list>" command.
- *
- * @ingroup cli
- */
-class I2_CLI_API BlackAndWhitelistCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(BlackAndWhitelistCommand);
-
- BlackAndWhitelistCommand(const String& type, BlackAndWhitelistCommandType command);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual void InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-
-private:
- String m_Type;
- BlackAndWhitelistCommandType m_Command;
-};
-
-#define REGISTER_BLACKANDWHITELIST_CLICOMMAND(type) \
- INITIALIZE_ONCE([]() { \
- String ltype = #type; \
- boost::algorithm::to_lower(ltype); \
-\
- std::vector<String> name; \
- name.push_back("node"); \
- name.push_back(ltype); \
- name.push_back("add"); \
- CLICommand::Register(name, new BlackAndWhitelistCommand(#type, BlackAndWhitelistCommandAdd)); \
-\
- name[2] = "remove"; \
- CLICommand::Register(name, new BlackAndWhitelistCommand(#type, BlackAndWhitelistCommandRemove)); \
-\
- name[2] = "list"; \
- CLICommand::Register(name, new BlackAndWhitelistCommand(#type, BlackAndWhitelistCommandList)); \
- })
-
-}
-
-#endif /* BLACKANDWHITELISTCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/nodelistcommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/console.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("node/list", NodeListCommand);
-
-String NodeListCommand::GetDescription(void) const
-{
- return "Lists all Icinga 2 nodes.";
-}
-
-String NodeListCommand::GetShortDescription(void) const
-{
- return "lists all nodes";
-}
-
-bool NodeListCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-void NodeListCommand::InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const
-{
- visibleDesc.add_options()
- ("batch", "list nodes in json");
-}
-
-/**
- * The entry point for the "node list" CLI command.
- *
- * @returns An exit status.
- */
-int NodeListCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- if (!ap.empty()) {
- Log(LogWarning, "cli")
- << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
- }
-
- if (vm.count("batch"))
- NodeUtility::PrintNodesJson(std::cout);
- else
- NodeUtility::PrintNodes(std::cout);
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef NODELISTCOMMAND_H
-#define NODELISTCOMMAND_H
-
-#include "cli/clicommand.hpp"
-
-namespace icinga
-{
-
-/**
- * The "node list" command.
- *
- * @ingroup cli
- */
-class NodeListCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(NodeListCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual void InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* NODELISTCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/noderemovecommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("node/remove", NodeRemoveCommand);
-
-String NodeRemoveCommand::GetDescription(void) const
-{
- return "Removes Icinga 2 node.";
-}
-
-String NodeRemoveCommand::GetShortDescription(void) const
-{
- return "removes node";
-}
-
-std::vector<String> NodeRemoveCommand::GetPositionalSuggestions(const String& word) const
-{
- return NodeUtility::GetNodeCompletionSuggestions(word);
-}
-
-int NodeRemoveCommand::GetMinArguments(void) const
-{
- return 1;
-}
-
-int NodeRemoveCommand::GetMaxArguments(void) const
-{
- return -1;
-}
-
-bool NodeRemoveCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "node remove" CLI command.
- *
- * @returns An exit status.
- */
-int NodeRemoveCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- for (const String& node : ap) {
- NodeUtility::RemoveNode(node);
- }
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef NODEREMOVECOMMAND_H
-#define NODEREMOVECOMMAND_H
-
-#include "cli/clicommand.hpp"
-
-namespace icinga
-{
-
-/**
- * The "node remove" command.
- *
- * @ingroup cli
- */
-class NodeRemoveCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(NodeRemoveCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual int GetMinArguments(void) const override;
- virtual int GetMaxArguments(void) const override;
- virtual std::vector<String> GetPositionalSuggestions(const String& word) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* NODEREMOVECOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/nodesetcommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("node/set", NodeSetCommand);
-
-String NodeSetCommand::GetDescription(void) const
-{
- return "Set node attribute(s).";
-}
-
-String NodeSetCommand::GetShortDescription(void) const
-{
- return "set node attributes";
-}
-
-void NodeSetCommand::InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const
-{
- visibleDesc.add_options()
- ("host", po::value<std::string>(), "Icinga 2 host")
- ("port", po::value<std::string>(), "Icinga 2 port")
- ("log_duration", po::value<double>(), "Log duration (in seconds)");
-}
-
-int NodeSetCommand::GetMinArguments(void) const
-{
- return 1;
-}
-
-bool NodeSetCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "node set" CLI command.
- *
- * @returns An exit status.
- */
-int NodeSetCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- String repoFile = NodeUtility::GetNodeRepositoryFile(ap[0]);
-
- if (!Utility::PathExists(repoFile)) {
- Log(LogCritical, "cli")
- << "Node '" << ap[0] << "' does not exist.";
- return 1;
- }
-
- String host, port = "5665";
- double log_duration = 24 * 60 * 60;
-
- if (vm.count("host"))
- host = vm["host"].as<std::string>();
-
- if (vm.count("port"))
- port = vm["port"].as<std::string>();
-
- if (vm.count("log_duration"))
- log_duration = vm["log_duration"].as<double>();
-
- NodeUtility::AddNodeSettings(ap[0], host, port, log_duration);
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef NODESETCOMMAND_H
-#define NODESETCOMMAND_H
-
-#include "cli/clicommand.hpp"
-
-namespace icinga
-{
-
-/**
- * The "node set" command.
- *
- * @ingroup cli
- */
-class NodeSetCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(NodeSetCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual int GetMinArguments(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual void InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* NODESETCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/nodeupdateconfigcommand.hpp"
-#include "cli/nodeutility.hpp"
-#include "cli/repositoryutility.hpp"
-#include "cli/variableutility.hpp"
-#include "base/logger.hpp"
-#include "base/console.hpp"
-#include "base/application.hpp"
-#include "base/tlsutility.hpp"
-#include "base/json.hpp"
-#include "base/objectlock.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("node/update-config", NodeUpdateConfigCommand);
-
-String NodeUpdateConfigCommand::GetDescription(void) const
-{
- return "Update Icinga 2 node config.";
-}
-
-String NodeUpdateConfigCommand::GetShortDescription(void) const
-{
- return "update node config";
-}
-
-ImpersonationLevel NodeUpdateConfigCommand::GetImpersonationLevel(void) const
-{
- return ImpersonateRoot;
-}
-
-bool NodeUpdateConfigCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "node update-config" CLI command.
- *
- * @returns An exit status.
- */
-int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- //If there are changes pending, abort the current operation
- if (RepositoryUtility::ChangeLogHasPendingChanges()) {
- Log(LogWarning, "cli")
- << "There are pending changes for commit.\n"
- << "Please review and commit them using 'icinga2 repository commit [--simulate]'\n"
- << "or drop them using 'icinga2 repository clear-changes' before proceeding.";
- return 1;
- }
-
- String inventory_path = NodeUtility::GetRepositoryPath() + "/inventory.index";
-
- Dictionary::Ptr old_inventory = new Dictionary();
- if (Utility::PathExists(inventory_path)) {
- old_inventory = Utility::LoadJsonFile(inventory_path);
- }
-
- Dictionary::Ptr inventory = new Dictionary();
-
- Log(LogInformation, "cli")
- << "Updating node configuration for ";
-
- NodeUtility::PrintNodes(std::cout);
-
- /* cache all existing object configs only once and pass it to AddObject() */
- std::vector<String> object_paths = RepositoryUtility::GetObjects();
- /* cache all existing changes only once and pass it to AddObject() */
- Array::Ptr changes = new Array();
- RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
-
- std::vector<Dictionary::Ptr> nodes = NodeUtility::GetNodes();
-
- /* first make sure that all nodes are valid and should not be removed */
- for (const Dictionary::Ptr& node : nodes) {
- Dictionary::Ptr repository = node->Get("repository");
- String zone = node->Get("zone");
- String endpoint = node->Get("endpoint");
- String node_name = endpoint;
-
- /* store existing structure in index */
- inventory->Set(endpoint, node);
- }
-
- if (old_inventory) {
- /* check if there are objects inside the old_inventory which do not exist anymore */
- ObjectLock ulock(old_inventory);
- for (const Dictionary::Pair& old_node_objs : old_inventory) {
-
- String old_node_name = old_node_objs.first;
-
- /* check if the node was dropped */
- if (!inventory->Contains(old_node_name)) {
- Log(LogInformation, "cli")
- << "Node update found old node '" << old_node_name << "'. Removing it and all of its hosts/services.";
-
- //TODO Remove an node and all of his hosts
- Dictionary::Ptr old_node = old_node_objs.second;
- Dictionary::Ptr old_node_repository = old_node->Get("repository");
-
- if (old_node_repository) {
- ObjectLock olock(old_node_repository);
- for (const Dictionary::Pair& kv : old_node_repository) {
- String host = kv.first;
-
- Dictionary::Ptr host_attrs = new Dictionary();
- host_attrs->Set("name", host);
- RepositoryUtility::RemoveObject(host, "Host", host_attrs, changes); //this removes all services for this host as well
- }
- }
-
- String zone = old_node->Get("zone");
- String endpoint = old_node->Get("endpoint");
-
- Dictionary::Ptr zone_attrs = new Dictionary();
- zone_attrs->Set("name", zone);
- RepositoryUtility::RemoveObject(zone, "Zone", zone_attrs, changes);
-
- Dictionary::Ptr endpoint_attrs = new Dictionary();
- endpoint_attrs->Set("name", endpoint);
- RepositoryUtility::RemoveObject(endpoint, "Endpoint", endpoint_attrs, changes);
- } else {
- /* get the current node */
- Dictionary::Ptr new_node = inventory->Get(old_node_name);
- Dictionary::Ptr new_node_repository = new_node->Get("repository");
-
- Dictionary::Ptr old_node = old_node_objs.second;
- Dictionary::Ptr old_node_repository = old_node->Get("repository");
-
- if (old_node_repository) {
- ObjectLock xlock(old_node_repository);
- for (const Dictionary::Pair& kv : old_node_repository) {
- String old_host = kv.first;
-
- if (old_host == "localhost") {
- Log(LogWarning, "cli")
- << "Ignoring host '" << old_host << "'. Please make sure to configure a unique name on your node '" << old_node_name << "'.";
- continue;
- }
-
- /* check against black/whitelist before trying to remove host */
- if (NodeUtility::CheckAgainstBlackAndWhiteList("blacklist", old_node_name, old_host, Empty) &&
- !NodeUtility::CheckAgainstBlackAndWhiteList("whitelist", old_node_name, old_host, Empty)) {
- Log(LogWarning, "cli")
- << "Host '" << old_node_name << "' on node '" << old_node_name << "' is blacklisted, but not whitelisted. Skipping.";
- continue;
- }
-
- if (!new_node_repository->Contains(old_host)) {
- Log(LogInformation, "cli")
- << "Node update found old host '" << old_host << "' on node '" << old_node_name << "'. Removing it.";
-
- Dictionary::Ptr host_attrs = new Dictionary();
- host_attrs->Set("name", old_host);
- RepositoryUtility::RemoveObject(old_host, "Host", host_attrs, changes); //this will remove all services for this host too
- } else {
- /* host exists, now check all services for this host */
- Array::Ptr old_services = kv.second;
- Array::Ptr new_services = new_node_repository->Get(old_host);
-
- ObjectLock ylock(old_services);
- for (const String& old_service : old_services) {
- /* check against black/whitelist before trying to remove service */
- if (NodeUtility::CheckAgainstBlackAndWhiteList("blacklist", old_node_name, old_host, old_service) &&
- !NodeUtility::CheckAgainstBlackAndWhiteList("whitelist", old_node_name, old_host, old_service)) {
- Log(LogWarning, "cli")
- << "Service '" << old_service << "' on host '" << old_host << "' on node '"
- << old_node_name << "' is blacklisted, but not whitelisted. Skipping.";
- continue;
- }
-
- if (!new_services->Contains(old_service)) {
- Log(LogInformation, "cli")
- << "Node update found old service '" << old_service << "' on host '" << old_host
- << "' on node '" << old_node_name << "'. Removing it.";
-
- Dictionary::Ptr service_attrs = new Dictionary();
- service_attrs->Set("name", old_service);
- service_attrs->Set("host_name", old_host);
- RepositoryUtility::RemoveObject(old_service, "Service", service_attrs, changes);
- }
- }
- }
- }
- }
- }
- }
- }
-
- /* next iterate over all nodes and add hosts/services */
- for (const Dictionary::Ptr& node : nodes) {
- Dictionary::Ptr repository = node->Get("repository");
- String zone = node->Get("zone");
- String endpoint = node->Get("endpoint");
- String node_name = endpoint;
-
- Dictionary::Ptr host_services = new Dictionary();
-
- if (NodeUtility::CheckAgainstBlackAndWhiteList("blacklist", node_name, "*", Empty) &&
- !NodeUtility::CheckAgainstBlackAndWhiteList("whitelist", node_name, "*", Empty)) {
- Log(LogWarning, "cli")
- << "Skipping node '" << node_name << "' on blacklist.";
- continue;
- }
-
- Log(LogInformation, "cli")
- << "Adding host '" << zone << "' to the repository.";
-
- Dictionary::Ptr host_attrs = new Dictionary();
- host_attrs->Set("__name", zone);
- host_attrs->Set("name", zone);
- host_attrs->Set("check_command", "cluster-zone");
- Array::Ptr host_imports = new Array();
- host_imports->Add("satellite-host"); //default host node template
- host_attrs->Set("import", host_imports);
-
- if (!RepositoryUtility::AddObject(object_paths, zone, "Host", host_attrs, changes, false)) {
- Log(LogWarning, "cli")
- << "Cannot add node host '" << zone << "' to the config repository!\n";
- }
-
- if (repository) {
- ObjectLock olock(repository);
- for (const Dictionary::Pair& kv : repository) {
- String host = kv.first;
- String host_pattern = host + ".conf";
- bool skip_host = false;
-
- if (host == "localhost") {
- Log(LogWarning, "cli")
- << "Ignoring host '" << host << "'. Please make sure to configure a unique name on your node '" << endpoint << "'.";
- continue;
- }
-
- for (const String& object_path : object_paths) {
- if (object_path.Contains(host_pattern)) {
- Log(LogNotice, "cli")
- << "Host '" << host << "' already exists.";
- skip_host = true;
- break;
- }
- }
-
- /* host has already been created above */
- if (host == zone)
- skip_host = true;
-
- bool host_was_blacklisted = false;
-
- /* check against black/whitelist before trying to add host */
- if (NodeUtility::CheckAgainstBlackAndWhiteList("blacklist", node_name, host, Empty) &&
- !NodeUtility::CheckAgainstBlackAndWhiteList("whitelist", node_name, host, Empty)) {
- Log(LogWarning, "cli")
- << "Host '" << host << "' on node '" << node_name << "' is blacklisted, but not whitelisted. Not creating host object.";
- skip_host = true;
- host_was_blacklisted = true; //check this for services on this blacklisted host
- }
-
- if (!skip_host) {
- /* add a new host to the config repository */
- Dictionary::Ptr host_attrs = new Dictionary();
- host_attrs->Set("__name", host);
- host_attrs->Set("name", host);
-
- if (host == zone)
- host_attrs->Set("check_command", "cluster-zone");
- else {
- host_attrs->Set("check_command", "dummy");
- host_attrs->Set("zone", zone);
- }
-
- Array::Ptr host_imports = new Array();
- host_imports->Add("satellite-host"); //default host node template
- host_attrs->Set("import", host_imports);
-
- RepositoryUtility::AddObject(object_paths, host, "Host", host_attrs, changes, false);
- }
-
- /* special condition: what if the host was blacklisted before, but the services should be generated? */
- if (host_was_blacklisted) {
- Log(LogNotice, "cli")
- << "Host '" << host << "' was blacklisted. Won't generate any services.";
- continue;
- }
-
- Array::Ptr services = kv.second;
-
- if (services->GetLength() == 0) {
- Log(LogNotice, "cli")
- << "Host '" << host << "' without services.";
- continue;
- }
-
- ObjectLock xlock(services);
- for (const String& service : services) {
- bool skip_service = false;
-
- String service_pattern = host + "/" + service + ".conf";
-
- for (const String& object_path : object_paths) {
- if (object_path.Contains(service_pattern)) {
- Log(LogNotice, "cli")
- << "Service '" << service << "' on Host '" << host << "' already exists.";
- skip_service = true;
- break;
- }
- }
-
- /* check against black/whitelist before trying to add service */
- if (NodeUtility::CheckAgainstBlackAndWhiteList("blacklist", endpoint, host, service) &&
- !NodeUtility::CheckAgainstBlackAndWhiteList("whitelist", endpoint, host, service)) {
- Log(LogWarning, "cli")
- << "Service '" << service << "' on host '" << host << "' on node '"
- << node_name << "' is blacklisted, but not whitelisted. Not creating service object.";
- skip_service = true;
- }
-
- if (skip_service)
- continue;
-
- /* add a new service for this host to the config repository */
- Dictionary::Ptr service_attrs = new Dictionary();
- String long_name = host + "!" + service; //use NameComposer?
- service_attrs->Set("__name", long_name);
- service_attrs->Set("name", service);
- service_attrs->Set("host_name", host); //Required for host-service relation
- service_attrs->Set("check_command", "dummy");
- service_attrs->Set("zone", zone);
-
- Array::Ptr service_imports = new Array();
- service_imports->Add("satellite-service"); //default service node template
- service_attrs->Set("import", service_imports);
-
- if (!RepositoryUtility::AddObject(object_paths, service, "Service", service_attrs, changes, false))
- continue;
- }
- }
- }
-
- /* write a new zone and endpoint for the node */
- Dictionary::Ptr endpoint_attrs = new Dictionary();
- endpoint_attrs->Set("__name", endpoint);
- endpoint_attrs->Set("name", endpoint);
-
- Dictionary::Ptr settings = node->Get("settings");
-
- if (settings) {
- if (settings->Contains("host"))
- endpoint_attrs->Set("host", settings->Get("host"));
- if (settings->Contains("port"))
- endpoint_attrs->Set("port", settings->Get("port"));
- }
-
- Log(LogInformation, "cli")
- << "Adding endpoint '" << endpoint << "' to the repository.";
-
- if (!RepositoryUtility::AddObject(object_paths, endpoint, "Endpoint", endpoint_attrs, changes, false)) {
- Log(LogWarning, "cli")
- << "Cannot add node endpoint '" << endpoint << "' to the config repository!\n";
- }
-
- Dictionary::Ptr zone_attrs = new Dictionary();
- Array::Ptr zone_members = new Array();
-
- zone_members->Add(endpoint);
- zone_attrs->Set("__name", zone);
- zone_attrs->Set("name", zone);
- zone_attrs->Set("endpoints", zone_members);
-
- String parent_zone = VariableUtility::GetVariable("ZoneName");
-
- if (parent_zone.IsEmpty()) {
- Log(LogWarning, "cli")
- << "Variable 'ZoneName' is not set. Falling back to using 'master' as default. Please verify the generated configuration.";
- parent_zone = "master";
- }
-
- zone_attrs->Set("parent", parent_zone);
-
- Log(LogInformation, "cli")
- << "Adding zone '" << zone << "' to the repository.";
-
- if (!RepositoryUtility::AddObject(object_paths, zone, "Zone", zone_attrs, changes, false)) {
- Log(LogWarning, "cli")
- << "Cannot add node zone '" << zone << "' to the config repository!\n";
- }
- }
-
- Log(LogInformation, "cli", "Committing node configuration.");
-
- RepositoryUtility::PrintChangeLog(std::cout);
- std::cout << "\n";
- RepositoryUtility::CommitChangeLog();
-
- /* store the new inventory for next run */
- NodeUtility::CreateRepositoryPath();
- Utility::SaveJsonFile(inventory_path, 0600, inventory);
-
- std::cout << "Make sure to reload Icinga 2 for these changes to take effect." << std::endl;
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef NODEUPDATECONFIGCOMMAND_H
-#define NODEUPDATECONFIGCOMMAND_H
-
-#include "cli/clicommand.hpp"
-
-namespace icinga
-{
-
-/**
- * The "agent update-config" command.
- *
- * @ingroup cli
- */
-class NodeUpdateConfigCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(NodeUpdateConfigCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
- virtual ImpersonationLevel GetImpersonationLevel(void) const override;
-};
-
-}
-
-#endif /* NODEUPDATECONFIGCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/repositoryclearchangescommand.hpp"
-#include "cli/repositoryutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/utility.hpp"
-#include <fstream>
-#include <iostream>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("repository/clear-changes", RepositoryClearChangesCommand);
-
-String RepositoryClearChangesCommand::GetDescription(void) const
-{
- return "Clear uncommitted Icinga 2 repository changes";
-}
-
-String RepositoryClearChangesCommand::GetShortDescription(void) const
-{
- return "clear uncommitted repository changes";
-}
-
-ImpersonationLevel RepositoryClearChangesCommand::GetImpersonationLevel(void) const
-{
- return ImpersonateRoot;
-}
-
-bool RepositoryClearChangesCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "repository clear-changes" CLI command.
- *
- * @returns An exit status.
- */
-int RepositoryClearChangesCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- if (!Utility::PathExists(RepositoryUtility::GetRepositoryChangeLogPath())) {
- std::cout << "Repository Changelog path '" << RepositoryUtility::GetRepositoryChangeLogPath() << "' does not exist. Add objects first!\n";
- return 1;
- }
-
- std::cout << "Clearing all remaining changes\n";
- RepositoryUtility::ClearChangeLog();
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef REPOSITORYCLEARCHANGESCOMMAND_H
-#define REPOSITORYCLEARCHANGESCOMMAND_H
-
-#include "base/dictionary.hpp"
-#include "base/array.hpp"
-#include "cli/clicommand.hpp"
-#include <ostream>
-
-namespace icinga
-{
-
-/**
- * The "repository clear-changes" command.
- *
- * @ingroup cli
- */
-class RepositoryClearChangesCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(RepositoryClearChangesCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual ImpersonationLevel GetImpersonationLevel(void) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* REPOSITORYCLEARCHANGESCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/repositorycommitcommand.hpp"
-#include "cli/repositoryutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/utility.hpp"
-#include <fstream>
-#include <iostream>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_CLICOMMAND("repository/commit", RepositoryCommitCommand);
-
-String RepositoryCommitCommand::GetDescription(void) const
-{
- return "Commit Icinga 2 repository changes";
-}
-
-String RepositoryCommitCommand::GetShortDescription(void) const
-{
- return "commit repository changes";
-}
-
-void RepositoryCommitCommand::InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const
-{
- visibleDesc.add_options()
- ("simulate", "Simulate to-be-committed changes");
-}
-
-ImpersonationLevel RepositoryCommitCommand::GetImpersonationLevel(void) const
-{
- return ImpersonateRoot;
-}
-
-bool RepositoryCommitCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-/**
- * The entry point for the "repository commit" CLI command.
- *
- * @returns An exit status.
- */
-int RepositoryCommitCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- if (!Utility::PathExists(RepositoryUtility::GetRepositoryChangeLogPath())) {
- std::cout << "Repository Changelog path '" << RepositoryUtility::GetRepositoryChangeLogPath() << "' does not exist. Add objects first!\n";
- return 1;
- }
-
- if (vm.count("simulate")) {
- RepositoryUtility::PrintChangeLog(std::cout);
- std::cout << "\n";
- std::cout << "Simulation not yet implemented.\n";
- //TODO
- return 1;
- } else {
- RepositoryUtility::PrintChangeLog(std::cout);
- std::cout << "\n";
- RepositoryUtility::CommitChangeLog();
- }
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef REPOSITORYCOMMITCOMMAND_H
-#define REPOSITORYCOMMITCOMMAND_H
-
-#include "base/dictionary.hpp"
-#include "base/array.hpp"
-#include "cli/clicommand.hpp"
-#include <ostream>
-
-namespace icinga
-{
-
-/**
- * The "repository commit" command.
- *
- * @ingroup cli
- */
-class RepositoryCommitCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(RepositoryCommitCommand);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual void InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const override;
- virtual ImpersonationLevel GetImpersonationLevel(void) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-};
-
-}
-
-#endif /* REPOSITORYCOMMITCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/repositoryobjectcommand.hpp"
-#include "cli/repositoryutility.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/utility.hpp"
-#include <fstream>
-#include <iostream>
-
-using namespace icinga;
-namespace po = boost::program_options;
-
-REGISTER_REPOSITORY_CLICOMMAND(Host);
-REGISTER_REPOSITORY_CLICOMMAND(Service);
-REGISTER_REPOSITORY_CLICOMMAND(Zone);
-REGISTER_REPOSITORY_CLICOMMAND(Endpoint);
-
-RepositoryObjectCommand::RepositoryObjectCommand(const String& type, RepositoryCommandType command)
- : m_Type(type), m_Command(command)
-{ }
-
-String RepositoryObjectCommand::GetDescription(void) const
-{
- String description;
-
- switch (m_Command) {
- case RepositoryCommandAdd:
- description = "Adds a new";
- break;
- case RepositoryCommandRemove:
- description = "Removes a";
- break;
- case RepositoryCommandList:
- description = "Lists all";
- break;
- case RepositoryCommandSet:
- description = "Set attributes for a";
- break;
- default:
- break;
- }
-
- description += " " + m_Type + " object";
-
- if (m_Command == RepositoryCommandList)
- description += "s";
-
- return description;
-}
-
-String RepositoryObjectCommand::GetShortDescription(void) const
-{
- String description;
-
- switch (m_Command) {
- case RepositoryCommandAdd:
- description = "adds a new";
- break;
- case RepositoryCommandRemove:
- description = "removes a";
- break;
- case RepositoryCommandList:
- description = "lists all";
- break;
- case RepositoryCommandSet:
- description = "set attributes for a";
- break;
- default:
- break;
- }
-
- description += " " + m_Type + " object";
-
- if (m_Command == RepositoryCommandList)
- description += "s";
-
- return description;
-}
-
-bool RepositoryObjectCommand::IsDeprecated(void) const
-{
- return true;
-}
-
-void RepositoryObjectCommand::InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const
-{
- if (m_Command == RepositoryCommandAdd) {
- visibleDesc.add_options()
- ("import", po::value<std::vector<std::string> >(), "Import the defined template into the object. Must be defined and included separately in Icinga 2");
- }
-}
-
-std::vector<String> RepositoryObjectCommand::GetPositionalSuggestions(const String& word) const
-{
- if (m_Command == RepositoryCommandAdd) {
- Type::Ptr ptype = Type::GetByName(m_Type);
- ASSERT(ptype);
- return GetFieldCompletionSuggestions(ptype, word);
- } else if (m_Command == RepositoryCommandRemove) {
- std::vector<String> suggestions;
-
- String argName = "name=";
- if (argName.Find(word) == 0)
- suggestions.push_back(argName);
-
- if (m_Type == "Service") {
- String argHostName = "host_name=";
- if (argHostName.Find(word) == 0)
- suggestions.push_back(argHostName);
- }
-
- return suggestions;
- } else
- return CLICommand::GetPositionalSuggestions(word);
-}
-
-ImpersonationLevel RepositoryObjectCommand::GetImpersonationLevel(void) const
-{
- return ImpersonateRoot;
-}
-
-int RepositoryObjectCommand::GetMaxArguments(void) const
-{
- return -1;
-}
-
-/**
- * The entry point for the "repository <type> <add/remove/list>" CLI command.
- *
- * @returns An exit status.
- */
-int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
-{
- Dictionary::Ptr attrs = RepositoryUtility::GetArgumentAttributes(ap);
-
- /* shortcut for list command */
- if (m_Command == RepositoryCommandList) {
- RepositoryUtility::PrintObjects(std::cout, m_Type);
- return 0;
- }
-
- if (!attrs->Contains("name")) {
- Log(LogCritical, "cli", "Object requires a name (Hint: 'name=<objectname>')!");
- return 1;
- }
-
- String name = attrs->Get("name");
-
- if (vm.count("import")) {
- Array::Ptr imports = new Array();
-
- for (const String& import : vm["import"].as<std::vector<std::string> >()) {
- imports->Add(import);
- }
-
- //Update object attributes
- if (imports->GetLength() > 0)
- attrs->Set("import", imports);
- }
-
- if (m_Command == RepositoryCommandAdd) {
- std::vector<String> object_paths = RepositoryUtility::GetObjects();
-
- Array::Ptr changes = new Array();
- RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
-
- RepositoryUtility::AddObject(object_paths, name, m_Type, attrs, changes);
- } else if (m_Command == RepositoryCommandRemove) {
- Array::Ptr changes = new Array();
- RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
-
- /* pass attrs for service->host_name requirement */
- RepositoryUtility::RemoveObject(name, m_Type, attrs, changes);
- } else if (m_Command == RepositoryCommandSet) {
- Log(LogWarning, "cli")
- << "Not supported yet. Please check the roadmap at https://github.com/Icinga/icinga2\n";
- return 1;
- } else {
- Log(LogCritical, "cli")
- << "Invalid command '" << m_Command << "'specified.\n";
- return 1;
- }
-
- return 0;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef REPOSITORYOBJECTCOMMAND_H
-#define REPOSITORYOBJECTCOMMAND_H
-
-#include "cli/clicommand.hpp"
-#include <boost/algorithm/string/case_conv.hpp>
-
-namespace icinga
-{
-
-enum RepositoryCommandType
-{
- RepositoryCommandAdd,
- RepositoryCommandRemove,
- RepositoryCommandList,
- RepositoryCommandSet
-};
-
-/**
- * The "repository <type> <add/remove/list>" command.
- *
- * @ingroup cli
- */
-class I2_CLI_API RepositoryObjectCommand : public CLICommand
-{
-public:
- DECLARE_PTR_TYPEDEFS(RepositoryObjectCommand);
-
- RepositoryObjectCommand(const String& type, RepositoryCommandType command);
-
- virtual String GetDescription(void) const override;
- virtual String GetShortDescription(void) const override;
- virtual int GetMaxArguments(void) const override;
- virtual bool IsDeprecated(void) const override;
- virtual void InitParameters(boost::program_options::options_description& visibleDesc,
- boost::program_options::options_description& hiddenDesc) const override;
- virtual ImpersonationLevel GetImpersonationLevel(void) const override;
- virtual std::vector<String> GetPositionalSuggestions(const String& word) const override;
- virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
-
-private:
- String m_Type;
- RepositoryCommandType m_Command;
-};
-
-#define REGISTER_REPOSITORY_CLICOMMAND(type) \
- INITIALIZE_ONCE([]() { \
- String ltype = #type; \
- boost::algorithm::to_lower(ltype); \
-\
- std::vector<String> name; \
- name.push_back("repository"); \
- name.push_back(ltype); \
- name.push_back("add"); \
- CLICommand::Register(name, new RepositoryObjectCommand(#type, RepositoryCommandAdd)); \
-\
- name[2] = "remove"; \
- CLICommand::Register(name, new RepositoryObjectCommand(#type, RepositoryCommandRemove)); \
-\
- name[2] = "list"; \
- CLICommand::Register(name, new RepositoryObjectCommand(#type, RepositoryCommandList)); \
- })
-
-}
-
-#endif /* REPOSITORYOBJECTCOMMAND_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "cli/repositoryutility.hpp"
-#include "cli/clicommand.hpp"
-#include "base/logger.hpp"
-#include "base/application.hpp"
-#include "base/convert.hpp"
-#include "base/configwriter.hpp"
-#include "base/scriptglobal.hpp"
-#include "base/json.hpp"
-#include "base/netstring.hpp"
-#include "base/tlsutility.hpp"
-#include "base/stdiostream.hpp"
-#include "base/debug.hpp"
-#include "base/objectlock.hpp"
-#include "base/console.hpp"
-#include "base/serializer.hpp"
-#include "base/exception.hpp"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/regex.hpp>
-#include <fstream>
-#include <iostream>
-
-using namespace icinga;
-
-Dictionary::Ptr RepositoryUtility::GetArgumentAttributes(const std::vector<std::string>& arguments)
-{
- Dictionary::Ptr attrs = new Dictionary();
-
- for (const String& kv : arguments) {
- std::vector<String> tokens;
- boost::algorithm::split(tokens, kv, boost::is_any_of("="));
-
- if (tokens.size() != 2) {
- Log(LogWarning, "cli")
- << "Cannot parse passed attributes: " << boost::algorithm::join(tokens, "=");
- continue;
- }
-
- Value value;
-
- try {
- value = Convert::ToDouble(tokens[1]);
- } catch (...) {
- value = tokens[1];
- }
-
- attrs->Set(tokens[0], value);
- }
-
- return attrs;
-}
-
-String RepositoryUtility::GetRepositoryConfigPath(void)
-{
- return Application::GetSysconfDir() + "/icinga2/repository.d";
-}
-
-String RepositoryUtility::GetRepositoryObjectConfigPath(const String& type, const Dictionary::Ptr& object)
-{
- String path = GetRepositoryConfigPath() + "/";
-
- if (type == "Host")
- path += "hosts";
- else if (type == "Service")
- path += "hosts/" + EscapeName(object->Get("host_name"));
- else if (type == "Zone")
- path += "zones";
- else if (type == "Endpoint")
- path += "endpoints";
-
- return path;
-}
-
-bool RepositoryUtility::FilterRepositoryObjects(const String& type, const String& path)
-{
- if (type == "Host") {
- boost::regex expr("hosts/[^/]*.conf", boost::regex::icase);
- boost::smatch what;
- return boost::regex_search(path.GetData(), what, expr);
- }
- else if (type == "Service")
- return Utility::Match("*hosts/*/*.conf", path);
- else if (type == "Zone")
- return Utility::Match("*zones/*.conf", path);
- else if (type == "Endpoints")
- return Utility::Match("*endpoints/*.conf", path);
-
- return false;
-}
-
-String RepositoryUtility::GetRepositoryObjectConfigFilePath(const String& type, const Dictionary::Ptr& object)
-{
- String path = GetRepositoryObjectConfigPath(type, object);
-
- path += "/" + EscapeName(object->Get("name")) + ".conf";
-
- return path;
-}
-
-String RepositoryUtility::GetRepositoryChangeLogPath(void)
-{
- return Application::GetLocalStateDir() + "/lib/icinga2/repository/changes";
-}
-
-void RepositoryUtility::CreateRepositoryPath(const String& path)
-{
- if (!Utility::PathExists(path))
- Utility::MkDirP(path, 0750);
-
- String user = ScriptGlobal::Get("RunAsUser");
- String group = ScriptGlobal::Get("RunAsGroup");
-
- if (!Utility::SetFileOwnership(path, user, group)) {
- Log(LogWarning, "cli")
- << "Cannot set ownership for user '" << user << "' group '" << group << "' on path '" << path << "'. Verify it yourself!";
- }
-}
-
-/* printers */
-void RepositoryUtility::PrintObjects(std::ostream& fp, const String& type)
-{
- std::vector<String> objects = GetObjects(); //full path
-
- for (const String& object : objects) {
- if (!FilterRepositoryObjects(type, object)) {
- Log(LogDebug, "cli")
- << "Ignoring object '" << object << "'. Type '" << type << "' does not match.";
- continue;
- }
-
- String file = Utility::BaseName(object);
- boost::algorithm::replace_all(file, ".conf", "");
- file = UnescapeName(file);
-
- fp << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << type << ConsoleColorTag(Console_Normal)
- << " '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << file << ConsoleColorTag(Console_Normal) << "'";
-
- String prefix = Utility::DirName(object);
-
- if (type == "Service") {
- std::vector<String> tokens;
- boost::algorithm::split(tokens, prefix, boost::is_any_of("/"));
-
- String host_name = UnescapeName(tokens[tokens.size()-1]);
- fp << " (on " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << "Host" << ConsoleColorTag(Console_Normal)
- << " '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << host_name << ConsoleColorTag(Console_Normal) << "')";
-
- }
-
- fp << "\n";
- }
-}
-
-void RepositoryUtility::PrintChangeLog(std::ostream& fp)
-{
- Array::Ptr changelog = new Array();
-
- GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changelog));
-
- ObjectLock olock(changelog);
-
- std::cout << "Changes to be committed:\n\n";
-
- for (const Value& entry : changelog) {
- FormatChangelogEntry(std::cout, entry);
- }
-}
-
-class RepositoryValidationUtils : public ValidationUtils
-{
-public:
- virtual bool ValidateName(const String& type, const String& name) const
- {
- return true;
- }
-};
-
-/* modify objects and write changelog */
-bool RepositoryUtility::AddObject(const std::vector<String>& object_paths, const String& name, const String& type,
- const Dictionary::Ptr& attrs, const Array::Ptr& changes, bool check_config)
-{
- String pattern;
-
- if (type == "Service")
- pattern = EscapeName(attrs->Get("host_name")) + "/" + EscapeName(name) + ".conf";
- else
- pattern = EscapeName(name) + ".conf";
-
- for (const String& object_path : object_paths) {
- if (object_path.Contains(pattern)) {
- Log(LogWarning, "cli")
- << type << " '" << name << "' already exists. Skipping creation.";
- return false;
- }
- }
-
- /* add a new changelog entry by timestamp */
- String path = GetRepositoryChangeLogPath() + "/" + Convert::ToString(Utility::GetTime()) + "-" + type + "-" + SHA256(name) + ".change";
-
- Dictionary::Ptr change = new Dictionary();
-
- change->Set("timestamp", Utility::GetTime());
- change->Set("name", name);
- change->Set("type", type);
- change->Set("command", "add");
- change->Set("attrs", attrs);
-
- Type::Ptr utype = Type::GetByName(type);
- ASSERT(utype);
-
- if (check_config) {
- try {
- ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(utype->Instantiate(std::vector<Value>()));
- /* temporarly set the object type for validation */
- attrs->Set("type", utype->GetName());
- Deserialize(object, attrs, false, FAConfig);
- object->SetName(name);
-
- RepositoryValidationUtils utils;
- static_pointer_cast<ConfigObject>(object)->Validate(FAConfig, utils);
-
- attrs->Remove("type");
- } catch (const ValidationError& ex) {
- Log(LogCritical, "config", DiagnosticInformation(ex));
- return false;
- }
- }
-
- if (CheckChangeExists(change, changes)) {
- Log(LogWarning, "cli")
- << "Change '" << change->Get("command") << "' for type '"
- << change->Get("type") << "' and name '" << change->Get("name")
- << "' already exists.";
-
- return false;
- }
-
- /* store the cached change */
- changes->Add(change);
-
- return WriteObjectToRepositoryChangeLog(path, change);
-}
-
-bool RepositoryUtility::RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes)
-{
- /* add a new changelog entry by timestamp */
- String path = GetRepositoryChangeLogPath() + "/" + Convert::ToString(Utility::GetTime()) + "-" + type + "-" + SHA256(name) + ".change";
-
- Dictionary::Ptr change = new Dictionary();
-
- change->Set("timestamp", Utility::GetTime());
- change->Set("name", name);
- change->Set("type", type);
- change->Set("command", "remove");
- change->Set("attrs", attrs); //required for service->host_name
-
- if (CheckChangeExists(change, changes)) {
- Log(LogWarning, "cli")
- << "Change '" << change->Get("command") << "' for type '"
- << change->Get("type") << "' and name '" << change->Get("name")
- << "' already exists.";
-
- return false;
- }
-
- /* store the cached change */
- changes->Add(change);
-
- return WriteObjectToRepositoryChangeLog(path, change);
-}
-
-bool RepositoryUtility::SetObjectAttribute(const String& name, const String& type, const String& attr, const Value& val)
-{
- //TODO: Implement modification commands
- return true;
-}
-
-bool RepositoryUtility::CheckChangeExists(const Dictionary::Ptr& change, const Array::Ptr& changes)
-{
- Dictionary::Ptr attrs = change->Get("attrs");
-
- ObjectLock olock(changes);
- for (const Dictionary::Ptr& entry : changes) {
- if (entry->Get("type") != change->Get("type"))
- continue;
-
- if (entry->Get("name") != change->Get("name"))
- continue;
-
- Dictionary::Ptr their_attrs = entry->Get("attrs");
-
- if (entry->Get("type") == "Service" && attrs->Get("host_name") != their_attrs->Get("host_name"))
- continue;
-
- if (entry->Get("command") != change->Get("command"))
- continue;
-
- /* only works for add/remove commands (no set) */
- if (change->Get("command") == "add" || change->Get("command") == "remove")
- return true;
- }
-
- return false;
-}
-
-bool RepositoryUtility::ClearChangeLog(void)
-{
- GetChangeLog(boost::bind(RepositoryUtility::ClearChange, _1, _2));
-
- return true;
-}
-
-bool RepositoryUtility::ChangeLogHasPendingChanges(void)
-{
- Array::Ptr changelog = new Array();
- GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changelog));
-
- return changelog->GetLength() > 0;
-}
-
-/* commit changelog */
-bool RepositoryUtility::CommitChangeLog(void)
-{
- GetChangeLog(boost::bind(RepositoryUtility::CommitChange, _1, _2));
-
- return true;
-}
-
-/* write/read from changelog repository */
-bool RepositoryUtility::WriteObjectToRepositoryChangeLog(const String& path, const Dictionary::Ptr& item)
-{
- Log(LogInformation, "cli", "Dumping changelog items to file '" + path + "'");
-
- CreateRepositoryPath(Utility::DirName(path));
-
- std::fstream fp;
- String tempFilename = Utility::CreateTempFile(path + ".XXXXXX", 0600, fp);
-
- fp << JsonEncode(item);
- fp.close();
-
-#ifdef _WIN32
- _unlink(path.CStr());
-#endif /* _WIN32 */
-
- if (rename(tempFilename.CStr(), path.CStr()) < 0) {
- BOOST_THROW_EXCEPTION(posix_error()
- << boost::errinfo_api_function("rename")
- << boost::errinfo_errno(errno)
- << boost::errinfo_file_name(tempFilename));
- }
-
- return true;
-}
-
-Dictionary::Ptr RepositoryUtility::GetObjectFromRepositoryChangeLog(const String& filename)
-{
- std::fstream fp;
- fp.open(filename.CStr(), std::ifstream::in);
-
- if (!fp)
- return Dictionary::Ptr();
-
- String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
-
- fp.close();
-
- return JsonDecode(content);
-}
-
-/* internal implementation when changes are committed */
-bool RepositoryUtility::AddObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs)
-{
- String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
-
- return WriteObjectToRepository(path, name, type, attrs);
-}
-
-bool RepositoryUtility::RemoveObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs)
-{
- String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
-
- if (!Utility::PathExists(path)) {
- Log(LogWarning, "cli")
- << type << " '" << name << "' does not exist.";
- return true;
- }
-
- bool success = RemoveObjectFileInternal(path);
-
- if (success)
- Log(LogInformation, "cli")
- << "Removing config object '" << name << "' in file '" << path << "'";
-
- /* special treatment for hosts -> remove the services too */
- if (type == "Host") {
- path = GetRepositoryObjectConfigPath(type, attrs) + "/" + name;
-
- /* if path does not exist, this host does not have any services */
- if (!Utility::PathExists(path)) {
- Log(LogNotice, "cli")
- << type << " '" << name << "' does not have any services configured.";
- return success;
- }
-
- std::vector<String> files;
-
- Utility::GlobRecursive(path, "*.conf",
- boost::bind(&RepositoryUtility::CollectObjects, _1, boost::ref(files)), GlobFile);
-
-
- for (const String& file : files) {
- RemoveObjectFileInternal(file);
- }
-#ifndef _WIN32
- rmdir(path.CStr());
-#else
- _rmdir(path.CStr());
-#endif /* _WIN32 */
-
- }
-
- return success;
-}
-
-bool RepositoryUtility::RemoveObjectFileInternal(const String& path)
-{
- if (!Utility::PathExists(path) ) {
- Log(LogCritical, "cli", "Cannot remove '" + path + "'. Does not exist.");
- return false;
- }
-
- if (unlink(path.CStr()) < 0) {
- Log(LogCritical, "cli", "Cannot remove path '" + path +
- "'. Failed with error code " + Convert::ToString(errno) + ", \"" + Utility::FormatErrorNumber(errno) + "\".");
- return false;
- }
-
- return true;
-}
-
-bool RepositoryUtility::SetObjectAttributeInternal(const String& name, const String& type, const String& key, const Value& val, const Dictionary::Ptr& attrs)
-{
- //TODO
- String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
-
- Dictionary::Ptr obj = GetObjectFromRepository(path); //TODO
-
- if (!obj) {
- Log(LogCritical, "cli")
- << "Can't get object " << name << " from repository.\n";
- return false;
- }
-
- obj->Set(key, val);
-
- std::cout << "Writing object '" << name << "' to path '" << path << "'.\n";
-
- //TODO: Create a patch file
- if (!WriteObjectToRepository(path, name, type, obj)) {
- Log(LogCritical, "cli")
- << "Can't write object " << name << " to repository.\n";
- return false;
- }
-
- return true;
-}
-
-bool RepositoryUtility::WriteObjectToRepository(const String& path, const String& name, const String& type, const Dictionary::Ptr& item)
-{
- Log(LogInformation, "cli")
- << "Writing config object '" << name << "' to file '" << path << "'";
-
- CreateRepositoryPath(Utility::DirName(path));
-
- std::fstream fp;
- String tempFilename = Utility::CreateTempFile(path + ".XXXXXX", 0644, fp);
-
- SerializeObject(fp, name, type, item);
- fp << std::endl;
- fp.close();
-
-#ifdef _WIN32
- _unlink(path.CStr());
-#endif /* _WIN32 */
-
- if (rename(tempFilename.CStr(), path.CStr()) < 0) {
- BOOST_THROW_EXCEPTION(posix_error()
- << boost::errinfo_api_function("rename")
- << boost::errinfo_errno(errno)
- << boost::errinfo_file_name(tempFilename));
- }
-
- return true;
-}
-
-Dictionary::Ptr RepositoryUtility::GetObjectFromRepository(const String& filename)
-{
- //TODO: Parse existing configuration objects
- return Dictionary::Ptr();
-}
-
-String RepositoryUtility::EscapeName(const String& name)
-{
- return Utility::EscapeString(name, "<>:\"/\\|?*", true);
-}
-
-String RepositoryUtility::UnescapeName(const String& name)
-{
- return Utility::UnescapeString(name);
-}
-
-/*
- * collect functions
- */
-std::vector<String> RepositoryUtility::GetObjects(void)
-{
- std::vector<String> objects;
- String path = GetRepositoryConfigPath();
-
- Utility::GlobRecursive(path, "*.conf",
- boost::bind(&RepositoryUtility::CollectObjects, _1, boost::ref(objects)), GlobFile);
-
- return objects;
-}
-
-void RepositoryUtility::CollectObjects(const String& object_file, std::vector<String>& objects)
-{
- Log(LogDebug, "cli")
- << "Adding object: '" << object_file << "'.";
-
- objects.push_back(object_file);
-}
-
-
-bool RepositoryUtility::GetChangeLog(const boost::function<void (const Dictionary::Ptr&, const String&)>& callback)
-{
- std::vector<String> changelog;
- String path = GetRepositoryChangeLogPath() + "/";
-
- Utility::MkDirP(path, 0700);
-
- Utility::Glob(path + "/*.change",
- boost::bind(&RepositoryUtility::CollectChangeLog, _1, boost::ref(changelog)), GlobFile);
-
- /* sort by timestamp ascending */
- std::sort(changelog.begin(), changelog.end());
-
- for (const String& entry : changelog) {
- String file = path + entry + ".change";
- Dictionary::Ptr change = GetObjectFromRepositoryChangeLog(file);
-
- Log(LogDebug, "cli")
- << "Collecting entry " << entry << "\n";
-
- if (change)
- callback(change, file);
- }
-
- return true;
-}
-
-void RepositoryUtility::CollectChangeLog(const String& change_file, std::vector<String>& changelog)
-{
- String file = Utility::BaseName(change_file);
- boost::algorithm::replace_all(file, ".change", "");
-
- Log(LogDebug, "cli")
- << "Adding change file: '" << file << "'.";
-
- changelog.push_back(file);
-}
-
-void RepositoryUtility::CollectChange(const Dictionary::Ptr& change, Array::Ptr& changes)
-{
- changes->Add(change);
-}
-
-/*
- * Commit Changelog entry
- */
-void RepositoryUtility::CommitChange(const Dictionary::Ptr& change, const String& path)
-{
- Log(LogDebug, "cli")
- << "Got change " << change->Get("name");
-
- String name = change->Get("name");
- String type = change->Get("type");
- String command = change->Get("command");
- Dictionary::Ptr attrs;
-
- if (change->Contains("attrs"))
- attrs = change->Get("attrs");
-
- bool success = false;
-
- if (command == "add")
- success = AddObjectInternal(name, type, attrs);
- else if (command == "remove")
- success = RemoveObjectInternal(name, type, attrs);
-
- if (success) {
- Log(LogNotice, "cli")
- << "Removing changelog file '" << path << "'.";
- RemoveObjectFileInternal(path);
- }
-}
-
-/*
- * Clear Changelog entry
- */
-void RepositoryUtility::ClearChange(const Dictionary::Ptr& change, const String& path)
-{
- Log(LogDebug, "cli")
- << "Clearing change " << change->Get("name");
-
- Log(LogInformation, "cli")
- << "Removing changelog file '" << path << "'.";
-
- RemoveObjectFileInternal(path);
-}
-
-/*
- * Print Changelog helpers
- */
-void RepositoryUtility::FormatChangelogEntry(std::ostream& fp, const Dictionary::Ptr& change)
-{
- if (!change)
- return;
-
- if (change->Get("command") == "add")
- fp << "Adding";
- if (change->Get("command") == "remove")
- fp << "Removing";
-
- String type = change->Get("type");
- boost::algorithm::to_lower(type);
- Dictionary::Ptr attrs = change->Get("attrs");
-
- fp << " " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << type << ConsoleColorTag(Console_Normal) << " '";
- fp << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << change->Get("name") << ConsoleColorTag(Console_Normal) << "'\n";
-
- ObjectLock olock(attrs);
- for (const Dictionary::Pair& kv : attrs) {
- /* skip the name */
- if (kv.first == "name" || kv.first == "__name")
- continue;
-
- fp << std::setw(4) << " " << ConsoleColorTag(Console_ForegroundGreen) << kv.first << ConsoleColorTag(Console_Normal) << " = ";
- ConfigWriter::EmitValue(fp, 0, kv.second);
- fp << "\n";
- }
-}
-
-/*
- * print helpers for configuration
- * TODO: Move into a separate class
- */
-void RepositoryUtility::SerializeObject(std::ostream& fp, const String& name, const String& type, const Dictionary::Ptr& object)
-{
- fp << "object " << type << " ";
- ConfigWriter::EmitString(fp, name);
- fp << " {\n";
-
- if (!object) {
- fp << "}\n";
- return;
- }
-
- if (object->Contains("import")) {
- Array::Ptr imports = object->Get("import");
-
- ObjectLock olock(imports);
- for (const String& import : imports) {
- fp << "\t" << "import ";
- ConfigWriter::EmitString(fp, import);
- fp << '\n';
- }
- }
-
- ObjectLock xlock(object);
- for (const Dictionary::Pair& kv : object) {
- if (kv.first == "import" || kv.first == "name" || kv.first == "__name") {
- continue;
- } else {
- fp << "\t";
- ConfigWriter::EmitIdentifier(fp, kv.first, true);
- fp << " = ";
- ConfigWriter::EmitValue(fp, 1, kv.second);
- }
- fp << "\n";
- }
- fp << "}\n";
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef REPOSITORYUTILITY_H
-#define REPOSITORYUTILITY_H
-
-#include "base/i2-base.hpp"
-#include "cli/i2-cli.hpp"
-#include "base/dictionary.hpp"
-#include "base/array.hpp"
-#include "base/value.hpp"
-#include "base/string.hpp"
-#include <boost/function.hpp>
-
-namespace icinga
-{
-
-/**
- * @ingroup cli
- */
-class I2_CLI_API RepositoryUtility
-{
-public:
- static Dictionary::Ptr GetArgumentAttributes(const std::vector<std::string>& arguments);
-
- static String GetRepositoryConfigPath(void);
- static String GetRepositoryObjectConfigPath(const String& type, const Dictionary::Ptr& object);
- static String GetRepositoryObjectConfigFilePath(const String& type, const Dictionary::Ptr& object);
-
- static String GetRepositoryChangeLogPath(void);
-
- static void CreateRepositoryPath(const String& path);
-
- static bool FilterRepositoryObjects(const String& type, const String& path);
-
- static void PrintObjects(std::ostream& fp, const String& type);
-
- static void PrintChangeLog(std::ostream& fp);
-
- static bool AddObject(const std::vector<String>& object_paths, const String& name, const String& type, const Dictionary::Ptr& attrs,
- const Array::Ptr& changes, bool check_config = true);
- static bool RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes);
-
- static bool CheckChangeExists(const Dictionary::Ptr& change, const Array::Ptr& changes);
-
- static bool SetObjectAttribute(const String& name, const String& type, const String& attr, const Value& val);
-
- static bool CommitChangeLog(void);
- static bool ClearChangeLog(void);
- static bool ChangeLogHasPendingChanges(void);
- static bool GetChangeLog(const boost::function<void (const Dictionary::Ptr&, const String&)>& callback);
- static void CollectChangeLog(const String& change_file, std::vector<String>& changelog);
- static void CollectChange(const Dictionary::Ptr& change, Array::Ptr& changes);
-
- static std::vector<String> GetObjects(void);
- static void CollectObjects(const String& object_file, std::vector<String>& objects);
-
-private:
- RepositoryUtility(void);
-
- static bool RemoveObjectFileInternal(const String& path);
-
- static bool AddObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs);
- static bool RemoveObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs);
- static bool SetObjectAttributeInternal(const String& name, const String& type, const String& key,
- const Value& val, const Dictionary::Ptr& attrs);
-
- /* repository.d */
- static bool WriteObjectToRepository(const String& path, const String& name, const String& type, const Dictionary::Ptr& item);
- static Dictionary::Ptr GetObjectFromRepository(const String& filename);
-
- /* changelog */
- static bool WriteObjectToRepositoryChangeLog(const String& path, const Dictionary::Ptr& item);
- static Dictionary::Ptr GetObjectFromRepositoryChangeLog(const String& filename);
-
- static void CommitChange(const Dictionary::Ptr& change, const String& path);
- static void ClearChange(const Dictionary::Ptr& change, const String& path);
-
- static void FormatChangelogEntry(std::ostream& fp, const Dictionary::Ptr& change);
-
- /* config print helpers */
- static void SerializeObject(std::ostream& fp, const String& name, const String& type, const Dictionary::Ptr& object);
- static void FormatValue(std::ostream& fp, const Value& val);
- static void FormatArray(std::ostream& fp, const Array::Ptr& arr);
-
- static String EscapeName(const String& name);
- static String UnescapeName(const String& name);
-};
-
-}
-
-#endif /* REPOSITORYUTILITY_H */
#install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/icinga2/api\")")
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/icinga2/api/log\")")
-install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/icinga2/api/repository\")")
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/icinga2/api/zones\")")