mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 21:24:41 +02:00
Implement support for namespaces
This commit is contained in:
parent
9d513d8f05
commit
1a8692d972
@ -203,6 +203,38 @@ to dereference a reference:
|
|||||||
*p = "Hi!"
|
*p = "Hi!"
|
||||||
log(value) // Prints "Hi!" because the variable was changed
|
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
|
||||||
|
* Types
|
||||||
|
* Icinga
|
||||||
|
|
||||||
### Function Calls <a id="function-calls"></a>
|
### Function Calls <a id="function-calls"></a>
|
||||||
|
|
||||||
Functions can be called using the `()` operator:
|
Functions can be called using the `()` operator:
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config/configcompilercontext.hpp"
|
#include "config/configcompilercontext.hpp"
|
||||||
#include "config/configcompiler.hpp"
|
#include "config/configcompiler.hpp"
|
||||||
#include "config/configitembuilder.hpp"
|
#include "config/configitembuilder.hpp"
|
||||||
|
#include "config/expression.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/timer.hpp"
|
#include "base/timer.hpp"
|
||||||
@ -440,7 +441,24 @@ static int Main()
|
|||||||
key = define;
|
key = define;
|
||||||
value = "1";
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
if (!globals.irc) {
|
if (!globals.contains("irc")) {
|
||||||
globals.irc = globals.log
|
globals.irc = log
|
||||||
}
|
}
|
||||||
|
|
||||||
hm = {
|
hm = {
|
||||||
|
@ -54,6 +54,7 @@ set(base_SOURCES
|
|||||||
math-script.cpp
|
math-script.cpp
|
||||||
netstring.cpp netstring.hpp
|
netstring.cpp netstring.hpp
|
||||||
networkstream.cpp networkstream.hpp
|
networkstream.cpp networkstream.hpp
|
||||||
|
namespace.cpp namespace.hpp namespace-script.cpp
|
||||||
number.cpp number.hpp number-script.cpp
|
number.cpp number.hpp number-script.cpp
|
||||||
object.cpp object.hpp object-script.cpp
|
object.cpp object.hpp object-script.cpp
|
||||||
objectlock.cpp objectlock.hpp
|
objectlock.cpp objectlock.hpp
|
||||||
|
@ -75,13 +75,29 @@ private:
|
|||||||
#define REGISTER_FUNCTION(ns, name, callback, args) \
|
#define REGISTER_FUNCTION(ns, name, callback, args) \
|
||||||
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
|
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
|
||||||
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), false); \
|
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)
|
}, 10)
|
||||||
|
|
||||||
#define REGISTER_SAFE_FUNCTION(ns, name, callback, args) \
|
#define REGISTER_SAFE_FUNCTION(ns, name, callback, args) \
|
||||||
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
|
INITIALIZE_ONCE_WITH_PRIORITY([]() { \
|
||||||
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
|
Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), true); \
|
||||||
ScriptGlobal::Set(#ns "." #name, sf); \
|
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); \
|
||||||
|
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
|
||||||
|
nsp->SetAttribute(#name, std::make_shared<EmbeddedNamespaceValue>(sf)); \
|
||||||
|
}, 10)
|
||||||
|
|
||||||
|
#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); \
|
||||||
|
Namespace::Ptr nsp = ScriptGlobal::Get(#ns); \
|
||||||
|
nsp->SetAttribute(#name, std::make_shared<EmbeddedNamespaceValue>(sf)); \
|
||||||
}, 10)
|
}, 10)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,15 @@ static String JsonEncodeShim(const Value& value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
INITIALIZE_ONCE([]() {
|
INITIALIZE_ONCE([]() {
|
||||||
Dictionary::Ptr jsonObj = new Dictionary({
|
auto jsonNSBehavior = new ConstNamespaceBehavior();
|
||||||
/* Methods */
|
Namespace::Ptr jsonNS = new Namespace(jsonNSBehavior);
|
||||||
{ "encode", new Function("Json#encode", JsonEncodeShim, { "value" }, true) },
|
|
||||||
{ "decode", new Function("Json#decode", JsonDecode, { "value" }, true) }
|
|
||||||
});
|
|
||||||
|
|
||||||
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));
|
||||||
});
|
});
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/debug.hpp"
|
#include "base/debug.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include "base/dictionary.hpp"
|
#include "base/dictionary.hpp"
|
||||||
#include "base/array.hpp"
|
#include "base/array.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
@ -39,6 +40,19 @@ typedef unsigned int yajl_size;
|
|||||||
typedef size_t yajl_size;
|
typedef size_t yajl_size;
|
||||||
#endif /* YAJL_MAJOR */
|
#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)
|
static void EncodeDictionary(yajl_gen handle, const Dictionary::Ptr& dict)
|
||||||
{
|
{
|
||||||
yajl_gen_map_open(handle);
|
yajl_gen_map_open(handle);
|
||||||
@ -83,6 +97,13 @@ static void Encode(yajl_gen handle, const Value& value)
|
|||||||
case ValueObject:
|
case ValueObject:
|
||||||
{
|
{
|
||||||
const Object::Ptr& obj = value.Get<Object::Ptr>();
|
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);
|
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(obj);
|
||||||
|
|
||||||
if (dict) {
|
if (dict) {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "base/functionwrapper.hpp"
|
#include "base/functionwrapper.hpp"
|
||||||
#include "base/scriptframe.hpp"
|
#include "base/scriptframe.hpp"
|
||||||
#include "base/initialize.hpp"
|
#include "base/initialize.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include <boost/math/special_functions/round.hpp>
|
#include <boost/math/special_functions/round.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@ -158,40 +159,44 @@ static double MathSign(double x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
INITIALIZE_ONCE([]() {
|
INITIALIZE_ONCE([]() {
|
||||||
Dictionary::Ptr mathObj = new Dictionary({
|
auto mathNSBehavior = new ConstNamespaceBehavior();
|
||||||
|
Namespace::Ptr mathNS = new Namespace(mathNSBehavior);
|
||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
{ "E", 2.71828182845904523536 },
|
mathNS->Set("E", 2.71828182845904523536);
|
||||||
{ "LN2", 0.693147180559945309417 },
|
mathNS->Set("LN2", 0.693147180559945309417);
|
||||||
{ "LN10", 2.30258509299404568402 },
|
mathNS->Set("LN10", 2.30258509299404568402);
|
||||||
{ "LOG2E", 1.44269504088896340736 },
|
mathNS->Set("LOG2E", 1.44269504088896340736);
|
||||||
{ "LOG10E", 0.434294481903251827651 },
|
mathNS->Set("LOG10E", 0.434294481903251827651);
|
||||||
{ "PI", 3.14159265358979323846 },
|
mathNS->Set("PI", 3.14159265358979323846);
|
||||||
{ "SQRT1_2", 0.707106781186547524401 },
|
mathNS->Set("SQRT1_2", 0.707106781186547524401);
|
||||||
{ "SQRT2", 1.41421356237309504880 },
|
mathNS->Set("SQRT2", 1.41421356237309504880);
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
{ "abs", new Function("Math#abs", MathAbs, { "x" }, true) },
|
mathNS->Set("abs", new Function("Math#abs", MathAbs, { "x" }, true));
|
||||||
{ "acos", new Function("Math#acos", MathAcos, { "x" }, true) },
|
mathNS->Set("acos", new Function("Math#acos", MathAcos, { "x" }, true));
|
||||||
{ "asin", new Function("Math#asin", MathAsin, { "x" }, true) },
|
mathNS->Set("asin", new Function("Math#asin", MathAsin, { "x" }, true));
|
||||||
{ "atan", new Function("Math#atan", MathAtan, { "x" }, true) },
|
mathNS->Set("atan", new Function("Math#atan", MathAtan, { "x" }, true));
|
||||||
{ "atan2", new Function("Math#atan2", MathAtan2, { "x", "y" }, true) },
|
mathNS->Set("atan2", new Function("Math#atan2", MathAtan2, { "x", "y" }, true));
|
||||||
{ "ceil", new Function("Math#ceil", MathCeil, { "x" }, true) },
|
mathNS->Set("ceil", new Function("Math#ceil", MathCeil, { "x" }, true));
|
||||||
{ "cos", new Function("Math#cos", MathCos, { "x" }, true) },
|
mathNS->Set("cos", new Function("Math#cos", MathCos, { "x" }, true));
|
||||||
{ "exp", new Function("Math#exp", MathExp, { "x" }, true) },
|
mathNS->Set("exp", new Function("Math#exp", MathExp, { "x" }, true));
|
||||||
{ "floor", new Function("Math#floor", MathFloor, { "x" }, true) },
|
mathNS->Set("floor", new Function("Math#floor", MathFloor, { "x" }, true));
|
||||||
{ "log", new Function("Math#log", MathLog, { "x" }, true) },
|
mathNS->Set("log", new Function("Math#log", MathLog, { "x" }, true));
|
||||||
{ "max", new Function("Math#max", MathMax, {}, true) },
|
mathNS->Set("max", new Function("Math#max", MathMax, {}, true));
|
||||||
{ "min", new Function("Math#min", MathMin, {}, true) },
|
mathNS->Set("min", new Function("Math#min", MathMin, {}, true));
|
||||||
{ "pow", new Function("Math#pow", MathPow, { "x", "y" }, true) },
|
mathNS->Set("pow", new Function("Math#pow", MathPow, { "x", "y" }, true));
|
||||||
{ "random", new Function("Math#random", MathRandom, {}, true) },
|
mathNS->Set("random", new Function("Math#random", MathRandom, {}, true));
|
||||||
{ "round", new Function("Math#round", MathRound, { "x" }, true) },
|
mathNS->Set("round", new Function("Math#round", MathRound, { "x" }, true));
|
||||||
{ "sin", new Function("Math#sin", MathSin, { "x" }, true) },
|
mathNS->Set("sin", new Function("Math#sin", MathSin, { "x" }, true));
|
||||||
{ "sqrt", new Function("Math#sqrt", MathSqrt, { "x" }, true) },
|
mathNS->Set("sqrt", new Function("Math#sqrt", MathSqrt, { "x" }, true));
|
||||||
{ "tan", new Function("Math#tan", MathTan, { "x" }, true) },
|
mathNS->Set("tan", new Function("Math#tan", MathTan, { "x" }, true));
|
||||||
{ "isnan", new Function("Math#isnan", MathIsnan, { "x" }, true) },
|
mathNS->Set("isnan", new Function("Math#isnan", MathIsnan, { "x" }, true));
|
||||||
{ "isinf", new Function("Math#isinf", MathIsinf, { "x" }, true) },
|
mathNS->Set("isinf", new Function("Math#isinf", MathIsinf, { "x" }, true));
|
||||||
{ "sign", new Function("Math#sign", MathSign, { "x" }, true) }
|
mathNS->Set("sign", new Function("Math#sign", MathSign, { "x" }, true));
|
||||||
});
|
|
||||||
|
|
||||||
ScriptGlobal::Set("Math", mathObj);
|
mathNSBehavior->Freeze();
|
||||||
|
|
||||||
|
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
|
||||||
|
systemNS->SetAttribute("Math", std::make_shared<ConstEmbeddedNamespaceValue>(mathNS));
|
||||||
});
|
});
|
||||||
|
101
lib/base/namespace-script.cpp
Normal file
101
lib/base/namespace-script.cpp
Normal 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
223
lib/base/namespace.cpp
Normal 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
123
lib/base/namespace.hpp
Normal 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 */
|
@ -26,11 +26,12 @@
|
|||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
using namespace icinga;
|
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)
|
Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
|
||||||
{
|
{
|
||||||
@ -46,7 +47,7 @@ Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
|
|||||||
return result;
|
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(".");
|
std::vector<String> tokens = name.Split(".");
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ void ScriptGlobal::Set(const String& name, const Value& value)
|
|||||||
{
|
{
|
||||||
ObjectLock olock(m_Globals);
|
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++) {
|
for (std::vector<String>::size_type i = 0; i < tokens.size(); i++) {
|
||||||
const String& token = tokens[i];
|
const String& token = tokens[i];
|
||||||
@ -65,7 +66,7 @@ void ScriptGlobal::Set(const String& name, const Value& value)
|
|||||||
Value vparent;
|
Value vparent;
|
||||||
|
|
||||||
if (!parent->Get(token, &vparent)) {
|
if (!parent->Get(token, &vparent)) {
|
||||||
Dictionary::Ptr dict = new Dictionary();
|
Namespace::Ptr dict = new Namespace();
|
||||||
parent->Set(token, dict);
|
parent->Set(token, dict);
|
||||||
parent = dict;
|
parent = dict;
|
||||||
} else {
|
} 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)
|
bool ScriptGlobal::Exists(const String& name)
|
||||||
{
|
{
|
||||||
return m_Globals->Contains(name);
|
return m_Globals->Contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr ScriptGlobal::GetGlobals()
|
Namespace::Ptr ScriptGlobal::GetGlobals()
|
||||||
{
|
{
|
||||||
return m_Globals;
|
return m_Globals;
|
||||||
}
|
}
|
||||||
@ -102,8 +108,8 @@ void ScriptGlobal::WriteToFile(const String& filename)
|
|||||||
StdioStream::Ptr sfp = new StdioStream(&fp, false);
|
StdioStream::Ptr sfp = new StdioStream(&fp, false);
|
||||||
|
|
||||||
ObjectLock olock(m_Globals);
|
ObjectLock olock(m_Globals);
|
||||||
for (const Dictionary::Pair& kv : m_Globals) {
|
for (const Namespace::Pair& kv : m_Globals) {
|
||||||
Value value = kv.second;
|
Value value = kv.second->Get();
|
||||||
|
|
||||||
if (value.IsObject())
|
if (value.IsObject())
|
||||||
value = Convert::ToString(value);
|
value = Convert::ToString(value);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#define SCRIPTGLOBAL_H
|
#define SCRIPTGLOBAL_H
|
||||||
|
|
||||||
#include "base/i2-base.hpp"
|
#include "base/i2-base.hpp"
|
||||||
#include "base/dictionary.hpp"
|
#include "base/namespace.hpp"
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
@ -35,15 +35,16 @@ class ScriptGlobal
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Value Get(const String& name, const Value *defaultValue = nullptr);
|
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 bool Exists(const String& name);
|
||||||
|
|
||||||
static void WriteToFile(const String& filename);
|
static void WriteToFile(const String& filename);
|
||||||
|
|
||||||
static Dictionary::Ptr GetGlobals();
|
static Namespace::Ptr GetGlobals();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Dictionary::Ptr m_Globals;
|
static Namespace::Ptr m_Globals;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,11 @@ enum MatchType
|
|||||||
|
|
||||||
void ScriptUtils::StaticInitialize()
|
void ScriptUtils::StaticInitialize()
|
||||||
{
|
{
|
||||||
ScriptGlobal::Set("MatchAll", MatchAll);
|
ScriptGlobal::Set("MatchAll", MatchAll, true);
|
||||||
ScriptGlobal::Set("MatchAny", MatchAny);
|
ScriptGlobal::Set("MatchAny", MatchAny, true);
|
||||||
|
|
||||||
ScriptGlobal::Set("GlobFile", GlobFile);
|
ScriptGlobal::Set("GlobFile", GlobFile, true);
|
||||||
ScriptGlobal::Set("GlobDirectory", GlobDirectory);
|
ScriptGlobal::Set("GlobDirectory", GlobDirectory, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
String ScriptUtils::CastString(const Value& value)
|
String ScriptUtils::CastString(const Value& value)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
@ -119,6 +120,22 @@ static Dictionary::Ptr SerializeDictionary(const Dictionary::Ptr& input, int att
|
|||||||
return new Dictionary(std::move(result));
|
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)
|
static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes, SerializeStack& stack)
|
||||||
{
|
{
|
||||||
Type::Ptr type = input->GetReflectionType();
|
Type::Ptr type = input->GetReflectionType();
|
||||||
@ -243,6 +260,11 @@ static Value SerializeInternal(const Value& value, int attributeTypes, Serialize
|
|||||||
if (dict)
|
if (dict)
|
||||||
return SerializeDictionary(dict, attributeTypes, stack);
|
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);
|
return SerializeObject(input, attributeTypes, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "base/type.hpp"
|
#include "base/type.hpp"
|
||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -39,19 +40,19 @@ String Type::ToString() const
|
|||||||
|
|
||||||
void Type::Register(const Type::Ptr& type)
|
void Type::Register(const Type::Ptr& type)
|
||||||
{
|
{
|
||||||
VERIFY(!GetByName(type->GetName()));
|
ScriptGlobal::Set("Types." + type->GetName(), type, true);
|
||||||
|
|
||||||
ScriptGlobal::Set("Types." + type->GetName(), type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Ptr Type::GetByName(const String& name)
|
Type::Ptr Type::GetByName(const String& name)
|
||||||
{
|
{
|
||||||
Dictionary::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
|
Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
|
||||||
|
|
||||||
if (!typesNS)
|
if (!typesNS)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Value ptype = typesNS->Get(name);
|
Value ptype;
|
||||||
|
if (!typesNS->Get(name, &ptype))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (!ptype.IsObjectType<Type>())
|
if (!ptype.IsObjectType<Type>())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -63,14 +64,16 @@ std::vector<Type::Ptr> Type::GetAllTypes()
|
|||||||
{
|
{
|
||||||
std::vector<Type::Ptr> types;
|
std::vector<Type::Ptr> types;
|
||||||
|
|
||||||
Dictionary::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
|
Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
|
||||||
|
|
||||||
if (typesNS) {
|
if (typesNS) {
|
||||||
ObjectLock olock(typesNS);
|
ObjectLock olock(typesNS);
|
||||||
|
|
||||||
for (const Dictionary::Pair& kv : typesNS) {
|
for (const Namespace::Pair& kv : typesNS) {
|
||||||
if (kv.second.IsObjectType<Type>())
|
Value value = kv.second->Get();
|
||||||
types.push_back(kv.second);
|
|
||||||
|
if (value.IsObjectType<Type>())
|
||||||
|
types.push_back(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +648,7 @@ lterm: T_LIBRARY rterm
|
|||||||
}
|
}
|
||||||
| T_CONST T_IDENTIFIER T_SET 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;
|
delete $2;
|
||||||
}
|
}
|
||||||
| T_VAR rterm
|
| T_VAR rterm
|
||||||
|
@ -31,6 +31,7 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
|
|||||||
|
|
||||||
void ConfigItemBuilder::SetType(const Type::Ptr& type)
|
void ConfigItemBuilder::SetType(const Type::Ptr& type)
|
||||||
{
|
{
|
||||||
|
ASSERT(type);
|
||||||
m_Type = type;
|
m_Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
#include "base/loader.hpp"
|
#include "base/loader.hpp"
|
||||||
#include "base/reference.hpp"
|
#include "base/reference.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include <boost/exception_ptr.hpp>
|
#include <boost/exception_ptr.hpp>
|
||||||
#include <boost/exception/errinfo_nested_exception.hpp>
|
#include <boost/exception/errinfo_nested_exception.hpp>
|
||||||
|
|
||||||
@ -625,6 +626,28 @@ void SetExpression::SetOverrideFrozen()
|
|||||||
m_OverrideFrozen = true;
|
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 ConditionalExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||||
{
|
{
|
||||||
ExpressionResult condition = m_Condition->Evaluate(frame, dhint);
|
ExpressionResult condition = m_Condition->Evaluate(frame, dhint);
|
||||||
@ -701,7 +724,16 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *
|
|||||||
|
|
||||||
if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
|
if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
|
||||||
if (init_dict) {
|
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())
|
if (old_value.IsEmpty() && !old_value.IsString())
|
||||||
VMOps::SetField(vparent, vindex, new Dictionary(), m_OverrideFrozen, m_Operand1->GetDebugInfo());
|
VMOps::SetField(vparent, vindex, new Dictionary(), m_OverrideFrozen, m_Operand1->GetDebugInfo());
|
||||||
|
@ -637,6 +637,19 @@ private:
|
|||||||
friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
|
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
|
class SetExpression final : public BinaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "base/debuginfo.hpp"
|
#include "base/debuginfo.hpp"
|
||||||
#include "base/array.hpp"
|
#include "base/array.hpp"
|
||||||
#include "base/dictionary.hpp"
|
#include "base/dictionary.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include "base/function.hpp"
|
#include "base/function.hpp"
|
||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
@ -225,6 +226,26 @@ public:
|
|||||||
ExpressionResult res = expression->Evaluate(frame);
|
ExpressionResult res = expression->Evaluate(frame);
|
||||||
CHECK_RESULT_LOOP(res);
|
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
|
} else
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Invalid type in for expression: " + value.GetTypeName(), debugInfo));
|
BOOST_THROW_EXCEPTION(ScriptError("Invalid type in for expression: " + value.GetTypeName(), debugInfo));
|
||||||
|
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
System.assert(Internal.run_with_activation_context(function() {
|
System.assert(Internal.run_with_activation_context(function() {
|
||||||
var _Internal = Internal.clone()
|
template CheckCommand "ido-check-command" use (checkFunc = Internal.IdoCheck) {
|
||||||
|
execute = checkFunc
|
||||||
template CheckCommand "ido-check-command" use (_Internal) {
|
|
||||||
execute = _Internal.IdoCheck
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object CheckCommand "ido" {
|
object CheckCommand "ido" {
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -268,13 +268,13 @@ std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats()
|
|||||||
Dictionary::Ptr status = new Dictionary();
|
Dictionary::Ptr status = new Dictionary();
|
||||||
Array::Ptr perfdata = new Array();
|
Array::Ptr perfdata = new Array();
|
||||||
|
|
||||||
Dictionary::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
|
Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
|
||||||
|
|
||||||
if (statsFunctions) {
|
if (statsFunctions) {
|
||||||
ObjectLock olock(statsFunctions);
|
ObjectLock olock(statsFunctions);
|
||||||
|
|
||||||
for (const Dictionary::Pair& kv : statsFunctions)
|
for (const Namespace::Pair& kv : statsFunctions)
|
||||||
static_cast<Function::Ptr>(kv.second)->Invoke({ status, perfdata });
|
static_cast<Function::Ptr>(kv.second->Get())->Invoke({ status, perfdata });
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair(status, perfdata);
|
return std::make_pair(status, perfdata);
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
System.assert(Internal.run_with_activation_context(function() {
|
System.assert(Internal.run_with_activation_context(function() {
|
||||||
var _Internal = Internal.clone()
|
template TimePeriod "legacy-timeperiod" use (LegacyTimePeriod = Internal.LegacyTimePeriod) default {
|
||||||
|
update = LegacyTimePeriod
|
||||||
template TimePeriod "legacy-timeperiod" use (_Internal) default {
|
|
||||||
update = _Internal.LegacyTimePeriod
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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)
|
bool LegacyTimePeriod::IsInTimeRange(tm *begin, tm *end, int stride, tm *reference)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -18,68 +18,58 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
System.assert(Internal.run_with_activation_context(function() {
|
System.assert(Internal.run_with_activation_context(function() {
|
||||||
var _Internal = Internal.clone()
|
template CheckCommand "icinga-check-command" use (IcingaCheck = Internal.IcingaCheck) {
|
||||||
|
execute = IcingaCheck
|
||||||
template CheckCommand "icinga-check-command" use (_Internal) {
|
|
||||||
execute = _Internal.IcingaCheck
|
|
||||||
|
|
||||||
vars.icinga_min_version = ""
|
vars.icinga_min_version = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "cluster-check-command" use (_Internal) {
|
template CheckCommand "cluster-check-command" use (ClusterCheck = Internal.ClusterCheck) {
|
||||||
execute = _Internal.ClusterCheck
|
execute = ClusterCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "cluster-zone-check-command" use (_Internal) {
|
template CheckCommand "cluster-zone-check-command" use (ClusterZoneCheck = Internal.ClusterZoneCheck) {
|
||||||
execute = _Internal.ClusterZoneCheck
|
execute = ClusterZoneCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "plugin-check-command" use (_Internal) default {
|
template CheckCommand "plugin-check-command" use (PluginCheck = Internal.PluginCheck) default {
|
||||||
execute = _Internal.PluginCheck
|
execute = PluginCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "clr-check-command" use (_Internal) {
|
template NotificationCommand "plugin-notification-command" use (PluginNotification = Internal.PluginNotification) default {
|
||||||
if (_Internal.ClrCheck) {
|
execute = PluginNotification
|
||||||
execute = _Internal.ClrCheck
|
|
||||||
} else {
|
|
||||||
execute = _Internal.NullCheck
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template NotificationCommand "plugin-notification-command" use (_Internal) default {
|
template EventCommand "plugin-event-command" use (PluginEvent = Internal.PluginEvent) default {
|
||||||
execute = _Internal.PluginNotification
|
execute = PluginEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
template EventCommand "plugin-event-command" use (_Internal) default {
|
template CheckCommand "dummy-check-command" use (DummyCheck = Internal.DummyCheck) {
|
||||||
execute = _Internal.PluginEvent
|
execute = DummyCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "dummy-check-command" use (_Internal) {
|
template CheckCommand "random-check-command" use (RandomCheck = Internal.RandomCheck) {
|
||||||
execute = _Internal.DummyCheck
|
execute = RandomCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "random-check-command" use (_Internal) {
|
template CheckCommand "exception-check-command" use (ExceptionCheck = Internal.ExceptionCheck) {
|
||||||
execute = _Internal.RandomCheck
|
execute = ExceptionCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "exception-check-command" use (_Internal) {
|
template CheckCommand "null-check-command" use (NullCheck = Internal.NullCheck) {
|
||||||
execute = _Internal.ExceptionCheck
|
execute = NullCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
template CheckCommand "null-check-command" use (_Internal) {
|
template EventCommand "null-event-command" use (NullEvent = Internal.NullEvent) {
|
||||||
execute = _Internal.NullCheck
|
execute = NullEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
template EventCommand "null-event-command" use (_Internal) {
|
template TimePeriod "empty-timeperiod" use (EmptyTimePeriod = Internal.EmptyTimePeriod) {
|
||||||
execute = _Internal.NullEvent
|
update = EmptyTimePeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
template TimePeriod "empty-timeperiod" use (_Internal) {
|
template TimePeriod "even-minutes-timeperiod" use (EvenMinutesTimePeriod = Internal.EvenMinutesTimePeriod) {
|
||||||
update = _Internal.EmptyTimePeriod
|
update = EvenMinutesTimePeriod
|
||||||
}
|
|
||||||
|
|
||||||
template TimePeriod "even-minutes-timeperiod" use (_Internal) {
|
|
||||||
update = _Internal.EvenMinutesTimePeriod
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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)
|
void NullEventTask::ScriptFunc(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(Internal, PluginEvent, &PluginEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
|
REGISTER_FUNCTION_NONCONST(Internal, PluginEvent, &PluginEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros");
|
||||||
|
|
||||||
void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable,
|
void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
|
||||||
const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
|
const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(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,
|
void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
|
||||||
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_FUNCTION(Internal, EmptyTimePeriod, &TimePeriodTask::EmptyTimePeriodUpdate, "tp:begin:end");
|
REGISTER_FUNCTION_NONCONST(Internal, EmptyTimePeriod, &TimePeriodTask::EmptyTimePeriodUpdate, "tp:begin:end");
|
||||||
REGISTER_FUNCTION(Internal, EvenMinutesTimePeriod, &TimePeriodTask::EvenMinutesTimePeriodUpdate, "tp:begin:end");
|
REGISTER_FUNCTION_NONCONST(Internal, EvenMinutesTimePeriod, &TimePeriodTask::EvenMinutesTimePeriodUpdate, "tp:begin:end");
|
||||||
|
|
||||||
Array::Ptr TimePeriodTask::EmptyTimePeriodUpdate(const TimePeriod::Ptr& tp, double, double)
|
Array::Ptr TimePeriodTask::EmptyTimePeriodUpdate(const TimePeriod::Ptr& tp, double, double)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/serializer.hpp"
|
#include "base/serializer.hpp"
|
||||||
#include "base/timer.hpp"
|
#include "base/timer.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include "base/initialize.hpp"
|
#include "base/initialize.hpp"
|
||||||
#include <boost/thread/once.hpp>
|
#include <boost/thread/once.hpp>
|
||||||
#include <set>
|
#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) {
|
if (withFields) {
|
||||||
Type::Ptr type = value.GetReflectionType();
|
Type::Ptr type = value.GetReflectionType();
|
||||||
|
|
||||||
@ -275,7 +285,7 @@ std::vector<String> ConsoleHandler::GetAutocompletionSuggestions(const String& w
|
|||||||
|
|
||||||
{
|
{
|
||||||
ObjectLock olock(ScriptGlobal::GetGlobals());
|
ObjectLock olock(ScriptGlobal::GetGlobals());
|
||||||
for (const Dictionary::Pair& kv : ScriptGlobal::GetGlobals()) {
|
for (const Namespace::Pair& kv : ScriptGlobal::GetGlobals()) {
|
||||||
AddSuggestion(matches, word, kv.first);
|
AddSuggestion(matches, word, kv.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ static bool GetDebugJsonRpcCached()
|
|||||||
|
|
||||||
debugJsonRpc = false;
|
debugJsonRpc = false;
|
||||||
|
|
||||||
Dictionary::Ptr internal = ScriptGlobal::Get("Internal", &Empty);
|
Namespace::Ptr internal = ScriptGlobal::Get("Internal", &Empty);
|
||||||
|
|
||||||
if (!internal)
|
if (!internal)
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "remote/filterutility.hpp"
|
#include "remote/filterutility.hpp"
|
||||||
#include "base/serializer.hpp"
|
#include "base/serializer.hpp"
|
||||||
#include "base/statsfunction.hpp"
|
#include "base/statsfunction.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
@ -35,24 +36,29 @@ public:
|
|||||||
void FindTargets(const String& type,
|
void FindTargets(const String& type,
|
||||||
const std::function<void (const Value&)>& addTarget) const override
|
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) {
|
if (statsFunctions) {
|
||||||
ObjectLock olock(statsFunctions);
|
ObjectLock olock(statsFunctions);
|
||||||
|
|
||||||
for (const Dictionary::Pair& kv : statsFunctions)
|
for (const Namespace::Pair& kv : statsFunctions)
|
||||||
addTarget(GetTargetByName("Status", kv.first));
|
addTarget(GetTargetByName("Status", kv.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value GetTargetByName(const String& type, const String& name) const override
|
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)
|
if (!statsFunctions)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("No status functions are available."));
|
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)
|
if (!func)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid status function name."));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid status function name."));
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/serializer.hpp"
|
#include "base/serializer.hpp"
|
||||||
|
#include "base/namespace.hpp"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -48,10 +49,10 @@ public:
|
|||||||
const std::function<void (const Value&)>& addTarget) const override
|
const std::function<void (const Value&)>& addTarget) const override
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Dictionary::Ptr globals = ScriptGlobal::GetGlobals();
|
Namespace::Ptr globals = ScriptGlobal::GetGlobals();
|
||||||
ObjectLock olock(globals);
|
ObjectLock olock(globals);
|
||||||
for (const Dictionary::Pair& kv : globals) {
|
for (const Namespace::Pair& kv : globals) {
|
||||||
addTarget(GetTargetForVar(kv.first, kv.second));
|
addTarget(GetTargetForVar(kv.first, kv.second->Get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user