Implement the "import" keyword.

Refs #5869
This commit is contained in:
Gunnar Beutner 2014-03-27 12:30:24 +01:00
parent 10207b99c9
commit 8958d2f69f
36 changed files with 310 additions and 225 deletions

View File

@ -3,7 +3,9 @@
* in the conf.d directory (e.g. one per host). By default all *.conf
* files in this directory are included.
*/
object Host "nsca-ng" inherits "generic-host" {
object Host "nsca-ng" {
import "generic-host",
display_name = "nsca-ng test",
services["PassiveService1"] = {
@ -15,4 +17,4 @@ object Host "nsca-ng" inherits "generic-host" {
templates = [ "generic-service" ],
check_command = "passive",
},
}
}

View File

@ -59,7 +59,9 @@ then use these macros on the command line.
> the service using the check command `disk`. The macros can also
> be inherited from a parent template using additive inheritance (`+=`).
object CheckCommand "disk" inherits "plugin-check-command" {
object CheckCommand "disk" {
import "plugin-check-command",
command = [
"$plugindir$/check_disk",
"-w", "$wfree$%",
@ -76,7 +78,8 @@ The host `localhost` with the service `disk` checks all disks with modified
macros (warning thresholds at `10%`, critical thresholds at `5%` free disk
space).
object Host "localhost" inherits "generic-host" {
object Host "localhost" {
import "generic-host",
services["disk"] = {
templates = [ "generic-service" ],
@ -112,7 +115,9 @@ notification itself (`email` macro attribute provided as `$USERMACRO$`).
If you require default macro definitions, you can add a macro dictionary as shown for the
`CheckCommand` object.
object NotificationCommand "mail-service-notification" inherits "plugin-notification-command" {
object NotificationCommand "mail-service-notification" {
import "plugin-notification-command",
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ],
export_macros = [
@ -187,7 +192,9 @@ send a check result using the `process_check_result` script forcibly
changing the service state back to `OK` (`-r 0`) providing some debug
information in the check output (`-o`).
object EventCommand "plugin-event-process-check-result" inherits "plugin-event-command" {
object EventCommand "plugin-event-process-check-result" {
import "plugin-event-command",
command = [
"$plugindir$/process_check_result",
"-H",

View File

@ -21,7 +21,9 @@ using the available runtime macros for output formatting.
Here is an example of a command definition which uses user-defined macros:
object CheckCommand "my-ping" inherits "plugin-check-command" {
object CheckCommand "my-ping" {
import "plugin-check-command",
command = [
"$plugindir$/check_ping",
"-4",
@ -126,8 +128,10 @@ Node 2:
CheckCommand definition:
object CheckCommand "whatever" inherits "plugin-check-command" {
command = "$plugindir$/check_whatever"
object CheckCommand "whatever" {
import "plugin-check-command",
command = "$plugindir$/check_whatever"
}
On Node 1, this will be evaluated into `/usr/lib/icinga/plugins/check_whatever`.
@ -246,18 +250,20 @@ be exported as environment variables prior to executing the command.
This is useful for example for hiding sensitive information on the command line output
when passing credentials to database checks:
object CheckCommand "mysql-health" inherits "plugin-check-command" {
command = "$plugindir$/check_mysql -H $address$ -d $db$",
/* default macro values */
macros = {
"MYSQLUSER" = "icinga_check",
"MYSQLPASS" = "1c1ng42r0xx"
},
object CheckCommand "mysql-health" {
import "plugin-check-command",
export_macros = [
"MYSQLUSER",
"MYSQLPASS"
]
command = "$plugindir$/check_mysql -H $address$ -d $db$",
/* default macro values */
macros = {
"MYSQLUSER" = "icinga_check",
"MYSQLPASS" = "1c1ng42r0xx"
},
export_macros = [
"MYSQLUSER",
"MYSQLPASS"
]
}
### <a id="configuration-macros"></a> Configuration Macros

View File

@ -58,7 +58,9 @@ your environment.
There are various macros available at runtime execution of the `NotificationCommand`.
The example below may or may not fit your needs.
object NotificationCommand "mail-service-notification" inherits "plugin-notification-command" {
object NotificationCommand "mail-service-notification" {
import "plugin-notification-command",
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ],
export_macros = [

View File

@ -15,11 +15,15 @@ configuration:
check = "ping"
}
object Host "my-server1" inherits "linux-server" {
object Host "my-server1" {
import "linux-server",
macros["address"] = "10.0.0.1"
}
object Host "my-server2" inherits "linux-server" {
object Host "my-server2" {
import "linux-server",
macros["address"] = "10.0.0.2"
}

View File

@ -61,13 +61,17 @@ the user groups are associated as attributes in `Notification` objects.
groups = [ "windows-mssql-admins" ]
}
object User "win-mssql-noc" inherits "generic-windows-mssql-users" {
object User "win-mssql-noc" {
import "generic-windows-mssql-users",
macros = {
"email" = "noc@company.com"
}
}
object User "win-mssql-ops" inherits "generic-windows-mssql-users" {
object User "win-mssql-ops" {
import "generic-windows-mssql-users",
macros = {
"email" = "ops@company.com"
}

View File

@ -31,7 +31,9 @@ If you don't set any `check_period` or `notification_period` attribute
on your configuration objects Icinga 2 assumes `24x7` as time period
as shown below.
object TimePeriod "24x7" inherits "legacy-timeperiod" {
object TimePeriod "24x7" {
import "legacy-timeperiod",
display_name = "Icinga 2 24x7 TimePeriod",
ranges = {
"monday" = "00:00-24:00",
@ -48,7 +50,9 @@ If your operation staff should only be notified during workhours
create a new timeperiod named `workhours` defining a work day with
09:00 to 17:00.
object TimePeriod "workhours" inherits "legacy-timeperiod" {
object TimePeriod "workhours" {
import "legacy-timeperiod",
display_name = "Icinga 2 8x5 TimePeriod",
ranges = {
"monday" = "09:00-17:00",

View File

@ -25,7 +25,9 @@ The following example uses the [SNMP ITL](#itl-snmp) `CheckCommand` and only def
additional macros (note the `+=` operator) as command parameters for the `oid`
(`community` is already set):
object Host "remote-snmp-host" inherits "generic-host" {
object Host "remote-snmp-host" {
import "generic-host",
...
services["uptime"] = {
templates = [ "generic-service" ],
@ -44,7 +46,9 @@ additional macros (note the `+=` operator) as command parameters for the `oid`
Calling a plugin using the SSH protocol to execute a plugin on the remote server fetching
its return code and output. `check_by_ssh` is available in the [Monitoring Plugins package](#setting-up-check-plugins).
object CheckCommand "check_by_ssh_swap" inherits "plugin-check-command" {
object CheckCommand "check_by_ssh_swap" {
import "plugin-check-command",
command = [ "$plugindir$/check_by_ssh",
"-l", "remoteuser",
"-H", "$address$",
@ -52,7 +56,9 @@ its return code and output. `check_by_ssh` is available in the [Monitoring Plugi
]
}
object Host "remote-ssh-host" inherits "generic-host" {
object Host "remote-ssh-host" {
import "generic-host",
...
services["swap"] = {
templates = [ "generic-service" ],
@ -82,14 +88,18 @@ remote client.
Example:
object CheckCommand "check_nrpe" inherits "plugin-check-command" {
object CheckCommand "check_nrpe" {
import "plugin-check-command",
command = [ "$plugindir$/check_nrpe",
"-H", "$address$",
"-c", "$remote_nrpe_command$",
],
}
object Host "remote-nrpe-host" inherits "generic-host" {
object Host "remote-nrpe-host" {
import "generic-host",
...
services["users"] = {
templates = [ "generic-service" ],
@ -122,7 +132,9 @@ the required output and performance counters.
Example:
object CheckCommand "check_nscp" inherits "plugin-check-command" {
object CheckCommand "check_nscp" {
import "plugin-check-command",
command = [ "$plugindir$/check_nt",
"-H", "$address$",
"-p", "$port$",
@ -138,7 +150,9 @@ Example:
}
}
object Host "remote-windows-host" inherits "generic-host" {
object Host "remote-windows-host" {
import "generic-host",
...
services["users"] = {
templates = [ "generic-service" ],

View File

@ -317,11 +317,15 @@ Example:
macros["color"] = "red"
}
template Host "test-host" inherits "default-host" {
template Host "test-host" {
import "default-host",
macros["color"] = "blue"
}
object Host "localhost" inherits "test-host" {
object Host "localhost" {
import "test-host",
macros["address"] = "127.0.0.1",
macros["address6"] = "::1"
}
@ -337,7 +341,7 @@ templates though in general they are.
> `color` has the value `"blue"`.
Parent objects are resolved in the order they're specified using the
`inherits` keyword.
`import` keyword.
### <a id="disable-override-objects-attributes"></a> Disable/Override Objects and Attributes

View File

@ -327,7 +327,9 @@ when notifications should be sent out.
Example:
object TimePeriod "24x7" inherits "legacy-timeperiod" {
object TimePeriod "24x7" {
import "legacy-timeperiod",
display_name = "Icinga 2 24x7 TimePeriod",
ranges = {
"monday" = "00:00-24:00",
@ -431,7 +433,9 @@ defined here.
Example:
object CheckCommand "check_snmp" inherits "plugin-check-command" {
object CheckCommand "check_snmp" {
import "plugin-check-command",
command = "$plugindir$/check_snmp -H $address$ -C $community$ -o $oid$",
macros = {
@ -457,7 +461,9 @@ A notification command definition.
Example:
object NotificationCommand "mail-service-notification" inherits "plugin-notification-command" {
object NotificationCommand "mail-service-notification" {
import "plugin-notification-command",
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ],
export_macros = [
@ -497,7 +503,9 @@ An event command definition.
Example:
object EventCommand "restart-httpd-event" inherits "plugin-event-command" {
object EventCommand "restart-httpd-event" {
import "plugin-event-command",
command = "/opt/bin/restart-httpd.sh",
}

View File

@ -81,7 +81,9 @@ does not fit everyone, split it into two.
Or rather inherit that template into a new template, and override/disable
unwanted values.
template Service "generic-service-disable-notifications" inherits "generic-service" {
template Service "generic-service-disable-notifications" {
import "generic-service",
notifications["mail-icingaadmin"] = null
}
@ -201,8 +203,8 @@ downtimes through the template automatism.
check = "ping4"
}
object Host "localhost" inherits "linux-server" {
object Host "localhost" {
import "linux-server",
}

View File

@ -88,7 +88,9 @@ Example:
}
}
object Host "localhost" inherits "generic-host" {
object Host "localhost" {
import "generic-host",
...
services["load"] = {
templates = [ "generic-service" ],
@ -99,4 +101,4 @@ Example:
templates = [ "backup-downtime" ]
}
},
}
}

View File

@ -210,7 +210,9 @@ If you require specific services to be only executed by one or more checker node
within the cluster, you must define `authorities` as additional service object
attribute. Required Endpoints must be defined as array.
object Host "dmz-host1" inherits "generic-host" {
object Host "dmz-host1" {
import "generic-host",
services["dmz-oracledb"] = {
templates = [ "generic-service" ],
authorities = [ "icinga-node-1" ],
@ -232,7 +234,9 @@ one or more configured nodes are not connected.
Example:
object Host "icinga2a" inherits "generic-host" {
object Host "icinga2a" {
import "generic-host",
services["cluster"] = {
templates = [ "generic-service" ],
check_interval = 1m,

View File

@ -15,7 +15,9 @@ by any cluster event message, and could be checked by the local authority too pr
a different state history. `icinga-node-dmz-2` still receives all cluster message updates
from the `icinga-node-dmz-1` endpoint.
object Host "dmz-host1" inherits "generic-host" {
object Host "dmz-host1" {
import "generic-host",
services["dmz-oracledb"] = {
templates = [ "generic-service" ],
domains = [ "dmz-db" ],
@ -28,4 +30,4 @@ from the `icinga-node-dmz-1` endpoint.
icinga-node-dmz-1 = DomainPrivReadOnly,
icinga-node-dmz-2 = DomainPrivReadWrite
}
}
}

View File

@ -123,15 +123,17 @@ uses the `template` identifier:
template Service "ping4-template" { }
Icinga 1.x objects inherit from templates using the `use` attribute.
Icinga 2 uses the keyword `inherits` after the object name and requires a
comma-separated list with template names in double quotes.
Icinga 2 uses the keyword `import` with template names in double quotes.
define service {
service_description testservice
use tmpl1,tmpl2,tmpl3
}
object Service "testservice" inherits "tmpl1", "tmpl2", "tmpl3" {
object Service "testservice" {
import "tmpl1",
import "tmpl2",
import "tmpl3"
}
## <a id="differences-1x-2-object-attributes"></a> Object attributes
@ -375,7 +377,9 @@ The preferred way of assigning objects to groups is by using a template:
}
}
object Host "web-dev" inherits "dev-host" { }
object Host "web-dev" {
import "dev-host"
}
Host groups in Icinga 2 cannot be used to associate services with all members
of that group. The example above shows how to use templates to accomplish

View File

@ -6,7 +6,9 @@ template Host "generic-host" {
}
template Host "linux-server" inherits "generic-host" {
template Host "linux-server" {
import "generic-host",
groups += [ "linux-servers" ],
services["ping4"] = {
@ -18,7 +20,9 @@ template Host "linux-server" inherits "generic-host" {
check = "ping4"
}
template Host "windows-server" inherits "generic-host" {
template Host "windows-server" {
import "generic-host",
groups += [ "windows-servers" ],
services["ping4"] = {
@ -30,7 +34,9 @@ template Host "windows-server" inherits "generic-host" {
check = "ping4"
}
template Host "generic-printer" inherits "generic-host" {
template Host "generic-printer" {
import "generic-host",
services["ping4"] = {
templates = [ "generic-service" ],
@ -40,7 +46,9 @@ template Host "generic-printer" inherits "generic-host" {
check = "ping4"
}
template Host "generic-switch" inherits "generic-host" {
template Host "generic-switch" {
import "generic-host",
services["ping4"] = {
templates = [ "generic-service" ],

View File

@ -3,7 +3,9 @@
* in the conf.d directory (e.g. one per host). By default all *.conf
* files in this directory are included.
*/
object Host "localhost" inherits "linux-server" {
object Host "localhost" {
import "linux-server",
display_name = "localhost",
services["icinga"] = {

View File

@ -22,7 +22,9 @@ template Notification "mail-notification" {
notification_period = "24x7"
}
object NotificationCommand "mail-service-notification" inherits "plugin-notification-command" {
object NotificationCommand "mail-service-notification" {
import "plugin-notification-command",
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ],
export_macros = [

View File

@ -3,7 +3,9 @@
* 'legacy-timeperiod' template from the ITL.
*/
object TimePeriod "24x7" inherits "legacy-timeperiod" {
object TimePeriod "24x7" {
import "legacy-timeperiod",
display_name = "Icinga 2 24x7 TimePeriod",
ranges = {
"monday" = "00:00-24:00",
@ -16,7 +18,9 @@ object TimePeriod "24x7" inherits "legacy-timeperiod" {
}
}
object TimePeriod "9to5" inherits "legacy-timeperiod" {
object TimePeriod "9to5" {
import "legacy-timeperiod",
display_name = "Icinga 2 9to5 TimePeriod",
ranges = {
"monday" = "09:00-17:00",
@ -27,7 +31,9 @@ object TimePeriod "9to5" inherits "legacy-timeperiod" {
}
}
object TimePeriod "never" inherits "legacy-timeperiod" {
object TimePeriod "never" {
import "legacy-timeperiod",
display_name = "Icinga 2 never TimePeriod",
ranges = {
}

View File

@ -3,7 +3,9 @@
* group 'icingaadmins'.
*/
object User "icingaadmin" inherits "generic-user" {
object User "icingaadmin" {
import "generic-user",
display_name = "Icinga 2 Admin",
groups = [ "icingaadmins" ],

View File

@ -17,7 +17,9 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
object CheckCommand "ping4" inherits "plugin-check-command" {
object CheckCommand "ping4" {
import "plugin-check-command",
command = [
"$plugindir$/check_ping",
"-4",
@ -40,7 +42,9 @@ object CheckCommand "ping4" inherits "plugin-check-command" {
}
}
object CheckCommand "ping6" inherits "plugin-check-command" {
object CheckCommand "ping6" {
import "plugin-check-command",
command = [
"$plugindir$/check_ping",
"-6",
@ -63,7 +67,9 @@ object CheckCommand "ping6" inherits "plugin-check-command" {
}
}
object CheckCommand "dummy" inherits "plugin-check-command" {
object CheckCommand "dummy" {
import "plugin-check-command",
command = [
"$plugindir$/check_dummy",
"$state$",
@ -76,14 +82,18 @@ object CheckCommand "dummy" inherits "plugin-check-command" {
}
}
object CheckCommand "passive" inherits "dummy" {
object CheckCommand "passive" {
import "dummy",
macros = {
state = 3,
text = "No Passive Check Result Received."
}
}
object CheckCommand "tcp" inherits "plugin-check-command" {
object CheckCommand "tcp" {
import "plugin-check-command",
command = [
"$plugindir$/check_tcp",
"-H", "$address$",
@ -91,7 +101,9 @@ object CheckCommand "tcp" inherits "plugin-check-command" {
]
}
object CheckCommand "udp" inherits "plugin-check-command" {
object CheckCommand "udp" {
import "plugin-check-command",
command = [
"$plugindir$/check_udp",
"-H", "$address$",
@ -99,42 +111,54 @@ object CheckCommand "udp" inherits "plugin-check-command" {
]
}
object CheckCommand "http_vhost" inherits "plugin-check-command" {
object CheckCommand "http_vhost" {
import "plugin-check-command",
command = [
"$plugindir$/check_http",
"-H", "$vhost$"
]
}
object CheckCommand "http_ip" inherits "plugin-check-command" {
object CheckCommand "http_ip" {
import "plugin-check-command",
command = [
"$plugindir$/check_http",
"-H", "$address$"
]
}
object CheckCommand "https_vhost" inherits "plugin-check-command" {
object CheckCommand "https_vhost" {
import "plugin-check-command",
command = [
"$plugindir$/check_http",
"-H", "$vhost$", "-S"
]
}
object CheckCommand "https_ip" inherits "plugin-check-command" {
object CheckCommand "https_ip" {
import "plugin-check-command",
command = [
"$plugindir$/check_http",
"-I", "$address$", "-S"
]
}
object CheckCommand "smtp" inherits "plugin-check-command" {
object CheckCommand "smtp" {
import "plugin-check-command",
command = [
"$plugindir$/check_smtp",
"-H", "$address$"
]
}
object CheckCommand "ssmtp" inherits "plugin-check-command" {
object CheckCommand "ssmtp" {
import "plugin-check-command",
command = [
"$plugindir$/check_ssmtp",
"-H", "$address$",
@ -146,21 +170,27 @@ object CheckCommand "ssmtp" inherits "plugin-check-command" {
}
}
object CheckCommand "ntp_time" inherits "plugin-check-command" {
object CheckCommand "ntp_time" {
import "plugin-check-command",
command = [
"$plugindir$/check_ntp_time",
"-H", "$address$"
]
}
object CheckCommand "ssh" inherits "plugin-check-command" {
object CheckCommand "ssh" {
import "plugin-check-command",
command = [
"$plugindir$/check_ssh",
"$address$"
]
}
object CheckCommand "disk" inherits "plugin-check-command" {
object CheckCommand "disk" {
import "plugin-check-command",
command = [
"$plugindir$/check_disk",
"-w", "$wfree$%",
@ -173,7 +203,9 @@ object CheckCommand "disk" inherits "plugin-check-command" {
}
}
object CheckCommand "users" inherits "plugin-check-command" {
object CheckCommand "users"{
import "plugin-check-command",
command = [
"$plugindir$/check_users",
"-w", "$wgreater$",
@ -186,7 +218,9 @@ object CheckCommand "users" inherits "plugin-check-command" {
}
}
object CheckCommand "processes" inherits "plugin-check-command" {
object CheckCommand "processes"{
import "plugin-check-command",
command = [
"$plugindir$/check_procs",
"-w", "$wgreater$",
@ -199,7 +233,9 @@ object CheckCommand "processes" inherits "plugin-check-command" {
}
}
object CheckCommand "load" inherits "plugin-check-command" {
object CheckCommand "load"{
import "plugin-check-command",
command = [
"$plugindir$/check_load",
"-w", "$wload1$,$wload5$,$wload15$",
@ -217,7 +253,9 @@ object CheckCommand "load" inherits "plugin-check-command" {
}
}
object CheckCommand "snmp" inherits "plugin-check-command" {
object CheckCommand "snmp"{
import "plugin-check-command",
command = [
"$plugindir$/check_snmp",
"-H", "$address$",
@ -230,19 +268,27 @@ object CheckCommand "snmp" inherits "plugin-check-command" {
}
}
object CheckCommand "snmp-uptime" inherits "snmp" {
object CheckCommand "snmp-uptime"{
import "snmp",
macros += {
oid = "1.3.6.1.2.1.1.3.0"
}
}
object CheckCommand "icinga" inherits "icinga-check-command" {
object CheckCommand "icinga"{
import "icinga-check-command",
}
object CheckCommand "cluster" inherits "cluster-check-command" {
object CheckCommand "cluster"{
import "cluster-check-command",
}
object CheckCommand "snmp-extend" inherits "plugin-check-command" {
object CheckCommand "snmp-extend"{
import "plugin-check-command",
command = [
IcingaSysconfDir + "/icinga2/scripts/snmp-extend.sh",
"$HOSTADDRESS$",

View File

@ -19,6 +19,7 @@
#include "config/aexpression.h"
#include "config/configerror.h"
#include "config/configitem.h"
#include "base/array.h"
#include "base/serializer.h"
#include "base/context.h"
@ -459,3 +460,18 @@ Value AExpression::OpIndexer(const AExpression *expr, const Dictionary::Ptr& loc
return dict->Get(expr->m_Operand2);
}
Value AExpression::OpImport(const AExpression *expr, const Dictionary::Ptr& locals)
{
Value type = expr->EvaluateOperand1(locals);
Value name = expr->EvaluateOperand2(locals);
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
if (!item)
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
item->GetExpressionList()->Evaluate(locals);
return Empty;
}

View File

@ -79,6 +79,7 @@ public:
static Value OpSetMultiply(const AExpression *expr, const Dictionary::Ptr& locals);
static Value OpSetDivide(const AExpression *expr, const Dictionary::Ptr& locals);
static Value OpIndexer(const AExpression *expr, const Dictionary::Ptr& locals);
static Value OpImport(const AExpression *expr, const Dictionary::Ptr& locals);
private:
OpCallback m_Operator;

View File

@ -224,6 +224,7 @@ const return T_CONST;
apply return T_APPLY;
to return T_TO;
where return T_WHERE;
import return T_IMPORT;
\<\< { yylval->op = &AExpression::OpShiftLeft; return T_SHIFT_LEFT; }
\>\> { yylval->op = &AExpression::OpShiftRight; return T_SHIFT_RIGHT; }
\<= { yylval->op = &AExpression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; }

View File

@ -144,6 +144,7 @@ using namespace icinga;
%token T_APPLY "apply (T_APPLY)"
%token T_TO "to (T_TO)"
%token T_WHERE "where (T_WHERE)"
%token T_IMPORT "import (T_IMPORT)"
%type <text> identifier
%type <array> rterm_items
%type <array> rterm_items_inner
@ -154,8 +155,6 @@ using namespace icinga;
%type <op> rbinary_op
%type <type> type
%type <num> partial_specifier
%type <slist> object_inherits_list
%type <slist> object_inherits_specifier
%type <variant> rterm
%type <variant> rterm_scope
%type <variant> lterm
@ -411,9 +410,9 @@ object:
{
m_Abstract = false;
}
object_declaration identifier rterm object_inherits_specifier rterm_scope
object_declaration identifier rterm rterm_scope
{
DebugInfo di = DebugInfoRange(@2, @6);
DebugInfo di = DebugInfoRange(@2, @5);
ConfigItemBuilder::Ptr item = make_shared<ConfigItemBuilder>(di);
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$4);
@ -444,16 +443,8 @@ object:
item->SetName(name);
if ($5) {
BOOST_FOREACH(const String& parent, *$5) {
item->AddParent(parent);
}
delete $5;
}
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$6);
delete $6;
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$5);
delete $5;
exprl->MakeInline();
item->AddExpression(exprl);
@ -473,38 +464,6 @@ object_declaration: T_OBJECT
m_Abstract = true;
}
object_inherits_list:
{
$$ = NULL;
}
| T_STRING
{
$$ = new std::vector<String>();
$$->push_back($1);
free($1);
}
| object_inherits_list ',' T_STRING
{
if ($1)
$$ = $1;
else
$$ = new std::vector<String>();
$$->push_back($3);
free($3);
}
;
object_inherits_specifier:
{
$$ = NULL;
}
| T_INHERITS object_inherits_list
{
$$ = $2;
}
;
lbinary_op: T_SET
| T_SET_PLUS
| T_SET_MINUS
@ -661,6 +620,13 @@ rterm: T_STRING
$$ = new Value(make_shared<AExpression>(&AExpression::OpFunctionCall, $1, make_shared<AExpression>(&AExpression::OpLiteral, arguments, @3), DebugInfoRange(@1, @4)));
free($1);
}
| T_IMPORT rterm
{
AExpression::Ptr avar = make_shared<AExpression>(&AExpression::OpVariable, "__type", DebugInfoRange(@1, @2));
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$2);
delete $2;
$$ = new Value(make_shared<AExpression>(&AExpression::OpImport, avar, aexpr, DebugInfoRange(@1, @2)));
}
| T_IDENTIFIER
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpVariable, $1, @1));

View File

@ -44,15 +44,13 @@ ConfigItem::ItemMap ConfigItem::m_Items;
* @param unit The unit of the item.
* @param abstract Whether the item is a template.
* @param exprl Expression list for the item.
* @param parents Parent objects for the item.
* @param debuginfo Debug information.
*/
ConfigItem::ConfigItem(const String& type, const String& name,
bool abstract, const AExpression::Ptr& exprl,
const std::vector<String>& parents, const DebugInfo& debuginfo,
const Dictionary::Ptr& scope)
const DebugInfo& debuginfo, const Dictionary::Ptr& scope)
: m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo),
m_ExpressionList(exprl), m_DebugInfo(debuginfo),
m_Scope(scope)
{
}
@ -112,42 +110,6 @@ AExpression::Ptr ConfigItem::GetExpressionList(void) const
return m_ExpressionList;
}
AExpression::Ptr ConfigItem::GetLinkedExpressionList(void)
{
ASSERT(OwnsLock());
if (m_LinkedExpressionList)
return m_LinkedExpressionList;
Array::Ptr subexprs = make_shared<Array>();
BOOST_FOREACH(const String& name, m_ParentNames) {
ConfigItem::Ptr parent = ConfigItem::GetObject(m_Type, name);
if (!parent) {
std::ostringstream message;
message << "Parent object '" << name << "' does not"
" exist (" << m_DebugInfo << ")";
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str(), m_DebugInfo);
} else {
AExpression::Ptr pexprl;
{
ObjectLock olock(parent);
pexprl = parent->GetLinkedExpressionList();
}
subexprs->Add(pexprl);
}
}
subexprs->Add(m_ExpressionList);
m_LinkedExpressionList = make_shared<AExpression>(&AExpression::OpDict, subexprs, true, m_DebugInfo);
return m_LinkedExpressionList;
}
Dictionary::Ptr ConfigItem::GetProperties(void)
{
ASSERT(OwnsLock());
@ -155,7 +117,7 @@ Dictionary::Ptr ConfigItem::GetProperties(void)
if (!m_Properties) {
m_Properties = make_shared<Dictionary>();
m_Properties->Set("__parent", m_Scope);
GetLinkedExpressionList()->Evaluate(m_Properties);
GetExpressionList()->Evaluate(m_Properties);
m_Properties->Remove("__parent");
VERIFY(m_Properties->Get("__type") == GetType() && m_Properties->Get("__name") == GetName());

View File

@ -45,8 +45,8 @@ public:
DECLARE_PTR_TYPEDEFS(ConfigItem);
ConfigItem(const String& type, const String& name, bool abstract,
const AExpression::Ptr& exprl, const std::vector<String>& parents,
const DebugInfo& debuginfo, const Dictionary::Ptr& scope);
const AExpression::Ptr& exprl, const DebugInfo& debuginfo,
const Dictionary::Ptr& scope);
String GetType(void) const;
String GetName(void) const;
@ -54,7 +54,7 @@ public:
std::vector<ConfigItem::Ptr> GetParents(void) const;
AExpression::Ptr GetLinkedExpressionList(void);
AExpression::Ptr GetExpressionList(void) const;
Dictionary::Ptr GetProperties(void);
DynamicObject::Ptr Commit(void);
@ -74,8 +74,6 @@ public:
static void DiscardItems(void);
private:
AExpression::Ptr GetExpressionList(void) const;
String m_Type; /**< The object type. */
String m_Name; /**< The name. */
bool m_Abstract; /**< Whether this is a template. */
@ -88,8 +86,6 @@ private:
DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
AExpression::Ptr m_LinkedExpressionList;
DynamicObject::Ptr m_Object;
static boost::mutex m_Mutex;

View File

@ -60,11 +60,6 @@ void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
m_Scope = scope;
}
void ConfigItemBuilder::AddParent(const String& parent)
{
m_Parents.push_back(parent);
}
void ConfigItemBuilder::AddExpression(const AExpression::Ptr& expr)
{
m_Expressions->Add(expr);
@ -90,18 +85,13 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
}
BOOST_FOREACH(const String& parent, m_Parents) {
if (parent == m_Name)
BOOST_THROW_EXCEPTION(std::invalid_argument("Configuration item '" + m_Name + "' of type '" + m_Type + "' must not inherit from itself."));
}
Array::Ptr exprs = make_shared<Array>();
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__type", make_shared<AExpression>(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo));
AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
m_Parents, m_DebugInfo, m_Scope);
m_DebugInfo, m_Scope);
}

View File

@ -47,8 +47,6 @@ public:
void SetAbstract(bool abstract);
void SetScope(const Dictionary::Ptr& scope);
void AddParent(const String& parent);
void AddExpression(const AExpression::Ptr& expr);
ConfigItem::Ptr Compile(void);
@ -57,8 +55,6 @@ private:
String m_Type; /**< The object type. */
String m_Name; /**< The name. */
bool m_Abstract; /**< Whether the item is abstract. */
std::vector<String> m_Parents; /**< The names of parent configuration
items. */
Array::Ptr m_Expressions; /**< Expressions for this item. */
DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */

View File

@ -49,8 +49,10 @@ void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
locals->Set("hostgroups", groups);
BOOST_FOREACH(const ApplyRule& rule, rules) {
DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << rule.GetDebugInfo() << ")";
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
Value result = rule.GetExpression()->Evaluate(locals);
@ -60,27 +62,30 @@ void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
continue;
} catch (...) {
std::ostringstream msgbuf;
msgbuf << "Apply rule (" << rule.GetDebugInfo() << ") returned invalid data type, expected bool: " + JsonSerialize(result);
msgbuf << "Apply rule (" << di << ") returned invalid data type, expected bool: " + JsonSerialize(result);
Log(LogCritical, "icinga", msgbuf.str());
continue;
}
std::ostringstream msgbuf2;
msgbuf2 << "Applying service template '" << rule.GetTemplate() << "' to host '" << host->GetName() << "' for rule " << rule.GetDebugInfo();
msgbuf2 << "Applying service template '" << rule.GetTemplate() << "' to host '" << host->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf;
namebuf << host->GetName() << "!apply!" << rule.GetTemplate();
String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo());
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Service");
builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo()));
builder->AddParent(rule.GetTemplate());
AExpression::Ptr atype = make_shared<AExpression>(&AExpression::OpLiteral, "Service", di);
AExpression::Ptr atmpl = make_shared<AExpression>(&AExpression::OpLiteral, rule.GetTemplate(), di);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpImport, atype, atmpl, di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), di), di));
ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register();

View File

@ -118,7 +118,7 @@ void Host::UpdateSlaveServices(void)
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
exprl = item->GetExpressionList();
}
DebugInfo di;
@ -130,12 +130,6 @@ void Host::UpdateSlaveServices(void)
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Service");
builder->SetName(name);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "display_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "short_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
if (!kv.second.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be either a string or a dictionary."));
Dictionary::Ptr service = kv.second;
@ -145,10 +139,19 @@ void Host::UpdateSlaveServices(void)
ObjectLock olock(templates);
BOOST_FOREACH(const Value& tmpl, templates) {
builder->AddParent(tmpl);
AExpression::Ptr atype = make_shared<AExpression>(&AExpression::OpLiteral, "Service", di);
AExpression::Ptr atmpl = make_shared<AExpression>(&AExpression::OpLiteral, tmpl, di);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpImport, atype, atmpl, di));
}
}
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "display_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "short_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
if (!kv.second.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be either a string or a dictionary."));
/* Clone attributes from the service expression list. */
Array::Ptr svc_exprl = make_shared<Array>();
exprl->ExtractPath(path, svc_exprl);

View File

@ -198,7 +198,7 @@ void Service::UpdateSlaveDependencies(void)
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
exprl = item->GetExpressionList();
}
DebugInfo di;
@ -210,8 +210,7 @@ void Service::UpdateSlaveDependencies(void)
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Dependency");
builder->SetName(name);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
Dictionary::Ptr dependency = kv.second;
@ -221,10 +220,15 @@ void Service::UpdateSlaveDependencies(void)
ObjectLock tlock(templates);
BOOST_FOREACH(const Value& tmpl, templates) {
builder->AddParent(tmpl);
AExpression::Ptr atype = make_shared<AExpression>(&AExpression::OpLiteral, "Dependency", di);
AExpression::Ptr atmpl = make_shared<AExpression>(&AExpression::OpLiteral, tmpl, di);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpImport, atype, atmpl, di));
}
}
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
/* Clone attributes from the scheduled downtime expression list. */
Array::Ptr sd_exprl = make_shared<Array>();
exprl->ExtractPath(path, sd_exprl);

View File

@ -347,7 +347,7 @@ void Service::UpdateSlaveScheduledDowntimes(void)
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
exprl = item->GetExpressionList();
}
DebugInfo di;
@ -359,8 +359,6 @@ void Service::UpdateSlaveScheduledDowntimes(void)
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("ScheduledDowntime");
builder->SetName(name);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
Dictionary::Ptr scheduledDowntime = kv.second;
@ -370,10 +368,15 @@ void Service::UpdateSlaveScheduledDowntimes(void)
ObjectLock tlock(templates);
BOOST_FOREACH(const Value& tmpl, templates) {
builder->AddParent(tmpl);
AExpression::Ptr atype = make_shared<AExpression>(&AExpression::OpLiteral, "ScheduledDowntime", di);
AExpression::Ptr atmpl = make_shared<AExpression>(&AExpression::OpLiteral, tmpl, di);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpImport, atype, atmpl, di));
}
}
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
/* Clone attributes from the scheduled downtime expression list. */
Array::Ptr sd_exprl = make_shared<Array>();
exprl->ExtractPath(path, sd_exprl);

View File

@ -126,7 +126,7 @@ void Service::UpdateSlaveNotifications(void)
{
ObjectLock ilock(item);
exprl = item->GetLinkedExpressionList();
exprl = item->GetExpressionList();
}
DebugInfo di;
@ -138,8 +138,6 @@ void Service::UpdateSlaveNotifications(void)
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Notification");
builder->SetName(name);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
Dictionary::Ptr notification = kv.second;
@ -149,10 +147,15 @@ void Service::UpdateSlaveNotifications(void)
ObjectLock tlock(templates);
BOOST_FOREACH(const Value& tmpl, templates) {
builder->AddParent(tmpl);
AExpression::Ptr atype = make_shared<AExpression>(&AExpression::OpLiteral, "Notification", di);
AExpression::Ptr atmpl = make_shared<AExpression>(&AExpression::OpLiteral, tmpl, di);
builder->AddExpression(make_shared<AExpression>(&AExpression::OpImport, atype, atmpl, di));
}
}
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
/* Clone attributes from the notification expression list. */
Array::Ptr nfc_exprl = make_shared<Array>();
exprl->ExtractPath(path, nfc_exprl);

View File

@ -1,4 +1,6 @@
object EventCommand "test_event" inherits "plugin-event-command" {
object EventCommand "test_event" {
import "plugin-event-command",
command = {{{echo "\
$$HOSTNAME$HOSTNAME$\
|HOSTNAME=$HOSTNAME$\

View File

@ -24,7 +24,9 @@ template Notification "mail-notification" {
/**
* 1:1 copy of the default command
*/
object NotificationCommand "mail-service-notification" inherits "plugin-notification-command" {
object NotificationCommand "mail-service-notification" {
import "plugin-notification-command",
command = [ (IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh") ],
export_macros = [