Merge pull request #6509 from gunnarbeutner/feature/real-constants

Implement support for namespaces
This commit is contained in:
Michael Friedrich 2018-08-24 12:10:10 +02:00 committed by GitHub
commit 237fd520db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 2043 additions and 675 deletions

View File

@ -2807,7 +2807,7 @@ or the `bind_host` and `bind_port` attributes of the
[ApiListener](09-object-types.md#objecttype-apilistener) object.
The environment must be set with the global constant `Environment` or as object attribute
of the [IcingaApplication](#objecttype-icingaapplication) object.
of the [IcingaApplication](09-object-types.md#objecttype-icingaapplication) object.
In any case the constant is default value for the attribute and the direct configuration in the objects
have more precedence. The constants have been added to allow the values being set from the CLI on startup.

View File

@ -44,6 +44,11 @@ New [Icinga constants](17-language-reference.md#icinga-constants) have been adde
* `Environment` for specifying the Icinga environment. Defaults to not set.
* `ApiBindHost` and `ApiBindPort` to allow overriding the default ApiListener values. This will be used for an Icinga addon only.
### Configuration: Namespaces <a id="upgrading-to-2-10-configuration-namespaces"></a>
The keywords `namespace` and `using` are now [reserved](17-language-reference.md#reserved-keywords) for the namespace functionality provided
with v2.10. Read more about how it works [here](17-language-reference.md#namespaces).
## Upgrading to v2.9 <a id="upgrading-to-2-9"></a>
### Deprecation and Removal Notes <a id="upgrading-to-2-9-deprecation-removal-notes"></a>

View File

@ -203,6 +203,39 @@ to dereference a reference:
*p = "Hi!"
log(value) // Prints "Hi!" because the variable was changed
### Namespaces <a id="namespaces"></a>
Namespaces can be used to organize variables and functions. They are used to avoid name conflicts. The `namespace`
keyword is used to create a new namespace:
namespace Utils {
function calculate() {
return 2 + 2
}
}
The namespace is made available as a global variable which has the namespace's name (e.g. `Utils`):
Utils.calculate()
The `using` keyword can be used to make all attributes in a namespace available to a script without having to
explicitly specify the namespace's name for each access:
using Utils
calculate()
The `using` keyword only has an effect for the current file and only for code that follows the keyword:
calculate() // This will not work.
using Utils
The following namespaces are automatically imported as if by using the `using` keyword:
* System
* System.Configuration
* Types
* Icinga
### Function Calls <a id="function-calls"></a>
Functions can be called using the `()` operator:
@ -1034,6 +1067,8 @@ These keywords are reserved and must not be used as constants or custom attribut
try
except
in
using
namespace
You can escape reserved keywords using the `@` character. The following example
tries to set `vars.include` which references a reserved keyword and generates

View File

@ -21,7 +21,9 @@
#include "config/configcompilercontext.hpp"
#include "config/configcompiler.hpp"
#include "config/configitembuilder.hpp"
#include "config/expression.hpp"
#include "base/application.hpp"
#include "base/configuration.hpp"
#include "base/logger.hpp"
#include "base/timer.hpp"
#include "base/utility.hpp"
@ -100,7 +102,7 @@ static void HandleLegacyDefines()
String dataPrefix = Utility::GetIcingaDataPath();
#endif /* _WIN32 */
Value localStateDir = Application::GetConst("LocalStateDir");
Value localStateDir = Configuration::LocalStateDir;
if (!localStateDir.IsEmpty()) {
Log(LogWarning, "icinga-app")
@ -109,51 +111,51 @@ static void HandleLegacyDefines()
<< " For compatibility reasons, these are now set based on the 'LocalStateDir' constant.";
#ifdef _WIN32
ScriptGlobal::Set("DataDir", localStateDir + "\\lib\\icinga2");
ScriptGlobal::Set("LogDir", localStateDir + "\\log\\icinga2");
ScriptGlobal::Set("CacheDir", localStateDir + "\\cache\\icinga2");
ScriptGlobal::Set("SpoolDir", localStateDir + "\\spool\\icinga2");
Configuration::DataDir = localStateDir + "\\lib\\icinga2";
Configuration::LogDir = localStateDir + "\\log\\icinga2";
Configuration::CacheDir = localStateDir + "\\cache\\icinga2";
Configuration::SpoolDir = localStateDir + "\\spool\\icinga2";
} else {
ScriptGlobal::Set("LocalStateDir", dataPrefix + "\\var");
Configuration::LocalStateDir = dataPrefix + "\\var";
#else /* _WIN32 */
ScriptGlobal::Set("DataDir", localStateDir + "/lib/icinga2");
ScriptGlobal::Set("LogDir", localStateDir + "/log/icinga2");
ScriptGlobal::Set("CacheDir", localStateDir + "/cache/icinga2");
ScriptGlobal::Set("SpoolDir", localStateDir + "/spool/icinga2");
Configuration::DataDir = localStateDir + "/lib/icinga2";
Configuration::LogDir = localStateDir + "/log/icinga2";
Configuration::CacheDir = localStateDir + "/cache/icinga2";
Configuration::SpoolDir = localStateDir + "/spool/icinga2";
} else {
ScriptGlobal::Set("LocalStateDir", ICINGA_LOCALSTATEDIR);
Configuration::LocalStateDir = ICINGA_LOCALSTATEDIR;
#endif /* _WIN32 */
}
Value sysconfDir = Application::GetConst("SysconfDir");
Value sysconfDir = Configuration::SysconfDir;
if (!sysconfDir.IsEmpty()) {
Log(LogWarning, "icinga-app")
<< "Please do not set the deprecated 'Sysconfdir' constant, use the 'ConfigDir' constant instead! For compatibility reasons, their value is set based on the 'SysconfDir' constant.";
#ifdef _WIN32
ScriptGlobal::Set("ConfigDir", sysconfDir + "\\icinga2");
Configuration::ConfigDir = sysconfDir + "\\icinga2";
} else {
ScriptGlobal::Set("SysconfDir", dataPrefix + "\\etc");
Configuration::SysconfDir = dataPrefix + "\\etc";
#else /* _WIN32 */
ScriptGlobal::Set("ConfigDir", sysconfDir + "/icinga2");
Configuration::ConfigDir = sysconfDir + "/icinga2";
} else {
ScriptGlobal::Set("SysconfDir", ICINGA_SYSCONFDIR);
Configuration::SysconfDir = ICINGA_SYSCONFDIR;
#endif /* _WIN32 */
}
Value runDir = Application::GetConst("RunDir");
Value runDir = Configuration::RunDir;
if (!runDir.IsEmpty()) {
Log(LogWarning, "icinga-app")
<< "Please do not set the deprecated 'RunDir' constant, use the 'InitRunDir' constant instead! For compatiblity reasons, their value is set based on the 'RunDir' constant.";
#ifdef _WIN32
ScriptGlobal::Set("InitRunDir", runDir + "\\icinga2");
Configuration::InitRunDir = runDir + "\\icinga2";
} else {
ScriptGlobal::Set("RunDir", dataPrefix + "\\var\\run");
Configuration::RunDir = dataPrefix + "\\var\\run";
#else /* _WIN32 */
ScriptGlobal::Set("InitRunDir", runDir + "/icinga2");
Configuration::InitRunDir = runDir + "/icinga2";
} else {
ScriptGlobal::Set("RunDir", ICINGA_RUNDIR);
Configuration::RunDir = ICINGA_RUNDIR;
#endif /* _WIN32 */
}
}
@ -198,43 +200,43 @@ static int Main()
String dataPrefix = Utility::GetIcingaDataPath();
if (!binaryPrefix.IsEmpty() && !dataPrefix.IsEmpty()) {
Application::DeclareConst("PrefixDir", binaryPrefix);
Application::DeclareConst("ProgramData", dataPrefix);
Configuration::PrefixDir = binaryPrefix;
Configuration::ProgramData = dataPrefix;
Application::DeclareConst("ConfigDir", dataPrefix + "\\etc\\icinga2");
Configuration::ConfigDir = dataPrefix + "\\etc\\icinga2";
Application::DeclareConst("DataDir", dataPrefix + "\\var\\lib\\icinga2");
Application::DeclareConst("LogDir", dataPrefix + "\\var\\log\\icinga2");
Application::DeclareConst("CacheDir", dataPrefix + "\\var\\cache\\icinga2");
Application::DeclareConst("SpoolDir", dataPrefix + "\\var\\spool\\icinga2");
Configuration::DataDir = dataPrefix + "\\var\\lib\\icinga2";
Configuration::LogDir = dataPrefix + "\\var\\log\\icinga2";
Configuration::CacheDir = dataPrefix + "\\var\\cache\\icinga2";
Configuration::SpoolDir = dataPrefix + "\\var\\spool\\icinga2";
/* Internal constants. */
Application::DeclareConst("PkgDataDir", binaryPrefix + "\\share\\icinga2");
Application::DeclareConst("IncludeConfDir", binaryPrefix + "\\share\\icinga2\\include");
Configuration::PkgDataDir = binaryPrefix + "\\share\\icinga2";
Configuration::IncludeConfDir = binaryPrefix + "\\share\\icinga2\\include";
} else {
Log(LogWarning, "icinga-app", "Registry key could not be read. Falling back to built-in paths.");
#endif /* _WIN32 */
Application::DeclareConst("ConfigDir", ICINGA_CONFIGDIR);
Configuration::ConfigDir = ICINGA_CONFIGDIR;
Application::DeclareConst("DataDir", ICINGA_DATADIR);
Application::DeclareConst("LogDir", ICINGA_LOGDIR);
Application::DeclareConst("CacheDir", ICINGA_CACHEDIR);
Application::DeclareConst("SpoolDir", ICINGA_SPOOLDIR);
Configuration::DataDir = ICINGA_DATADIR;
Configuration::LogDir = ICINGA_LOGDIR;
Configuration::CacheDir = ICINGA_CACHEDIR;
Configuration::SpoolDir = ICINGA_SPOOLDIR;
Application::DeclareConst("PrefixDir", ICINGA_PREFIX);
Configuration::PrefixDir = ICINGA_PREFIX;
/* Internal constants. */
Application::DeclareConst("PkgDataDir", ICINGA_PKGDATADIR);
Application::DeclareConst("IncludeConfDir", ICINGA_INCLUDECONFDIR);
Configuration::PkgDataDir = ICINGA_PKGDATADIR;
Configuration::IncludeConfDir = ICINGA_INCLUDECONFDIR;
Application::DeclareConst("InitRunDir", ICINGA_INITRUNDIR);
Configuration::InitRunDir = ICINGA_INITRUNDIR;
#ifdef _WIN32
}
#endif /* _WIN32 */
Application::DeclareConst("ZonesDir", Application::GetConst("ConfigDir") + "/zones.d");
Configuration::ZonesDir = Configuration::ConfigDir + "/zones.d";
String icingaUser = Utility::GetFromEnvironment("ICINGA2_USER");
if (icingaUser.IsEmpty())
@ -244,17 +246,17 @@ static int Main()
if (icingaGroup.IsEmpty())
icingaGroup = ICINGA_GROUP;
Application::DeclareConst("RunAsUser", icingaUser);
Application::DeclareConst("RunAsGroup", icingaGroup);
Configuration::RunAsUser = icingaUser;
Configuration::RunAsGroup = icingaGroup;
if (!autocomplete) {
#ifdef RLIMIT_NOFILE
String rLimitFiles = Utility::GetFromEnvironment("ICINGA2_RLIMIT_FILES");
if (rLimitFiles.IsEmpty())
Application::DeclareConst("RLimitFiles", Application::GetDefaultRLimitFiles());
Configuration::RLimitFiles = Application::GetDefaultRLimitFiles();
else {
try {
Application::DeclareConst("RLimitFiles", Convert::ToLong(rLimitFiles));
Configuration::RLimitFiles = Convert::ToLong(rLimitFiles);
} catch (const std::invalid_argument& ex) {
std::cout
<< "Error setting \"ICINGA2_RLIMIT_FILES\": " << ex.what() << '\n';
@ -266,10 +268,10 @@ static int Main()
#ifdef RLIMIT_NPROC
String rLimitProcesses = Utility::GetFromEnvironment("ICINGA2_RLIMIT_PROCESSES");
if (rLimitProcesses.IsEmpty())
Application::DeclareConst("RLimitProcesses", Application::GetDefaultRLimitProcesses());
Configuration::RLimitProcesses = Application::GetDefaultRLimitProcesses();
else {
try {
Application::DeclareConst("RLimitProcesses", Convert::ToLong(rLimitProcesses));
Configuration::RLimitProcesses = Convert::ToLong(rLimitProcesses);
} catch (const std::invalid_argument& ex) {
std::cout
<< "Error setting \"ICINGA2_RLIMIT_PROCESSES\": " << ex.what() << '\n';
@ -281,10 +283,10 @@ static int Main()
#ifdef RLIMIT_STACK
String rLimitStack = Utility::GetFromEnvironment("ICINGA2_RLIMIT_STACK");
if (rLimitStack.IsEmpty())
Application::DeclareConst("RLimitStack", Application::GetDefaultRLimitStack());
Configuration::RLimitStack = Application::GetDefaultRLimitStack();
else {
try {
Application::DeclareConst("RLimitStack", Convert::ToLong(rLimitStack));
Configuration::RLimitStack = Convert::ToLong(rLimitStack);
} catch (const std::invalid_argument& ex) {
std::cout
<< "Error setting \"ICINGA2_RLIMIT_STACK\": " << ex.what() << '\n';
@ -294,20 +296,19 @@ static int Main()
#endif /* RLIMIT_STACK */
}
Application::DeclareConst("Concurrency", std::thread::hardware_concurrency());
Application::DeclareConst("MaxConcurrentChecks", Application::GetDefaultMaxConcurrentChecks());
ScriptGlobal::Set("MaxConcurrentChecks", Application::GetDefaultMaxConcurrentChecks());
ScriptGlobal::Set("AttachDebugger", false);
ScriptGlobal::Set("Environment", "production");
ScriptGlobal::Set("PlatformKernel", Utility::GetPlatformKernel());
ScriptGlobal::Set("PlatformKernelVersion", Utility::GetPlatformKernelVersion());
ScriptGlobal::Set("PlatformName", Utility::GetPlatformName());
ScriptGlobal::Set("PlatformVersion", Utility::GetPlatformVersion());
ScriptGlobal::Set("PlatformArchitecture", Utility::GetPlatformArchitecture());
ScriptGlobal::Set("System.PlatformKernel", Utility::GetPlatformKernel(), true);
ScriptGlobal::Set("System.PlatformKernelVersion", Utility::GetPlatformKernelVersion(), true);
ScriptGlobal::Set("System.PlatformName", Utility::GetPlatformName(), true);
ScriptGlobal::Set("System.PlatformVersion", Utility::GetPlatformVersion(), true);
ScriptGlobal::Set("System.PlatformArchitecture", Utility::GetPlatformArchitecture(), true);
ScriptGlobal::Set("BuildHostName", ICINGA_BUILD_HOST_NAME);
ScriptGlobal::Set("BuildCompilerName", ICINGA_BUILD_COMPILER_NAME);
ScriptGlobal::Set("BuildCompilerVersion", ICINGA_BUILD_COMPILER_VERSION);
ScriptGlobal::Set("System.BuildHostName", ICINGA_BUILD_HOST_NAME, true);
ScriptGlobal::Set("System.BuildCompilerName", ICINGA_BUILD_COMPILER_NAME, true);
ScriptGlobal::Set("System.BuildCompilerVersion", ICINGA_BUILD_COMPILER_VERSION, true);
if (!autocomplete)
Application::SetResourceLimits();
@ -359,7 +360,7 @@ static int Main()
std::ifstream userFile;
/* The implicit string assignment is needed for Windows builds. */
String configDir = Application::GetConst("ConfigDir");
String configDir = Configuration::ConfigDir;
userFile.open(configDir + "/user");
if (userFile && command && !Application::IsProcessElevated()) {
@ -440,23 +441,42 @@ static int Main()
key = define;
value = "1";
}
ScriptGlobal::Set(key, value);
std::vector<String> keyTokens = key.Split(".");
std::unique_ptr<Expression> expr;
std::unique_ptr<VariableExpression> varExpr{new VariableExpression(keyTokens[0], {}, DebugInfo())};
expr = std::move(varExpr);
for (size_t i = 1; i < keyTokens.size(); i++) {
std::unique_ptr<IndexerExpression> indexerExpr{new IndexerExpression(std::move(expr), MakeLiteral(keyTokens[i]))};
indexerExpr->SetOverrideFrozen();
expr = std::move(indexerExpr);
}
std::unique_ptr<SetExpression> setExpr{new SetExpression(std::move(expr), OpSetLiteral, MakeLiteral(value))};
setExpr->SetOverrideFrozen();
ScriptFrame frame(true);
setExpr->Evaluate(frame);
}
}
Configuration::SetReadOnly(true);
/* Ensure that all defined constants work in the way we expect them. */
HandleLegacyDefines();
if (vm.count("script-debugger"))
Application::SetScriptDebuggerEnabled(true);
Application::DeclareConst("StatePath", Application::GetConst("DataDir") + "/icinga2.state");
Application::DeclareConst("ModAttrPath", Application::GetConst("DataDir") + "/modified-attributes.conf");
Application::DeclareConst("ObjectsPath", Application::GetConst("CacheDir") + "/icinga2.debug");
Application::DeclareConst("VarsPath", Application::GetConst("CacheDir") + "/icinga2.vars");
Application::DeclareConst("PidPath", Application::GetConst("InitRunDir") + "/icinga2.pid");
Configuration::StatePath = Configuration::DataDir + "/icinga2.state";
Configuration::ModAttrPath = Configuration::DataDir + "/modified-attributes.conf";
Configuration::ObjectsPath = Configuration::CacheDir + "/icinga2.debug";
Configuration::VarsPath = Configuration::CacheDir + "/icinga2.vars";
Configuration::PidPath = Configuration::InitRunDir + "/icinga2.pid";
ConfigCompiler::AddIncludeSearchDir(Application::GetConst("IncludeConfDir"));
ConfigCompiler::AddIncludeSearchDir(Configuration::IncludeConfDir);
if (!autocomplete && vm.count("include")) {
for (const String& includePath : vm["include"].as<std::vector<std::string> >()) {
@ -566,8 +586,8 @@ static int Main()
return 0;
}
} else if (command && command->GetImpersonationLevel() == ImpersonateIcinga) {
String group = Application::GetConst("RunAsGroup");
String user = Application::GetConst("RunAsUser");
String group = Configuration::RunAsGroup;
String user = Configuration::RunAsUser;
errno = 0;
struct group *gr = getgrnam(group.CStr());

View File

@ -17,8 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
if (!globals.irc) {
globals.irc = globals.log
if (!globals.contains("irc")) {
globals.irc = log
}
hm = {

View File

@ -17,6 +17,7 @@
mkclass_target(application.ti application-ti.cpp application-ti.hpp)
mkclass_target(configobject.ti configobject-ti.cpp configobject-ti.hpp)
mkclass_target(configuration.ti configuration-ti.cpp configuration-ti.hpp)
mkclass_target(datetime.ti datetime-ti.cpp datetime-ti.hpp)
mkclass_target(filelogger.ti filelogger-ti.cpp filelogger-ti.hpp)
mkclass_target(function.ti function-ti.cpp function-ti.hpp)
@ -33,6 +34,7 @@ set(base_SOURCES
boolean.cpp boolean.hpp boolean-script.cpp
configobject.cpp configobject.hpp configobject-ti.hpp configobject-script.cpp
configtype.cpp configtype.hpp
configuration.cpp configuration.hpp configuration-ti.hpp
configwriter.cpp configwriter.hpp
console.cpp console.hpp
context.cpp context.hpp
@ -54,6 +56,7 @@ set(base_SOURCES
math-script.cpp
netstring.cpp netstring.hpp
networkstream.cpp networkstream.hpp
namespace.cpp namespace.hpp namespace-script.cpp
number.cpp number.hpp number-script.cpp
object.cpp object.hpp object-script.cpp
objectlock.cpp objectlock.hpp

View File

@ -168,7 +168,7 @@ void Application::SetResourceLimits()
rlimit rl;
# ifdef RLIMIT_NOFILE
rlim_t fileLimit = GetConst("RLimitFiles");
rlim_t fileLimit = Configuration::RLimitFiles;
if (fileLimit != 0) {
if (fileLimit < GetDefaultRLimitFiles()) {
@ -189,7 +189,7 @@ void Application::SetResourceLimits()
}
# ifdef RLIMIT_NPROC
rlim_t processLimit = GetConst("RLimitProcesses");
rlim_t processLimit = Configuration::RLimitProcesses;
if (processLimit != 0) {
if (processLimit < GetDefaultRLimitProcesses()) {
@ -228,7 +228,7 @@ void Application::SetResourceLimits()
rlim_t stackLimit;
stackLimit = GetConst("RLimitStack");
stackLimit = Configuration::RLimitStack;
if (stackLimit != 0) {
if (stackLimit < GetDefaultRLimitStack()) {
@ -549,30 +549,32 @@ void Application::DisplayInfoMessage(std::ostream& os, bool skipVersion)
<< " Kernel version: " << Utility::GetPlatformKernelVersion() << "\n"
<< " Architecture: " << Utility::GetPlatformArchitecture() << "\n";
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
os << "\nBuild information:\n"
<< " Compiler: " << ScriptGlobal::Get("BuildCompilerName") << " " << ScriptGlobal::Get("BuildCompilerVersion") << "\n"
<< " Build host: " << ScriptGlobal::Get("BuildHostName") << "\n";
<< " Compiler: " << systemNS->Get("BuildCompilerName") << " " << systemNS->Get("BuildCompilerVersion") << "\n"
<< " Build host: " << systemNS->Get("BuildHostName") << "\n";
os << "\nApplication information:\n"
<< "\nGeneral paths:\n"
<< " Config directory: " << GetConst("ConfigDir") << "\n"
<< " Data directory: " << GetConst("DataDir") << "\n"
<< " Log directory: " << GetConst("LogDir") << "\n"
<< " Cache directory: " << GetConst("CacheDir") << "\n"
<< " Spool directory: " << GetConst("SpoolDir") << "\n"
<< " Run directory: " << GetConst("InitRunDir") << "\n"
<< " Config directory: " << Configuration::ConfigDir << "\n"
<< " Data directory: " << Configuration::DataDir << "\n"
<< " Log directory: " << Configuration::LogDir << "\n"
<< " Cache directory: " << Configuration::CacheDir << "\n"
<< " Spool directory: " << Configuration::SpoolDir << "\n"
<< " Run directory: " << Configuration::InitRunDir << "\n"
<< "\nOld paths (deprecated):\n"
<< " Installation root: " << GetConst("PrefixDir") << "\n"
<< " Sysconf directory: " << GetConst("SysconfDir") << "\n"
<< " Run directory (base): " << GetConst("RunDir") << "\n"
<< " Local state directory: " << GetConst("LocalStateDir") << "\n"
<< " Installation root: " << Configuration::PrefixDir << "\n"
<< " Sysconf directory: " << Configuration::SysconfDir << "\n"
<< " Run directory (base): " << Configuration::RunDir << "\n"
<< " Local state directory: " << Configuration::LocalStateDir << "\n"
<< "\nInternal paths:\n"
<< " Package data directory: " << GetConst("PkgDataDir") << "\n"
<< " State path: " << GetConst("StatePath") << "\n"
<< " Modified attributes path: " << GetConst("ModAttrPath") << "\n"
<< " Objects path: " << GetConst("ObjectsPath") << "\n"
<< " Vars path: " << GetConst("VarsPath") << "\n"
<< " PID path: " << GetConst("PidPath") << "\n";
<< " Package data directory: " << Configuration::PkgDataDir << "\n"
<< " State path: " << Configuration::StatePath << "\n"
<< " Modified attributes path: " << Configuration::ModAttrPath << "\n"
<< " Objects path: " << Configuration::ObjectsPath << "\n"
<< " Vars path: " << Configuration::VarsPath << "\n"
<< " PID path: " << Configuration::PidPath << "\n";
}
@ -590,7 +592,7 @@ void Application::DisplayBugMessage(std::ostream& os)
String Application::GetCrashReportFilename()
{
return GetConst("LogDir") + "/crash/report." + Convert::ToString(Utility::GetTime());
return Configuration::LogDir + "/crash/report." + Convert::ToString(Utility::GetTime());
}
@ -740,7 +742,7 @@ void Application::SigUsr2Handler(int)
*/
Application::Ptr instance = GetInstance();
try {
instance->UpdatePidFile(GetConst("PidPath"), m_ReloadProcess);
instance->UpdatePidFile(Configuration::PidPath, m_ReloadProcess);
} catch (const std::exception&) {
/* abort restart */
Log(LogCritical, "Application", "Cannot update PID file. Aborting restart operation.");
@ -783,7 +785,7 @@ void Application::SigAbrtHandler(int)
}
}
bool interactive_debugger = Convert::ToBool(ScriptGlobal::Get("AttachDebugger"));
bool interactive_debugger = Configuration::AttachDebugger;
if (!interactive_debugger) {
std::ofstream ofs;
@ -893,7 +895,7 @@ void Application::ExceptionHandler()
}
}
bool interactive_debugger = Convert::ToBool(ScriptGlobal::Get("AttachDebugger"));
bool interactive_debugger = Configuration::AttachDebugger;
if (!interactive_debugger) {
std::ofstream ofs;
@ -1012,10 +1014,10 @@ int Application::Run()
#endif /* _WIN32 */
try {
UpdatePidFile(GetConst("PidPath"));
UpdatePidFile(Configuration::PidPath);
} catch (const std::exception&) {
Log(LogCritical, "Application")
<< "Cannot update PID file '" << GetConst("PidPath") << "'. Aborting.";
<< "Cannot update PID file '" << Configuration::PidPath << "'. Aborting.";
return EXIT_FAILURE;
}
@ -1097,7 +1099,7 @@ void Application::ClosePidFile(bool unlink)
if (m_PidFile) {
if (unlink) {
String pidpath = GetConst("PidPath");
String pidpath = Configuration::PidPath;
::unlink(pidpath.CStr());
}
@ -1165,39 +1167,6 @@ pid_t Application::ReadPidFile(const String& filename)
return runningpid;
}
/**
* Declares a const with ScriptGlobal
*
* @param name The const name.
* @param value The new value.
*/
void Application::DeclareConst(const String& name, const Value& value)
{
if (!ScriptGlobal::Exists(name))
ScriptGlobal::Set(name, value);
}
/**
* Returns the value of a const from ScriptGlobal
*
* @param name The const name.
*/
Value Application::GetConst(const String& name)
{
return GetConst(name, Empty);
}
/**
* Returns the value of a const from ScriptGlobal with default value
*
* @param name The const name.
* @param def The default value.
*/
Value Application::GetConst(const String& name, Value defaultValue)
{
return ScriptGlobal::Get(name, &defaultValue);
}
int Application::GetDefaultRLimitFiles()
{
return 16 * 1024;
@ -1213,17 +1182,6 @@ int Application::GetDefaultRLimitStack()
return 256 * 1024;
}
/**
* Retrieves the concurrency level.
*
* @returns The concurrency level.
*/
int Application::GetConcurrency()
{
Value defaultConcurrency = std::thread::hardware_concurrency();
return ScriptGlobal::Get("Concurrency", &defaultConcurrency);
}
/**
* Sets the max concurrent checks.
*

View File

@ -23,6 +23,7 @@
#include "base/i2-base.hpp"
#include "base/application-ti.hpp"
#include "base/logger.hpp"
#include "base/configuration.hpp"
#include <iosfwd>
namespace icinga
@ -85,10 +86,6 @@ public:
static String GetExePath(const String& argv0);
static void DeclareConst(const String& name, const Value& value);
static Value GetConst(const String& name);
static Value GetConst(const String& name, Value defaultValue);
#ifdef _WIN32
static bool IsProcessElevated();
#endif /* _WIN32 */
@ -97,7 +94,6 @@ public:
static int GetDefaultRLimitProcesses();
static int GetDefaultRLimitStack();
static int GetConcurrency();
static int GetMaxConcurrentChecks();
static int GetDefaultMaxConcurrentChecks();
static void SetMaxConcurrentChecks(int maxChecks);

View File

@ -62,13 +62,14 @@ Value Array::Get(SizeType index) const
*
* @param index The index.
* @param value The value.
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Set(SizeType index, const Value& value)
void Array::Set(SizeType index, const Value& value, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Value in array must not be modified."));
m_Data.at(index) = value;
}
@ -78,12 +79,13 @@ void Array::Set(SizeType index, const Value& value)
*
* @param index The index.
* @param value The value.
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Set(SizeType index, Value&& value)
void Array::Set(SizeType index, Value&& value, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.at(index).Swap(value);
@ -93,12 +95,13 @@ void Array::Set(SizeType index, Value&& value)
* Adds a value to the array.
*
* @param value The value.
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Add(Value value)
void Array::Add(Value value, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.push_back(std::move(value));
@ -162,14 +165,15 @@ bool Array::Contains(const Value& value) const
*
* @param index The index
* @param value The value to add
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Insert(SizeType index, Value value)
void Array::Insert(SizeType index, Value value, bool overrideFrozen)
{
ObjectLock olock(this);
ASSERT(index <= m_Data.size());
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.insert(m_Data.begin() + index, std::move(value));
@ -179,12 +183,13 @@ void Array::Insert(SizeType index, Value value)
* Removes the specified index from the array.
*
* @param index The index.
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Remove(SizeType index)
void Array::Remove(SizeType index, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.erase(m_Data.begin() + index);
@ -194,42 +199,43 @@ void Array::Remove(SizeType index)
* Removes the item specified by the iterator from the array.
*
* @param it The iterator.
* @param overrideFrozen Whether to allow modifying frozen arrays.
*/
void Array::Remove(Array::Iterator it)
void Array::Remove(Array::Iterator it, bool overrideFrozen)
{
ASSERT(OwnsLock());
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.erase(it);
}
void Array::Resize(SizeType newSize)
void Array::Resize(SizeType newSize, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.resize(newSize);
}
void Array::Clear()
void Array::Clear(bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.clear();
}
void Array::Reserve(SizeType newSize)
void Array::Reserve(SizeType newSize, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
m_Data.reserve(newSize);
@ -288,11 +294,11 @@ Array::Ptr Array::Reverse() const
return result;
}
void Array::Sort()
void Array::Sort(bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be modified."));
std::sort(m_Data.begin(), m_Data.end());
@ -342,7 +348,7 @@ Value Array::GetFieldByName(const String& field, bool sandboxed, const DebugInfo
return Get(index);
}
void Array::SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo)
void Array::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
{
ObjectLock olock(this);
@ -352,9 +358,9 @@ void Array::SetFieldByName(const String& field, const Value& value, const DebugI
BOOST_THROW_EXCEPTION(ScriptError("Array index '" + Convert::ToString(index) + "' is out of bounds.", debugInfo));
if (static_cast<size_t>(index) >= GetLength())
Resize(index + 1);
Resize(index + 1, overrideFrozen);
Set(index, value);
Set(index, value, overrideFrozen);
}
Array::Iterator icinga::begin(const Array::Ptr& x)

View File

@ -55,9 +55,9 @@ public:
Array(std::initializer_list<Value> init);
Value Get(SizeType index) const;
void Set(SizeType index, const Value& value);
void Set(SizeType index, Value&& value);
void Add(Value value);
void Set(SizeType index, const Value& value, bool overrideFrozen = false);
void Set(SizeType index, Value&& value, bool overrideFrozen = false);
void Add(Value value, bool overrideFrozen = false);
Iterator Begin();
Iterator End();
@ -65,14 +65,14 @@ public:
size_t GetLength() const;
bool Contains(const Value& value) const;
void Insert(SizeType index, Value value);
void Remove(SizeType index);
void Remove(Iterator it);
void Insert(SizeType index, Value value, bool overrideFrozen = false);
void Remove(SizeType index, bool overrideFrozen = false);
void Remove(Iterator it, bool overrideFrozen = false);
void Resize(SizeType newSize);
void Clear();
void Resize(SizeType newSize, bool overrideFrozen = false);
void Clear(bool overrideFrozen = false);
void Reserve(SizeType newSize);
void Reserve(SizeType newSize, bool overrideFrozen = false);
void CopyTo(const Array::Ptr& dest) const;
Array::Ptr ShallowClone() const;
@ -108,7 +108,7 @@ public:
Array::Ptr Reverse() const;
void Sort();
void Sort(bool overrideFrozen = false);
String ToString() const override;
@ -116,7 +116,7 @@ public:
void Freeze();
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override;
void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
private:
std::vector<Value> m_Data; /**< The data for the array. */

View File

@ -571,7 +571,7 @@ void ConfigObject::RestoreObjects(const String& filename, int attributeTypes)
unsigned long restored = 0;
WorkQueue upq(25000, Application::GetConcurrency());
WorkQueue upq(25000, Configuration::Concurrency);
upq.SetName("ConfigObject::RestoreObjects");
String message;

370
lib/base/configuration.cpp Normal file
View File

@ -0,0 +1,370 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 "base/configuration.hpp"
#include "base/configuration-ti.cpp"
#include "base/exception.hpp"
using namespace icinga;
REGISTER_TYPE(Configuration);
String Configuration::ApiBindHost;
String Configuration::ApiBindPort{"5665"};
bool Configuration::AttachDebugger{false};
String Configuration::CacheDir;
int Configuration::Concurrency{static_cast<int>(std::thread::hardware_concurrency())};
String Configuration::ConfigDir;
String Configuration::DataDir;
String Configuration::EventEngine;
String Configuration::IncludeConfDir;
String Configuration::InitRunDir;
String Configuration::LogDir;
String Configuration::ModAttrPath;
String Configuration::ObjectsPath;
String Configuration::PidPath;
String Configuration::PkgDataDir;
String Configuration::PrefixDir;
String Configuration::ProgramData;
int Configuration::RLimitFiles;
int Configuration::RLimitProcesses;
int Configuration::RLimitStack;
String Configuration::RunAsGroup;
String Configuration::RunAsUser;
String Configuration::SpoolDir;
String Configuration::StatePath;
String Configuration::VarsPath;
String Configuration::ZonesDir;
/* deprecated */
String Configuration::LocalStateDir;
String Configuration::RunDir;
String Configuration::SysconfDir;
/* internal */
bool Configuration::m_ReadOnly{false};
template<typename T>
void HandleUserWrite(const String& name, T *target, const T& value, bool readOnly)
{
if (readOnly)
BOOST_THROW_EXCEPTION(ScriptError("Configuration attribute '" + name + "' is read-only."));
*target = value;
}
String Configuration::GetApiBindHost() const
{
return Configuration::ApiBindHost;
}
void Configuration::SetApiBindHost(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ApiBindHost", &Configuration::ApiBindHost, val, m_ReadOnly);
}
String Configuration::GetApiBindPort() const
{
return Configuration::ApiBindPort;
}
void Configuration::SetApiBindPort(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ApiBindPort", &Configuration::ApiBindPort, val, m_ReadOnly);
}
bool Configuration::GetAttachDebugger() const
{
return Configuration::AttachDebugger;
}
void Configuration::SetAttachDebugger(bool val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("AttachDebugger", &Configuration::AttachDebugger, val, m_ReadOnly);
}
String Configuration::GetCacheDir() const
{
return Configuration::CacheDir;
}
void Configuration::SetCacheDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("CacheDir", &Configuration::CacheDir, val, m_ReadOnly);
}
int Configuration::GetConcurrency() const
{
return Configuration::Concurrency;
}
void Configuration::SetConcurrency(int val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("Concurrency", &Configuration::Concurrency, val, m_ReadOnly);
}
String Configuration::GetConfigDir() const
{
return Configuration::ConfigDir;
}
void Configuration::SetConfigDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ConfigDir", &Configuration::ConfigDir, val, m_ReadOnly);
}
String Configuration::GetDataDir() const
{
return Configuration::DataDir;
}
void Configuration::SetDataDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("DataDir", &Configuration::DataDir, val, m_ReadOnly);
}
String Configuration::GetEventEngine() const
{
return Configuration::EventEngine;
}
void Configuration::SetEventEngine(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("EventEngine", &Configuration::EventEngine, val, m_ReadOnly);
}
String Configuration::GetIncludeConfDir() const
{
return Configuration::IncludeConfDir;
}
void Configuration::SetIncludeConfDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("IncludeConfDir", &Configuration::IncludeConfDir, val, m_ReadOnly);
}
String Configuration::GetInitRunDir() const
{
return Configuration::InitRunDir;
}
void Configuration::SetInitRunDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("InitRunDir", &Configuration::InitRunDir, val, m_ReadOnly);
}
String Configuration::GetLogDir() const
{
return Configuration::LogDir;
}
void Configuration::SetLogDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("LogDir", &Configuration::LogDir, val, m_ReadOnly);
}
String Configuration::GetModAttrPath() const
{
return Configuration::ModAttrPath;
}
void Configuration::SetModAttrPath(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ModAttrPath", &Configuration::ModAttrPath, val, m_ReadOnly);
}
String Configuration::GetObjectsPath() const
{
return Configuration::ObjectsPath;
}
void Configuration::SetObjectsPath(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ObjectsPath", &Configuration::ObjectsPath, val, m_ReadOnly);
}
String Configuration::GetPidPath() const
{
return Configuration::PidPath;
}
void Configuration::SetPidPath(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("PidPath", &Configuration::PidPath, val, m_ReadOnly);
}
String Configuration::GetPkgDataDir() const
{
return Configuration::PkgDataDir;
}
void Configuration::SetPkgDataDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("PkgDataDir", &Configuration::PkgDataDir, val, m_ReadOnly);
}
String Configuration::GetPrefixDir() const
{
return Configuration::PrefixDir;
}
void Configuration::SetPrefixDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("PrefixDir", &Configuration::PrefixDir, val, m_ReadOnly);
}
String Configuration::GetProgramData() const
{
return Configuration::ProgramData;
}
void Configuration::SetProgramData(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ProgramData", &Configuration::ProgramData, val, m_ReadOnly);
}
int Configuration::GetRLimitFiles() const
{
return Configuration::RLimitFiles;
}
void Configuration::SetRLimitFiles(int val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RLimitFiles", &Configuration::RLimitFiles, val, m_ReadOnly);
}
int Configuration::GetRLimitProcesses() const
{
return RLimitProcesses;
}
void Configuration::SetRLimitProcesses(int val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RLimitProcesses", &Configuration::RLimitProcesses, val, m_ReadOnly);
}
int Configuration::GetRLimitStack() const
{
return Configuration::RLimitStack;
}
void Configuration::SetRLimitStack(int val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RLimitStack", &Configuration::RLimitStack, val, m_ReadOnly);
}
String Configuration::GetRunAsGroup() const
{
return Configuration::RunAsGroup;
}
void Configuration::SetRunAsGroup(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RunAsGroup", &Configuration::RunAsGroup, val, m_ReadOnly);
}
String Configuration::GetRunAsUser() const
{
return Configuration::RunAsUser;
}
void Configuration::SetRunAsUser(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RunAsUser", &Configuration::RunAsUser, val, m_ReadOnly);
}
String Configuration::GetSpoolDir() const
{
return Configuration::SpoolDir;
}
void Configuration::SetSpoolDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("SpoolDir", &Configuration::SpoolDir, val, m_ReadOnly);
}
String Configuration::GetStatePath() const
{
return Configuration::StatePath;
}
void Configuration::SetStatePath(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("StatePath", &Configuration::StatePath, val, m_ReadOnly);
}
String Configuration::GetVarsPath() const
{
return Configuration::VarsPath;
}
void Configuration::SetVarsPath(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("VarsPath", &Configuration::VarsPath, val, m_ReadOnly);
}
String Configuration::GetZonesDir() const
{
return Configuration::ZonesDir;
}
void Configuration::SetZonesDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ZonesDir", &Configuration::ZonesDir, val, m_ReadOnly);
}
String Configuration::GetLocalStateDir() const
{
return Configuration::LocalStateDir;
}
void Configuration::SetLocalStateDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("LocalStateDir", &Configuration::LocalStateDir, val, m_ReadOnly);
}
String Configuration::GetSysconfDir() const
{
return Configuration::SysconfDir;
}
void Configuration::SetSysconfDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("SysconfDir", &Configuration::SysconfDir, val, m_ReadOnly);
}
String Configuration::GetRunDir() const
{
return Configuration::RunDir;
}
void Configuration::SetRunDir(const String& val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("RunDir", &Configuration::RunDir, val, m_ReadOnly);
}
bool Configuration::GetReadOnly()
{
return m_ReadOnly;
}
void Configuration::SetReadOnly(bool readOnly)
{
m_ReadOnly = readOnly;
}

169
lib/base/configuration.hpp Normal file
View File

@ -0,0 +1,169 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 CONFIGURATION_H
#define CONFIGURATION_H
#include "base/i2-base.hpp"
#include "base/configuration-ti.hpp"
namespace icinga
{
/**
* Global configuration.
*
* @ingroup base
*/
class Configuration : public ObjectImpl<Configuration>
{
public:
DECLARE_OBJECT(Configuration);
String GetApiBindHost() const override;
void SetApiBindHost(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetApiBindPort() const override;
void SetApiBindPort(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
bool GetAttachDebugger() const override;
void SetAttachDebugger(bool value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetCacheDir() const override;
void SetCacheDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
int GetConcurrency() const override;
void SetConcurrency(int value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetConfigDir() const override;
void SetConfigDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetDataDir() const override;
void SetDataDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetEventEngine() const override;
void SetEventEngine(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetIncludeConfDir() const override;
void SetIncludeConfDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetInitRunDir() const override;
void SetInitRunDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetLogDir() const override;
void SetLogDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetModAttrPath() const override;
void SetModAttrPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetObjectsPath() const override;
void SetObjectsPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetPidPath() const override;
void SetPidPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetPkgDataDir() const override;
void SetPkgDataDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetPrefixDir() const override;
void SetPrefixDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetProgramData() const override;
void SetProgramData(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
int GetRLimitFiles() const override;
void SetRLimitFiles(int value, bool suppress_events = false, const Value& cookie = Empty) override;
int GetRLimitProcesses() const override;
void SetRLimitProcesses(int value, bool suppress_events = false, const Value& cookie = Empty) override;
int GetRLimitStack() const override;
void SetRLimitStack(int value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetRunAsGroup() const override;
void SetRunAsGroup(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetRunAsUser() const override;
void SetRunAsUser(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetSpoolDir() const override;
void SetSpoolDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetStatePath() const override;
void SetStatePath(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetVarsPath() const override;
void SetVarsPath(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetZonesDir() const override;
void SetZonesDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
/* deprecated */
String GetLocalStateDir() const override;
void SetLocalStateDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetSysconfDir() const override;
void SetSysconfDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
String GetRunDir() const override;
void SetRunDir(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
static bool GetReadOnly();
static void SetReadOnly(bool readOnly);
static String ApiBindHost;
static String ApiBindPort;
static bool AttachDebugger;
static String CacheDir;
static int Concurrency;
static String ConfigDir;
static String DataDir;
static String EventEngine;
static String IncludeConfDir;
static String InitRunDir;
static String LogDir;
static String ModAttrPath;
static String ObjectsPath;
static String PidPath;
static String PkgDataDir;
static String PrefixDir;
static String ProgramData;
static int RLimitFiles;
static int RLimitProcesses;
static int RLimitStack;
static String RunAsGroup;
static String RunAsUser;
static String SpoolDir;
static String StatePath;
static String VarsPath;
static String ZonesDir;
/* deprecated */
static String LocalStateDir;
static String RunDir;
static String SysconfDir;
private:
static bool m_ReadOnly;
};
}
#endif /* CONFIGURATION_H */

176
lib/base/configuration.ti Normal file
View File

@ -0,0 +1,176 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 "base/configobject.hpp"
library base;
namespace icinga
{
abstract class Configuration
{
[config, no_storage, virtual] String ApiBindHost {
get;
set;
};
[config, no_storage, virtual] String ApiBindPort {
get;
set;
};
[config, no_storage, virtual] bool AttachDebugger {
get;
set;
};
[config, no_storage, virtual] String CacheDir {
get;
set;
};
[config, no_storage, virtual] int Concurrency {
get;
set;
};
[config, no_storage, virtual] String ConfigDir {
get;
set;
};
[config, no_storage, virtual] String DataDir {
get;
set;
};
[config, no_storage, virtual] String EventEngine {
get;
set;
};
[config, no_storage, virtual] String IncludeConfDir {
get;
set;
};
[config, no_storage, virtual] String InitRunDir {
get;
set;
};
[config, no_storage, virtual] String LogDir {
get;
set;
};
[config, no_storage, virtual] String ModAttrPath {
get;
set;
};
[config, no_storage, virtual] String ObjectsPath {
get;
set;
};
[config, no_storage, virtual] String PidPath {
get;
set;
};
[config, no_storage, virtual] String PkgDataDir {
get;
set;
};
[config, no_storage, virtual] String PrefixDir {
get;
set;
};
[config, no_storage, virtual] String ProgramData {
get;
set;
};
[config, no_storage, virtual] int RLimitFiles {
get;
set;
};
[config, no_storage, virtual] int RLimitProcesses {
get;
set;
};
[config, no_storage, virtual] int RLimitStack {
get;
set;
};
[config, no_storage, virtual] String RunAsGroup {
get;
set;
};
[config, no_storage, virtual] String RunAsUser {
get;
set;
};
[config, no_storage, virtual] String SpoolDir {
get;
set;
};
[config, no_storage, virtual] String StatePath {
get;
set;
};
[config, no_storage, virtual] String VarsPath {
get;
set;
};
[config, no_storage, virtual] String ZonesDir {
get;
set;
};
/* deprecated */
[config, no_storage, virtual] String LocalStateDir {
get;
set;
};
[config, no_storage, virtual] String RunDir {
get;
set;
};
[config, no_storage, virtual] String SysconfDir {
get;
set;
};
};
}

View File

@ -239,7 +239,8 @@ const std::vector<String>& ConfigWriter::GetKeywords()
keywords.emplace_back("globals");
keywords.emplace_back("locals");
keywords.emplace_back("use");
keywords.emplace_back("__using");
keywords.emplace_back("using");
keywords.emplace_back("namespace");
keywords.emplace_back("default");
keywords.emplace_back("ignore_on_error");
keywords.emplace_back("current_filename");

View File

@ -89,13 +89,14 @@ bool Dictionary::Get(const String& key, Value *result) const
*
* @param key The key.
* @param value The value.
* @param overrideFrozen Whether to allow modifying frozen dictionaries.
*/
void Dictionary::Set(const String& key, Value value)
void Dictionary::Set(const String& key, Value value, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Value in dictionary must not be modified."));
m_Data[key] = std::move(value);
}
@ -157,12 +158,13 @@ Dictionary::Iterator Dictionary::End()
* Removes the item specified by the iterator from the dictionary.
*
* @param it The iterator.
* @param overrideFrozen Whether to allow modifying frozen dictionaries.
*/
void Dictionary::Remove(Dictionary::Iterator it)
void Dictionary::Remove(Dictionary::Iterator it, bool overrideFrozen)
{
ASSERT(OwnsLock());
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
m_Data.erase(it);
@ -172,12 +174,13 @@ void Dictionary::Remove(Dictionary::Iterator it)
* Removes the specified key from the dictionary.
*
* @param key The key.
* @param overrideFrozen Whether to allow modifying frozen dictionaries.
*/
void Dictionary::Remove(const String& key)
void Dictionary::Remove(const String& key, bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
Dictionary::Iterator it;
@ -191,12 +194,14 @@ void Dictionary::Remove(const String& key)
/**
* Removes all dictionary items.
*
* @param overrideFrozen Whether to allow modifying frozen dictionaries.
*/
void Dictionary::Clear()
void Dictionary::Clear(bool overrideFrozen)
{
ObjectLock olock(this);
if (m_Frozen)
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
m_Data.clear();
@ -288,9 +293,9 @@ Value Dictionary::GetFieldByName(const String& field, bool, const DebugInfo& deb
return GetPrototypeField(const_cast<Dictionary *>(this), field, false, debugInfo);
}
void Dictionary::SetFieldByName(const String& field, const Value& value, const DebugInfo&)
void Dictionary::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo&)
{
Set(field, value);
Set(field, value, overrideFrozen);
}
bool Dictionary::HasOwnField(const String& field) const

View File

@ -58,7 +58,7 @@ public:
Value Get(const String& key) const;
bool Get(const String& key, Value *result) const;
void Set(const String& key, Value value);
void Set(const String& key, Value value, bool overrideFrozen = false);
bool Contains(const String& key) const;
Iterator Begin();
@ -66,11 +66,11 @@ public:
size_t GetLength() const;
void Remove(const String& key);
void Remove(const String& key, bool overrideFrozen = false);
void Remove(Iterator it);
void Remove(Iterator it, bool overrideFrozen = false);
void Clear();
void Clear(bool overrideFrozen = false);
void CopyTo(const Dictionary::Ptr& dest) const;
Dictionary::Ptr ShallowClone() const;
@ -86,7 +86,7 @@ public:
void Freeze();
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo) override;
void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
bool HasOwnField(const String& field) const override;
bool GetOwnField(const String& field, Value *result) const override;

View File

@ -17,8 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef SCRIPTFUNCTION_H
#define SCRIPTFUNCTION_H
#ifndef FUNCTION_H
#define FUNCTION_H
#include "base/i2-base.hpp"
#include "base/function-ti.hpp"
@ -72,50 +72,34 @@ private:
bool side_effect_free, bool deprecated);
};
#define REGISTER_SCRIPTFUNCTION_NS(ns, name, callback, args) \
#define REGISTER_FUNCTION(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), false); \
ScriptGlobal::Set(#ns "." #name, sf); \
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
nsp->SetAttribute(#name, std::make_shared<ConstEmbeddedNamespaceValue>(sf)); \
}, 10)
#define REGISTER_SCRIPTFUNCTION_NS_PREFIX(ns, name, callback, args) \
#define REGISTER_SAFE_FUNCTION(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
nsp->SetAttribute(#name, std::make_shared<ConstEmbeddedNamespaceValue>(sf)); \
}, 10)
#define REGISTER_FUNCTION_NONCONST(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), false); \
ScriptGlobal::Set(#ns "." #name, sf); \
Function::Ptr dsf = new icinga::Function("Deprecated#__" #name " (deprecated)", WrapFunction(callback), String(args).Split(":"), false, true); \
ScriptGlobal::Set("Deprecated.__" #name, dsf); \
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
nsp->SetAttribute(#name, std::make_shared<EmbeddedNamespaceValue>(sf)); \
}, 10)
#define REGISTER_SCRIPTFUNCTION_NS_DEPRECATED(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), false); \
ScriptGlobal::Set(#ns "." #name, sf); \
Function::Ptr dsf = new icinga::Function("Deprecated#" #name " (deprecated)", WrapFunction(callback), String(args).Split(":"), false, true); \
ScriptGlobal::Set("Deprecated." #name, dsf); \
}, 10)
#define REGISTER_SAFE_SCRIPTFUNCTION_NS(ns, name, callback, args) \
#define REGISTER_SAFE_FUNCTION_NONCONST(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
ScriptGlobal::Set(#ns "." #name, sf); \
}, 10)
#define REGISTER_SAFE_SCRIPTFUNCTION_NS_PREFIX(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
ScriptGlobal::Set(#ns "." #name, sf); \
Function::Ptr dsf = new icinga::Function("Deprecated#__" #name " (deprecated)", WrapFunction(callback), String(args).Split(":"), true, true); \
ScriptGlobal::Set("Deprecated.__" #name, dsf); \
}, 10)
#define REGISTER_SAFE_SCRIPTFUNCTION_NS_DEPRECATED(ns, name, callback, args) \
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
ScriptGlobal::Set(#ns "." #name, sf); \
Function::Ptr dsf = new icinga::Function("Deprecated#" #name " (deprecated)", WrapFunction(callback), String(args).Split(":"), true, true); \
ScriptGlobal::Set("Deprecated." #name, dsf); \
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
nsp->SetAttribute(#name, std::make_shared<EmbeddedNamespaceValue>(sf)); \
}, 10)
}
#endif /* SCRIPTFUNCTION_H */
#endif /* FUNCTION_H */

View File

@ -32,11 +32,15 @@ static String JsonEncodeShim(const Value& value)
}
INITIALIZE_ONCE([]() {
Dictionary::Ptr jsonObj = new Dictionary({
/* Methods */
{ "encode", new Function("Json#encode", JsonEncodeShim, { "value" }, true) },
{ "decode", new Function("Json#decode", JsonDecode, { "value" }, true) }
});
auto jsonNSBehavior = new ConstNamespaceBehavior();
Namespace::Ptr jsonNS = new Namespace(jsonNSBehavior);
ScriptGlobal::Set("Json", jsonObj);
/* Methods */
jsonNS->Set("encode", new Function("Json#encode", JsonEncodeShim, { "value" }, true));
jsonNS->Set("decode", new Function("Json#decode", JsonDecode, { "value" }, true));
jsonNSBehavior->Freeze();
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
systemNS->SetAttribute("Json", std::make_shared<ConstEmbeddedNamespaceValue>(jsonNS));
});

View File

@ -19,6 +19,7 @@
#include "base/json.hpp"
#include "base/debug.hpp"
#include "base/namespace.hpp"
#include "base/dictionary.hpp"
#include "base/array.hpp"
#include "base/objectlock.hpp"
@ -39,6 +40,19 @@ typedef unsigned int yajl_size;
typedef size_t yajl_size;
#endif /* YAJL_MAJOR */
static void EncodeNamespace(yajl_gen handle, const Namespace::Ptr& ns)
{
yajl_gen_map_open(handle);
ObjectLock olock(ns);
for (const Namespace::Pair& kv : ns) {
yajl_gen_string(handle, reinterpret_cast<const unsigned char *>(kv.first.CStr()), kv.first.GetLength());
Encode(handle, kv.second->Get());
}
yajl_gen_map_close(handle);
}
static void EncodeDictionary(yajl_gen handle, const Dictionary::Ptr& dict)
{
yajl_gen_map_open(handle);
@ -83,6 +97,13 @@ static void Encode(yajl_gen handle, const Value& value)
case ValueObject:
{
const Object::Ptr& obj = value.Get<Object::Ptr>();
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(obj);
if (ns) {
EncodeNamespace(handle, ns);
break;
}
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(obj);
if (dict) {

View File

@ -49,11 +49,11 @@ bool Logger::m_TimestampEnabled = true;
LogSeverity Logger::m_ConsoleLogSeverity = LogInformation;
INITIALIZE_ONCE([]() {
ScriptGlobal::Set("LogDebug", LogDebug);
ScriptGlobal::Set("LogNotice", LogNotice);
ScriptGlobal::Set("LogInformation", LogInformation);
ScriptGlobal::Set("LogWarning", LogWarning);
ScriptGlobal::Set("LogCritical", LogCritical);
ScriptGlobal::Set("System.LogDebug", LogDebug, true);
ScriptGlobal::Set("System.LogNotice", LogNotice, true);
ScriptGlobal::Set("System.LogInformation", LogInformation, true);
ScriptGlobal::Set("System.LogWarning", LogWarning, true);
ScriptGlobal::Set("System.LogCritical", LogCritical, true);
});
/**

View File

@ -22,6 +22,7 @@
#include "base/functionwrapper.hpp"
#include "base/scriptframe.hpp"
#include "base/initialize.hpp"
#include "base/namespace.hpp"
#include <boost/math/special_functions/round.hpp>
#include <cmath>
@ -158,40 +159,44 @@ static double MathSign(double x)
}
INITIALIZE_ONCE([]() {
Dictionary::Ptr mathObj = new Dictionary({
/* Constants */
{ "E", 2.71828182845904523536 },
{ "LN2", 0.693147180559945309417 },
{ "LN10", 2.30258509299404568402 },
{ "LOG2E", 1.44269504088896340736 },
{ "LOG10E", 0.434294481903251827651 },
{ "PI", 3.14159265358979323846 },
{ "SQRT1_2", 0.707106781186547524401 },
{ "SQRT2", 1.41421356237309504880 },
auto mathNSBehavior = new ConstNamespaceBehavior();
Namespace::Ptr mathNS = new Namespace(mathNSBehavior);
/* Methods */
{ "abs", new Function("Math#abs", MathAbs, { "x" }, true) },
{ "acos", new Function("Math#acos", MathAcos, { "x" }, true) },
{ "asin", new Function("Math#asin", MathAsin, { "x" }, true) },
{ "atan", new Function("Math#atan", MathAtan, { "x" }, true) },
{ "atan2", new Function("Math#atan2", MathAtan2, { "x", "y" }, true) },
{ "ceil", new Function("Math#ceil", MathCeil, { "x" }, true) },
{ "cos", new Function("Math#cos", MathCos, { "x" }, true) },
{ "exp", new Function("Math#exp", MathExp, { "x" }, true) },
{ "floor", new Function("Math#floor", MathFloor, { "x" }, true) },
{ "log", new Function("Math#log", MathLog, { "x" }, true) },
{ "max", new Function("Math#max", MathMax, {}, true) },
{ "min", new Function("Math#min", MathMin, {}, true) },
{ "pow", new Function("Math#pow", MathPow, { "x", "y" }, true) },
{ "random", new Function("Math#random", MathRandom, {}, true) },
{ "round", new Function("Math#round", MathRound, { "x" }, true) },
{ "sin", new Function("Math#sin", MathSin, { "x" }, true) },
{ "sqrt", new Function("Math#sqrt", MathSqrt, { "x" }, true) },
{ "tan", new Function("Math#tan", MathTan, { "x" }, true) },
{ "isnan", new Function("Math#isnan", MathIsnan, { "x" }, true) },
{ "isinf", new Function("Math#isinf", MathIsinf, { "x" }, true) },
{ "sign", new Function("Math#sign", MathSign, { "x" }, true) }
});
/* Constants */
mathNS->Set("E", 2.71828182845904523536);
mathNS->Set("LN2", 0.693147180559945309417);
mathNS->Set("LN10", 2.30258509299404568402);
mathNS->Set("LOG2E", 1.44269504088896340736);
mathNS->Set("LOG10E", 0.434294481903251827651);
mathNS->Set("PI", 3.14159265358979323846);
mathNS->Set("SQRT1_2", 0.707106781186547524401);
mathNS->Set("SQRT2", 1.41421356237309504880);
ScriptGlobal::Set("Math", mathObj);
/* Methods */
mathNS->Set("abs", new Function("Math#abs", MathAbs, { "x" }, true));
mathNS->Set("acos", new Function("Math#acos", MathAcos, { "x" }, true));
mathNS->Set("asin", new Function("Math#asin", MathAsin, { "x" }, true));
mathNS->Set("atan", new Function("Math#atan", MathAtan, { "x" }, true));
mathNS->Set("atan2", new Function("Math#atan2", MathAtan2, { "x", "y" }, true));
mathNS->Set("ceil", new Function("Math#ceil", MathCeil, { "x" }, true));
mathNS->Set("cos", new Function("Math#cos", MathCos, { "x" }, true));
mathNS->Set("exp", new Function("Math#exp", MathExp, { "x" }, true));
mathNS->Set("floor", new Function("Math#floor", MathFloor, { "x" }, true));
mathNS->Set("log", new Function("Math#log", MathLog, { "x" }, true));
mathNS->Set("max", new Function("Math#max", MathMax, {}, true));
mathNS->Set("min", new Function("Math#min", MathMin, {}, true));
mathNS->Set("pow", new Function("Math#pow", MathPow, { "x", "y" }, true));
mathNS->Set("random", new Function("Math#random", MathRandom, {}, true));
mathNS->Set("round", new Function("Math#round", MathRound, { "x" }, true));
mathNS->Set("sin", new Function("Math#sin", MathSin, { "x" }, true));
mathNS->Set("sqrt", new Function("Math#sqrt", MathSqrt, { "x" }, true));
mathNS->Set("tan", new Function("Math#tan", MathTan, { "x" }, true));
mathNS->Set("isnan", new Function("Math#isnan", MathIsnan, { "x" }, true));
mathNS->Set("isinf", new Function("Math#isinf", MathIsinf, { "x" }, true));
mathNS->Set("sign", new Function("Math#sign", MathSign, { "x" }, true));
mathNSBehavior->Freeze();
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
systemNS->SetAttribute("Math", std::make_shared<ConstEmbeddedNamespaceValue>(mathNS));
});

View File

@ -0,0 +1,101 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 "base/namespace.hpp"
#include "base/function.hpp"
#include "base/functionwrapper.hpp"
#include "base/scriptframe.hpp"
#include "base/array.hpp"
using namespace icinga;
static void NamespaceSet(const String& key, const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Set(key, value);
}
static Value NamespaceGet(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Get(key);
}
static void NamespaceRemove(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Remove(key);
}
static bool NamespaceContains(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Contains(key);
}
static Array::Ptr NamespaceKeys()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
ArrayData keys;
ObjectLock olock(self);
for (const Namespace::Pair& kv : self) {
keys.push_back(kv.first);
}
return new Array(std::move(keys));
}
static Array::Ptr NamespaceValues()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Namespace::Ptr self = static_cast<Namespace::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
ArrayData values;
ObjectLock olock(self);
for (const Namespace::Pair& kv : self) {
values.push_back(kv.second->Get());
}
return new Array(std::move(values));
}
Object::Ptr Namespace::GetPrototype()
{
static Dictionary::Ptr prototype = new Dictionary({
{ "set", new Function("Namespace#set", NamespaceSet, { "key", "value" }) },
{ "get", new Function("Namespace#get", NamespaceGet, { "key" }) },
{ "remove", new Function("Namespace#remove", NamespaceRemove, { "key" }) },
{ "contains", new Function("Namespace#contains", NamespaceContains, { "key" }, true) },
{ "keys", new Function("Namespace#keys", NamespaceKeys, {}, true) },
{ "values", new Function("Namespace#values", NamespaceValues, {}, true) },
});
return prototype;
}

223
lib/base/namespace.cpp Normal file
View File

@ -0,0 +1,223 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 "base/namespace.hpp"
#include "base/objectlock.hpp"
#include "base/debug.hpp"
#include "base/primitivetype.hpp"
#include "base/debuginfo.hpp"
#include "base/exception.hpp"
#include <sstream>
using namespace icinga;
template class std::map<icinga::String, std::shared_ptr<icinga::NamespaceValue> >;
REGISTER_PRIMITIVE_TYPE(Namespace, Object, Namespace::GetPrototype());
Namespace::Namespace(NamespaceBehavior *behavior)
: m_Behavior(std::unique_ptr<NamespaceBehavior>(behavior))
{ }
Value Namespace::Get(const String& field) const
{
Value value;
if (!GetOwnField(field, &value))
BOOST_THROW_EXCEPTION(ScriptError("Namespace does not contain field '" + field + "'"));
return value;
}
bool Namespace::Get(const String& field, Value *value) const
{
auto nsVal = GetAttribute(field);
if (!nsVal)
return false;
*value = nsVal->Get(DebugInfo());
return true;
}
void Namespace::Set(const String& field, const Value& value, bool overrideFrozen)
{
return SetFieldByName(field, value, overrideFrozen, DebugInfo());
}
bool Namespace::Contains(const String& field) const
{
return HasOwnField(field);
}
void Namespace::Remove(const String& field, bool overrideFrozen)
{
m_Behavior->Remove(this, field, overrideFrozen);
}
void Namespace::RemoveAttribute(const String& field)
{
ObjectLock olock(this);
Namespace::Iterator it;
it = m_Data.find(field);
if (it == m_Data.end())
return;
m_Data.erase(it);
}
std::shared_ptr<NamespaceValue> Namespace::GetAttribute(const String& key) const
{
ObjectLock olock(this);
auto it = m_Data.find(key);
if (it == m_Data.end())
return nullptr;
return it->second;
}
void Namespace::SetAttribute(const String& key, const std::shared_ptr<NamespaceValue>& nsVal)
{
ObjectLock olock(this);
m_Data[key] = nsVal;
}
Value Namespace::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const
{
auto nsVal = GetAttribute(field);
if (nsVal)
return nsVal->Get(debugInfo);
else
return GetPrototypeField(const_cast<Namespace *>(this), field, true, debugInfo);
}
void Namespace::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
{
auto nsVal = GetAttribute(field);
if (!nsVal)
m_Behavior->Register(this, field, value, overrideFrozen, debugInfo);
else
nsVal->Set(value, overrideFrozen, debugInfo);
}
bool Namespace::HasOwnField(const String& field) const
{
return GetAttribute(field) != nullptr;
}
bool Namespace::GetOwnField(const String& field, Value *result) const
{
auto nsVal = GetAttribute(field);
if (!nsVal)
return false;
*result = nsVal->Get(DebugInfo());
return true;
}
EmbeddedNamespaceValue::EmbeddedNamespaceValue(const Value& value)
: m_Value(value)
{ }
Value EmbeddedNamespaceValue::Get(const DebugInfo& debugInfo) const
{
return m_Value;
}
void EmbeddedNamespaceValue::Set(const Value& value, bool, const DebugInfo&)
{
m_Value = value;
}
void ConstEmbeddedNamespaceValue::Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
{
if (!overrideFrozen)
BOOST_THROW_EXCEPTION(ScriptError("Constant must not be modified.", debugInfo));
EmbeddedNamespaceValue::Set(value, overrideFrozen, debugInfo);
}
void NamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
{
ns->SetAttribute(field, std::make_shared<EmbeddedNamespaceValue>(value));
}
void NamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
{
if (!overrideFrozen) {
auto attr = ns->GetAttribute(field);
if (dynamic_pointer_cast<ConstEmbeddedNamespaceValue>(attr))
BOOST_THROW_EXCEPTION(ScriptError("Constants must not be removed."));
}
ns->RemoveAttribute(field);
}
void ConstNamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
{
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified.", debugInfo));
ns->SetAttribute(field, std::make_shared<ConstEmbeddedNamespaceValue>(value));
}
void ConstNamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
{
if (m_Frozen && !overrideFrozen)
BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified."));
NamespaceBehavior::Remove(ns, field, overrideFrozen);
}
void ConstNamespaceBehavior::Freeze()
{
m_Frozen = true;
}
Namespace::Iterator Namespace::Begin()
{
ASSERT(OwnsLock());
return m_Data.begin();
}
Namespace::Iterator Namespace::End()
{
ASSERT(OwnsLock());
return m_Data.end();
}
Namespace::Iterator icinga::begin(const Namespace::Ptr& x)
{
return x->Begin();
}
Namespace::Iterator icinga::end(const Namespace::Ptr& x)
{
return x->End();
}

123
lib/base/namespace.hpp Normal file
View File

@ -0,0 +1,123 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 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 NAMESPACE_H
#define NAMESPACE_H
#include "base/i2-base.hpp"
#include "base/object.hpp"
#include "base/value.hpp"
#include "base/debuginfo.hpp"
#include <map>
#include <vector>
namespace icinga
{
struct NamespaceValue
{
virtual Value Get(const DebugInfo& debugInfo = DebugInfo()) const = 0;
virtual void Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo = DebugInfo()) = 0;
};
struct EmbeddedNamespaceValue : public NamespaceValue
{
EmbeddedNamespaceValue(const Value& value);
Value Get(const DebugInfo& debugInfo) const override;
void Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
private:
Value m_Value;
};
struct ConstEmbeddedNamespaceValue : public EmbeddedNamespaceValue
{
using EmbeddedNamespaceValue::EmbeddedNamespaceValue;
void Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
};
class Namespace;
struct NamespaceBehavior
{
virtual void Register(const boost::intrusive_ptr<Namespace>& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const;
virtual void Remove(const boost::intrusive_ptr<Namespace>& ns, const String& field, bool overrideFrozen);
};
struct ConstNamespaceBehavior : public NamespaceBehavior
{
void Register(const boost::intrusive_ptr<Namespace>& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const override;
void Remove(const boost::intrusive_ptr<Namespace>& ns, const String& field, bool overrideFrozen) override;
void Freeze();
private:
bool m_Frozen;
};
/**
* A namespace.
*
* @ingroup base
*/
class Namespace final : public Object
{
public:
DECLARE_OBJECT(Namespace);
typedef std::map<String, std::shared_ptr<NamespaceValue> >::iterator Iterator;
typedef std::map<String, std::shared_ptr<NamespaceValue> >::value_type Pair;
Namespace(NamespaceBehavior *behavior = new NamespaceBehavior);
Value Get(const String& field) const;
bool Get(const String& field, Value *value) const;
void Set(const String& field, const Value& value, bool overrideFrozen = false);
bool Contains(const String& field) const;
void Remove(const String& field, bool overrideFrozen = false);
std::shared_ptr<NamespaceValue> GetAttribute(const String& field) const;
void SetAttribute(const String& field, const std::shared_ptr<NamespaceValue>& nsVal);
void RemoveAttribute(const String& field);
Iterator Begin();
Iterator End();
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
bool HasOwnField(const String& field) const override;
bool GetOwnField(const String& field, Value *result) const override;
static Object::Ptr GetPrototype();
private:
std::map<String, std::shared_ptr<NamespaceValue> > m_Data;
std::unique_ptr<NamespaceBehavior> m_Behavior;
};
Namespace::Iterator begin(const Namespace::Ptr& x);
Namespace::Iterator end(const Namespace::Ptr& x);
}
extern template class std::map<icinga::String, std::shared_ptr<icinga::NamespaceValue> >;
#endif /* NAMESPACE_H */

View File

@ -138,7 +138,7 @@ Value Object::GetFieldByName(const String& field, bool sandboxed, const DebugInf
return GetField(fid);
}
void Object::SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo)
void Object::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
{
Type::Ptr type = GetReflectionType();

View File

@ -183,7 +183,7 @@ public:
virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty);
virtual Value GetField(int id) const;
virtual Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const;
virtual void SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo);
virtual void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo);
virtual bool HasOwnField(const String& field) const;
virtual bool GetOwnField(const String& field, Value *result) const;
virtual void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils);

View File

@ -27,7 +27,7 @@
using namespace icinga;
REGISTER_TYPE(PerfdataValue);
REGISTER_SCRIPTFUNCTION_NS(System, parse_performance_data, PerfdataValue::Parse, "perfdata");
REGISTER_FUNCTION(System, parse_performance_data, PerfdataValue::Parse, "perfdata");
PerfdataValue::PerfdataValue(const String& label, double value, bool counter,
const String& unit, const Value& warn, const Value& crit, const Value& min,

View File

@ -41,7 +41,7 @@ Value Reference::Get() const
void Reference::Set(const Value& value)
{
m_Parent->SetFieldByName(m_Index, value, DebugInfo());
m_Parent->SetFieldByName(m_Index, value, false, DebugInfo());
}
Object::Ptr Reference::GetParent() const

View File

@ -19,27 +19,44 @@
#include "base/scriptframe.hpp"
#include "base/scriptglobal.hpp"
#include "base/namespace.hpp"
#include "base/exception.hpp"
#include "base/configuration.hpp"
using namespace icinga;
boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
Array::Ptr ScriptFrame::m_Imports;
static auto l_InternalNSBehavior = new ConstNamespaceBehavior();
INITIALIZE_ONCE_WITH_PRIORITY([]() {
Dictionary::Ptr systemNS = new Dictionary();
ScriptGlobal::Set("System", systemNS);
ScriptFrame::AddImport(systemNS);
Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
Dictionary::Ptr typesNS = new Dictionary();
ScriptGlobal::Set("Types", typesNS);
ScriptFrame::AddImport(typesNS);
auto systemNSBehavior = new ConstNamespaceBehavior();
systemNSBehavior->Freeze();
Namespace::Ptr systemNS = new Namespace(systemNSBehavior);
globalNS->SetAttribute("System", std::make_shared<ConstEmbeddedNamespaceValue>(systemNS));
Dictionary::Ptr deprecatedNS = new Dictionary();
ScriptGlobal::Set("Deprecated", deprecatedNS);
ScriptFrame::AddImport(deprecatedNS);
systemNS->SetAttribute("Configuration", std::make_shared<EmbeddedNamespaceValue>(new Configuration()));
auto typesNSBehavior = new ConstNamespaceBehavior();
typesNSBehavior->Freeze();
Namespace::Ptr typesNS = new Namespace(typesNSBehavior);
globalNS->SetAttribute("Types", std::make_shared<ConstEmbeddedNamespaceValue>(typesNS));
auto statsNSBehavior = new ConstNamespaceBehavior();
statsNSBehavior->Freeze();
Namespace::Ptr statsNS = new Namespace(statsNSBehavior);
globalNS->SetAttribute("StatsFunctions", std::make_shared<ConstEmbeddedNamespaceValue>(statsNS));
Namespace::Ptr internalNS = new Namespace(l_InternalNSBehavior);
globalNS->SetAttribute("Internal", std::make_shared<ConstEmbeddedNamespaceValue>(internalNS));
}, 50);
INITIALIZE_ONCE_WITH_PRIORITY([]() {
l_InternalNSBehavior->Freeze();
}, 0);
ScriptFrame::ScriptFrame(bool allocLocals)
: Locals(allocLocals ? new Dictionary() : nullptr), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0)
{
@ -120,23 +137,3 @@ void ScriptFrame::PushFrame(ScriptFrame *frame)
frames->push(frame);
}
Array::Ptr ScriptFrame::GetImports()
{
return m_Imports;
}
void ScriptFrame::AddImport(const Object::Ptr& import)
{
Array::Ptr imports;
if (!m_Imports)
imports = new Array();
else
imports = m_Imports->ShallowClone();
imports->Add(import);
m_Imports = imports;
}

View File

@ -45,12 +45,8 @@ struct ScriptFrame
static ScriptFrame *GetCurrentFrame();
static Array::Ptr GetImports();
static void AddImport(const Object::Ptr& import);
private:
static boost::thread_specific_ptr<std::stack<ScriptFrame *> > m_ScriptFrames;
static Array::Ptr m_Imports;
static void PushFrame(ScriptFrame *frame);
static ScriptFrame *PopFrame();

View File

@ -26,11 +26,12 @@
#include "base/convert.hpp"
#include "base/objectlock.hpp"
#include "base/exception.hpp"
#include "base/namespace.hpp"
#include <fstream>
using namespace icinga;
Dictionary::Ptr ScriptGlobal::m_Globals = new Dictionary();
Namespace::Ptr ScriptGlobal::m_Globals = new Namespace();
Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
{
@ -46,7 +47,7 @@ Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
return result;
}
void ScriptGlobal::Set(const String& name, const Value& value)
void ScriptGlobal::Set(const String& name, const Value& value, bool overrideFrozen)
{
std::vector<String> tokens = name.Split(".");
@ -56,7 +57,7 @@ void ScriptGlobal::Set(const String& name, const Value& value)
{
ObjectLock olock(m_Globals);
Dictionary::Ptr parent = m_Globals;
Namespace::Ptr parent = m_Globals;
for (std::vector<String>::size_type i = 0; i < tokens.size(); i++) {
const String& token = tokens[i];
@ -65,7 +66,7 @@ void ScriptGlobal::Set(const String& name, const Value& value)
Value vparent;
if (!parent->Get(token, &vparent)) {
Dictionary::Ptr dict = new Dictionary();
Namespace::Ptr dict = new Namespace();
parent->Set(token, dict);
parent = dict;
} else {
@ -74,16 +75,21 @@ void ScriptGlobal::Set(const String& name, const Value& value)
}
}
parent->Set(tokens[tokens.size() - 1], value);
parent->SetFieldByName(tokens[tokens.size() - 1], value, overrideFrozen, DebugInfo());
}
}
void ScriptGlobal::SetConst(const String& name, const Value& value)
{
GetGlobals()->SetAttribute(name, std::make_shared<ConstEmbeddedNamespaceValue>(value));
}
bool ScriptGlobal::Exists(const String& name)
{
return m_Globals->Contains(name);
}
Dictionary::Ptr ScriptGlobal::GetGlobals()
Namespace::Ptr ScriptGlobal::GetGlobals()
{
return m_Globals;
}
@ -102,8 +108,8 @@ void ScriptGlobal::WriteToFile(const String& filename)
StdioStream::Ptr sfp = new StdioStream(&fp, false);
ObjectLock olock(m_Globals);
for (const Dictionary::Pair& kv : m_Globals) {
Value value = kv.second;
for (const Namespace::Pair& kv : m_Globals) {
Value value = kv.second->Get();
if (value.IsObject())
value = Convert::ToString(value);

View File

@ -21,7 +21,7 @@
#define SCRIPTGLOBAL_H
#include "base/i2-base.hpp"
#include "base/dictionary.hpp"
#include "base/namespace.hpp"
namespace icinga
{
@ -35,15 +35,16 @@ class ScriptGlobal
{
public:
static Value Get(const String& name, const Value *defaultValue = nullptr);
static void Set(const String& name, const Value& value);
static void Set(const String& name, const Value& value, bool overrideFrozen = false);
static void SetConst(const String& name, const Value& value);
static bool Exists(const String& name);
static void WriteToFile(const String& filename);
static Dictionary::Ptr GetGlobals();
static Namespace::Ptr GetGlobals();
private:
static Dictionary::Ptr m_Globals;
static Namespace::Ptr m_Globals;
};
}

View File

@ -30,6 +30,7 @@
#include "base/application.hpp"
#include "base/dependencygraph.hpp"
#include "base/initialize.hpp"
#include "base/namespace.hpp"
#include <boost/regex.hpp>
#include <algorithm>
#include <set>
@ -39,39 +40,39 @@
using namespace icinga;
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, regex, &ScriptUtils::Regex, "pattern:text:mode");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, match, &ScriptUtils::Match, "pattern:text:mode");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, cidr_match, &ScriptUtils::CidrMatch, "pattern:ip:mode");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, len, &ScriptUtils::Len, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, union, &ScriptUtils::Union, "");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, intersection, &ScriptUtils::Intersection, "");
REGISTER_SCRIPTFUNCTION_NS(System, log, &ScriptUtils::Log, "severity:facility:value");
REGISTER_SCRIPTFUNCTION_NS(System, range, &ScriptUtils::Range, "start:end:increment");
REGISTER_SCRIPTFUNCTION_NS(System, exit, &Application::Exit, "status");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, typeof, &ScriptUtils::TypeOf, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, keys, &ScriptUtils::Keys, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, random, &Utility::Random, "");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, get_object, &ScriptUtils::GetObject, "type:name");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, get_objects, &ScriptUtils::GetObjects, "type");
REGISTER_SCRIPTFUNCTION_NS(System, assert, &ScriptUtils::Assert, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, string, &ScriptUtils::CastString, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, number, &ScriptUtils::CastNumber, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, bool, &ScriptUtils::CastBool, "value");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, get_time, &Utility::GetTime, "");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, basename, &Utility::BaseName, "path");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, dirname, &Utility::DirName, "path");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, msi_get_component_path, &ScriptUtils::MsiGetComponentPathShim, "component");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, track_parents, &ScriptUtils::TrackParents, "child");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, escape_shell_cmd, &Utility::EscapeShellCmd, "cmd");
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, escape_shell_arg, &Utility::EscapeShellArg, "arg");
REGISTER_SAFE_FUNCTION(System, regex, &ScriptUtils::Regex, "pattern:text:mode");
REGISTER_SAFE_FUNCTION(System, match, &ScriptUtils::Match, "pattern:text:mode");
REGISTER_SAFE_FUNCTION(System, cidr_match, &ScriptUtils::CidrMatch, "pattern:ip:mode");
REGISTER_SAFE_FUNCTION(System, len, &ScriptUtils::Len, "value");
REGISTER_SAFE_FUNCTION(System, union, &ScriptUtils::Union, "");
REGISTER_SAFE_FUNCTION(System, intersection, &ScriptUtils::Intersection, "");
REGISTER_FUNCTION(System, log, &ScriptUtils::Log, "severity:facility:value");
REGISTER_FUNCTION(System, range, &ScriptUtils::Range, "start:end:increment");
REGISTER_FUNCTION(System, exit, &Application::Exit, "status");
REGISTER_SAFE_FUNCTION(System, typeof, &ScriptUtils::TypeOf, "value");
REGISTER_SAFE_FUNCTION(System, keys, &ScriptUtils::Keys, "value");
REGISTER_SAFE_FUNCTION(System, random, &Utility::Random, "");
REGISTER_SAFE_FUNCTION(System, get_object, &ScriptUtils::GetObject, "type:name");
REGISTER_SAFE_FUNCTION(System, get_objects, &ScriptUtils::GetObjects, "type");
REGISTER_FUNCTION(System, assert, &ScriptUtils::Assert, "value");
REGISTER_SAFE_FUNCTION(System, string, &ScriptUtils::CastString, "value");
REGISTER_SAFE_FUNCTION(System, number, &ScriptUtils::CastNumber, "value");
REGISTER_SAFE_FUNCTION(System, bool, &ScriptUtils::CastBool, "value");
REGISTER_SAFE_FUNCTION(System, get_time, &Utility::GetTime, "");
REGISTER_SAFE_FUNCTION(System, basename, &Utility::BaseName, "path");
REGISTER_SAFE_FUNCTION(System, dirname, &Utility::DirName, "path");
REGISTER_SAFE_FUNCTION(System, msi_get_component_path, &ScriptUtils::MsiGetComponentPathShim, "component");
REGISTER_SAFE_FUNCTION(System, track_parents, &ScriptUtils::TrackParents, "child");
REGISTER_SAFE_FUNCTION(System, escape_shell_cmd, &Utility::EscapeShellCmd, "cmd");
REGISTER_SAFE_FUNCTION(System, escape_shell_arg, &Utility::EscapeShellArg, "arg");
#ifdef _WIN32
REGISTER_SAFE_SCRIPTFUNCTION_NS(System, escape_create_process_arg, &Utility::EscapeCreateProcessArg, "arg");
REGISTER_SAFE_FUNCTION(System, escape_create_process_arg, &Utility::EscapeCreateProcessArg, "arg");
#endif /* _WIN32 */
REGISTER_SCRIPTFUNCTION_NS(System, ptr, &ScriptUtils::Ptr, "object");
REGISTER_SCRIPTFUNCTION_NS(System, sleep, &Utility::Sleep, "interval");
REGISTER_SCRIPTFUNCTION_NS(System, path_exists, &Utility::PathExists, "path");
REGISTER_SCRIPTFUNCTION_NS(System, glob, &ScriptUtils::Glob, "pathspec:callback:type");
REGISTER_SCRIPTFUNCTION_NS(System, glob_recursive, &ScriptUtils::GlobRecursive, "pathspec:callback:type");
REGISTER_FUNCTION(System, ptr, &ScriptUtils::Ptr, "object");
REGISTER_FUNCTION(System, sleep, &Utility::Sleep, "interval");
REGISTER_FUNCTION(System, path_exists, &Utility::PathExists, "path");
REGISTER_FUNCTION(System, glob, &ScriptUtils::Glob, "pathspec:callback:type");
REGISTER_FUNCTION(System, glob_recursive, &ScriptUtils::GlobRecursive, "pathspec:callback:type");
INITIALIZE_ONCE(&ScriptUtils::StaticInitialize);
@ -83,11 +84,11 @@ enum MatchType
void ScriptUtils::StaticInitialize()
{
ScriptGlobal::Set("MatchAll", MatchAll);
ScriptGlobal::Set("MatchAny", MatchAny);
ScriptGlobal::Set("System.MatchAll", MatchAll, true);
ScriptGlobal::Set("System.MatchAny", MatchAny, true);
ScriptGlobal::Set("GlobFile", GlobFile);
ScriptGlobal::Set("GlobDirectory", GlobDirectory);
ScriptGlobal::Set("System.GlobFile", GlobFile, true);
ScriptGlobal::Set("System.GlobDirectory", GlobDirectory, true);
}
String ScriptUtils::CastString(const Value& value)
@ -397,10 +398,12 @@ Type::Ptr ScriptUtils::TypeOf(const Value& value)
return value.GetReflectionType();
}
Array::Ptr ScriptUtils::Keys(const Dictionary::Ptr& dict)
Array::Ptr ScriptUtils::Keys(const Object::Ptr& obj)
{
ArrayData result;
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(obj);
if (dict) {
ObjectLock olock(dict);
for (const Dictionary::Pair& kv : dict) {
@ -408,6 +411,15 @@ Array::Ptr ScriptUtils::Keys(const Dictionary::Ptr& dict)
}
}
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(obj);
if (ns) {
ObjectLock olock(ns);
for (const Namespace::Pair& kv : ns) {
result.push_back(kv.first);
}
}
return new Array(std::move(result));
}

View File

@ -49,7 +49,7 @@ public:
static void Log(const std::vector<Value>& arguments);
static Array::Ptr Range(const std::vector<Value>& arguments);
static Type::Ptr TypeOf(const Value& value);
static Array::Ptr Keys(const Dictionary::Ptr& dict);
static Array::Ptr Keys(const Object::Ptr& obj);
static ConfigObject::Ptr GetObject(const Value& type, const String& name);
static Array::Ptr GetObjects(const Type::Ptr& type);
static void Assert(const Value& arg);

View File

@ -23,6 +23,7 @@
#include "base/objectlock.hpp"
#include "base/convert.hpp"
#include "base/exception.hpp"
#include "base/namespace.hpp"
#include <boost/algorithm/string/join.hpp>
#include <deque>
@ -119,6 +120,22 @@ static Dictionary::Ptr SerializeDictionary(const Dictionary::Ptr& input, int att
return new Dictionary(std::move(result));
}
static Dictionary::Ptr SerializeNamespace(const Namespace::Ptr& input, int attributeTypes, SerializeStack& stack)
{
DictionaryData result;
ObjectLock olock(input);
for (const Namespace::Pair& kv : input) {
Value val = kv.second->Get();
stack.Push(kv.first, val);
result.emplace_back(kv.first, Serialize(val, attributeTypes));
stack.Pop();
}
return new Dictionary(std::move(result));
}
static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes, SerializeStack& stack)
{
Type::Ptr type = input->GetReflectionType();
@ -243,6 +260,11 @@ static Value SerializeInternal(const Value& value, int attributeTypes, Serialize
if (dict)
return SerializeDictionary(dict, attributeTypes, stack);
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(input);
if (ns)
return SerializeNamespace(ns, attributeTypes, stack);
return SerializeObject(input, attributeTypes, stack);
}

View File

@ -79,7 +79,7 @@ void SocketEventEngine::WakeUpThread(int sid, bool wait)
void SocketEvents::InitializeEngine()
{
String eventEngine = ScriptGlobal::Get("EventEngine", &Empty);
String eventEngine = Configuration::EventEngine;
if (eventEngine.IsEmpty())
#ifdef __linux__
@ -105,7 +105,7 @@ void SocketEvents::InitializeEngine()
l_SocketIOEngine->Start();
ScriptGlobal::Set("EventEngine", eventEngine);
Configuration::EventEngine = eventEngine;
}
/**

View File

@ -27,7 +27,7 @@ namespace icinga
{
#define REGISTER_STATSFUNCTION(name, callback) \
REGISTER_SCRIPTFUNCTION_NS(StatsFunctions, name, callback, "status:perfdata")
REGISTER_FUNCTION(StatsFunctions, name, callback, "status:perfdata")
}

View File

@ -35,26 +35,26 @@ std::map<String, int> SyslogLogger::m_FacilityMap;
void SyslogLogger::StaticInitialize()
{
ScriptGlobal::Set("FacilityAuth", "LOG_AUTH");
ScriptGlobal::Set("FacilityAuthPriv", "LOG_AUTHPRIV");
ScriptGlobal::Set("FacilityCron", "LOG_CRON");
ScriptGlobal::Set("FacilityDaemon", "LOG_DAEMON");
ScriptGlobal::Set("FacilityFtp", "LOG_FTP");
ScriptGlobal::Set("FacilityKern", "LOG_KERN");
ScriptGlobal::Set("FacilityLocal0", "LOG_LOCAL0");
ScriptGlobal::Set("FacilityLocal1", "LOG_LOCAL1");
ScriptGlobal::Set("FacilityLocal2", "LOG_LOCAL2");
ScriptGlobal::Set("FacilityLocal3", "LOG_LOCAL3");
ScriptGlobal::Set("FacilityLocal4", "LOG_LOCAL4");
ScriptGlobal::Set("FacilityLocal5", "LOG_LOCAL5");
ScriptGlobal::Set("FacilityLocal6", "LOG_LOCAL6");
ScriptGlobal::Set("FacilityLocal7", "LOG_LOCAL7");
ScriptGlobal::Set("FacilityLpr", "LOG_LPR");
ScriptGlobal::Set("FacilityMail", "LOG_MAIL");
ScriptGlobal::Set("FacilityNews", "LOG_NEWS");
ScriptGlobal::Set("FacilitySyslog", "LOG_SYSLOG");
ScriptGlobal::Set("FacilityUser", "LOG_USER");
ScriptGlobal::Set("FacilityUucp", "LOG_UUCP");
ScriptGlobal::Set("System.FacilityAuth", "LOG_AUTH", true);
ScriptGlobal::Set("System.FacilityAuthPriv", "LOG_AUTHPRIV", true);
ScriptGlobal::Set("System.FacilityCron", "LOG_CRON", true);
ScriptGlobal::Set("System.FacilityDaemon", "LOG_DAEMON", true);
ScriptGlobal::Set("System.FacilityFtp", "LOG_FTP", true);
ScriptGlobal::Set("System.FacilityKern", "LOG_KERN", true);
ScriptGlobal::Set("System.FacilityLocal0", "LOG_LOCAL0", true);
ScriptGlobal::Set("System.FacilityLocal1", "LOG_LOCAL1", true);
ScriptGlobal::Set("System.FacilityLocal2", "LOG_LOCAL2", true);
ScriptGlobal::Set("System.FacilityLocal3", "LOG_LOCAL3", true);
ScriptGlobal::Set("System.FacilityLocal4", "LOG_LOCAL4", true);
ScriptGlobal::Set("System.FacilityLocal5", "LOG_LOCAL5", true);
ScriptGlobal::Set("System.FacilityLocal6", "LOG_LOCAL6", true);
ScriptGlobal::Set("System.FacilityLocal7", "LOG_LOCAL7", true);
ScriptGlobal::Set("System.FacilityLpr", "LOG_LPR", true);
ScriptGlobal::Set("System.FacilityMail", "LOG_MAIL", true);
ScriptGlobal::Set("System.FacilityNews", "LOG_NEWS", true);
ScriptGlobal::Set("System.FacilitySyslog", "LOG_SYSLOG", true);
ScriptGlobal::Set("System.FacilityUser", "LOG_USER", true);
ScriptGlobal::Set("System.FacilityUucp", "LOG_UUCP", true);
m_FacilityMap["LOG_AUTH"] = LOG_AUTH;
m_FacilityMap["LOG_AUTHPRIV"] = LOG_AUTHPRIV;

View File

@ -535,7 +535,7 @@ std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME
String GetIcingaCADir()
{
return Application::GetConst("DataDir") + "/ca";
return Configuration::DataDir + "/ca";
}
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject)

View File

@ -19,6 +19,7 @@
#include "base/type.hpp"
#include "base/scriptglobal.hpp"
#include "base/namespace.hpp"
#include "base/objectlock.hpp"
using namespace icinga;
@ -39,19 +40,19 @@ String Type::ToString() const
void Type::Register(const Type::Ptr& type)
{
VERIFY(!GetByName(type->GetName()));
ScriptGlobal::Set("Types." + type->GetName(), type);
ScriptGlobal::Set("Types." + type->GetName(), type, true);
}
Type::Ptr Type::GetByName(const String& name)
{
Dictionary::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
if (!typesNS)
return nullptr;
Value ptype = typesNS->Get(name);
Value ptype;
if (!typesNS->Get(name, &ptype))
return nullptr;
if (!ptype.IsObjectType<Type>())
return nullptr;
@ -63,14 +64,16 @@ std::vector<Type::Ptr> Type::GetAllTypes()
{
std::vector<Type::Ptr> types;
Dictionary::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
if (typesNS) {
ObjectLock olock(typesNS);
for (const Dictionary::Pair& kv : typesNS) {
if (kv.second.IsObjectType<Type>())
types.push_back(kv.second);
for (const Namespace::Pair& kv : typesNS) {
Value value = kv.second->Get();
if (value.IsObjectType<Type>())
types.push_back(value);
}
}

View File

@ -40,7 +40,7 @@ using namespace icinga;
String ApiSetupUtility::GetConfdPath()
{
return Application::GetConst("ConfigDir") + "/conf.d";
return Configuration::ConfigDir + "/conf.d";
}
String ApiSetupUtility::GetApiUsersConfPath()
@ -80,8 +80,8 @@ bool ApiSetupUtility::SetupMasterCertificates(const String& cn)
String pki_path = ApiListener::GetCertsDir();
Utility::MkDirP(pki_path, 0700);
String user = ScriptGlobal::Get("RunAsUser");
String group = ScriptGlobal::Get("RunAsGroup");
String user = Configuration::RunAsUser;
String group = Configuration::RunAsGroup;
if (!Utility::SetFileOwnership(pki_path, user, group)) {
Log(LogWarning, "cli")

View File

@ -72,7 +72,7 @@ static bool Daemonize()
do {
Utility::Sleep(0.1);
readpid = Application::ReadPidFile(Application::GetConst("PidPath"));
readpid = Application::ReadPidFile(Configuration::PidPath);
ret = waitpid(pid, &status, WNOHANG);
} while (readpid != pid && ret == 0);
@ -193,7 +193,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
<< ")";
if (!vm.count("validate") && !vm.count("reload-internal")) {
pid_t runningpid = Application::ReadPidFile(Application::GetConst("PidPath"));
pid_t runningpid = Application::ReadPidFile(Configuration::PidPath);
if (runningpid > 0) {
Log(LogCritical, "cli")
<< "Another instance of Icinga already running with PID " << runningpid;
@ -206,7 +206,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
configs = vm["config"].as<std::vector<std::string> >();
else if (!vm.count("no-config")) {
/* The implicit string assignment is needed for Windows builds. */
String configDir = Application::GetConst("ConfigDir");
String configDir = Configuration::ConfigDir;
configs.push_back(configDir + "/icinga2.conf");
}
@ -214,7 +214,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
std::vector<ConfigItem::Ptr> newItems;
if (!DaemonUtility::LoadConfigFiles(configs, newItems, Application::GetConst("ObjectsPath"), Application::GetConst("VarsPath")))
if (!DaemonUtility::LoadConfigFiles(configs, newItems, Configuration::ObjectsPath, Configuration::VarsPath))
return EXIT_FAILURE;
if (vm.count("validate")) {
@ -256,7 +256,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
/* restore the previous program state */
try {
ConfigObject::RestoreObjects(Application::GetConst("StatePath"));
ConfigObject::RestoreObjects(Configuration::StatePath);
} catch (const std::exception& ex) {
Log(LogCritical, "cli")
<< "Failed to restore state file: " << DiagnosticInformation(ex);
@ -264,7 +264,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
}
{
WorkQueue upq(25000, Application::GetConcurrency());
WorkQueue upq(25000, Configuration::Concurrency);
upq.SetName("DaemonCommand::Run");
// activate config only after daemonization: it starts threads and that is not compatible with fork()

View File

@ -121,7 +121,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
* unfortunately moving it there is somewhat non-trivial. */
success = true;
String zonesEtcDir = Application::GetConst("ZonesDir");
String zonesEtcDir = Configuration::ZonesDir;
if (!zonesEtcDir.IsEmpty() && Utility::PathExists(zonesEtcDir))
Utility::Glob(zonesEtcDir + "/*", std::bind(&IncludeZoneDirRecursive, _1, "_etc", std::ref(success)), GlobDirectory);
@ -130,7 +130,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
/* Load package config files - they may contain additional zones which
* are authoritative on this node and are checked in HasZoneConfigAuthority(). */
String packagesVarDir = Application::GetConst("DataDir") + "/api/packages";
String packagesVarDir = Configuration::DataDir + "/api/packages";
if (Utility::PathExists(packagesVarDir))
Utility::Glob(packagesVarDir + "/*", std::bind(&IncludePackage, _1, std::ref(success)), GlobDirectory);
@ -138,14 +138,18 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
return false;
/* Load cluster synchronized configuration files */
String zonesVarDir = Application::GetConst("DataDir") + "/api/zones";
String zonesVarDir = Configuration::DataDir + "/api/zones";
if (Utility::PathExists(zonesVarDir))
Utility::Glob(zonesVarDir + "/*", std::bind(&IncludeNonLocalZone, _1, "_cluster", std::ref(success)), GlobDirectory);
if (!success)
return false;
Type::Ptr appType = Type::GetByName(ScriptGlobal::Get("ApplicationType", &Empty));
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
Value vAppType;
VERIFY(systemNS->Get("ApplicationType", &vAppType));
Type::Ptr appType = Type::GetByName(vAppType);
if (ConfigItem::GetItems(appType).empty()) {
ConfigItemBuilder builder;
@ -170,7 +174,7 @@ bool DaemonUtility::LoadConfigFiles(const std::vector<std::string>& configs,
return false;
}
WorkQueue upq(25000, Application::GetConcurrency());
WorkQueue upq(25000, Configuration::Concurrency);
upq.SetName("DaemonUtility::LoadConfigFiles");
bool result = ConfigItem::CommitItems(ascope.GetContext(), upq, newItems);

View File

@ -31,12 +31,12 @@ using namespace icinga;
String FeatureUtility::GetFeaturesAvailablePath()
{
return Application::GetConst("ConfigDir") + "/features-available";
return Configuration::ConfigDir + "/features-available";
}
String FeatureUtility::GetFeaturesEnabledPath()
{
return Application::GetConst("ConfigDir") + "/features-enabled";
return Configuration::ConfigDir + "/features-enabled";
}
std::vector<String> FeatureUtility::GetFieldCompletionSuggestions(const String& word, bool enable)

View File

@ -353,8 +353,8 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
String certsDir = ApiListener::GetCertsDir();
Utility::MkDirP(certsDir, 0700);
String user = ScriptGlobal::Get("RunAsUser");
String group = ScriptGlobal::Get("RunAsGroup");
String user = Configuration::RunAsUser;
String group = Configuration::RunAsGroup;
if (!Utility::SetFileOwnership(certsDir, user, group)) {
Log(LogWarning, "cli")

View File

@ -43,12 +43,12 @@ using namespace icinga;
String NodeUtility::GetConstantsConfPath()
{
return Application::GetConst("ConfigDir") + "/constants.conf";
return Configuration::ConfigDir + "/constants.conf";
}
String NodeUtility::GetZonesConfPath()
{
return Application::GetConst("ConfigDir") + "/zones.conf";
return Configuration::ConfigDir + "/zones.conf";
}
/*
@ -170,8 +170,8 @@ bool NodeUtility::WriteNodeConfigObjects(const String& filename, const Array::Pt
Utility::MkDirP(path, 0755);
String user = ScriptGlobal::Get("RunAsUser");
String group = ScriptGlobal::Get("RunAsGroup");
String user = Configuration::RunAsUser;
String group = Configuration::RunAsGroup;
if (!Utility::SetFileOwnership(path, user, group)) {
Log(LogWarning, "cli")
@ -274,7 +274,7 @@ void NodeUtility::SerializeObject(std::ostream& fp, const Dictionary::Ptr& objec
*/
bool NodeUtility::UpdateConfiguration(const String& value, bool include, bool recursive)
{
String configurationFile = Application::GetConst("ConfigDir") + "/icinga2.conf";
String configurationFile = Configuration::ConfigDir + "/icinga2.conf";
Log(LogInformation, "cli")
<< "Updating '" << value << "' include in '" << configurationFile << "'.";

View File

@ -272,8 +272,8 @@ wizard_endpoint_loop_start:
String certsDir = ApiListener::GetCertsDir();
Utility::MkDirP(certsDir, 0700);
String user = ScriptGlobal::Get("RunAsUser");
String group = ScriptGlobal::Get("RunAsGroup");
String user = Configuration::RunAsUser;
String group = Configuration::RunAsGroup;
if (!Utility::SetFileOwnership(certsDir, user, group)) {
Log(LogWarning, "cli")
@ -850,7 +850,7 @@ wizard_global_zone_loop_start:
}
/* Include api-users.conf */
String apiUsersFilePath = Application::GetConst("ConfigDir") + "/conf.d/api-users.conf";
String apiUsersFilePath = Configuration::ConfigDir + "/conf.d/api-users.conf";
std::cout << ConsoleColorTag(Console_Bold | Console_ForegroundGreen)
<< "Checking if the api-users.conf file exists...\n"

View File

@ -67,11 +67,11 @@ void ObjectListCommand::InitParameters(boost::program_options::options_descripti
*/
int ObjectListCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
String objectfile = Application::GetConst("ObjectsPath");
String objectfile = Configuration::ObjectsPath;
if (!Utility::PathExists(objectfile)) {
Log(LogCritical, "cli")
<< "Cannot open objects file '" << Application::GetConst("ObjectsPath") << "'.";
<< "Cannot open objects file '" << Configuration::ObjectsPath << "'.";
Log(LogCritical, "cli", "Run 'icinga2 daemon -C' to validate config and generate the cache file.");
return 1;
}

View File

@ -147,26 +147,26 @@ bool TroubleshootCommand::GeneralInfo(InfoLog& log, const boost::program_options
//Application::DisplayInfoMessage() but formatted
InfoLogLine(log)
<< "\tApplication version: " << Application::GetConst("AppVersion") << '\n'
<< "\tApplication version: " << Application::GetAppVersion() << '\n'
<< "\t\n"
<< "\tConfig directory: " << Application::GetConst("ConfigDir") << "\n"
<< "\tData directory: " << Application::GetConst("DataDir") << "\n"
<< "\tLog directory: " << Application::GetConst("LogDir") << "\n"
<< "\tCache directory: " << Application::GetConst("CacheDir") << "\n"
<< "\tRun directory: " << Application::GetConst("InitRunDir") << "\n"
<< "\tConfig directory: " << Configuration::ConfigDir << "\n"
<< "\tData directory: " << Configuration::DataDir << "\n"
<< "\tLog directory: " << Configuration::LogDir << "\n"
<< "\tCache directory: " << Configuration::CacheDir << "\n"
<< "\tRun directory: " << Configuration::InitRunDir << "\n"
<< "\t\n"
<< "Old paths (deprecated):\n"
<< "\tInstallation root: " << Application::GetConst("PrefixDir") << '\n'
<< "\tSysconf directory: " << Application::GetConst("SysconfDir") << '\n'
<< "\tRun directory: " << Application::GetConst("RunDir") << '\n'
<< "\tLocal state directory: " << Application::GetConst("LocalStateDir") << '\n'
<< "\tInstallation root: " << Configuration::PrefixDir << '\n'
<< "\tSysconf directory: " << Configuration::SysconfDir << '\n'
<< "\tRun directory: " << Configuration::RunDir << '\n'
<< "\tLocal state directory: " << Configuration::LocalStateDir << '\n'
<< "\t\n"
<< "Internal paths:\n"
<< "\tPackage data directory: " << Application::GetConst("PkgDataDir") << '\n'
<< "\tState path: " << Application::GetConst("StatePath") << '\n'
<< "\tObjects path: " << Application::GetConst("ObjectsPath") << '\n'
<< "\tVars path: " << Application::GetConst("VarsPath") << '\n'
<< "\tPID path: " << Application::GetConst("PidPath") << '\n';
<< "\tPackage data directory: " << Configuration::PkgDataDir << '\n'
<< "\tState path: " << Configuration::StatePath << '\n'
<< "\tObjects path: " << Configuration::ObjectsPath << '\n'
<< "\tVars path: " << Configuration::VarsPath << '\n'
<< "\tPID path: " << Configuration::PidPath << '\n';
InfoLogLine(log)
<< '\n';
@ -186,7 +186,7 @@ bool TroubleshootCommand::ObjectInfo(InfoLog& log, const boost::program_options:
InfoLogLine(log, Console_ForegroundBlue)
<< std::string(14, '=') << " OBJECT INFORMATION " << std::string(14, '=') << "\n\n";
String objectfile = Application::GetConst("ObjectsPath");
String objectfile = Configuration::ObjectsPath;
std::set<String> configs;
if (!Utility::PathExists(objectfile)) {
@ -262,14 +262,14 @@ bool TroubleshootCommand::ConfigInfo(InfoLog& log, const boost::program_options:
InfoLogLine(log)
<< "A collection of important configuration files follows, please make sure to remove any sensitive data such as credentials, internal company names, etc\n";
if (!PrintFile(log, Application::GetConst("ConfigDir") + "/icinga2.conf")) {
if (!PrintFile(log, Configuration::ConfigDir + "/icinga2.conf")) {
InfoLogLine(log, 0, LogWarning)
<< "icinga2.conf not found, therefore skipping validation.\n"
<< "If you are using an icinga2.conf somewhere but the default path please validate it via 'icinga2 daemon -C -c \"path\to/icinga2.conf\"'\n"
<< "and provide it with your support request.\n";
}
if (!PrintFile(log, Application::GetConst("ConfigDir") + "/zones.conf")) {
if (!PrintFile(log, Configuration::ConfigDir + "/zones.conf")) {
InfoLogLine(log, 0, LogWarning)
<< "zones.conf not found.\n"
<< "If you are using a zones.conf somewhere but the default path please provide it with your support request\n";
@ -380,7 +380,7 @@ void TroubleshootCommand::GetLatestReport(const String& filename, time_t& bestTi
bool TroubleshootCommand::PrintCrashReports(InfoLog& log)
{
String spath = Application::GetConst("LogDir") + "/crash/report.*";
String spath = Configuration::LogDir + "/crash/report.*";
time_t bestTimestamp = 0;
String bestFilename;
@ -393,7 +393,7 @@ bool TroubleshootCommand::PrintCrashReports(InfoLog& log)
if (int const * err = boost::get_error_info<errinfo_win32_error>(ex)) {
if (*err != 3) {//Error code for path does not exist
InfoLogLine(log, 0, LogWarning)
<< Application::GetConst("LogDir") + "/crash/ does not exist\n";
<< Configuration::LogDir + "/crash/ does not exist\n";
return false;
}
@ -406,7 +406,7 @@ bool TroubleshootCommand::PrintCrashReports(InfoLog& log)
#else
catch (...) {
InfoLogLine(log, 0, LogWarning) << "Error printing crash reports.\n"
<< "Does " << Application::GetConst("LogDir") + "/crash/ exist?\n";
<< "Does " << Configuration::LogDir + "/crash/ exist?\n";
return false;
}
@ -414,7 +414,7 @@ bool TroubleshootCommand::PrintCrashReports(InfoLog& log)
if (!bestTimestamp)
InfoLogLine(log, Console_ForegroundYellow)
<< "No crash logs found in " << Application::GetConst("LogDir") << "/crash/\n\n";
<< "No crash logs found in " << Configuration::LogDir << "/crash/\n\n";
else {
InfoLogLine(log)
<< "Latest crash report is from " << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime()) << '\n'
@ -454,8 +454,8 @@ bool TroubleshootCommand::PrintFile(InfoLog& log, const String& path)
bool TroubleshootCommand::CheckConfig()
{
String configDir = Application::GetConst("ConfigDir");
String objectsPath = Application::GetConst("ObjectsPath");
String configDir = Configuration::ConfigDir;
String objectsPath = Configuration::ObjectsPath;
return DaemonUtility::ValidateConfigFiles({ configDir + "/icinga2.conf" }, objectsPath);
}
@ -622,10 +622,10 @@ void TroubleshootCommand::InitParameters(boost::program_options::options_descrip
int TroubleshootCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
#ifdef _WIN32 //Dislikes ':' in filenames
String path = Application::GetConst("LogDir") + "/troubleshooting-"
String path = Configuration::LogDir + "/troubleshooting-"
+ Utility::FormatDateTime("%Y-%m-%d_%H-%M-%S", Utility::GetTime()) + ".log";
#else
String path = Application::GetConst("LogDir") + "/troubleshooting-"
String path = Configuration::LogDir + "/troubleshooting-"
+ Utility::FormatDateTime("%Y-%m-%d_%H:%M:%S", Utility::GetTime()) + ".log";
#endif /*_WIN32*/

View File

@ -75,7 +75,7 @@ int VariableGetCommand::Run(const boost::program_options::variables_map& vm, con
return 0;
}
String varsfile = Application::GetConst("VarsPath");
String varsfile = Configuration::VarsPath;
if (!Utility::PathExists(varsfile)) {
Log(LogCritical, "cli")

View File

@ -53,7 +53,7 @@ String VariableListCommand::GetShortDescription() const
*/
int VariableListCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
String varsfile = Application::GetConst("VarsPath");
String varsfile = Configuration::VarsPath;
if (!Utility::PathExists(varsfile)) {
Log(LogCritical, "cli")

View File

@ -31,7 +31,7 @@ using namespace icinga;
Value VariableUtility::GetVariable(const String& name)
{
String varsfile = Application::GetConst("VarsPath");
String varsfile = Configuration::VarsPath;
std::fstream fp;
fp.open(varsfile.CStr(), std::ios_base::in);
@ -61,7 +61,7 @@ Value VariableUtility::GetVariable(const String& name)
void VariableUtility::PrintVariables(std::ostream& outfp)
{
String varsfile = Application::GetConst("VarsPath");
String varsfile = Configuration::VarsPath;
std::fstream fp;
fp.open(varsfile.CStr(), std::ios_base::in);

View File

@ -30,7 +30,7 @@ class CheckResultReader : ConfigObject
activation_priority 100;
[config] String spool_dir {
default {{{ return Application::GetConst("DataDir") + "/spool/checkresults/"; }}}
default {{{ return Configuration::DataDir + "/spool/checkresults/"; }}}
};
};

View File

@ -30,7 +30,7 @@ class CompatLogger : ConfigObject
activation_priority 100;
[config] String log_dir {
default {{{ return Application::GetConst("LogDir") + "/compat"; }}}
default {{{ return Configuration::LogDir + "/compat"; }}}
};
[config] String rotation_method {
default {{{ return "HOURLY"; }}}

View File

@ -30,7 +30,7 @@ class ExternalCommandListener : ConfigObject
activation_priority 100;
[config] String command_path {
default {{{ return Application::GetConst("InitRunDir") + "/cmd/icinga2.cmd"; }}}
default {{{ return Configuration::InitRunDir + "/cmd/icinga2.cmd"; }}}
};
};

View File

@ -559,7 +559,7 @@ void StatusDataWriter::UpdateObjectsCache()
{
CONTEXT("Writing objects.cache file");
String objectsPath = Application::GetConst("ObjectsPath");
String objectsPath = Configuration::ObjectsPath;
std::fstream objectfp;
String tempObjectsPath = Utility::CreateTempFile(objectsPath + ".XXXXXX", 0644, objectfp);

View File

@ -30,10 +30,10 @@ class StatusDataWriter : ConfigObject
activation_priority 100;
[config] String status_path {
default {{{ return Application::GetConst("CacheDir") + "/status.dat"; }}}
default {{{ return Configuration::CacheDir + "/status.dat"; }}}
};
[config] String objects_path {
default {{{ return Application::GetConst("CacheDir") + "/objects.cache"; }}}
default {{{ return Configuration::CacheDir + "/objects.cache"; }}}
};
[config] double update_interval {
default {{{ return 15; }}}

View File

@ -180,7 +180,7 @@ this return T_THIS;
globals return T_GLOBALS;
locals return T_LOCALS;
use return T_USE;
__using return T_USING;
using return T_USING;
apply return T_APPLY;
default return T_DEFAULT;
to return T_TO;
@ -203,6 +203,7 @@ ignore_on_error return T_IGNORE_ON_ERROR;
current_filename return T_CURRENT_FILENAME;
current_line return T_CURRENT_LINE;
debugger return T_DEBUGGER;
namespace return T_NAMESPACE;
=\> return T_FOLLOWS;
\<\< return T_SHIFT_LEFT;
\>\> return T_SHIFT_RIGHT;

View File

@ -149,8 +149,9 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
%token T_CURRENT_FILENAME "current_filename (T_CURRENT_FILENAME)"
%token T_CURRENT_LINE "current_line (T_CURRENT_LINE)"
%token T_DEBUGGER "debugger (T_DEBUGGER)"
%token T_NAMESPACE "namespace (T_NAMESPACE)"
%token T_USE "use (T_USE)"
%token T_USING "__using (T_USING)"
%token T_USING "using (T_USING)"
%token T_OBJECT "object (T_OBJECT)"
%token T_TEMPLATE "template (T_TEMPLATE)"
%token T_INCLUDE "include (T_INCLUDE)"
@ -602,9 +603,23 @@ lterm: T_LIBRARY rterm
{
$$ = new BreakpointExpression(@$);
}
| T_NAMESPACE rterm
{
BeginFlowControlBlock(context, FlowControlReturn, false);
}
rterm_scope_require_side_effect
{
EndFlowControlBlock(context);
std::unique_ptr<Expression> expr{$2};
BindToScope(expr, ScopeGlobal);
$$ = new SetExpression(std::move(expr), OpSetLiteral, std::unique_ptr<Expression>(new NamespaceExpression(std::unique_ptr<Expression>($4), @$)), @$);
}
| T_USING rterm
{
$$ = new UsingExpression(std::unique_ptr<Expression>($2), @$);
std::shared_ptr<Expression> expr{$2};
context->AddImport(expr);
$$ = MakeLiteralRaw();
}
| apply
| object
@ -648,7 +663,7 @@ lterm: T_LIBRARY rterm
}
| T_CONST T_IDENTIFIER T_SET rterm
{
$$ = new SetExpression(MakeIndexer(ScopeGlobal, *$2), OpSetLiteral, std::unique_ptr<Expression>($4));
$$ = new SetConstExpression(*$2, std::unique_ptr<Expression>($4), @$);
delete $2;
}
| T_VAR rterm
@ -879,7 +894,7 @@ rterm_no_side_effect_no_dict: T_STRING
}
| T_IDENTIFIER
{
$$ = new VariableExpression(*$1, @1);
$$ = new VariableExpression(*$1, context->GetImports(), @1);
delete $1;
}
| T_MULTIPLY rterm %prec DEREF_OP
@ -1105,7 +1120,7 @@ use_specifier_items: use_specifier_item
use_specifier_item: identifier
{
$$ = new std::pair<String, std::unique_ptr<Expression> >(*$1, std::unique_ptr<Expression>(new VariableExpression(*$1, @1)));
$$ = new std::pair<String, std::unique_ptr<Expression> >(*$1, std::unique_ptr<Expression>(new VariableExpression(*$1, context->GetImports(), @1)));
delete $1;
}
| identifier T_SET rterm

View File

@ -361,3 +361,12 @@ bool ConfigCompiler::IsAbsolutePath(const String& path)
#endif /* _WIN32 */
}
void ConfigCompiler::AddImport(const std::shared_ptr<Expression>& import)
{
m_Imports.push_back(import);
}
std::vector<std::shared_ptr<Expression> > ConfigCompiler::GetImports() const
{
return m_Imports;
}

View File

@ -109,6 +109,9 @@ public:
void SetPackage(const String& package);
String GetPackage() const;
void AddImport(const std::shared_ptr<Expression>& import);
std::vector<std::shared_ptr<Expression> > GetImports() const;
static void CollectIncludes(std::vector<std::unique_ptr<Expression> >& expressions,
const String& file, const String& zone, const String& package);
@ -134,6 +137,7 @@ private:
std::istream *m_Input;
String m_Zone;
String m_Package;
std::vector<std::shared_ptr<Expression> > m_Imports;
void *m_Scanner;

View File

@ -48,7 +48,7 @@ ConfigItem::TypeMap ConfigItem::m_DefaultTemplates;
ConfigItem::ItemList ConfigItem::m_UnnamedItems;
ConfigItem::IgnoredItemList ConfigItem::m_IgnoredItems;
REGISTER_SCRIPTFUNCTION_NS(Internal, run_with_activation_context, &ConfigItem::RunWithActivationContext, "func");
REGISTER_FUNCTION(Internal, run_with_activation_context, &ConfigItem::RunWithActivationContext, "func");
/**
* Constructor for the ConfigItem class.
@ -577,8 +577,8 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, const std::vector<ConfigItem::Ptr
if (withModAttrs) {
/* restore modified attributes */
if (Utility::PathExists(Application::GetConst("ModAttrPath"))) {
std::unique_ptr<Expression> expression = ConfigCompiler::CompileFile(Application::GetConst("ModAttrPath"));
if (Utility::PathExists(Configuration::ModAttrPath)) {
std::unique_ptr<Expression> expression = ConfigCompiler::CompileFile(Configuration::ModAttrPath);
if (expression) {
try {
@ -675,7 +675,7 @@ bool ConfigItem::RunWithActivationContext(const Function::Ptr& function)
function->Invoke();
WorkQueue upq(25000, Application::GetConcurrency());
WorkQueue upq(25000, Configuration::Concurrency);
upq.SetName("ConfigItem::RunWithActivationContext");
std::vector<ConfigItem::Ptr> newItems;

View File

@ -31,6 +31,7 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
void ConfigItemBuilder::SetType(const Type::Ptr& type)
{
ASSERT(type);
m_Type = type;
}

View File

@ -29,6 +29,7 @@
#include "base/scriptglobal.hpp"
#include "base/loader.hpp"
#include "base/reference.hpp"
#include "base/namespace.hpp"
#include <boost/exception_ptr.hpp>
#include <boost/exception/errinfo_nested_exception.hpp>
@ -116,6 +117,15 @@ const DebugInfo& DebuggableExpression::GetDebugInfo() const
return m_DebugInfo;
}
VariableExpression::VariableExpression(String variable, std::vector<std::shared_ptr<Expression> > imports, const DebugInfo& debugInfo)
: DebuggableExpression(debugInfo), m_Variable(std::move(variable)), m_Imports(std::move(imports))
{
m_Imports.push_back(MakeIndexer(ScopeGlobal, "System"));
m_Imports.push_back(std::unique_ptr<Expression>(new IndexerExpression(MakeIndexer(ScopeGlobal, "System"), MakeLiteral("Configuration"))));
m_Imports.push_back(MakeIndexer(ScopeGlobal, "Types"));
m_Imports.push_back(MakeIndexer(ScopeGlobal, "Icinga"));
}
ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
Value value;
@ -124,7 +134,7 @@ ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *d
return value;
else if (frame.Self.IsObject() && frame.Locals != frame.Self.Get<Object::Ptr>() && frame.Self.Get<Object::Ptr>()->GetOwnField(m_Variable, &value))
return value;
else if (VMOps::FindVarImport(frame, m_Variable, &value, m_DebugInfo))
else if (VMOps::FindVarImport(frame, m_Imports, m_Variable, &value, m_DebugInfo))
return value;
else
return ScriptGlobal::Get(m_Variable);
@ -144,7 +154,7 @@ bool VariableExpression::GetReference(ScriptFrame& frame, bool init_dict, Value
if (dhint && *dhint)
*dhint = new DebugHint((*dhint)->GetChild(m_Variable));
} else if (VMOps::FindVarImportRef(frame, m_Variable, parent, m_DebugInfo)) {
} else if (VMOps::FindVarImportRef(frame, m_Imports, m_Variable, parent, m_DebugInfo)) {
return true;
} else if (ScriptGlobal::Exists(m_Variable)) {
*parent = ScriptGlobal::GetGlobals();
@ -608,7 +618,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
}
}
VMOps::SetField(parent, index, operand2.GetValue(), m_DebugInfo);
VMOps::SetField(parent, index, operand2.GetValue(), m_OverrideFrozen, m_DebugInfo);
if (psdhint) {
psdhint->AddMessage("=", m_DebugInfo);
@ -620,6 +630,33 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
return Empty;
}
void SetExpression::SetOverrideFrozen()
{
m_OverrideFrozen = true;
}
ExpressionResult SetConstExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
auto globals = ScriptGlobal::GetGlobals();
auto attr = globals->GetAttribute(m_Name);
if (dynamic_pointer_cast<ConstEmbeddedNamespaceValue>(attr)) {
std::ostringstream msgbuf;
msgbuf << "Value for constant '" << m_Name << "' was modified. This behaviour is deprecated.\n";
ShowCodeLocation(msgbuf, GetDebugInfo(), false);
Log(LogWarning, msgbuf.str());
}
ExpressionResult operandres = m_Operand->Evaluate(frame);
CHECK_RESULT(operandres);
Value operand = operandres.GetValue();
globals->SetAttribute(m_Name, std::make_shared<ConstEmbeddedNamespaceValue>(operand));
return Empty;
}
ExpressionResult ConditionalExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
ExpressionResult condition = m_Condition->Evaluate(frame, dhint);
@ -696,10 +733,19 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *
if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
if (init_dict) {
Value old_value = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());
Value old_value;
bool has_field = true;
if (vparent.IsObject()) {
Object::Ptr oparent = vparent;
has_field = oparent->HasOwnField(vindex);
}
if (has_field)
old_value = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());
if (old_value.IsEmpty() && !old_value.IsString())
VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo());
VMOps::SetField(vparent, vindex, new Dictionary(), m_OverrideFrozen, m_Operand1->GetDebugInfo());
}
*parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo);
@ -725,6 +771,11 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *
return true;
}
void IndexerExpression::SetOverrideFrozen()
{
m_OverrideFrozen = true;
}
void icinga::BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec)
{
auto *dexpr = dynamic_cast<DictExpression *>(expr.get());
@ -841,6 +892,17 @@ ExpressionResult ApplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhin
m_Package, m_FKVar, m_FVVar, m_FTerm, m_ClosedVars, m_IgnoreOnError, m_Expression, m_DebugInfo);
}
ExpressionResult NamespaceExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
Namespace::Ptr ns = new Namespace(new ConstNamespaceBehavior());
ScriptFrame innerFrame(true, ns);
ExpressionResult result = m_Expression->Evaluate(innerFrame);
CHECK_RESULT(result);
return ns;
}
ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
if (frame.Sandboxed)
@ -964,23 +1026,6 @@ ExpressionResult BreakpointExpression::DoEvaluate(ScriptFrame& frame, DebugHint
return Empty;
}
ExpressionResult UsingExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
if (frame.Sandboxed)
BOOST_THROW_EXCEPTION(ScriptError("Using directives are not allowed in sandbox mode.", m_DebugInfo));
ExpressionResult importres = m_Name->Evaluate(frame);
CHECK_RESULT(importres);
Value import = importres.GetValue();
if (!import.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(ScriptError("The parameter must resolve to an object of type 'Dictionary'", m_DebugInfo));
ScriptFrame::AddImport(import);
return Empty;
}
ExpressionResult TryExceptExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
try {

View File

@ -305,9 +305,7 @@ protected:
class VariableExpression final : public DebuggableExpression
{
public:
VariableExpression(String variable, const DebugInfo& debugInfo = DebugInfo())
: DebuggableExpression(debugInfo), m_Variable(std::move(variable))
{ }
VariableExpression(String variable, std::vector<std::shared_ptr<Expression> > imports, const DebugInfo& debugInfo = DebugInfo());
String GetVariable() const
{
@ -320,6 +318,7 @@ protected:
private:
String m_Variable;
std::vector<std::shared_ptr<Expression> > m_Imports;
friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
};
@ -637,6 +636,19 @@ private:
friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
};
class SetConstExpression final : public UnaryExpression
{
public:
SetConstExpression(const String& name, std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
: UnaryExpression(std::move(operand), debugInfo), m_Name(name)
{ }
protected:
String m_Name;
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
};
class SetExpression final : public BinaryExpression
{
public:
@ -644,11 +656,14 @@ public:
: BinaryExpression(std::move(operand1), std::move(operand2), debugInfo), m_Op(op)
{ }
void SetOverrideFrozen();
protected:
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
private:
CombinedSetOp m_Op;
bool m_OverrideFrozen{false};
friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
};
@ -739,7 +754,11 @@ public:
: BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
{ }
void SetOverrideFrozen();
protected:
bool m_OverrideFrozen{false};
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
@ -836,6 +855,20 @@ private:
std::shared_ptr<Expression> m_Expression;
};
class NamespaceExpression final : public DebuggableExpression
{
public:
NamespaceExpression(std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
: DebuggableExpression(debugInfo), m_Expression(std::move(expression))
{ }
protected:
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
private:
std::shared_ptr<Expression> m_Expression;
};
class ObjectExpression final : public DebuggableExpression
{
public:
@ -932,20 +965,6 @@ protected:
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
};
class UsingExpression final : public DebuggableExpression
{
public:
UsingExpression(std::unique_ptr<Expression> name, const DebugInfo& debugInfo = DebugInfo())
: DebuggableExpression(debugInfo), m_Name(std::move(name))
{ }
protected:
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
private:
std::unique_ptr<Expression> m_Name;
};
class TryExceptExpression final : public DebuggableExpression
{
public:

View File

@ -28,6 +28,7 @@
#include "base/debuginfo.hpp"
#include "base/array.hpp"
#include "base/dictionary.hpp"
#include "base/namespace.hpp"
#include "base/function.hpp"
#include "base/scriptglobal.hpp"
#include "base/exception.hpp"
@ -42,15 +43,13 @@ namespace icinga
class VMOps
{
public:
static inline bool FindVarImportRef(ScriptFrame& frame, const String& name, Value *result, const DebugInfo& debugInfo = DebugInfo())
static inline bool FindVarImportRef(ScriptFrame& frame, const std::vector<std::shared_ptr<Expression> >& imports, const String& name, Value *result, const DebugInfo& debugInfo = DebugInfo())
{
Array::Ptr imports = ScriptFrame::GetImports();
ObjectLock olock(imports);
for (const Value& import : imports) {
Object::Ptr obj = import;
for (const auto& import : imports) {
ExpressionResult res = import->Evaluate(frame);
Object::Ptr obj = res.GetValue();
if (obj->HasOwnField(name)) {
*result = import;
*result = obj;
return true;
}
}
@ -58,11 +57,11 @@ public:
return false;
}
static inline bool FindVarImport(ScriptFrame& frame, const String& name, Value *result, const DebugInfo& debugInfo = DebugInfo())
static inline bool FindVarImport(ScriptFrame& frame, const std::vector<std::shared_ptr<Expression> >& imports, const String& name, Value *result, const DebugInfo& debugInfo = DebugInfo())
{
Value parent;
if (FindVarImportRef(frame, name, &parent, debugInfo)) {
if (FindVarImportRef(frame, imports, name, &parent, debugInfo)) {
*result = GetField(parent, name, frame.Sandboxed, debugInfo);
return true;
}
@ -225,6 +224,26 @@ public:
ExpressionResult res = expression->Evaluate(frame);
CHECK_RESULT_LOOP(res);
}
} else if (value.IsObjectType<Namespace>()) {
if (fvvar.IsEmpty())
BOOST_THROW_EXCEPTION(ScriptError("Cannot use array iterator for namespace.", debugInfo));
Namespace::Ptr ns = value;
std::vector<String> keys;
{
ObjectLock olock(ns);
for (const Namespace::Pair& kv : ns) {
keys.push_back(kv.first);
}
}
for (const String& key : keys) {
frame.Locals->Set(fkvar, key);
frame.Locals->Set(fvvar, ns->Get(key));
ExpressionResult res = expression->Evaluate(frame);
CHECK_RESULT_LOOP(res);
}
} else
BOOST_THROW_EXCEPTION(ScriptError("Invalid type in for expression: " + value.GetTypeName(), debugInfo));
@ -244,12 +263,12 @@ public:
return object->GetFieldByName(field, sandboxed, debugInfo);
}
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value, const DebugInfo& debugInfo = DebugInfo())
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo = DebugInfo())
{
if (!context)
BOOST_THROW_EXCEPTION(ScriptError("Cannot set field '" + field + "' on a value that is not an object.", debugInfo));
return context->SetFieldByName(field, value, debugInfo);
return context->SetFieldByName(field, value, overrideFrozen, debugInfo);
}
private:

View File

@ -18,10 +18,8 @@
******************************************************************************/
System.assert(Internal.run_with_activation_context(function() {
var _Internal = Internal.clone()
template CheckCommand "ido-check-command" use (_Internal) {
execute = _Internal.IdoCheck
template CheckCommand "ido-check-command" use (checkFunc = Internal.IdoCheck) {
execute = checkFunc
}
object CheckCommand "ido" {

View File

@ -29,22 +29,22 @@ std::map<String, int> DbQuery::m_CategoryFilterMap;
void DbQuery::StaticInitialize()
{
ScriptGlobal::Set("DbCatConfig", DbCatConfig);
ScriptGlobal::Set("DbCatState", DbCatState);
ScriptGlobal::Set("DbCatAcknowledgement", DbCatAcknowledgement);
ScriptGlobal::Set("DbCatComment", DbCatComment);
ScriptGlobal::Set("DbCatDowntime", DbCatDowntime);
ScriptGlobal::Set("DbCatEventHandler", DbCatEventHandler);
ScriptGlobal::Set("DbCatExternalCommand", DbCatExternalCommand);
ScriptGlobal::Set("DbCatFlapping", DbCatFlapping);
ScriptGlobal::Set("DbCatCheck", DbCatCheck);
ScriptGlobal::Set("DbCatLog", DbCatLog);
ScriptGlobal::Set("DbCatNotification", DbCatNotification);
ScriptGlobal::Set("DbCatProgramStatus", DbCatProgramStatus);
ScriptGlobal::Set("DbCatRetention", DbCatRetention);
ScriptGlobal::Set("DbCatStateHistory", DbCatStateHistory);
ScriptGlobal::Set("Icinga.DbCatConfig", DbCatConfig, true);
ScriptGlobal::Set("Icinga.DbCatState", DbCatState, true);
ScriptGlobal::Set("Icinga.DbCatAcknowledgement", DbCatAcknowledgement, true);
ScriptGlobal::Set("Icinga.DbCatComment", DbCatComment, true);
ScriptGlobal::Set("Icinga.DbCatDowntime", DbCatDowntime, true);
ScriptGlobal::Set("Icinga.DbCatEventHandler", DbCatEventHandler, true);
ScriptGlobal::Set("Icinga.DbCatExternalCommand", DbCatExternalCommand, true);
ScriptGlobal::Set("Icinga.DbCatFlapping", DbCatFlapping, true);
ScriptGlobal::Set("Icinga.DbCatCheck", DbCatCheck, true);
ScriptGlobal::Set("Icinga.DbCatLog", DbCatLog, true);
ScriptGlobal::Set("Icinga.DbCatNotification", DbCatNotification, true);
ScriptGlobal::Set("Icinga.DbCatProgramStatus", DbCatProgramStatus, true);
ScriptGlobal::Set("Icinga.DbCatRetention", DbCatRetention, true);
ScriptGlobal::Set("Icinga.DbCatStateHistory", DbCatStateHistory, true);
ScriptGlobal::Set("DbCatEverything", DbCatEverything);
ScriptGlobal::Set("Icinga.DbCatEverything", DbCatEverything, true);
m_CategoryFilterMap["DbCatConfig"] = DbCatConfig;
m_CategoryFilterMap["DbCatState"] = DbCatState;

View File

@ -32,7 +32,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -26,13 +26,13 @@ using namespace icinga;
REGISTER_TYPE(CheckResult);
INITIALIZE_ONCE([]() {
ScriptGlobal::Set("ServiceOK", ServiceOK);
ScriptGlobal::Set("ServiceWarning", ServiceWarning);
ScriptGlobal::Set("ServiceCritical", ServiceCritical);
ScriptGlobal::Set("ServiceUnknown", ServiceUnknown);
ScriptGlobal::Set("Icinga.ServiceOK", ServiceOK, true);
ScriptGlobal::Set("Icinga.ServiceWarning", ServiceWarning, true);
ScriptGlobal::Set("Icinga.ServiceCritical", ServiceCritical, true);
ScriptGlobal::Set("Icinga.ServiceUnknown", ServiceUnknown, true);
ScriptGlobal::Set("HostUp", HostUp);
ScriptGlobal::Set("HostDown", HostDown);
ScriptGlobal::Set("Icinga.HostUp", HostUp, true);
ScriptGlobal::Set("Icinga.HostDown", HostDown, true);
})
double CheckResult::CalculateExecutionTime() const

View File

@ -268,13 +268,13 @@ std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats()
Dictionary::Ptr status = new Dictionary();
Array::Ptr perfdata = new Array();
Dictionary::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
if (statsFunctions) {
ObjectLock olock(statsFunctions);
for (const Dictionary::Pair& kv : statsFunctions)
static_cast<Function::Ptr>(kv.second)->Invoke({ status, perfdata });
for (const Namespace::Pair& kv : statsFunctions)
static_cast<Function::Ptr>(kv.second->Get())->Invoke({ status, perfdata });
}
return std::make_pair(status, perfdata);

View File

@ -18,10 +18,8 @@
******************************************************************************/
System.assert(Internal.run_with_activation_context(function() {
var _Internal = Internal.clone()
template TimePeriod "legacy-timeperiod" use (_Internal) default {
update = _Internal.LegacyTimePeriod
template TimePeriod "legacy-timeperiod" use (LegacyTimePeriod = Internal.LegacyTimePeriod) default {
update = LegacyTimePeriod
}
}))

View File

@ -41,7 +41,7 @@ using namespace icinga;
static Timer::Ptr l_RetentionTimer;
REGISTER_TYPE(IcingaApplication);
INITIALIZE_ONCE(&IcingaApplication::StaticInitialize);
INITIALIZE_ONCE_WITH_PRIORITY(&IcingaApplication::StaticInitialize, 50);
void IcingaApplication::StaticInitialize()
{
@ -59,9 +59,16 @@ void IcingaApplication::StaticInitialize()
ScriptGlobal::Set("NodeName", node_name);
ScriptGlobal::Set("ApplicationType", "IcingaApplication");
ScriptGlobal::Set("System.ApplicationType", "IcingaApplication", true);
ScriptGlobal::Set("ApplicationVersion", Application::GetAppVersion());
ScriptGlobal::Set("System.ApplicationVersion", Application::GetAppVersion(), true);
Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
auto icingaNSBehavior = new ConstNamespaceBehavior();
icingaNSBehavior->Freeze();
Namespace::Ptr icingaNS = new Namespace(icingaNSBehavior);
globalNS->SetAttribute("Icinga", std::make_shared<ConstEmbeddedNamespaceValue>(icingaNS));
}
REGISTER_STATSFUNCTION(IcingaApplication, &IcingaApplication::StatsFunc);
@ -156,13 +163,13 @@ static void PersistModAttrHelper(std::fstream& fp, ConfigObject::Ptr& previousOb
void IcingaApplication::DumpProgramState()
{
ConfigObject::DumpObjects(GetConst("StatePath"));
ConfigObject::DumpObjects(Configuration::StatePath);
DumpModifiedAttributes();
}
void IcingaApplication::DumpModifiedAttributes()
{
String path = GetConst("ModAttrPath");
String path = Configuration::ModAttrPath;
std::fstream fp;
String tempFilename = Utility::CreateTempFile(path + ".XXXXXX", 0644, fp);

View File

@ -28,7 +28,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, LegacyTimePeriod, &LegacyTimePeriod::ScriptFunc, "tp:begin:end");
REGISTER_FUNCTION_NONCONST(Internal, LegacyTimePeriod, &LegacyTimePeriod::ScriptFunc, "tp:begin:end");
bool LegacyTimePeriod::IsInTimeRange(tm *begin, tm *end, int stride, tm *reference)
{

View File

@ -79,22 +79,22 @@ Dictionary::Ptr NotificationNameComposer::ParseName(const String& name) const
void Notification::StaticInitialize()
{
ScriptGlobal::Set("OK", "OK");
ScriptGlobal::Set("Warning", "Warning");
ScriptGlobal::Set("Critical", "Critical");
ScriptGlobal::Set("Unknown", "Unknown");
ScriptGlobal::Set("Up", "Up");
ScriptGlobal::Set("Down", "Down");
ScriptGlobal::Set("Icinga.OK", "OK", true);
ScriptGlobal::Set("Icinga.Warning", "Warning", true);
ScriptGlobal::Set("Icinga.Critical", "Critical", true);
ScriptGlobal::Set("Icinga.Unknown", "Unknown", true);
ScriptGlobal::Set("Icinga.Up", "Up", true);
ScriptGlobal::Set("Icinga.Down", "Down", true);
ScriptGlobal::Set("DowntimeStart", "DowntimeStart");
ScriptGlobal::Set("DowntimeEnd", "DowntimeEnd");
ScriptGlobal::Set("DowntimeRemoved", "DowntimeRemoved");
ScriptGlobal::Set("Custom", "Custom");
ScriptGlobal::Set("Acknowledgement", "Acknowledgement");
ScriptGlobal::Set("Problem", "Problem");
ScriptGlobal::Set("Recovery", "Recovery");
ScriptGlobal::Set("FlappingStart", "FlappingStart");
ScriptGlobal::Set("FlappingEnd", "FlappingEnd");
ScriptGlobal::Set("Icinga.DowntimeStart", "DowntimeStart", true);
ScriptGlobal::Set("Icinga.DowntimeEnd", "DowntimeEnd", true);
ScriptGlobal::Set("Icinga.DowntimeRemoved", "DowntimeRemoved", true);
ScriptGlobal::Set("Icinga.Custom", "Custom", true);
ScriptGlobal::Set("Icinga.Acknowledgement", "Acknowledgement", true);
ScriptGlobal::Set("Icinga.Problem", "Problem", true);
ScriptGlobal::Set("Icinga.Recovery", "Recovery", true);
ScriptGlobal::Set("Icinga.FlappingStart", "FlappingStart", true);
ScriptGlobal::Set("Icinga.FlappingEnd", "FlappingEnd", true);
m_StateFilterMap["OK"] = StateFilterOK;
m_StateFilterMap["Warning"] = StateFilterWarning;

View File

@ -29,17 +29,17 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(System, get_host, &Host::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_service, &ObjectUtils::GetService, "host:name");
REGISTER_SCRIPTFUNCTION_NS(System, get_services, &ObjectUtils::GetServices, "host");
REGISTER_SCRIPTFUNCTION_NS(System, get_user, &User::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_check_command, &CheckCommand::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_event_command, &EventCommand::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_notification_command, &NotificationCommand::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_host_group, &HostGroup::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_service_group, &ServiceGroup::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_user_group, &UserGroup::GetByName, "name");
REGISTER_SCRIPTFUNCTION_NS(System, get_time_period, &TimePeriod::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_host, &Host::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_service, &ObjectUtils::GetService, "host:name");
REGISTER_FUNCTION(Icinga, get_services, &ObjectUtils::GetServices, "host");
REGISTER_FUNCTION(Icinga, get_user, &User::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_check_command, &CheckCommand::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_event_command, &EventCommand::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_notification_command, &NotificationCommand::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_host_group, &HostGroup::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_service_group, &ServiceGroup::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_user_group, &UserGroup::GetByName, "name");
REGISTER_FUNCTION(Icinga, get_time_period, &TimePeriod::GetByName, "name");
Service::Ptr ObjectUtils::GetService(const Value& host, const String& name)
{

View File

@ -32,7 +32,7 @@ class LivestatusListener : ConfigObject {
default {{{ return "unix"; }}}
};
[config] String socket_path {
default {{{ return Application::GetConst("InitRunDir") + "/cmd/livestatus"; }}}
default {{{ return Configuration::InitRunDir + "/cmd/livestatus"; }}}
};
[config] String bind_host {
default {{{ return "127.0.0.1"; }}}
@ -41,7 +41,7 @@ class LivestatusListener : ConfigObject {
default {{{ return "6558"; }}}
};
[config] String compat_log_path {
default {{{ return Application::GetConst("LogDir") + "/compat"; }}}
default {{{ return Configuration::LogDir + "/compat"; }}}
};
};

View File

@ -33,7 +33,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -29,7 +29,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -31,7 +31,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -29,7 +29,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -34,7 +34,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -18,68 +18,58 @@
******************************************************************************/
System.assert(Internal.run_with_activation_context(function() {
var _Internal = Internal.clone()
template CheckCommand "icinga-check-command" use (_Internal) {
execute = _Internal.IcingaCheck
template CheckCommand "icinga-check-command" use (IcingaCheck = Internal.IcingaCheck) {
execute = IcingaCheck
vars.icinga_min_version = ""
}
template CheckCommand "cluster-check-command" use (_Internal) {
execute = _Internal.ClusterCheck
template CheckCommand "cluster-check-command" use (ClusterCheck = Internal.ClusterCheck) {
execute = ClusterCheck
}
template CheckCommand "cluster-zone-check-command" use (_Internal) {
execute = _Internal.ClusterZoneCheck
template CheckCommand "cluster-zone-check-command" use (ClusterZoneCheck = Internal.ClusterZoneCheck) {
execute = ClusterZoneCheck
}
template CheckCommand "plugin-check-command" use (_Internal) default {
execute = _Internal.PluginCheck
template CheckCommand "plugin-check-command" use (PluginCheck = Internal.PluginCheck) default {
execute = PluginCheck
}
template CheckCommand "clr-check-command" use (_Internal) {
if (_Internal.ClrCheck) {
execute = _Internal.ClrCheck
} else {
execute = _Internal.NullCheck
}
template NotificationCommand "plugin-notification-command" use (PluginNotification = Internal.PluginNotification) default {
execute = PluginNotification
}
template NotificationCommand "plugin-notification-command" use (_Internal) default {
execute = _Internal.PluginNotification
template EventCommand "plugin-event-command" use (PluginEvent = Internal.PluginEvent) default {
execute = PluginEvent
}
template EventCommand "plugin-event-command" use (_Internal) default {
execute = _Internal.PluginEvent
template CheckCommand "dummy-check-command" use (DummyCheck = Internal.DummyCheck) {
execute = DummyCheck
}
template CheckCommand "dummy-check-command" use (_Internal) {
execute = _Internal.DummyCheck
template CheckCommand "random-check-command" use (RandomCheck = Internal.RandomCheck) {
execute = RandomCheck
}
template CheckCommand "random-check-command" use (_Internal) {
execute = _Internal.RandomCheck
template CheckCommand "exception-check-command" use (ExceptionCheck = Internal.ExceptionCheck) {
execute = ExceptionCheck
}
template CheckCommand "exception-check-command" use (_Internal) {
execute = _Internal.ExceptionCheck
template CheckCommand "null-check-command" use (NullCheck = Internal.NullCheck) {
execute = NullCheck
}
template CheckCommand "null-check-command" use (_Internal) {
execute = _Internal.NullCheck
template EventCommand "null-event-command" use (NullEvent = Internal.NullEvent) {
execute = NullEvent
}
template EventCommand "null-event-command" use (_Internal) {
execute = _Internal.NullEvent
template TimePeriod "empty-timeperiod" use (EmptyTimePeriod = Internal.EmptyTimePeriod) {
update = EmptyTimePeriod
}
template TimePeriod "empty-timeperiod" use (_Internal) {
update = _Internal.EmptyTimePeriod
}
template TimePeriod "even-minutes-timeperiod" use (_Internal) {
update = _Internal.EvenMinutesTimePeriod
template TimePeriod "even-minutes-timeperiod" use (EvenMinutesTimePeriod = Internal.EvenMinutesTimePeriod) {
update = EvenMinutesTimePeriod
}
}))

View File

@ -30,7 +30,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -23,7 +23,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, NullEvent, &NullEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, NullEvent, &NullEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
void NullEventTask::ScriptFunc(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{

View File

@ -31,7 +31,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -31,7 +31,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, PluginEvent, &PluginEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, PluginEvent, &PluginEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -32,7 +32,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, PluginNotification, &PluginNotificationTask::ScriptFunc, "notification:user:cr:itype:author:comment:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, PluginNotification, &PluginNotificationTask::ScriptFunc, "notification:user:cr:itype:author:comment:resolvedMacros:useResolvedMacros");
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
const User::Ptr& user, const CheckResult::Ptr& cr, int itype,

View File

@ -29,7 +29,7 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
REGISTER_FUNCTION_NONCONST(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)

View File

@ -22,8 +22,8 @@
using namespace icinga;
REGISTER_SCRIPTFUNCTION_NS(Internal, EmptyTimePeriod, &TimePeriodTask::EmptyTimePeriodUpdate, "tp:begin:end");
REGISTER_SCRIPTFUNCTION_NS(Internal, EvenMinutesTimePeriod, &TimePeriodTask::EvenMinutesTimePeriodUpdate, "tp:begin:end");
REGISTER_FUNCTION_NONCONST(Internal, EmptyTimePeriod, &TimePeriodTask::EmptyTimePeriodUpdate, "tp:begin:end");
REGISTER_FUNCTION_NONCONST(Internal, EvenMinutesTimePeriod, &TimePeriodTask::EvenMinutesTimePeriodUpdate, "tp:begin:end");
Array::Ptr TimePeriodTask::EmptyTimePeriodUpdate(const TimePeriod::Ptr& tp, double, double)
{

View File

@ -30,16 +30,16 @@ class PerfdataWriter : ConfigObject
activation_priority 100;
[config] String host_perfdata_path {
default {{{ return Application::GetConst("SpoolDir") + "/perfdata/host-perfdata"; }}}
default {{{ return Configuration::SpoolDir + "/perfdata/host-perfdata"; }}}
};
[config] String service_perfdata_path {
default {{{ return Application::GetConst("SpoolDir") + "/perfdata/service-perfdata"; }}}
default {{{ return Configuration::SpoolDir + "/perfdata/service-perfdata"; }}}
};
[config] String host_temp_path {
default {{{ return Application::GetConst("SpoolDir") + "/tmp/host-perfdata"; }}}
default {{{ return Configuration::SpoolDir + "/tmp/host-perfdata"; }}}
};
[config] String service_temp_path {
default {{{ return Application::GetConst("SpoolDir") + "/tmp/service-perfdata"; }}}
default {{{ return Configuration::SpoolDir + "/tmp/service-perfdata"; }}}
};
[config] String host_format_template {
default {{{

View File

@ -202,7 +202,7 @@ void ApiListener::SyncZoneDir(const Zone::Ptr& zone) const
if (sumUpdates == 0)
return;
String oldDir = Application::GetConst("DataDir") + "/api/zones/" + zone->GetName();
String oldDir = Configuration::DataDir + "/api/zones/" + zone->GetName();
Log(LogInformation, "ApiListener")
<< "Copying " << sumUpdates << " zone configuration files for zone '" << zone->GetName() << "' to '" << oldDir << "'.";
@ -240,7 +240,7 @@ void ApiListener::SendConfigUpdate(const JsonRpcConnection::Ptr& aclient)
Dictionary::Ptr configUpdateV1 = new Dictionary();
Dictionary::Ptr configUpdateV2 = new Dictionary();
String zonesDir = Application::GetConst("DataDir") + "/api/zones";
String zonesDir = Configuration::DataDir + "/api/zones";
for (const Zone::Ptr& zone : ConfigType::GetObjectsByType<Zone>()) {
String zoneDir = zonesDir + "/" + zone->GetName();
@ -315,7 +315,7 @@ Value ApiListener::ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const D
continue;
}
String oldDir = Application::GetConst("DataDir") + "/api/zones/" + zone->GetName();
String oldDir = Configuration::DataDir + "/api/zones/" + zone->GetName();
Utility::MkDirP(oldDir, 0700);

View File

@ -56,22 +56,22 @@ ApiListener::ApiListener()
String ApiListener::GetApiDir()
{
return Application::GetConst("DataDir") + "/api/";
return Configuration::DataDir + "/api/";
}
String ApiListener::GetCertsDir()
{
return Application::GetConst("DataDir") + "/certs/";
return Configuration::DataDir + "/certs/";
}
String ApiListener::GetCaDir()
{
return Application::GetConst("DataDir") + "/ca/";
return Configuration::DataDir + "/ca/";
}
String ApiListener::GetCertificateRequestsDir()
{
return Application::GetConst("DataDir") + "/certificate-requests/";
return Configuration::DataDir + "/certificate-requests/";
}
String ApiListener::GetDefaultCertPath()
@ -1479,7 +1479,7 @@ String ApiListener::GetFromZoneName(const Zone::Ptr& fromZone)
void ApiListener::UpdateStatusFile(TcpSocket::Ptr socket)
{
String path = Application::GetConst("CacheDir") + "/api-state.json";
String path = Configuration::CacheDir + "/api-state.json";
std::pair<String, String> details = socket->GetClientAddressDetails();
Utility::SaveJsonFile(path, 0644, new Dictionary({
@ -1490,7 +1490,7 @@ void ApiListener::UpdateStatusFile(TcpSocket::Ptr socket)
void ApiListener::RemoveStatusFile()
{
String path = Application::GetConst("CacheDir") + "/api-state.json";
String path = Configuration::CacheDir + "/api-state.json";
if (Utility::PathExists(path)) {
if (unlink(path.CStr()) < 0 && errno != ENOENT) {

View File

@ -42,10 +42,10 @@ class ApiListener : ConfigObject
};
[config] String bind_host {
default {{{ return Application::GetConst("ApiBindHost"); }}}
default {{{ return Configuration::ApiBindHost; }}}
};
[config] String bind_port {
default {{{ return Application::GetConst("ApiBindPort", "5665"); }}}
default {{{ return Configuration::ApiBindPort; }}}
};
[config] bool accept_config;

View File

@ -30,7 +30,7 @@ using namespace icinga;
String ConfigPackageUtility::GetPackageDir()
{
return Application::GetConst("DataDir") + "/api/packages";
return Configuration::DataDir + "/api/packages";
}
void ConfigPackageUtility::CreatePackage(const String& name)

View File

@ -27,6 +27,7 @@
#include "base/logger.hpp"
#include "base/serializer.hpp"
#include "base/timer.hpp"
#include "base/namespace.hpp"
#include "base/initialize.hpp"
#include <boost/thread/once.hpp>
#include <set>
@ -233,6 +234,15 @@ static void AddSuggestions(std::vector<String>& matches, const String& word, con
}
}
if (value.IsObjectType<Namespace>()) {
Namespace::Ptr ns = value;
ObjectLock olock(ns);
for (const Namespace::Pair& kv : ns) {
AddSuggestion(matches, word, prefix + kv.first);
}
}
if (withFields) {
Type::Ptr type = value.GetReflectionType();
@ -275,18 +285,17 @@ std::vector<String> ConsoleHandler::GetAutocompletionSuggestions(const String& w
{
ObjectLock olock(ScriptGlobal::GetGlobals());
for (const Dictionary::Pair& kv : ScriptGlobal::GetGlobals()) {
for (const Namespace::Pair& kv : ScriptGlobal::GetGlobals()) {
AddSuggestion(matches, word, kv.first);
}
}
{
Array::Ptr imports = ScriptFrame::GetImports();
ObjectLock olock(imports);
for (const Value& import : imports) {
AddSuggestions(matches, word, "", false, import);
}
}
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
AddSuggestions(matches, word, "", false, systemNS);
AddSuggestions(matches, word, "", true, systemNS->Get("Configuration"));
AddSuggestions(matches, word, "", false, ScriptGlobal::Get("Types"));
AddSuggestions(matches, word, "", false, ScriptGlobal::Get("Icinga"));
String::SizeType cperiod = word.RFind(".");

View File

@ -37,7 +37,7 @@ static bool GetDebugJsonRpcCached()
debugJsonRpc = false;
Dictionary::Ptr internal = ScriptGlobal::Get("Internal", &Empty);
Namespace::Ptr internal = ScriptGlobal::Get("Internal", &Empty);
if (!internal)
return false;

View File

@ -59,7 +59,7 @@ void JsonRpcConnection::StaticInitialize()
l_JsonRpcConnectionTimeoutTimer->SetInterval(15);
l_JsonRpcConnectionTimeoutTimer->Start();
l_JsonRpcConnectionWorkQueueCount = Application::GetConcurrency();
l_JsonRpcConnectionWorkQueueCount = Configuration::Concurrency;
l_JsonRpcConnectionWorkQueues = new WorkQueue[l_JsonRpcConnectionWorkQueueCount];
for (size_t i = 0; i < l_JsonRpcConnectionWorkQueueCount; i++) {

View File

@ -22,6 +22,7 @@
#include "remote/filterutility.hpp"
#include "base/serializer.hpp"
#include "base/statsfunction.hpp"
#include "base/namespace.hpp"
using namespace icinga;
@ -35,24 +36,29 @@ public:
void FindTargets(const String& type,
const std::function<void (const Value&)>& addTarget) const override
{
Dictionary::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
if (statsFunctions) {
ObjectLock olock(statsFunctions);
for (const Dictionary::Pair& kv : statsFunctions)
for (const Namespace::Pair& kv : statsFunctions)
addTarget(GetTargetByName("Status", kv.first));
}
}
Value GetTargetByName(const String& type, const String& name) const override
{
Dictionary::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
if (!statsFunctions)
BOOST_THROW_EXCEPTION(std::invalid_argument("No status functions are available."));
Function::Ptr func = statsFunctions->Get(name);
Value vfunc;
if (!statsFunctions->Get(name, &vfunc))
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid status function name."));
Function::Ptr func = vfunc;
if (!func)
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid status function name."));

Some files were not shown because too many files have changed in this diff Show More