mirror of https://github.com/Icinga/icinga2.git
parent
1d1d2ceb96
commit
6fa58a520c
|
@ -321,7 +321,7 @@ int Main(void)
|
||||||
|
|
||||||
std::cout << appName << " " << "- The Icinga 2 network monitoring daemon (version: "
|
std::cout << appName << " " << "- The Icinga 2 network monitoring daemon (version: "
|
||||||
<< ConsoleColorTag(vm.count("version") ? Console_ForegroundRed : Console_Normal)
|
<< ConsoleColorTag(vm.count("version") ? Console_ForegroundRed : Console_Normal)
|
||||||
<< Application::GetVersion()
|
<< Application::GetAppVersion()
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
<< "; debug"
|
<< "; debug"
|
||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
|
@ -384,10 +384,10 @@ int Main(void)
|
||||||
Logger::DisableTimestamp(true);
|
Logger::DisableTimestamp(true);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (command->GetImpersonationLevel() == ImpersonateRoot) {
|
if (command->GetImpersonationLevel() == ImpersonateRoot) {
|
||||||
if (getuid() != 0) {
|
/*if (getuid() != 0) {
|
||||||
Log(LogCritical, "cli", "This command must be run as root.");
|
Log(LogCritical, "cli", "This command must be run as root.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}*/
|
||||||
} else if (command && command->GetImpersonationLevel() == ImpersonateIcinga) {
|
} else if (command && command->GetImpersonationLevel() == ImpersonateIcinga) {
|
||||||
String group = Application::GetRunAsGroup();
|
String group = Application::GetRunAsGroup();
|
||||||
String user = Application::GetRunAsUser();
|
String user = Application::GetRunAsUser();
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
String Application::GetVersion(void)
|
String Application::GetAppVersion(void)
|
||||||
{
|
{
|
||||||
return VERSION;
|
return VERSION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -591,7 +591,7 @@ void Application::DisplayInfoMessage(std::ostream& os, bool skipVersion)
|
||||||
os << "Application information:" << "\n";
|
os << "Application information:" << "\n";
|
||||||
|
|
||||||
if (!skipVersion)
|
if (!skipVersion)
|
||||||
os << " Application version: " << GetVersion() << "\n";
|
os << " Application version: " << GetAppVersion() << "\n";
|
||||||
|
|
||||||
os << " Installation root: " << GetPrefixDir() << "\n"
|
os << " Installation root: " << GetPrefixDir() << "\n"
|
||||||
<< " Sysconf directory: " << GetSysconfDir() << "\n"
|
<< " Sysconf directory: " << GetSysconfDir() << "\n"
|
||||||
|
|
|
@ -129,7 +129,7 @@ public:
|
||||||
|
|
||||||
static ThreadPool& GetTP(void);
|
static ThreadPool& GetTP(void);
|
||||||
|
|
||||||
static String GetVersion(void);
|
static String GetAppVersion(void);
|
||||||
|
|
||||||
static double GetStartTime(void);
|
static double GetStartTime(void);
|
||||||
static void SetStartTime(double ts);
|
static void SetStartTime(double ts);
|
||||||
|
|
|
@ -184,6 +184,7 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
|
||||||
ValidateField(fid, newValue, utils);
|
ValidateField(fid, newValue, utils);
|
||||||
|
|
||||||
SetField(fid, newValue);
|
SetField(fid, newValue);
|
||||||
|
SetVersion(GetVersion() + 1);
|
||||||
|
|
||||||
if (updated_original_attributes)
|
if (updated_original_attributes)
|
||||||
NotifyOriginalAttributes();
|
NotifyOriginalAttributes();
|
||||||
|
|
|
@ -94,6 +94,9 @@ abstract class ConfigObject : ConfigObjectBase
|
||||||
|
|
||||||
[protected] bool state_loaded;
|
[protected] bool state_loaded;
|
||||||
Dictionary::Ptr original_attributes;
|
Dictionary::Ptr original_attributes;
|
||||||
|
[state] int version {
|
||||||
|
default {{{ return 1; }}}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
|
||||||
scriptFrame.Sandboxed = true;
|
scriptFrame.Sandboxed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Icinga (version: " << Application::GetVersion() << ")\n";
|
std::cout << "Icinga (version: " << Application::GetAppVersion() << ")\n";
|
||||||
|
|
||||||
while (std::cin.good()) {
|
while (std::cin.good()) {
|
||||||
String fileName = "<" + Convert::ToString(next_line) + ">";
|
String fileName = "<" + Convert::ToString(next_line) + ">";
|
||||||
|
|
|
@ -209,7 +209,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
|
||||||
Logger::DisableTimestamp(false);
|
Logger::DisableTimestamp(false);
|
||||||
|
|
||||||
Log(LogInformation, "cli")
|
Log(LogInformation, "cli")
|
||||||
<< "Icinga application loader (version: " << Application::GetVersion()
|
<< "Icinga application loader (version: " << Application::GetAppVersion()
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
<< "; debug"
|
<< "; debug"
|
||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
|
|
|
@ -148,7 +148,7 @@ bool TroubleshootCommand::GeneralInfo(InfoLog& log, const boost::program_options
|
||||||
|
|
||||||
//Application::DisplayInfoMessage() but formatted
|
//Application::DisplayInfoMessage() but formatted
|
||||||
InfoLogLine(log)
|
InfoLogLine(log)
|
||||||
<< "\tApplication version: " << Application::GetVersion() << '\n'
|
<< "\tApplication version: " << Application::GetAppVersion() << '\n'
|
||||||
<< "\tInstallation root: " << Application::GetPrefixDir() << '\n'
|
<< "\tInstallation root: " << Application::GetPrefixDir() << '\n'
|
||||||
<< "\tSysconf directory: " << Application::GetSysconfDir() << '\n'
|
<< "\tSysconf directory: " << Application::GetSysconfDir() << '\n'
|
||||||
<< "\tRun directory: " << Application::GetRunDir() << '\n'
|
<< "\tRun directory: " << Application::GetRunDir() << '\n'
|
||||||
|
|
|
@ -800,7 +800,7 @@ void StatusDataWriter::StatusTimerHandler(void)
|
||||||
|
|
||||||
statusfp << "info {" "\n"
|
statusfp << "info {" "\n"
|
||||||
"\t" "created=" << Utility::GetTime() << "\n"
|
"\t" "created=" << Utility::GetTime() << "\n"
|
||||||
"\t" "version=" << Application::GetVersion() << "\n"
|
"\t" "version=" << Application::GetAppVersion() << "\n"
|
||||||
"\t" "}" "\n"
|
"\t" "}" "\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,11 @@ Dictionary::Ptr ConfigItem::GetScope(void) const
|
||||||
return m_Scope;
|
return m_Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigObject::Ptr ConfigItem::GetObject(void) const
|
||||||
|
{
|
||||||
|
return m_Object;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the expression list for the configuration item.
|
* Retrieves the expression list for the configuration item.
|
||||||
*
|
*
|
||||||
|
@ -140,7 +145,7 @@ class DefaultValidationUtils : public ValidationUtils
|
||||||
public:
|
public:
|
||||||
virtual bool ValidateName(const String& type, const String& name) const override
|
virtual bool ValidateName(const String& type, const String& name) const override
|
||||||
{
|
{
|
||||||
return ConfigItem::GetObject(type, name) != ConfigItem::Ptr();
|
return ConfigItem::GetByTypeAndName(type, name) != ConfigItem::Ptr();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,7 +307,7 @@ void ConfigItem::Unregister(void)
|
||||||
* @param name The name of the ConfigItem that is to be looked up.
|
* @param name The name of the ConfigItem that is to be looked up.
|
||||||
* @returns The configuration item.
|
* @returns The configuration item.
|
||||||
*/
|
*/
|
||||||
ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
ConfigItem::Ptr ConfigItem::GetByTypeAndName(const String& type, const String& name)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,9 @@ public:
|
||||||
DebugInfo GetDebugInfo(void) const;
|
DebugInfo GetDebugInfo(void) const;
|
||||||
Dictionary::Ptr GetScope(void) const;
|
Dictionary::Ptr GetScope(void) const;
|
||||||
|
|
||||||
static ConfigItem::Ptr GetObject(const String& type,
|
ConfigObject::Ptr GetObject(void) const;
|
||||||
|
|
||||||
|
static ConfigItem::Ptr GetByTypeAndName(const String& type,
|
||||||
const String& name);
|
const String& name);
|
||||||
|
|
||||||
static bool CommitItems(WorkQueue& upq);
|
static bool CommitItems(WorkQueue& upq);
|
||||||
|
|
|
@ -30,38 +30,34 @@
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
ConfigWriter::ConfigWriter(const String& fileName)
|
void ConfigWriter::EmitBoolean(std::ostream& fp, bool val)
|
||||||
: m_FP(fileName.CStr(), std::ofstream::out | std::ostream::trunc)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void ConfigWriter::EmitBoolean(bool val)
|
|
||||||
{
|
{
|
||||||
m_FP << (val ? "true" : "false");
|
fp << (val ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitNumber(double val)
|
void ConfigWriter::EmitNumber(std::ostream& fp, double val)
|
||||||
{
|
{
|
||||||
m_FP << val;
|
fp << val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitString(const String& val)
|
void ConfigWriter::EmitString(std::ostream& fp, const String& val)
|
||||||
{
|
{
|
||||||
m_FP << "\"" << EscapeIcingaString(val) << "\"";
|
fp << "\"" << EscapeIcingaString(val) << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitEmpty(void)
|
void ConfigWriter::EmitEmpty(std::ostream& fp)
|
||||||
{
|
{
|
||||||
m_FP << "null";
|
fp << "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitArray(const Array::Ptr& val)
|
void ConfigWriter::EmitArray(std::ostream& fp, const Array::Ptr& val)
|
||||||
{
|
{
|
||||||
m_FP << "[ ";
|
fp << "[ ";
|
||||||
EmitArrayItems(val);
|
EmitArrayItems(fp, val);
|
||||||
m_FP << " ]";
|
fp << " ]";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitArrayItems(const Array::Ptr& val)
|
void ConfigWriter::EmitArrayItems(std::ostream& fp, const Array::Ptr& val)
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
|
@ -70,80 +66,82 @@ void ConfigWriter::EmitArrayItems(const Array::Ptr& val)
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
m_FP << ", ";
|
fp << ", ";
|
||||||
|
|
||||||
EmitValue(0, item);
|
EmitValue(fp, 0, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitScope(int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports)
|
void ConfigWriter::EmitScope(std::ostream& fp, int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports)
|
||||||
{
|
{
|
||||||
m_FP << "{";
|
fp << "{";
|
||||||
|
|
||||||
if (imports && imports->GetLength() > 0) {
|
if (imports && imports->GetLength() > 0) {
|
||||||
ObjectLock xlock(imports);
|
ObjectLock xlock(imports);
|
||||||
BOOST_FOREACH(const Value& import, imports) {
|
BOOST_FOREACH(const Value& import, imports) {
|
||||||
m_FP << "\n";
|
fp << "\n";
|
||||||
EmitIndent(indentLevel);
|
EmitIndent(fp, indentLevel);
|
||||||
m_FP << "import \"" << import << "\"";
|
fp << "import \"" << import << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_FP << "\n";
|
fp << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (val) {
|
||||||
ObjectLock olock(val);
|
ObjectLock olock(val);
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, val) {
|
BOOST_FOREACH(const Dictionary::Pair& kv, val) {
|
||||||
m_FP << "\n";
|
fp << "\n";
|
||||||
EmitIndent(indentLevel);
|
EmitIndent(fp, indentLevel);
|
||||||
|
|
||||||
std::vector<String> tokens;
|
std::vector<String> tokens;
|
||||||
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));
|
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));
|
||||||
|
|
||||||
EmitIdentifier(tokens[0], true);
|
EmitIdentifier(fp, tokens[0], true);
|
||||||
|
|
||||||
for (std::vector<String>::size_type i = 1; i < tokens.size(); i++) {
|
for (std::vector<String>::size_type i = 1; i < tokens.size(); i++) {
|
||||||
m_FP << "[";
|
fp << "[";
|
||||||
EmitString(tokens[i]);
|
EmitString(fp, tokens[i]);
|
||||||
m_FP << "]";
|
fp << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_FP << " = ";
|
fp << " = ";
|
||||||
EmitValue(indentLevel + 1, kv.second);
|
EmitValue(fp, indentLevel + 1, kv.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_FP << "\n";
|
fp << "\n";
|
||||||
EmitIndent(indentLevel - 1);
|
EmitIndent(fp, indentLevel - 1);
|
||||||
m_FP << "}";
|
fp << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitValue(int indentLevel, const Value& val)
|
void ConfigWriter::EmitValue(std::ostream& fp, int indentLevel, const Value& val)
|
||||||
{
|
{
|
||||||
if (val.IsObjectType<Array>())
|
if (val.IsObjectType<Array>())
|
||||||
EmitArray(val);
|
EmitArray(fp, val);
|
||||||
else if (val.IsObjectType<Dictionary>())
|
else if (val.IsObjectType<Dictionary>())
|
||||||
EmitScope(indentLevel, val);
|
EmitScope(fp, indentLevel, val);
|
||||||
else if (val.IsString())
|
else if (val.IsString())
|
||||||
EmitString(val);
|
EmitString(fp, val);
|
||||||
else if (val.IsNumber())
|
else if (val.IsNumber())
|
||||||
EmitNumber(val);
|
EmitNumber(fp, val);
|
||||||
else if (val.IsBoolean())
|
else if (val.IsBoolean())
|
||||||
EmitBoolean(val);
|
EmitBoolean(fp, val);
|
||||||
else if (val.IsEmpty())
|
else if (val.IsEmpty())
|
||||||
EmitEmpty();
|
EmitEmpty(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitRaw(const String& val)
|
void ConfigWriter::EmitRaw(std::ostream& fp, const String& val)
|
||||||
{
|
{
|
||||||
m_FP << val;
|
fp << val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitIndent(int indentLevel)
|
void ConfigWriter::EmitIndent(std::ostream& fp, int indentLevel)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < indentLevel; i++)
|
for (int i = 0; i < indentLevel; i++)
|
||||||
m_FP << "\t";
|
fp << "\t";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitIdentifier(const String& identifier, bool inAssignment)
|
void ConfigWriter::EmitIdentifier(std::ostream& fp, const String& identifier, bool inAssignment)
|
||||||
{
|
{
|
||||||
static std::set<String> keywords;
|
static std::set<String> keywords;
|
||||||
if (keywords.empty()) {
|
if (keywords.empty()) {
|
||||||
|
@ -152,46 +150,46 @@ void ConfigWriter::EmitIdentifier(const String& identifier, bool inAssignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keywords.find(identifier) != keywords.end()) {
|
if (keywords.find(identifier) != keywords.end()) {
|
||||||
m_FP << "@" << identifier;
|
fp << "@" << identifier;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::regex expr("^[a-zA-Z_][a-zA-Z0-9\\_]*$");
|
boost::regex expr("^[a-zA-Z_][a-zA-Z0-9\\_]*$");
|
||||||
boost::smatch what;
|
boost::smatch what;
|
||||||
if (boost::regex_search(identifier.GetData(), what, expr))
|
if (boost::regex_search(identifier.GetData(), what, expr))
|
||||||
m_FP << identifier;
|
fp << identifier;
|
||||||
else if (inAssignment)
|
else if (inAssignment)
|
||||||
EmitString(identifier);
|
EmitString(fp, identifier);
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid identifier"));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid identifier"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitConfigItem(const String& type, const String& name, bool isTemplate,
|
void ConfigWriter::EmitConfigItem(std::ostream& fp, const String& type, const String& name, bool isTemplate,
|
||||||
const Array::Ptr& imports, const Dictionary::Ptr& attrs)
|
const Array::Ptr& imports, const Dictionary::Ptr& attrs)
|
||||||
{
|
{
|
||||||
if (isTemplate)
|
if (isTemplate)
|
||||||
m_FP << "template ";
|
fp << "template ";
|
||||||
else
|
else
|
||||||
m_FP << "object ";
|
fp << "object ";
|
||||||
|
|
||||||
EmitIdentifier(type, false);
|
EmitIdentifier(fp, type, false);
|
||||||
m_FP << " ";
|
fp << " ";
|
||||||
EmitString(name);
|
EmitString(fp, name);
|
||||||
m_FP << " ";
|
fp << " ";
|
||||||
EmitScope(1, attrs, imports);
|
EmitScope(fp, 1, attrs, imports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitComment(const String& text)
|
void ConfigWriter::EmitComment(std::ostream& fp, const String& text)
|
||||||
{
|
{
|
||||||
m_FP << "/* " << text << " */\n";
|
fp << "/* " << text << " */\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWriter::EmitFunctionCall(const String& name, const Array::Ptr& arguments)
|
void ConfigWriter::EmitFunctionCall(std::ostream& fp, const String& name, const Array::Ptr& arguments)
|
||||||
{
|
{
|
||||||
EmitIdentifier(name, false);
|
EmitIdentifier(fp, name, false);
|
||||||
m_FP << "(";
|
fp << "(";
|
||||||
EmitArrayItems(arguments);
|
EmitArrayItems(fp, arguments);
|
||||||
m_FP << ")";
|
fp << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
String ConfigWriter::EscapeIcingaString(const String& str)
|
String ConfigWriter::EscapeIcingaString(const String& str)
|
||||||
|
|
|
@ -34,34 +34,30 @@ namespace icinga
|
||||||
*
|
*
|
||||||
* @ingroup config
|
* @ingroup config
|
||||||
*/
|
*/
|
||||||
class I2_CONFIG_API ConfigWriter : public Object
|
class I2_CONFIG_API ConfigWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(ConfigWriter);
|
static void EmitBoolean(std::ostream& fp, bool val);
|
||||||
|
static void EmitNumber(std::ostream& fp, double val);
|
||||||
|
static void EmitString(std::ostream& fp, const String& val);
|
||||||
|
static void EmitEmpty(std::ostream& fp);
|
||||||
|
static void EmitArray(std::ostream& fp, const Array::Ptr& val);
|
||||||
|
static void EmitArrayItems(std::ostream& fp, const Array::Ptr& val);
|
||||||
|
static void EmitDictionary(std::ostream& fp, const Dictionary::Ptr& val);
|
||||||
|
static void EmitScope(std::ostream& fp, int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports = Array::Ptr());
|
||||||
|
static void EmitValue(std::ostream& fp, int indentLevel, const Value& val);
|
||||||
|
static void EmitRaw(std::ostream& fp, const String& val);
|
||||||
|
static void EmitIndent(std::ostream& fp, int indentLevel);
|
||||||
|
|
||||||
ConfigWriter(const String& fileName);
|
static void EmitIdentifier(std::ostream& fp, const String& identifier, bool inAssignment);
|
||||||
|
static void EmitConfigItem(std::ostream& fp, const String& type, const String& name, bool isTemplate,
|
||||||
void EmitBoolean(bool val);
|
|
||||||
void EmitNumber(double val);
|
|
||||||
void EmitString(const String& val);
|
|
||||||
void EmitEmpty(void);
|
|
||||||
void EmitArray(const Array::Ptr& val);
|
|
||||||
void EmitArrayItems(const Array::Ptr& val);
|
|
||||||
void EmitDictionary(const Dictionary::Ptr& val);
|
|
||||||
void EmitScope(int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports = Array::Ptr());
|
|
||||||
void EmitValue(int indentLevel, const Value& val);
|
|
||||||
void EmitRaw(const String& val);
|
|
||||||
void EmitIndent(int indentLevel);
|
|
||||||
|
|
||||||
void EmitIdentifier(const String& identifier, bool inAssignment);
|
|
||||||
void EmitConfigItem(const String& type, const String& name, bool isTemplate,
|
|
||||||
const Array::Ptr& imports, const Dictionary::Ptr& attrs);
|
const Array::Ptr& imports, const Dictionary::Ptr& attrs);
|
||||||
|
|
||||||
void EmitComment(const String& text);
|
static void EmitComment(std::ostream& fp, const String& text);
|
||||||
void EmitFunctionCall(const String& name, const Array::Ptr& arguments);
|
static void EmitFunctionCall(std::ostream& fp, const String& name, const Array::Ptr& arguments);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ofstream m_FP;
|
ConfigWriter(void);
|
||||||
|
|
||||||
static String EscapeIcingaString(const String& str);
|
static String EscapeIcingaString(const String& str);
|
||||||
};
|
};
|
||||||
|
|
|
@ -724,7 +724,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi
|
||||||
if (!name.IsString())
|
if (!name.IsString())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo));
|
BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo));
|
||||||
|
|
||||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, name);
|
||||||
|
|
||||||
if (!item)
|
if (!item)
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo));
|
BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo));
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkName.IsEmpty()) {
|
if (!checkName.IsEmpty()) {
|
||||||
ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName);
|
ConfigItem::Ptr oldItem = ConfigItem::GetByTypeAndName(type, checkName);
|
||||||
|
|
||||||
if (oldItem) {
|
if (oldItem) {
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
|
|
|
@ -141,7 +141,7 @@ void DbConnection::ProgramStatusHandler(void)
|
||||||
|
|
||||||
query2.Fields = new Dictionary();
|
query2.Fields = new Dictionary();
|
||||||
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
|
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
|
||||||
query2.Fields->Set("program_version", Application::GetVersion());
|
query2.Fields->Set("program_version", Application::GetAppVersion());
|
||||||
query2.Fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
|
query2.Fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
|
||||||
query2.Fields->Set("program_start_time", DbValue::FromTimestamp(Application::GetStartTime()));
|
query2.Fields->Set("program_start_time", DbValue::FromTimestamp(Application::GetStartTime()));
|
||||||
query2.Fields->Set("is_currently_running", 1);
|
query2.Fields->Set("is_currently_running", 1);
|
||||||
|
|
|
@ -331,7 +331,7 @@ void IdoMysqlConnection::Reconnect(void)
|
||||||
/* record connection */
|
/* record connection */
|
||||||
Query("INSERT INTO " + GetTablePrefix() + "conninfo " +
|
Query("INSERT INTO " + GetTablePrefix() + "conninfo " +
|
||||||
"(instance_id, connect_time, last_checkin_time, agent_name, agent_version, connect_type, data_start_time) VALUES ("
|
"(instance_id, connect_time, last_checkin_time, agent_name, agent_version, connect_type, data_start_time) VALUES ("
|
||||||
+ Convert::ToString(static_cast<long>(m_InstanceID)) + ", NOW(), NOW(), 'icinga2 db_ido_mysql', '" + Escape(Application::GetVersion())
|
+ Convert::ToString(static_cast<long>(m_InstanceID)) + ", NOW(), NOW(), 'icinga2 db_ido_mysql', '" + Escape(Application::GetAppVersion())
|
||||||
+ "', '" + (reconnect ? "RECONNECT" : "INITIAL") + "', NOW())");
|
+ "', '" + (reconnect ? "RECONNECT" : "INITIAL") + "', NOW())");
|
||||||
|
|
||||||
/* clear config tables for the initial config dump */
|
/* clear config tables for the initial config dump */
|
||||||
|
|
|
@ -323,7 +323,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
||||||
/* record connection */
|
/* record connection */
|
||||||
Query("INSERT INTO " + GetTablePrefix() + "conninfo " +
|
Query("INSERT INTO " + GetTablePrefix() + "conninfo " +
|
||||||
"(instance_id, connect_time, last_checkin_time, agent_name, agent_version, connect_type, data_start_time) VALUES ("
|
"(instance_id, connect_time, last_checkin_time, agent_name, agent_version, connect_type, data_start_time) VALUES ("
|
||||||
+ Convert::ToString(static_cast<long>(m_InstanceID)) + ", NOW(), NOW(), E'icinga2 db_ido_pgsql', E'" + Escape(Application::GetVersion())
|
+ Convert::ToString(static_cast<long>(m_InstanceID)) + ", NOW(), NOW(), E'icinga2 db_ido_pgsql', E'" + Escape(Application::GetAppVersion())
|
||||||
+ "', E'" + (reconnect ? "RECONNECT" : "INITIAL") + "', NOW())");
|
+ "', E'" + (reconnect ? "RECONNECT" : "INITIAL") + "', NOW())");
|
||||||
|
|
||||||
/* clear config tables for the initial config dump */
|
/* clear config tables for the initial config dump */
|
||||||
|
|
|
@ -81,7 +81,7 @@ void IcingaApplication::StatsFunc(const Dictionary::Ptr& status, const Array::Pt
|
||||||
stats->Set("enable_perfdata", icingaapplication->GetEnablePerfdata());
|
stats->Set("enable_perfdata", icingaapplication->GetEnablePerfdata());
|
||||||
stats->Set("pid", Utility::GetPid());
|
stats->Set("pid", Utility::GetPid());
|
||||||
stats->Set("program_start", Application::GetStartTime());
|
stats->Set("program_start", Application::GetStartTime());
|
||||||
stats->Set("version", Application::GetVersion());
|
stats->Set("version", Application::GetAppVersion());
|
||||||
|
|
||||||
nodes->Set(icingaapplication->GetName(), stats);
|
nodes->Set(icingaapplication->GetName(), stats);
|
||||||
}
|
}
|
||||||
|
@ -139,30 +139,33 @@ void IcingaApplication::OnShutdown(void)
|
||||||
DumpProgramState();
|
DumpProgramState();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PersistModAttrHelper(const ConfigWriter::Ptr& cw, ConfigObject::Ptr& previousObject, const ConfigObject::Ptr& object, const String& attr, const Value& value)
|
static void PersistModAttrHelper(std::ofstream& fp, ConfigObject::Ptr& previousObject, const ConfigObject::Ptr& object, const String& attr, const Value& value)
|
||||||
{
|
{
|
||||||
if (object != previousObject) {
|
if (object != previousObject) {
|
||||||
if (previousObject)
|
if (previousObject) {
|
||||||
cw->EmitRaw("}\n\n");
|
ConfigWriter::EmitRaw(fp, "\tobj.version = ");
|
||||||
|
ConfigWriter::EmitValue(fp, 0, previousObject->GetVersion());
|
||||||
|
ConfigWriter::EmitRaw(fp, "\n}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
cw->EmitRaw("var obj = ");
|
ConfigWriter::EmitRaw(fp, "var obj = ");
|
||||||
|
|
||||||
Array::Ptr args1 = new Array();
|
Array::Ptr args1 = new Array();
|
||||||
args1->Add(object->GetReflectionType()->GetName());
|
args1->Add(object->GetReflectionType()->GetName());
|
||||||
args1->Add(object->GetName());
|
args1->Add(object->GetName());
|
||||||
cw->EmitFunctionCall("get_object", args1);
|
ConfigWriter::EmitFunctionCall(fp, "get_object", args1);
|
||||||
|
|
||||||
cw->EmitRaw("\nif (obj) {\n");
|
ConfigWriter::EmitRaw(fp, "\nif (obj) {\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cw->EmitRaw("\tobj.");
|
ConfigWriter::EmitRaw(fp, "\tobj.");
|
||||||
|
|
||||||
Array::Ptr args2 = new Array();
|
Array::Ptr args2 = new Array();
|
||||||
args2->Add(attr);
|
args2->Add(attr);
|
||||||
args2->Add(value);
|
args2->Add(value);
|
||||||
cw->EmitFunctionCall("modify_attribute", args2);
|
ConfigWriter::EmitFunctionCall(fp, "modify_attribute", args2);
|
||||||
|
|
||||||
cw->EmitRaw("\n");
|
ConfigWriter::EmitRaw(fp, "\n");
|
||||||
|
|
||||||
previousObject = object;
|
previousObject = object;
|
||||||
}
|
}
|
||||||
|
@ -171,12 +174,16 @@ void IcingaApplication::DumpProgramState(void)
|
||||||
{
|
{
|
||||||
ConfigObject::DumpObjects(GetStatePath());
|
ConfigObject::DumpObjects(GetStatePath());
|
||||||
|
|
||||||
ConfigWriter::Ptr cw = new ConfigWriter(GetModAttrPath());
|
String path = GetModAttrPath();
|
||||||
|
std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc);
|
||||||
ConfigObject::Ptr previousObject;
|
ConfigObject::Ptr previousObject;
|
||||||
ConfigObject::DumpModifiedAttributes(boost::bind(&PersistModAttrHelper, cw, boost::ref(previousObject), _1, _2, _3));
|
ConfigObject::DumpModifiedAttributes(boost::bind(&PersistModAttrHelper, boost::ref(fp), boost::ref(previousObject), _1, _2, _3));
|
||||||
|
|
||||||
if (previousObject)
|
if (previousObject) {
|
||||||
cw->EmitRaw("\n}\n");
|
ConfigWriter::EmitRaw(fp, "\tobj.version = ");
|
||||||
|
ConfigWriter::EmitValue(fp, 0, previousObject->GetVersion());
|
||||||
|
ConfigWriter::EmitRaw(fp, "\n}\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IcingaApplication::Ptr IcingaApplication::GetInstance(void)
|
IcingaApplication::Ptr IcingaApplication::GetInstance(void)
|
||||||
|
|
|
@ -217,12 +217,12 @@ Value StatusTable::NumServicesAccessor(const Value&)
|
||||||
|
|
||||||
Value StatusTable::ProgramVersionAccessor(const Value&)
|
Value StatusTable::ProgramVersionAccessor(const Value&)
|
||||||
{
|
{
|
||||||
return Application::GetVersion();
|
return Application::GetAppVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value StatusTable::LivestatusVersionAccessor(const Value&)
|
Value StatusTable::LivestatusVersionAccessor(const Value&)
|
||||||
{
|
{
|
||||||
return Application::GetVersion();
|
return Application::GetAppVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value StatusTable::LivestatusActiveConnectionsAccessor(const Value&)
|
Value StatusTable::LivestatusActiveConnectionsAccessor(const Value&)
|
||||||
|
|
|
@ -97,7 +97,7 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul
|
||||||
perfdata->Add(new PerfdataValue("num_hosts_acknowledged", hs.hosts_acknowledged));
|
perfdata->Add(new PerfdataValue("num_hosts_acknowledged", hs.hosts_acknowledged));
|
||||||
|
|
||||||
cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) +
|
cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) +
|
||||||
". Version: " + Application::GetVersion());
|
". Version: " + Application::GetAppVersion());
|
||||||
cr->SetPerformanceData(perfdata);
|
cr->SetPerformanceData(perfdata);
|
||||||
cr->SetState(ServiceOK);
|
cr->SetState(ServiceOK);
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ mkclass_target(zone.ti zone.tcpp zone.thpp)
|
||||||
|
|
||||||
set(remote_SOURCES
|
set(remote_SOURCES
|
||||||
actionshandler.cpp apiaction.cpp
|
actionshandler.cpp apiaction.cpp
|
||||||
apifunction.cpp apilistener.cpp apilistener.thpp apilistener-sync.cpp
|
apifunction.cpp apilistener.cpp apilistener.thpp apilistener-configsync.cpp
|
||||||
apiuser.cpp apiuser.thpp authority.cpp base64.cpp
|
apilistener-filesync.cpp apiuser.cpp apiuser.thpp authority.cpp base64.cpp
|
||||||
configfileshandler.cpp configpackageshandler.cpp configpackageutility.cpp configobjectutility.cpp
|
configfileshandler.cpp configpackageshandler.cpp configpackageutility.cpp configobjectutility.cpp
|
||||||
configstageshandler.cpp createobjecthandler.cpp deleteobjecthandler.cpp
|
configstageshandler.cpp createobjecthandler.cpp deleteobjecthandler.cpp
|
||||||
endpoint.cpp endpoint.thpp filterutility.cpp
|
endpoint.cpp endpoint.thpp filterutility.cpp
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||||
|
* *
|
||||||
|
* 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 "remote/apilistener.hpp"
|
||||||
|
#include "remote/apifunction.hpp"
|
||||||
|
#include "remote/configobjectutility.hpp"
|
||||||
|
#include "remote/jsonrpc.hpp"
|
||||||
|
#include "base/configtype.hpp"
|
||||||
|
#include "base/json.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
|
||||||
|
INITIALIZE_ONCE(&ApiListener::StaticInitialize);
|
||||||
|
|
||||||
|
REGISTER_APIFUNCTION(UpdateObject, config, &ApiListener::ConfigUpdateObjectAPIHandler);
|
||||||
|
REGISTER_APIFUNCTION(DeleteObject, config, &ApiListener::ConfigDeleteObjectAPIHandler);
|
||||||
|
|
||||||
|
|
||||||
|
void ApiListener::StaticInitialize(void)
|
||||||
|
{
|
||||||
|
ConfigObject::OnActiveChanged.connect(&ApiListener::ConfigUpdateObjectHandler);
|
||||||
|
ConfigObject::OnVersionChanged.connect(&ApiListener::ConfigUpdateObjectHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiListener::ConfigUpdateObjectHandler(const ConfigObject::Ptr& object, const Value& cookie)
|
||||||
|
{
|
||||||
|
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||||
|
|
||||||
|
if (!listener)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (object->IsActive()) {
|
||||||
|
/* Sync object config */
|
||||||
|
listener->UpdateConfigObject(object, cookie);
|
||||||
|
} else {
|
||||||
|
/* Delete object */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
|
{
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Received update for object: " << JsonEncode(params);
|
||||||
|
|
||||||
|
ConfigType::Ptr dtype = ConfigType::GetByName(params->Get("type"));
|
||||||
|
|
||||||
|
if (!dtype) {
|
||||||
|
Log(LogCritical, "ApiListener")
|
||||||
|
<< "Config type '" << params->Get("type") << "' does not exist.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigObject::Ptr object = dtype->GetObject(params->Get("name"));
|
||||||
|
|
||||||
|
if (!object) {
|
||||||
|
Array::Ptr errors = new Array();
|
||||||
|
if (!ConfigObjectUtility::CreateObject(Type::GetByName(params->Get("type")),
|
||||||
|
params->Get("name"), params->Get("config"), errors)) {
|
||||||
|
Log(LogCritical, "ApiListener", "Could not create object:");
|
||||||
|
|
||||||
|
ObjectLock olock(errors);
|
||||||
|
BOOST_FOREACH(const String& error, errors) {
|
||||||
|
Log(LogCritical, "ApiListener", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO-MA: modified attributes, same version
|
||||||
|
}
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
|
{
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiListener::UpdateConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,
|
||||||
|
const JsonRpcConnection::Ptr& client)
|
||||||
|
{
|
||||||
|
if (object->GetPackage() != "_api")
|
||||||
|
return;
|
||||||
|
|
||||||
|
Dictionary::Ptr message = new Dictionary();
|
||||||
|
message->Set("jsonrpc", "2.0");
|
||||||
|
message->Set("method", "config::UpdateObject");
|
||||||
|
|
||||||
|
Dictionary::Ptr params = new Dictionary();
|
||||||
|
params->Set("name", object->GetName());
|
||||||
|
params->Set("type", object->GetType()->GetName());
|
||||||
|
params->Set("version", object->GetVersion());
|
||||||
|
|
||||||
|
String file = ConfigObjectUtility::GetObjectConfigPath(object->GetReflectionType(), object->GetName());
|
||||||
|
|
||||||
|
std::ifstream fp(file.CStr(), std::ifstream::binary);
|
||||||
|
if (!fp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
|
||||||
|
params->Set("config", content);
|
||||||
|
|
||||||
|
Dictionary::Ptr original_attributes = object->GetOriginalAttributes();
|
||||||
|
Dictionary::Ptr modified_attributes = new Dictionary();
|
||||||
|
|
||||||
|
if (original_attributes) {
|
||||||
|
ObjectLock olock(original_attributes);
|
||||||
|
BOOST_FOREACH(const Dictionary::Pair& kv, original_attributes) {
|
||||||
|
int fid = object->GetReflectionType()->GetFieldId(kv.first);
|
||||||
|
//TODO-MA: vars.os
|
||||||
|
Value value = static_cast<Object::Ptr>(object)->GetField(fid);
|
||||||
|
modified_attributes->Set(kv.first, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params->Set("modified_attributes", modified_attributes);
|
||||||
|
|
||||||
|
message->Set("params", params);
|
||||||
|
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Sent update for object: " << JsonEncode(params);
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
JsonRpc::SendMessage(client->GetStream(), message);
|
||||||
|
else
|
||||||
|
RelayMessage(origin, object, message, false);
|
||||||
|
}
|
|
@ -46,6 +46,8 @@ public:
|
||||||
DECLARE_OBJECT(ApiListener);
|
DECLARE_OBJECT(ApiListener);
|
||||||
DECLARE_OBJECTNAME(ApiListener);
|
DECLARE_OBJECTNAME(ApiListener);
|
||||||
|
|
||||||
|
static void StaticInitialize(void);
|
||||||
|
|
||||||
static boost::signals2::signal<void(bool)> OnMasterChanged;
|
static boost::signals2::signal<void(bool)> OnMasterChanged;
|
||||||
|
|
||||||
ApiListener(void);
|
ApiListener(void);
|
||||||
|
@ -73,8 +75,14 @@ public:
|
||||||
void RemoveHttpClient(const HttpServerConnection::Ptr& aclient);
|
void RemoveHttpClient(const HttpServerConnection::Ptr& aclient);
|
||||||
std::set<HttpServerConnection::Ptr> GetHttpClients(void) const;
|
std::set<HttpServerConnection::Ptr> GetHttpClients(void) const;
|
||||||
|
|
||||||
|
/* filesync */
|
||||||
static Value ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
static Value ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
|
||||||
|
/* configsync */
|
||||||
|
static void ConfigUpdateObjectHandler(const ConfigObject::Ptr& object, const Value& cookie);
|
||||||
|
static Value ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
static Value ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
|
||||||
static Value HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
static Value HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
protected:
|
protected:
|
||||||
virtual void OnConfigLoaded(void) override;
|
virtual void OnConfigLoaded(void) override;
|
||||||
|
@ -121,6 +129,9 @@ private:
|
||||||
static bool IsConfigMaster(const Zone::Ptr& zone);
|
static bool IsConfigMaster(const Zone::Ptr& zone);
|
||||||
static void ConfigGlobHandler(Dictionary::Ptr& config, const String& path, const String& file);
|
static void ConfigGlobHandler(Dictionary::Ptr& config, const String& path, const String& file);
|
||||||
void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient);
|
void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient);
|
||||||
|
|
||||||
|
void UpdateConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,
|
||||||
|
const JsonRpcConnection::Ptr& client = JsonRpcConnection::Ptr());
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "remote/configobjectutility.hpp"
|
#include "remote/configobjectutility.hpp"
|
||||||
#include "remote/configpackageutility.hpp"
|
#include "remote/configpackageutility.hpp"
|
||||||
#include "config/configitembuilder.hpp"
|
#include "config/configcompiler.hpp"
|
||||||
#include "config/configitem.hpp"
|
#include "config/configitem.hpp"
|
||||||
#include "config/configwriter.hpp"
|
#include "config/configwriter.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
|
@ -37,13 +37,22 @@ String ConfigObjectUtility::GetConfigDir(void)
|
||||||
ConfigPackageUtility::GetActiveStage("_api");
|
ConfigPackageUtility::GetActiveStage("_api");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ConfigObjectUtility::GetObjectConfigPath(const Type::Ptr& type, const String& fullName)
|
||||||
|
{
|
||||||
|
String typeDir = type->GetPluralName();
|
||||||
|
boost::algorithm::to_lower(typeDir);
|
||||||
|
|
||||||
|
return GetConfigDir() + "/conf.d/" + typeDir +
|
||||||
|
"/" + EscapeName(fullName) + ".conf";
|
||||||
|
}
|
||||||
|
|
||||||
String ConfigObjectUtility::EscapeName(const String& name)
|
String ConfigObjectUtility::EscapeName(const String& name)
|
||||||
{
|
{
|
||||||
return Utility::EscapeString(name, "<>:\"/\\|?*", true);
|
return Utility::EscapeString(name, "<>:\"/\\|?*", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
|
String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const String& fullName,
|
||||||
const Array::Ptr& templates, const Dictionary::Ptr& attrs, const Array::Ptr& errors)
|
const Array::Ptr& templates, const Dictionary::Ptr& attrs)
|
||||||
{
|
{
|
||||||
NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
|
NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
|
||||||
Dictionary::Ptr nameParts;
|
Dictionary::Ptr nameParts;
|
||||||
|
@ -55,48 +64,47 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
||||||
} else
|
} else
|
||||||
name = fullName;
|
name = fullName;
|
||||||
|
|
||||||
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder();
|
Dictionary::Ptr allAttrs = new Dictionary();
|
||||||
builder->SetType(type->GetName());
|
|
||||||
builder->SetName(name);
|
|
||||||
builder->SetScope(ScriptGlobal::GetGlobals());
|
|
||||||
builder->SetPackage("_api");
|
|
||||||
|
|
||||||
if (templates) {
|
if (attrs)
|
||||||
ObjectLock olock(templates);
|
attrs->CopyTo(allAttrs);
|
||||||
BOOST_FOREACH(const String& tmpl, templates) {
|
|
||||||
ImportExpression *expr = new ImportExpression(MakeLiteral(tmpl));
|
if (nameParts)
|
||||||
builder->AddExpression(expr);
|
nameParts->CopyTo(allAttrs);
|
||||||
}
|
|
||||||
|
allAttrs->Remove("name");
|
||||||
|
|
||||||
|
std::ostringstream config;
|
||||||
|
ConfigWriter::EmitConfigItem(config, type->GetName(), name, false, templates, allAttrs);
|
||||||
|
ConfigWriter::EmitRaw(config, "\n");
|
||||||
|
|
||||||
|
return config.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
|
||||||
|
const String& config, const Array::Ptr& errors)
|
||||||
|
{
|
||||||
|
if (!ConfigPackageUtility::PackageExists("_api")) {
|
||||||
|
ConfigPackageUtility::CreatePackage("_api");
|
||||||
|
|
||||||
|
String stage = ConfigPackageUtility::CreateStage("_api");
|
||||||
|
ConfigPackageUtility::ActivateStage("_api", stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameParts) {
|
String path = GetObjectConfigPath(type, fullName);
|
||||||
ObjectLock olock(nameParts);
|
Utility::MkDirP(Utility::DirName(path), 0700);
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, nameParts) {
|
|
||||||
SetExpression *expr = new SetExpression(MakeIndexer(ScopeThis, kv.first), OpSetLiteral, MakeLiteral(kv.second));
|
|
||||||
builder->AddExpression(expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs) {
|
std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc);
|
||||||
ObjectLock olock(attrs);
|
fp << config;
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, attrs) {
|
fp.close();
|
||||||
std::vector<String> tokens;
|
|
||||||
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));
|
|
||||||
|
|
||||||
Expression *expr = new GetScopeExpression(ScopeThis);
|
Expression *expr = ConfigCompiler::CompileFile(path, String(), "_api");
|
||||||
|
|
||||||
BOOST_FOREACH(const String& val, tokens) {
|
|
||||||
expr = new IndexerExpression(expr, MakeLiteral(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
SetExpression *aexpr = new SetExpression(expr, OpSetLiteral, MakeLiteral(kv.second));
|
|
||||||
builder->AddExpression(aexpr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ConfigItem::Ptr item = builder->Compile();
|
ScriptFrame frame;
|
||||||
item->Register();
|
expr->Evaluate(frame);
|
||||||
|
delete expr;
|
||||||
|
expr = NULL;
|
||||||
|
|
||||||
WorkQueue upq;
|
WorkQueue upq;
|
||||||
|
|
||||||
|
@ -110,39 +118,14 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
|
delete expr;
|
||||||
|
|
||||||
if (errors)
|
if (errors)
|
||||||
errors->Add(DiagnosticInformation(ex));
|
errors->Add(DiagnosticInformation(ex));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ConfigPackageUtility::PackageExists("_api")) {
|
|
||||||
ConfigPackageUtility::CreatePackage("_api");
|
|
||||||
|
|
||||||
String stage = ConfigPackageUtility::CreateStage("_api");
|
|
||||||
ConfigPackageUtility::ActivateStage("_api", stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
String typeDir = type->GetPluralName();
|
|
||||||
boost::algorithm::to_lower(typeDir);
|
|
||||||
|
|
||||||
String path = GetConfigDir() + "/conf.d/" + typeDir;
|
|
||||||
Utility::MkDirP(path, 0700);
|
|
||||||
|
|
||||||
path += "/" + EscapeName(fullName) + ".conf";
|
|
||||||
|
|
||||||
Dictionary::Ptr allAttrs = new Dictionary();
|
|
||||||
attrs->CopyTo(allAttrs);
|
|
||||||
|
|
||||||
if (nameParts)
|
|
||||||
nameParts->CopyTo(allAttrs);
|
|
||||||
|
|
||||||
allAttrs->Remove("name");
|
|
||||||
|
|
||||||
ConfigWriter::Ptr cw = new ConfigWriter(path);
|
|
||||||
cw->EmitConfigItem(type->GetName(), name, false, templates, allAttrs);
|
|
||||||
cw->EmitRaw("\n");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +151,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
|
||||||
|
|
||||||
Type::Ptr type = object->GetReflectionType();
|
Type::Ptr type = object->GetReflectionType();
|
||||||
|
|
||||||
ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), object->GetName());
|
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type->GetName(), object->GetName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
object->Deactivate();
|
object->Deactivate();
|
||||||
|
@ -185,11 +168,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String typeDir = type->GetPluralName();
|
String path = GetObjectConfigPath(object->GetReflectionType(), object->GetName());
|
||||||
boost::algorithm::to_lower(typeDir);
|
|
||||||
|
|
||||||
String path = GetConfigDir() + "/conf.d/" + typeDir +
|
|
||||||
"/" + EscapeName(object->GetName()) + ".conf";
|
|
||||||
|
|
||||||
if (Utility::PathExists(path)) {
|
if (Utility::PathExists(path)) {
|
||||||
if (unlink(path.CStr()) < 0) {
|
if (unlink(path.CStr()) < 0) {
|
||||||
|
|
|
@ -39,10 +39,13 @@ class I2_REMOTE_API ConfigObjectUtility
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static String GetConfigDir(void);
|
static String GetConfigDir(void);
|
||||||
|
static String GetObjectConfigPath(const Type::Ptr& type, const String& fullName);
|
||||||
|
|
||||||
|
static String CreateObjectConfig(const Type::Ptr& type, const String& fullName,
|
||||||
|
const Array::Ptr& templates, const Dictionary::Ptr& attrs);
|
||||||
|
|
||||||
static bool CreateObject(const Type::Ptr& type, const String& fullName,
|
static bool CreateObject(const Type::Ptr& type, const String& fullName,
|
||||||
const Array::Ptr& templates, const Dictionary::Ptr& attrs,
|
const String& config, const Array::Ptr& errors);
|
||||||
const Array::Ptr& errors);
|
|
||||||
|
|
||||||
static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
|
static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,9 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||||
String status;
|
String status;
|
||||||
Array::Ptr errors = new Array();
|
Array::Ptr errors = new Array();
|
||||||
|
|
||||||
if (!ConfigObjectUtility::CreateObject(type, name, templates, attrs, errors)) {
|
String config = ConfigObjectUtility::CreateObjectConfig(type, name, templates, attrs);
|
||||||
|
|
||||||
|
if (!ConfigObjectUtility::CreateObject(type, name, config, errors)) {
|
||||||
result1->Set("errors", errors);
|
result1->Set("errors", errors);
|
||||||
code = 500;
|
code = 500;
|
||||||
status = "Object could not be created.";
|
status = "Object could not be created.";
|
||||||
|
|
|
@ -171,7 +171,7 @@ void HttpRequest::FinishHeaders(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_State == HttpRequestHeaders) {
|
if (m_State == HttpRequestHeaders) {
|
||||||
AddHeader("User-Agent", "Icinga/" + Application::GetVersion());
|
AddHeader("User-Agent", "Icinga/" + Application::GetAppVersion());
|
||||||
|
|
||||||
if (ProtocolVersion == HttpVersion11)
|
if (ProtocolVersion == HttpVersion11)
|
||||||
AddHeader("Transfer-Encoding", "chunked");
|
AddHeader("Transfer-Encoding", "chunked");
|
||||||
|
|
|
@ -65,7 +65,7 @@ void HttpResponse::FinishHeaders(void)
|
||||||
if (m_Request.ProtocolVersion == HttpVersion11)
|
if (m_Request.ProtocolVersion == HttpVersion11)
|
||||||
AddHeader("Transfer-Encoding", "chunked");
|
AddHeader("Transfer-Encoding", "chunked");
|
||||||
|
|
||||||
AddHeader("Server", "Icinga/" + Application::GetVersion());
|
AddHeader("Server", "Icinga/" + Application::GetAppVersion());
|
||||||
m_Stream->Write("\r\n", 2);
|
m_Stream->Write("\r\n", 2);
|
||||||
m_State = HttpResponseBody;
|
m_State = HttpResponseBody;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,6 @@ void JsonRpcConnection::SendMessageSync(const Dictionary::Ptr& message)
|
||||||
std::ostringstream info;
|
std::ostringstream info;
|
||||||
info << "Error while sending JSON-RPC message for identity '" << m_Identity << "'";
|
info << "Error while sending JSON-RPC message for identity '" << m_Identity << "'";
|
||||||
Log(LogWarning, "JsonRpcConnection")
|
Log(LogWarning, "JsonRpcConnection")
|
||||||
<< info.str();
|
|
||||||
Log(LogDebug, "JsonRpcConnection")
|
|
||||||
<< info.str() << "\n" << DiagnosticInformation(ex);
|
<< info.str() << "\n" << DiagnosticInformation(ex);
|
||||||
|
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
@ -181,8 +179,6 @@ bool JsonRpcConnection::ProcessMessage(void)
|
||||||
std::ostringstream info;
|
std::ostringstream info;
|
||||||
info << "Error while processing message for identity '" << m_Identity << "'";
|
info << "Error while processing message for identity '" << m_Identity << "'";
|
||||||
Log(LogWarning, "JsonRpcConnection")
|
Log(LogWarning, "JsonRpcConnection")
|
||||||
<< info.str();
|
|
||||||
Log(LogDebug, "JsonRpcConnection")
|
|
||||||
<< info.str() << "\n" << DiagnosticInformation(ex);
|
<< info.str() << "\n" << DiagnosticInformation(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue