Support new-lines in addition to commas to separate commands.

Fixes #5901
This commit is contained in:
Gunnar Beutner 2014-03-31 18:38:15 +02:00 committed by Gunnar Beutner
parent 2c17305536
commit 5eca503362
27 changed files with 535 additions and 477 deletions

View File

@ -107,9 +107,9 @@ the features which have been enabled with `icinga2-enable-feature`. See
/** /**
* Although in theory you could define all your objects in this file * Although in theory you could define all your objects in this file
* the preferred way is to create separate directories and files in the conf.d * the preferred way is to create separate directories and files in the conf.d
* directory. * directory. Each of these files must have the file extension ".conf".
*/ */
include_recursive "conf.d" "*.conf" include_recursive "conf.d"
You can put your own configuration files in the `conf.d` directory. This You can put your own configuration files in the `conf.d` directory. This
directive makes sure that all of your own configuration files are included. directive makes sure that all of your own configuration files are included.
@ -136,9 +136,9 @@ The `conf.d/localhost.conf` file contains our first host definition:
* files in this directory are included. * files in this directory are included.
*/ */
object Host "localhost" { object Host "localhost" {
import "linux-server", import "linux-server"
macros.address = "127.0.0.1", macros.address = "127.0.0.1"
macros.address6 = "::1" macros.address6 = "::1"
} }
@ -152,63 +152,63 @@ services which belong to this host. Most of the templates in the Icinga Template
Library require an `address` macro. Library require an `address` macro.
apply Service "icinga" { apply Service "icinga" {
import "generic-service", import "generic-service"
check_command = "icinga", check_command = "icinga"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "http" { apply Service "http" {
import "generic-service", import "generic-service"
check_command = "http_ip", check_command = "http_ip"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "ssh" { apply Service "ssh" {
import "generic-service", import "generic-service"
check_command = "ssh", check_command = "ssh"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "load" { apply Service "load" {
import "generic-service", import "generic-service"
check_command = "load", check_command = "load"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply ScheduledDowntime "backup-downtime" { apply ScheduledDowntime "backup-downtime" {
import "backup-downtime", import "backup-downtime"
assign where service.host == "localhost" && service.short_name == "load" assign where service.host == "localhost" && service.short_name == "load"
} }
apply Service "processes" { apply Service "processes" {
import "generic-service", import "generic-service"
check_command = "processes", check_command = "processes"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "users" { apply Service "users" {
import "generic-service", import "generic-service"
check_command = "users", check_command = "users"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "disk" { apply Service "disk" {
import "generic-service", import "generic-service"
check_command = "disk", check_command = "disk"
assign where host.name == "localhost" assign where host.name == "localhost"
} }

View File

@ -15,7 +15,7 @@ on the same physical device.
Here is an example of a host object which defines two child services: Here is an example of a host object which defines two child services:
object Host "my-server1" { object Host "my-server1" {
macros.address = "10.0.0.1", macros.address = "10.0.0.1"
check = "ping4" check = "ping4"
} }

View File

@ -60,7 +60,7 @@ then use these macros on the command line.
> be inherited from a parent template using additive inheritance (`+=`). > be inherited from a parent template using additive inheritance (`+=`).
object CheckCommand "disk" { object CheckCommand "disk" {
import "plugin-check-command", import "plugin-check-command"
command = [ command = [
PluginDir + "/check_disk", PluginDir + "/check_disk",
@ -68,7 +68,7 @@ then use these macros on the command line.
"-c", "$cfree$%" "-c", "$cfree$%"
], ],
macros.wfree = 20, macros.wfree = 20
macros.cfree = 10 macros.cfree = 10
} }
@ -77,18 +77,18 @@ macros (warning thresholds at `10%`, critical thresholds at `5%` free disk
space). space).
object Host "localhost" { object Host "localhost" {
import "generic-host", import "generic-host"
macros.address = "127.0.0.1", macros.address = "127.0.0.1"
macros.address6 = "::1" macros.address6 = "::1"
} }
apply Service "disk" { apply Service "disk" {
import "generic-service", import "generic-service"
check_command = "disk", check_command = "disk"
macros.wfree = 10, macros.wfree = 10
macros.cfree = 5 macros.cfree = 5
} }
@ -111,9 +111,9 @@ If you require default macro definitions, you can add a macro dictionary as show
`CheckCommand` object. `CheckCommand` object.
object NotificationCommand "mail-service-notification" { object NotificationCommand "mail-service-notification" {
import "plugin-notification-command", import "plugin-notification-command"
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ], command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ]
export_macros = [ export_macros = [
"NOTIFICATIONTYPE", "NOTIFICATIONTYPE",
@ -188,19 +188,14 @@ changing the service state back to `OK` (`-r 0`) providing some debug
information in the check output (`-o`). information in the check output (`-o`).
object EventCommand "plugin-event-process-check-result" { object EventCommand "plugin-event-process-check-result" {
import "plugin-event-command", import "plugin-event-command"
command = [ command = [
PluginDir + "/process_check_result", PluginDir + "/process_check_result",
"-H", "-H", "$HOSTNAME$",
"$HOSTNAME$", "-S", "$SERVICEDESC$",
"-S", "-c", "/var/run/icinga2/cmd/icinga2.cmd",
"$SERVICEDESC$", "-r", "0",
"-c", "-o", "Event Handler triggered in state '$SERVICESTATE$' with output '$SERVICEOUTPUT$'."
"/var/run/icinga2/cmd/icinga2.cmd",
"-r",
"0",
"-o",
"Event Handler triggered in state '$SERVICESTATE$' with output '$SERVICEOUTPUT$'."
] ]
} }

View File

@ -22,7 +22,7 @@ using the available runtime macros for output formatting.
Here is an example of a command definition which uses user-defined macros: Here is an example of a command definition which uses user-defined macros:
object CheckCommand "my-ping" { object CheckCommand "my-ping" {
import "plugin-check-command", import "plugin-check-command"
command = [ command = [
PluginDir + "/check_ping", PluginDir + "/check_ping",
@ -35,13 +35,13 @@ Here is an example of a command definition which uses user-defined macros:
], ],
macros = { macros = {
wrta = 100, wrta = 100
wpl = 5, wpl = 5
crta = 200, crta = 200
cpl = 15, cpl = 15
packets = 5, packets = 5
timeout = 0 timeout = 0
} }
} }
@ -76,7 +76,7 @@ When using the `my-ping` command you can override all or some of the macros
in the service definition like this: in the service definition like this:
apply Service "ping" { apply Service "ping" {
check_command = "my-ping", check_command = "my-ping"
macros.packets = 10 // Overrides the default value of 5 given in the command macros.packets = 10 // Overrides the default value of 5 given in the command

View File

@ -23,15 +23,15 @@ The user `icingaadmin` in the example below will get notified only on `WARNING`
`CRITICAL` states and `problem` and `recovery` notification types. `CRITICAL` states and `problem` and `recovery` notification types.
object User "icingaadmin" { object User "icingaadmin" {
display_name = "Icinga 2 Admin", display_name = "Icinga 2 Admin"
enable_notifications = 1, enable_notifications = 1
notification_state_filter = StateFilterOK | notification_state_filter = (StateFilterOK |
StateFilterWarning | StateFilterWarning |
StateFilterCritical, StateFilterCritical)
notification_type_filter = NotificationFilterProblem | notification_type_filter = (NotificationFilterProblem |
NotificationFilterRecovery, NotificationFilterRecovery)
macros = { macros = {
"email" = "icinga@localhost", "email" = "icinga@localhost"
"pager" = "+49123456789" "pager" = "+49123456789"
} }
} }
@ -59,9 +59,9 @@ There are various macros available at runtime execution of the `NotificationComm
The example below may or may not fit your needs. The example below may or may not fit your needs.
object NotificationCommand "mail-service-notification" { object NotificationCommand "mail-service-notification" {
import "plugin-notification-command", import "plugin-notification-command"
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ], command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ]
export_macros = [ export_macros = [
"NOTIFICATIONTYPE", "NOTIFICATIONTYPE",
@ -89,14 +89,14 @@ to the defined notifications. That way you'll save duplicated attributes in each
`Notification` object. Attributes can be overridden locally. `Notification` object. Attributes can be overridden locally.
template Notification "generic-notification" { template Notification "generic-notification" {
notification_interval = 15m, notification_interval = 15m
notification_command = "mail-service-notification", notification_command = "mail-service-notification"
notification_state_filter = StateFilterWarning | notification_state_filter = (StateFilterWarning |
StateFilterCritical | StateFilterCritical |
StateFilterUnknown, StateFilterUnknown)
notification_type_filter = NotificationFilterProblem | notification_type_filter = (NotificationFilterProblem |
NotificationFilterAcknowledgement | NotificationFilterAcknowledgement |
NotificationFilterRecovery | NotificationFilterRecovery |
NotificationFilterCustom | NotificationFilterCustom |
@ -104,7 +104,7 @@ to the defined notifications. That way you'll save duplicated attributes in each
NotificationFilterFlappingEnd | NotificationFilterFlappingEnd |
NotificationFilterDowntimeStart | NotificationFilterDowntimeStart |
NotificationFilterDowntimeEnd | NotificationFilterDowntimeEnd |
NotificationFilterDowntimeRemoved, NotificationFilterDowntimeRemoved)
notification_period = "24x7" notification_period = "24x7"
} }
@ -116,10 +116,10 @@ to the defined notifications. That way you'll save duplicated attributes in each
Use the `apply` keyword to create `Notification` objects for your services: Use the `apply` keyword to create `Notification` objects for your services:
apply Notification "mail" { apply Notification "mail" {
import "generic-notification", import "generic-notification"
notification_command = "mail-notification", notification_command = "mail-notification"
users = [ "icingaadmin" ], users = [ "icingaadmin" ]
assign where service.short_name == "ping4" assign where service.short_name == "ping4"
} }
@ -151,8 +151,8 @@ notifications between start and end time.
> are not set in this example. > are not set in this example.
object User "icinga-oncall-2nd-level" { object User "icinga-oncall-2nd-level" {
display_name = "Icinga 2nd Level", display_name = "Icinga 2nd Level"
enable_notifications = true, enable_notifications = true
macros = { macros = {
"mobile" = "+49123456781" "mobile" = "+49123456781"
@ -160,8 +160,8 @@ notifications between start and end time.
} }
object User "icinga-oncall-1st-level" { object User "icinga-oncall-1st-level" {
display_name = "Icinga 1st Level", display_name = "Icinga 1st Level"
enable_notifications = true, enable_notifications = true
macros.mobile = "+49123456782" macros.mobile = "+49123456782"
} }
@ -196,31 +196,31 @@ the `escalation-sms-1st-level` user will be escalated `1h` after the initial pro
notified, but only for one hour (`2h` as `end` key for the `times` dictionary). notified, but only for one hour (`2h` as `end` key for the `times` dictionary).
apply Notification "mail" { apply Notification "mail" {
import "generic-notification", import "generic-notification"
notification_command = "mail-notification", notification_command = "mail-notification"
users = [ "icingaadmin" ], users = [ "icingaadmin" ]
assign where service.short_name == "ping4" assign where service.short_name == "ping4"
} }
apply Notification "escalation-sms-2nd-level" { apply Notification "escalation-sms-2nd-level" {
import "generic-notification", import "generic-notification"
notification_command = "sms-notification", notification_command = "sms-notification"
users = [ "icinga-oncall-2nd-level" ], users = [ "icinga-oncall-2nd-level" ]
times = { times = {
begin = 30m, begin = 30m
end = 1h end = 1h
} }
} }
apply Notification "escalation-sms-1st-level" { apply Notification "escalation-sms-1st-level" {
import "generic-notification", import "generic-notification"
notification_command = "sms-notification", notification_command = "sms-notification"
users = [ "icinga-oncall-1st-level" ], users = [ "icinga-oncall-1st-level" ]
times = { times = {
begin = 1h, begin = 1h
end = 2h end = 2h
} }
} }
@ -241,9 +241,9 @@ in the first 15 minutes. Leave out the `end` key - if not set, Icinga 2 will not
end time for this notification. end time for this notification.
apply Notification "mail" { apply Notification "mail" {
import "generic-notification", import "generic-notification"
notification_command = "mail-notification", notification_command = "mail-notification"
users = [ "icingaadmin" ], users = [ "icingaadmin" ]
times.begin = 15m // delay first notification times.begin = 15m // delay first notification
} }
@ -265,10 +265,10 @@ Available state and type filters for notifications are:
template Notification "generic-notification" { template Notification "generic-notification" {
notification_state_filter = StateFilterWarning | notification_state_filter = (StateFilterWarning |
StateFilterCritical | StateFilterCritical |
StateFilterUnknown, StateFilterUnknown)
notification_type_filter = NotificationFilterProblem | notification_type_filter = (NotificationFilterProblem |
NotificationFilterAcknowledgement | NotificationFilterAcknowledgement |
NotificationFilterRecovery | NotificationFilterRecovery |
NotificationFilterCustom | NotificationFilterCustom |
@ -276,7 +276,7 @@ Available state and type filters for notifications are:
NotificationFilterFlappingEnd | NotificationFilterFlappingEnd |
NotificationFilterDowntimeStart | NotificationFilterDowntimeStart |
NotificationFilterDowntimeEnd | NotificationFilterDowntimeEnd |
NotificationFilterDowntimeRemoved, NotificationFilterDowntimeRemoved)
} }
> **Note** > **Note**

View File

@ -8,21 +8,21 @@ your hosts you can use templates to avoid having to copy & paste parts of your
configuration: configuration:
template Service "generic-service" { template Service "generic-service" {
max_check_attempts = 3, max_check_attempts = 3
check_interval = 5m, check_interval = 5m
retry_interval = 1m, retry_interval = 1m
enable_perfdata = true enable_perfdata = true
} }
apply Service "ping4" { apply Service "ping4" {
import "generic-service", import "generic-service"
check_command = "ping4", check_command = "ping4"
assign where host.macros.address assign where host.macros.address
} }
apply Service "ping6" { apply Service "ping6" {
import "generic-service", import "generic-service"
check_command = "ping6", check_command = "ping6"
assign where host.macros.address6 assign where host.macros.address6
} }

View File

@ -16,16 +16,13 @@ alert dashboard, first create the hostgroup:
Then add your hosts to this hostgroup Then add your hosts to this hostgroup
object Host "mssql-srv1" { object Host "mssql-srv1" {
groups = [ "windows" ], groups = [ "windows" ]
macros = { macros.mssql_port = 1433
"mssql_port" = 1433
}
} }
object Host "mssql-srv2" { object Host "mssql-srv2" {
groups = [ "windows" ], groups = [ "windows" ]
macros = { macros.mssql_port = 1433
"mssql_port" = 1433
} }
} }
@ -36,7 +33,7 @@ Then add your hosts to this hostgroup
> You can also define multiple group memberships. > You can also define multiple group memberships.
template Host "windows-mssql-template" { template Host "windows-mssql-template" {
groups = [ "windows" ], groups = [ "windows" ]
macros.mssql_port = 1433 macros.mssql_port = 1433
} }
} }
@ -61,19 +58,19 @@ the user groups are associated as attributes in `Notification` objects.
} }
object User "win-mssql-noc" { object User "win-mssql-noc" {
import "generic-windows-mssql-users", import "generic-windows-mssql-users"
macros.email = "noc@example.com" macros.email = "noc@example.com"
} }
object User "win-mssql-ops" { object User "win-mssql-ops" {
import "generic-windows-mssql-users", import "generic-windows-mssql-users"
macros.email = "ops@example.com" macros.email = "ops@example.com"
} }
apply Service "ping4" { apply Service "ping4" {
import "generic-notification", import "generic-notification"
notification_command = "mail-notification", notification_command = "mail-notification"
user_groups = [ "windows-admins" ], user_groups = [ "windows-admins" ]
} }

View File

@ -32,17 +32,17 @@ on your configuration objects Icinga 2 assumes `24x7` as time period
as shown below. as shown below.
object TimePeriod "24x7" { object TimePeriod "24x7" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 24x7 TimePeriod", display_name = "Icinga 2 24x7 TimePeriod"
ranges = { ranges = {
"monday" = "00:00-24:00", "monday" = "00:00-24:00"
"tuesday" = "00:00-24:00", "tuesday" = "00:00-24:00"
"wednesday" = "00:00-24:00", "wednesday" = "00:00-24:00"
"thursday" = "00:00-24:00", "thursday" = "00:00-24:00"
"friday" = "00:00-24:00", "friday" = "00:00-24:00"
"saturday" = "00:00-24:00", "saturday" = "00:00-24:00"
"sunday" = "00:00-24:00", "sunday" = "00:00-24:00"
} }
} }
@ -51,15 +51,15 @@ create a new timeperiod named `workhours` defining a work day with
09:00 to 17:00. 09:00 to 17:00.
object TimePeriod "workhours" { object TimePeriod "workhours" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 8x5 TimePeriod", display_name = "Icinga 2 8x5 TimePeriod"
ranges = { ranges = {
"monday" = "09:00-17:00", "monday" = "09:00-17:00"
"tuesday" = "09:00-17:00", "tuesday" = "09:00-17:00"
"wednesday" = "09:00-17:00", "wednesday" = "09:00-17:00"
"thursday" = "09:00-17:00", "thursday" = "09:00-17:00"
"friday" = "09:00-17:00", "friday" = "09:00-17:00"
} }
} }
@ -67,10 +67,10 @@ Assign the timeperiod as `notification_period` to the `Notification`
object then. object then.
apply Notification "mail" { apply Notification "mail" {
import "generic-notification", import "generic-notification"
notification_command = "mail-notification", notification_command = "mail-notification"
users = [ "icingaadmin" ], users = [ "icingaadmin" ]
notification_period = "workhours" notification_period = "workhours"
assign where host.name == "localhost" assign where host.name == "localhost"

View File

@ -24,7 +24,7 @@ the current performance files for their backend updates.
Therefore the Icinga 2 `PerfdataWriter` object allows you to define Therefore the Icinga 2 `PerfdataWriter` object allows you to define
the output template format backed with Icinga 2 runtime macros. the output template format backed with Icinga 2 runtime macros.
format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$", format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$"
The default template is already provided with the Icinga 2 feature configuration The default template is already provided with the Icinga 2 feature configuration
which can be enabled using which can be enabled using

View File

@ -26,11 +26,11 @@ overrides the `oid` macro. A service is created for all hosts which
have the `community` macro set. have the `community` macro set.
apply Service "uptime" { apply Service "uptime" {
import "generic-service", import "generic-service"
templates = [ "generic-service" ], templates = [ "generic-service" ]
check_command = "snmp", check_command = "snmp"
macros.oid = "1.3.6.1.2.1.1.3.0", macros.oid = "1.3.6.1.2.1.1.3.0"
assign where host.macros.community assign where host.macros.community
} }
@ -41,7 +41,7 @@ Calling a plugin using the SSH protocol to execute a plugin on the remote server
its return code and output. `check_by_ssh` is available in the [Monitoring Plugins package](#setting-up-check-plugins). 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" { object CheckCommand "check_by_ssh_swap" {
import "plugin-check-command", import "plugin-check-command"
command = [ PluginDir + "/check_by_ssh", command = [ PluginDir + "/check_by_ssh",
"-l", "remoteuser", "-l", "remoteuser",
@ -51,10 +51,10 @@ its return code and output. `check_by_ssh` is available in the [Monitoring Plugi
} }
apply Service "swap" { apply Service "swap" {
import "generic-service", import "generic-service"
check_command = "check_by_ssh_swap", check_command = "check_by_ssh_swap"
macros = { macros = {
"warn" = "50%", "warn" = "50%"
"crit" = "75%" "crit" = "75%"
} }
@ -76,19 +76,20 @@ remote client.
Example: Example:
object CheckCommand "check_nrpe" { object CheckCommand "check_nrpe" {
import "plugin-check-command", import "plugin-check-command"
command = [ PluginDir + "/check_nrpe", command = [
"-H", "$address$", PluginDir + "/check_nrpe",
"-c", "$remote_nrpe_command$", "-H", "$address$",
], "-c", "$remote_nrpe_command$",
]
} }
apply Service "users" { apply Service "users" {
import "generic-service", import "generic-service"
check_command = "check_nrpe", check_command = "check_nrpe"
macros.remote_nrpe_command = "check_users", macros.remote_nrpe_command = "check_users"
assign where host.name == "remote-nrpe-host" assign where host.name == "remote-nrpe-host"
} }
@ -112,32 +113,35 @@ the required output and performance counters.
Example: Example:
object CheckCommand "check_nscp" { object CheckCommand "check_nscp" {
import "plugin-check-command", import "plugin-check-command"
command = [
PluginDir + "/check_nt",
"-H", "$address$",
"-p", "$port$",
"-v", "$remote_nscp_command$",
"-l", "$partition$",
"-w", "$warn$",
"-c", "$crit$",
"-s", "$pass$"
]
command = [ PluginDir + "/check_nt",
"-H", "$address$",
"-p", "$port$",
"-v", "$remote_nscp_command$",
"-l", "$partition$",
"-w", "$warn$",
"-c", "$crit$",
"-s", "$pass$"
],
macros = { macros = {
"port" = "12489", "port" = "12489"
"pass" = "supersecret" "pass" = "supersecret"
} }
} }
apply Service "users" { apply Service "users" {
import "generic-service", import "generic-service"
check_command = "check_nscp", check_command = "check_nscp"
macros += { macros += {
"remote_nscp_command" = "USEDDISKSPACE", remote_nscp_command = "USEDDISKSPACE"
"partition" = "c", partition = "c"
"warn" = "70", warn = "70"
"crit" = "80" crit = "80"
} }
assign where host.name == "remote-windows-host" assign where host.name == "remote-windows-host"

View File

@ -6,17 +6,28 @@ Icinga 2 features an object-based configuration format. You can define new
objects using the `object` keyword: objects using the `object` keyword:
object Host "host1.example.org" { object Host "host1.example.org" {
display_name = "host1", display_name = "host1"
macros = { macros = {
address = "192.168.0.1" address = "192.168.0.1"
address6 = "::1"
} }
} }
> **Note** In general you need to write each statement on a new line. Expressions started
> with `{`, `(` and `[` extend until the matching closing brace and can be broken
> The Icinga 2 configuration format is agnostic to white space characters and up into multiple lines.
> new-lines.
Alternatively you can write multiple statements in a single line by separating
them with a semi-colon:
object Host "host1.example.org" {
display_name = "host1"
macros = { address = "192.168.0.1"; address6 = "::1"; }
}
The semi-colon after the last element (i.e. `address6`) may be omitted.
> **Note** > **Note**
> >
@ -116,7 +127,7 @@ comma. The comma after the last key-value pair is optional.
Example: Example:
{ {
address = "192.168.0.1", address = "192.168.0.1"
port = 443 port = 443
} }
@ -232,14 +243,14 @@ In this example a has the value 7 after both instructions are executed.
The += operator is a shortcut. The following expression: The += operator is a shortcut. The following expression:
{ {
a = [ "hello" ], a = [ "hello" ]
a += [ "world" ] a += [ "world" ]
} }
is equivalent to: is equivalent to:
{ {
a = [ "hello" ], a = [ "hello" ]
a = a + [ "world" ] a = a + [ "world" ]
} }
@ -248,14 +259,14 @@ is equivalent to:
The -= operator is a shortcut. The following expression: The -= operator is a shortcut. The following expression:
{ {
a = 10, a = 10
a -= 5 a -= 5
} }
is equivalent to: is equivalent to:
{ {
a = 10, a = 10
a = a - 5 a = a - 5
} }
@ -264,14 +275,14 @@ is equivalent to:
The *= operator is a shortcut. The following expression: The *= operator is a shortcut. The following expression:
{ {
a = 60, a = 60
a *= 5 a *= 5
} }
is equivalent to: is equivalent to:
{ {
a = 60, a = 60
a = a * 5 a = a * 5
} }
@ -280,14 +291,14 @@ is equivalent to:
The /= operator is a shortcut. The following expression: The /= operator is a shortcut. The following expression:
{ {
a = 300, a = 300
a /= 5 a /= 5
} }
is equivalent to: is equivalent to:
{ {
a = 300, a = 300
a = a / 5 a = a / 5
} }
@ -326,15 +337,15 @@ Example:
} }
template Host "test-host" { template Host "test-host" {
import "default-host", import "default-host"
macros.color = "blue" macros.color = "blue"
} }
object Host "localhost" { object Host "localhost" {
import "test-host", import "test-host"
macros.address = "127.0.0.1", macros.address = "127.0.0.1"
macros.address6 = "::1" macros.address6 = "::1"
} }
@ -366,9 +377,9 @@ The `apply` keyword can be used to create new objects which are associated with
another group of objects. another group of objects.
apply Service "ping" { apply Service "ping" {
import "generic-service", import "generic-service"
check_command = "ping4", check_command = "ping4"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
@ -421,7 +432,7 @@ Example:
This is a comment. This is a comment.
*/ */
object Host "localhost" { object Host "localhost" {
check_interval = 30, // this is also a comment. check_interval = 30 // this is also a comment.
retry_interval = 15 retry_interval = 15
} }
@ -460,7 +471,7 @@ files in a directory which match a certain pattern.
Example: Example:
include_recursive "conf.d" "*.conf" include_recursive "conf.d", "*.conf"
include_recursive "templates" include_recursive "templates"
The first parameter specifies the directory from which files should be The first parameter specifies the directory from which files should be

View File

@ -13,9 +13,9 @@ A host.
Example: Example:
object Host "localhost" { object Host "localhost" {
display_name = "The best host there is", display_name = "The best host there is"
groups = [ "all-hosts" ], groups = [ "all-hosts" ]
check = "ping" check = "ping"
} }
@ -36,7 +36,7 @@ A group of hosts.
Example: Example:
object HostGroup "my-hosts" { object HostGroup "my-hosts" {
display_name = "My hosts", display_name = "My hosts"
} }
Attributes: Attributes:
@ -59,22 +59,22 @@ by Icinga 2.
Example: Example:
object Service "localhost-uptime" { object Service "localhost-uptime" {
host = "localhost", host = "localhost"
short_name = "uptime", short_name = "uptime"
display_name = "localhost Uptime", display_name = "localhost Uptime"
check_command = "check_snmp", check_command = "check_snmp"
macros = { macros = {
community = "public", community = "public"
oid = "DISMAN-EVENT-MIB::sysUpTimeInstance" oid = "DISMAN-EVENT-MIB::sysUpTimeInstance"
} }
check_interval = 60s, check_interval = 60s
retry_interval = 15s, retry_interval = 15s
groups = [ "all-services", "snmp" ], groups = [ "all-services", "snmp" ]
} }
Attributes: Attributes:
@ -110,7 +110,7 @@ A group of services.
Example: Example:
object ServiceGroup "snmp" { object ServiceGroup "snmp" {
display_name = "SNMP services", display_name = "SNMP services"
} }
Attributes: Attributes:
@ -133,10 +133,10 @@ of service state changes and other events.
Example: Example:
object Notification "localhost-ping-notification" { object Notification "localhost-ping-notification" {
host = "localhost", host = "localhost"
service = "ping4", service = "ping4"
notification_command = "mail-notification", notification_command = "mail-notification"
users = [ "user1", "user2" ] users = [ "user1", "user2" ]
} }
@ -191,13 +191,13 @@ Dependency objects are used to specify dependencies between hosts and services.
Example: Example:
object Dependency "webserver-internet" { object Dependency "webserver-internet" {
child_host = "webserver", child_host = "webserver"
child_service = "ping4", child_service = "ping4"
parent_host = "internet", parent_host = "internet"
parent_service = "ping4", parent_service = "ping4"
state_filter = StateFilterOK, state_filter = StateFilterOK
disable_checks = true disable_checks = true
} }
@ -229,26 +229,27 @@ A user.
Example: Example:
object User "icingaadmin" { object User "icingaadmin" {
display_name = "Icinga 2 Admin", display_name = "Icinga 2 Admin"
groups = [ "icingaadmins" ], groups = [ "icingaadmins" ]
enable_notifications = 1, enable_notifications = 1
notification_period = "24x7", notification_period = "24x7"
notification_state_filter = StateFilterOK | notification_state_filter = (StateFilterOK |
StateFilterWarning | StateFilterWarning |
StateFilterCritical | StateFilterCritical |
StateFilterUnknown, StateFilterUnknown)
notification_type_filter = NotificationFilterProblem | notification_type_filter = (NotificationFilterProblem |
NotificationFilterRecovery, NotificationFilterRecovery)
macros = { macros = {
"name" = "Icinga 2 Admin", name = "Icinga 2 Admin"
"email" = "icinga@localhost", email = "icinga@localhost"
"pager" = "icingaadmin@localhost.localdomain" pager = "icingaadmin@localhost.localdomain"
}, }
custom = { custom = {
notes = "This is the Icinga 2 Admin account.", notes = "This is the Icinga 2 Admin account."
} }
} }
@ -311,17 +312,18 @@ when notifications should be sent out.
Example: Example:
object TimePeriod "24x7" { object TimePeriod "24x7" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 24x7 TimePeriod"
display_name = "Icinga 2 24x7 TimePeriod",
ranges = { ranges = {
"monday" = "00:00-24:00", monday = "00:00-24:00"
"tuesday" = "00:00-24:00", tuesday = "00:00-24:00"
"wednesday" = "00:00-24:00", wednesday = "00:00-24:00"
"thursday" = "00:00-24:00", thursday = "00:00-24:00"
"friday" = "00:00-24:00", friday = "00:00-24:00"
"saturday" = "00:00-24:00", saturday = "00:00-24:00"
"sunday" = "00:00-24:00", sunday = "00:00-24:00"
} }
} }
@ -349,14 +351,14 @@ ScheduledDowntime objects can be used to set up recurring downtimes for services
Example: Example:
object ScheduledDowntime "some-downtime" { object ScheduledDowntime "some-downtime" {
host = "localhost", host = "localhost"
service = "ping4", service = "ping4"
author = "icingaadmin", author = "icingaadmin"
comment = "Some comment", comment = "Some comment"
fixed = false, fixed = false
duration = 30m, duration = 30m
ranges = { ranges = {
"sunday" = "02:00-03:00" "sunday" = "02:00-03:00"
@ -382,7 +384,7 @@ Specifies Icinga 2 logging to a file.
Example: Example:
object FileLogger "my-debug-file" { object FileLogger "my-debug-file" {
severity = "debug", severity = "debug"
path = "/var/log/icinga2/icinga2-debug.log" path = "/var/log/icinga2/icinga2-debug.log"
} }
@ -417,18 +419,18 @@ defined here.
Example: Example:
object CheckCommand "check_snmp" { object CheckCommand "check_snmp" {
import "plugin-check-command", import "plugin-check-command"
command = [ command = [
PluginDir + "/check_snmp", PluginDir + "/check_snmp",
"-H", "$address$", "-H", "$address$",
"-C", "$community$", "-C", "$community$",
"-o", "$oid$" "-o", "$oid$"
], ]
macros = { macros = {
address = "127.0.0.1", address = "127.0.0.1"
community = "public", community = "public"
} }
} }
@ -450,11 +452,11 @@ A notification command definition.
Example: Example:
object NotificationCommand "mail-service-notification" { object NotificationCommand "mail-service-notification" {
import "plugin-notification-command", import "plugin-notification-command"
command = [ command = [
IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh"
], ]
export_macros = [ export_macros = [
"NOTIFICATIONTYPE", "NOTIFICATIONTYPE",
@ -494,9 +496,9 @@ An event command definition.
Example: Example:
object EventCommand "restart-httpd-event" { object EventCommand "restart-httpd-event" {
import "plugin-event-command", import "plugin-event-command"
command = "/opt/bin/restart-httpd.sh", command = "/opt/bin/restart-httpd.sh"
} }
@ -521,11 +523,11 @@ Example:
library "perfdata" library "perfdata"
object PerfdataWriter "pnp" { object PerfdataWriter "pnp" {
perfdata_path = "/var/spool/icinga2/perfdata/service-perfdata", perfdata_path = "/var/spool/icinga2/perfdata/service-perfdata"
format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$", format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$"
rotation_interval = 15s, rotation_interval = 15s
} }
Attributes: Attributes:
@ -552,7 +554,7 @@ Example:
library "perfdata" library "perfdata"
object GraphiteWriter "graphite" { object GraphiteWriter "graphite" {
host = "127.0.0.1", host = "127.0.0.1"
port = 2003 port = 2003
} }
@ -572,19 +574,19 @@ Example:
library "db_ido_mysql" library "db_ido_mysql"
object IdoMysqlConnection "mysql-ido" { object IdoMysqlConnection "mysql-ido" {
host = "127.0.0.1", host = "127.0.0.1"
port = 3306, port = 3306
user = "icinga", user = "icinga"
password = "icinga", password = "icinga"
database = "icinga", database = "icinga"
table_prefix = "icinga_", table_prefix = "icinga_"
instance_name = "icinga2", instance_name = "icinga2"
instance_description = "icinga2 dev instance", instance_description = "icinga2 dev instance"
cleanup = { cleanup = {
downtimehistory_age = 48h, downtimehistory_age = 48h
logentries_age = 31d, logentries_age = 31d
}, }
categories = DbCatConfig | DbCatState categories = DbCatConfig | DbCatState
} }
@ -656,19 +658,19 @@ Example:
library "db_ido_pgsql" library "db_ido_pgsql"
object IdoMysqlConnection "pgsql-ido" { object IdoMysqlConnection "pgsql-ido" {
host = "127.0.0.1", host = "127.0.0.1"
port = 5432, port = 5432
user = "icinga", user = "icinga"
password = "icinga", password = "icinga"
database = "icinga", database = "icinga"
table_prefix = "icinga_", table_prefix = "icinga_"
instance_name = "icinga2", instance_name = "icinga2"
instance_description = "icinga2 dev instance", instance_description = "icinga2 dev instance"
cleanup = { cleanup = {
downtimehistory_age = 48h, downtimehistory_age = 48h
logentries_age = 31d, logentries_age = 31d
}, }
categories = DbCatConfig | DbCatState categories = DbCatConfig | DbCatState
} }
@ -742,13 +744,13 @@ Example:
library "livestatus" library "livestatus"
object LivestatusListener "livestatus-tcp" { object LivestatusListener "livestatus-tcp" {
socket_type = "tcp", socket_type = "tcp"
bind_host = "127.0.0.1", bind_host = "127.0.0.1"
bind_port = "6558" bind_port = "6558"
} }
object LivestatusListener "livestatus-unix" { object LivestatusListener "livestatus-unix" {
socket_type = "unix", socket_type = "unix"
socket_path = "/var/run/icinga2/cmd/livestatus" socket_path = "/var/run/icinga2/cmd/livestatus"
} }
@ -775,8 +777,8 @@ Example:
library "compat" library "compat"
object StatusDataWriter "status" { object StatusDataWriter "status" {
status\_path = "/var/cache/icinga2/status.dat", status\_path = "/var/cache/icinga2/status.dat"
objects\_path = "/var/cache/icinga2/objects.path", objects\_path = "/var/cache/icinga2/objects.path"
update\_interval = 30s update\_interval = 30s
} }
@ -815,7 +817,7 @@ Example:
library "compat" library "compat"
object CompatLogger "my-log" { object CompatLogger "my-log" {
log\_dir = "/var/log/icinga2/compat", log\_dir = "/var/log/icinga2/compat"
rotation\_method = "HOURLY" rotation\_method = "HOURLY"
} }
@ -875,7 +877,7 @@ a defined JSON file.
Example: Example:
object IcingaStatusWriter "status" { object IcingaStatusWriter "status" {
status_path = IcingaLocalStateDir + "/cache/icinga2/status.json", status_path = IcingaLocalStateDir + "/cache/icinga2/status.json"
update_interval = 15s update_interval = 15s
} }
@ -897,11 +899,11 @@ Example:
library "cluster" library "cluster"
object ClusterListener "cluster" { object ClusterListener "cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/icinga-node-1.crt", cert_path = "/etc/icinga2/ca/icinga-node-1.crt"
key_path = "/etc/icinga2/ca/icinga-node-1.key", key_path = "/etc/icinga2/ca/icinga-node-1.key"
bind_port = 8888, bind_port = 8888
peers = [ "icinga-node-2" ] peers = [ "icinga-node-2" ]
} }
@ -928,14 +930,14 @@ Example:
library "cluster" library "cluster"
object Endpoint "icinga-c2" { object Endpoint "icinga-c2" {
host = "192.168.5.46", host = "192.168.5.46"
port = 7777, port = 7777
config_files = [ "/etc/icinga2/cluster.d/*" ], config_files = [ "/etc/icinga2/cluster.d/*" ]
config_files_recursive = [ config_files_recursive = [
"/etc/icinga2/cluster2", "/etc/icinga2/cluster2",
{ path = "/etc/icinga2/cluster3", pattern = "*.myconf" } { path = "/etc/icinga2/cluster3"; pattern = "*.myconf" }
] ]
} }
@ -960,7 +962,7 @@ Example:
object Domain "dmz-1" { object Domain "dmz-1" {
acl = { acl = {
node1 = DomainPrivCheckResult, node1 = DomainPrivCheckResult
node2 = DomainPrivReadWrite node2 = DomainPrivReadWrite
} }
} }

View File

@ -74,16 +74,16 @@ recurring downtimes for services.
Example: Example:
apply ScheduledDowntime "backup-downtime" { apply ScheduledDowntime "backup-downtime" {
author = "icingaadmin", author = "icingaadmin"
comment = "Scheduled downtime for backup", comment = "Scheduled downtime for backup"
ranges = { ranges = {
monday = "02:00-03:00", monday = "02:00-03:00"
tuesday = "02:00-03:00", tuesday = "02:00-03:00"
wednesday = "02:00-03:00", wednesday = "02:00-03:00"
thursday = "02:00-03:00", thursday = "02:00-03:00"
friday = "02:00-03:00", friday = "02:00-03:00"
saturday = "02:00-03:00", saturday = "02:00-03:00"
sunday = "02:00-03:00" sunday = "02:00-03:00"
} }

View File

@ -75,11 +75,11 @@ A sample config part can look like this:
library "cluster" library "cluster"
object ClusterListener "cluster" { object ClusterListener "cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/icinga-node-1.crt", cert_path = "/etc/icinga2/ca/icinga-node-1.crt"
key_path = "/etc/icinga2/ca/icinga-node-1.key", key_path = "/etc/icinga2/ca/icinga-node-1.key"
bind_port = 8888, bind_port = 8888
peers = [ "icinga-node-2" ] peers = [ "icinga-node-2" ]
} }
@ -120,8 +120,8 @@ A sample config part can look like this:
*/ */
object Endpoint "icinga-node-1" { object Endpoint "icinga-node-1" {
host = "icinga-node-1.localdomain", host = "icinga-node-1.localdomain"
port = 8888, port = 8888
config_files = ["/etc/icinga2/conf.d/*.conf"] config_files = ["/etc/icinga2/conf.d/*.conf"]
} }
@ -135,8 +135,8 @@ A sample config part for a config receiver endpoint can look like this:
*/ */
object Endpoint "icinga-node-2" { object Endpoint "icinga-node-2" {
host = "icinga-node-2.localdomain", host = "icinga-node-2.localdomain"
port = 8888, port = 8888
accept_config = [ "icinga-node-1" ] accept_config = [ "icinga-node-1" ]
} }
@ -163,7 +163,7 @@ Example:
# vim cluster.conf # vim cluster.conf
object Endpoint "icinga-node-1" { object Endpoint "icinga-node-1" {
host = "icinga-node-1.localdomain", host = "icinga-node-1.localdomain"
port = 8888 port = 8888
} }
@ -171,16 +171,16 @@ The [Endpoint](#objecttype-endpoint) name is further referenced as `peers` attri
[ClusterListener](pbjecttype-clusterlistener) object. [ClusterListener](pbjecttype-clusterlistener) object.
object Endpoint "icinga-node-2" { object Endpoint "icinga-node-2" {
host = "icinga-node-2.localdomain", host = "icinga-node-2.localdomain"
port = 8888 port = 8888
} }
object ClusterListener "cluster" { object ClusterListener "cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/icinga-node-1.crt", cert_path = "/etc/icinga2/ca/icinga-node-1.crt"
key_path = "/etc/icinga2/ca/icinga-node-1.key", key_path = "/etc/icinga2/ca/icinga-node-1.key"
bind_port = 8888, bind_port = 8888
peers = [ "icinga-node-2" ] peers = [ "icinga-node-2" ]
} }
@ -211,9 +211,9 @@ within the cluster, you must define `authorities` as additional service object
attribute. Required Endpoints must be defined as array. attribute. Required Endpoints must be defined as array.
apply Service "dmz-oracledb" { apply Service "dmz-oracledb" {
import "generic-service", import "generic-service"
authorities = [ "icinga-node-1" ], authorities = [ "icinga-node-1" ]
assign where "oracle" in host.groups assign where "oracle" in host.groups
} }
@ -234,11 +234,11 @@ one or more configured nodes are not connected.
Example: Example:
apply Service "cluster" { apply Service "cluster" {
import "generic-service", import "generic-service"
check_interval = 1m, check_interval = 1m
check_command = "cluster", check_command = "cluster"
authorities = [ "icinga2a" ], authorities = [ "icinga2a" ]
assign where host.name = "icinga2a" assign where host.name = "icinga2a"
} }
@ -310,20 +310,20 @@ The configuration deployment should look like:
The endpoint configuration on the `nuremberg` node would look like: The endpoint configuration on the `nuremberg` node would look like:
object Endpoint "nuremberg" { object Endpoint "nuremberg" {
host = "nuremberg.icinga.org", host = "nuremberg.icinga.org"
port = 8888, port = 8888
} }
object Endpoint "berlin" { object Endpoint "berlin" {
host = "berlin.icinga.org", host = "berlin.icinga.org"
port = 8888, port = 8888
config_files_recursive = [ "/etc/icinga2/conf.d/templates", config_files_recursive = [ "/etc/icinga2/conf.d/templates",
"/etc/icinga2/conf.d/germany/berlin" ] "/etc/icinga2/conf.d/germany/berlin" ]
} }
object Endpoint "vienna" { object Endpoint "vienna" {
host = "vienna.icinga.org", host = "vienna.icinga.org"
port = 8888, port = 8888
config_files_recursive = [ "/etc/icinga2/conf.d/templates", config_files_recursive = [ "/etc/icinga2/conf.d/templates",
"/etc/icinga2/conf.d/austria/vienna" ] "/etc/icinga2/conf.d/austria/vienna" ]
} }
@ -335,13 +335,13 @@ node must include the received configuration by the cluster functionality.
Example for the configuration on the `berlin` node: Example for the configuration on the `berlin` node:
object Endpoint "nuremberg" { object Endpoint "nuremberg" {
host = "nuremberg.icinga.org", host = "nuremberg.icinga.org"
port = 8888, port = 8888
} }
object Endpoint "berlin" { object Endpoint "berlin" {
host = "berlin.icinga.org", host = "berlin.icinga.org"
port = 8888, port = 8888
accept_config = [ "nuremberg" ] accept_config = [ "nuremberg" ]
} }
@ -355,10 +355,10 @@ Example for `berlin` node connecting to central `nuremberg` node:
library "cluster" library "cluster"
object ClusterListener "berlin-cluster" { object ClusterListener "berlin-cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/berlin.crt", cert_path = "/etc/icinga2/ca/berlin.crt"
key_path = "/etc/icinga2/ca/berlin.key", key_path = "/etc/icinga2/ca/berlin.key"
bind_port = 8888, bind_port = 8888
peers = [ "nuremberg" ] peers = [ "nuremberg" ]
} }
@ -367,10 +367,10 @@ Example for central `nuremberg` node connecting to remote nodes:
library "cluster" library "cluster"
object ClusterListener "nuremberg-cluster" { object ClusterListener "nuremberg-cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/nuremberg.crt", cert_path = "/etc/icinga2/ca/nuremberg.crt"
key_path = "/etc/icinga2/ca/nuremberg.key", key_path = "/etc/icinga2/ca/nuremberg.key"
bind_port = 8888, bind_port = 8888
peers = [ "berlin", "vienna" ] peers = [ "berlin", "vienna" ]
} }
@ -404,53 +404,53 @@ just pin them using the [authorities](#assign-services-to-cluster-nodes) attribu
Example on the `central` node: Example on the `central` node:
object Endpoint "central" { object Endpoint "central" {
host = "central.icinga.org", host = "central.icinga.org"
port = 8888, port = 8888
} }
object Endpoint "checker1" { object Endpoint "checker1" {
host = "checker1.icinga.org", host = "checker1.icinga.org"
port = 8888, port = 8888
config_files_recursive = [ "/etc/icinga2/conf.d" ] config_files_recursive = [ "/etc/icinga2/conf.d" ]
} }
object Endpoint "checker2" { object Endpoint "checker2" {
host = "checker2.icinga.org", host = "checker2.icinga.org"
port = 8888, port = 8888
config_files_recursive = [ "/etc/icinga2/conf.d" ] config_files_recursive = [ "/etc/icinga2/conf.d" ]
} }
object ClusterListener "central-cluster" { object ClusterListener "central-cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/central.crt", cert_path = "/etc/icinga2/ca/central.crt"
key_path = "/etc/icinga2/ca/central.key", key_path = "/etc/icinga2/ca/central.key"
bind_port = 8888, bind_port = 8888
peers = [ "checker1", "checker2" ] peers = [ "checker1", "checker2" ]
} }
Example on `checker1` node: Example on `checker1` node:
object Endpoint "central" { object Endpoint "central" {
host = "central.icinga.org", host = "central.icinga.org"
port = 8888, port = 8888
} }
object Endpoint "checker1" { object Endpoint "checker1" {
host = "checker1.icinga.org", host = "checker1.icinga.org"
port = 8888, port = 8888
accept_config = [ "central" ] accept_config = [ "central" ]
} }
object Endpoint "checker2" { object Endpoint "checker2" {
host = "checker2.icinga.org", host = "checker2.icinga.org"
port = 8888, port = 8888
accept_config = [ "central" ] accept_config = [ "central" ]
} }
object ClusterListener "checker1-cluster" { object ClusterListener "checker1-cluster" {
ca_path = "/etc/icinga2/ca/ca.crt", ca_path = "/etc/icinga2/ca/ca.crt"
cert_path = "/etc/icinga2/ca/checker1.crt", cert_path = "/etc/icinga2/ca/checker1.crt"
key_path = "/etc/icinga2/ca/checker1.key", key_path = "/etc/icinga2/ca/checker1.key"
bind_port = 8888 bind_port = 8888
} }

View File

@ -16,18 +16,18 @@ a different state history. `icinga-node-dmz-2` still receives all cluster messag
from the `icinga-node-dmz-1` endpoint. from the `icinga-node-dmz-1` endpoint.
object Host "dmz-host1" { object Host "dmz-host1" {
import "generic-host", import "generic-host"
services["dmz-oracledb"] = { services["dmz-oracledb"] = {
templates = [ "generic-service" ], templates = [ "generic-service" ]
domains = [ "dmz-db" ], domains = [ "dmz-db" ]
authorities = [ "icinga-node-dmz-1", "icinga-node-dmz-2"], authorities = [ "icinga-node-dmz-1", "icinga-node-dmz-2"]
} }
} }
object Domain "dmz-db" { object Domain "dmz-db" {
acl = { acl = {
icinga-node-dmz-1 = DomainPrivReadOnly, icinga-node-dmz-1 = DomainPrivReadOnly
icinga-node-dmz-2 = DomainPrivReadWrite icinga-node-dmz-2 = DomainPrivReadWrite
} }
} }

View File

@ -25,11 +25,11 @@ be suppressed. This is achieved by setting the `disable_checks` attribute to `tr
} }
object Host "google-dns" { object Host "google-dns" {
macros.address = "8.8.8.8", macros.address = "8.8.8.8"
} }
apply Service "ping4" { apply Service "ping4" {
import "generic-service", import "generic-service"
check_command = "ping4" check_command = "ping4"
@ -37,7 +37,7 @@ be suppressed. This is achieved by setting the `disable_checks` attribute to `tr
} }
apply Dependency "internet" { apply Dependency "internet" {
parent_host = "dsl-router", parent_host = "dsl-router"
disable_checks = true disable_checks = true
assign where host.name != "dsl-router" assign where host.name != "dsl-router"

View File

@ -16,10 +16,10 @@ the Icinga daemon at startup.
Icinga 2 supports objects and (global) variables, but does not make a difference Icinga 2 supports objects and (global) variables, but does not make a difference
if it's the main configuration file, or any included file. if it's the main configuration file, or any included file.
set IcingaEnableNotifications = 1, const IcingaEnableNotifications = true
object Service "test" { object Service "test" {
enable_notifications = 0, enable_notifications = 0
} }
### <a id="differences-1x-2-sample-configuration-itl"></a> Sample Configuration and ITL ### <a id="differences-1x-2-sample-configuration-itl"></a> Sample Configuration and ITL
@ -132,8 +132,8 @@ Icinga 2 uses the keyword `import` with template names in double quotes.
} }
object Service "testservice" { object Service "testservice" {
import "tmpl1", import "tmpl1"
import "tmpl2", import "tmpl2"
import "tmpl3" import "tmpl3"
} }
@ -147,7 +147,7 @@ requires an equal sign (=) between them.
} }
object Service "test" { object Service "test" {
check_interval = 5m, check_interval = 5m
} }
> **Note** > **Note**
@ -185,13 +185,13 @@ These attributes can be set using the `custom` dictionary in Icinga 2 `Host`
or `Service` objects: or `Service` objects:
custom = { custom = {
notes = "Icinga 2 is the best!", notes = "Icinga 2 is the best!"
notes_url = "http://docs.icinga.org", notes_url = "http://docs.icinga.org"
action_url = "http://dev.icinga.org", action_url = "http://dev.icinga.org"
icon_image = "../../images/logos/Stats2.png", icon_image = "../../images/logos/Stats2.png"
icon_image_alt = "icinga2 alt icon text", icon_image_alt = "icinga2 alt icon text"
"2d_coords" = "1,2", "2d_coords" = "1,2"
statusmap_image = "../../images/logos/icinga.gif", statusmap_image = "../../images/logos/icinga.gif"
} }
External interfaces will recognize and display these attributes accordingly. External interfaces will recognize and display these attributes accordingly.
@ -202,8 +202,8 @@ Icinga 1.x custom variable attributes must be prefixed using an underscore (`_`)
In Icinga 2 these attributes must be added to the `custom`dictionary. In Icinga 2 these attributes must be added to the `custom`dictionary.
custom = { custom = {
DN = "cn=icinga2-dev-host,ou=icinga,ou=main,ou=IcingaConfig,ou=LConf,dc=icinga,dc=org", DN = "cn=icinga2-dev-host,ou=icinga,ou=main,ou=IcingaConfig,ou=LConf,dc=icinga,dc=org"
CV = "my custom cmdb description", CV = "my custom cmdb description"
} }
> **Note** > **Note**
@ -281,15 +281,15 @@ are separated from the command name using an exclamation mark (`!`).
With the freely definable macros in Icinga 2 it looks like this: With the freely definable macros in Icinga 2 it looks like this:
object CheckCommand "ping4" { object CheckCommand "ping4" {
command = PluginDir + "/check_ping -H $HOSTADDRESS$ -w $wrta$,$wpl%$ -c $crta$,$cpl%$", command = PluginDir + "/check_ping -H $HOSTADDRESS$ -w $wrta$,$wpl%$ -c $crta$,$cpl%$"
} }
object Service "PING" { object Service "PING" {
check_command = "ping4", check_command = "ping4"
macros = { macros = {
wrta = 100, wrta = 100
wpl = 20, wpl = 20
crta = 500, crta = 500
cpl = 60 cpl = 60
} }
} }
@ -367,7 +367,7 @@ attribute in the object. The old way of listing all group members in the group's
The preferred way of assigning objects to groups is by using a template: The preferred way of assigning objects to groups is by using a template:
template Host "dev-host" { template Host "dev-host" {
groups += [ "dev-hosts" ], groups += [ "dev-hosts" ]
} }
object Host "web-dev" { object Host "web-dev" {
@ -378,9 +378,9 @@ In order to associate a service with all hosts in a host group the `apply`
keyword can be used: keyword can be used:
apply Service "ping" { apply Service "ping" {
import "generic-service", import "generic-service"
check_command = "ping4", check_command = "ping4"
assign where "group" in host.groups assign where "group" in host.groups
} }

View File

@ -3,16 +3,16 @@
*/ */
template ScheduledDowntime "backup-downtime" { template ScheduledDowntime "backup-downtime" {
author = "icingaadmin", author = "icingaadmin"
comment = "Scheduled downtime for backup", comment = "Scheduled downtime for backup"
ranges = { ranges = {
monday = "02:00-03:00", monday = "02:00-03:00"
tuesday = "02:00-03:00", tuesday = "02:00-03:00"
wednesday = "02:00-03:00", wednesday = "02:00-03:00"
thursday = "02:00-03:00", thursday = "02:00-03:00"
friday = "02:00-03:00", friday = "02:00-03:00"
saturday = "02:00-03:00", saturday = "02:00-03:00"
sunday = "02:00-03:00" sunday = "02:00-03:00"
} }
} }

View File

@ -7,39 +7,39 @@ template Host "generic-host" {
} }
apply Service "ping4" { apply Service "ping4" {
import "generic-service", import "generic-service"
check_command = "ping4", check_command = "ping4"
assign where "generic-host" in host.templates, assign where "generic-host" in host.templates
ignore where !host.macros.address ignore where !host.macros.address
} }
apply Service "ping6" { apply Service "ping6" {
import "generic-service", import "generic-service"
check_command = "ping6", check_command = "ping6"
assign where "generic-host" in host.templates, assign where "generic-host" in host.templates
ignore where !host.macros.address6 ignore where !host.macros.address6
} }
template Host "linux-server" { template Host "linux-server" {
import "generic-host", import "generic-host"
groups += [ "linux-servers" ], groups += [ "linux-servers" ]
} }
template Host "windows-server" { template Host "windows-server" {
import "generic-host", import "generic-host"
groups += [ "windows-servers" ], groups += [ "windows-servers" ]
} }
template Host "generic-printer" { template Host "generic-printer" {
import "generic-host", import "generic-host"
} }
template Host "generic-switch" { template Host "generic-switch" {
import "generic-host", import "generic-host"
} }

View File

@ -3,16 +3,16 @@
* all services should import this template. * all services should import this template.
*/ */
template Service "generic-service" { template Service "generic-service" {
max_check_attempts = 3, max_check_attempts = 3
check_interval = 5m, check_interval = 5m
retry_interval = 1m, retry_interval = 1m
enable_perfdata = true enable_perfdata = true
} }
apply Notification "mail-icingaadmin" { apply Notification "mail-icingaadmin" {
import "mail-notification", import "mail-notification"
user_groups = [ "icingaadmins"], user_groups = [ "icingaadmins"]
assign where "generic-service" in service.templates assign where "generic-service" in service.templates
} }

View File

@ -4,70 +4,70 @@
* files in this directory are included. * files in this directory are included.
*/ */
object Host "localhost" { object Host "localhost" {
import "linux-server", import "linux-server"
macros.address = "127.0.0.1", macros.address = "127.0.0.1"
macros.address6 = "::1" macros.address6 = "::1"
} }
apply Service "icinga" { apply Service "icinga" {
import "generic-service", import "generic-service"
check_command = "icinga", check_command = "icinga"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "http" { apply Service "http" {
import "generic-service", import "generic-service"
check_command = "http_ip", check_command = "http_ip"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "ssh" { apply Service "ssh" {
import "generic-service", import "generic-service"
check_command = "ssh", check_command = "ssh"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "load" { apply Service "load" {
import "generic-service", import "generic-service"
check_command = "load", check_command = "load"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply ScheduledDowntime "backup-downtime" { apply ScheduledDowntime "backup-downtime" {
import "backup-downtime", import "backup-downtime"
assign where service.host == "localhost" && service.short_name == "load" assign where service.host == "localhost" && service.short_name == "load"
} }
apply Service "processes" { apply Service "processes" {
import "generic-service", import "generic-service"
check_command = "processes", check_command = "processes"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "users" { apply Service "users" {
import "generic-service", import "generic-service"
check_command = "users", check_command = "users"
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply Service "disk" { apply Service "disk" {
import "generic-service", import "generic-service"
check_command = "disk", check_command = "disk"
assign where host.name == "localhost" assign where host.name == "localhost"
} }

View File

@ -3,13 +3,13 @@
*/ */
template Notification "mail-notification" { template Notification "mail-notification" {
notification_command = "mail-service-notification", notification_command = "mail-service-notification"
notification_state_filter = StateFilterOK | notification_state_filter = (StateFilterOK |
StateFilterWarning | StateFilterWarning |
StateFilterCritical | StateFilterCritical |
StateFilterUnknown, StateFilterUnknown)
notification_type_filter = NotificationFilterProblem | notification_type_filter = (NotificationFilterProblem |
NotificationFilterAcknowledgement | NotificationFilterAcknowledgement |
NotificationFilterRecovery | NotificationFilterRecovery |
NotificationFilterCustom | NotificationFilterCustom |
@ -17,15 +17,15 @@ template Notification "mail-notification" {
NotificationFilterFlappingEnd | NotificationFilterFlappingEnd |
NotificationFilterDowntimeStart | NotificationFilterDowntimeStart |
NotificationFilterDowntimeEnd | NotificationFilterDowntimeEnd |
NotificationFilterDowntimeRemoved, NotificationFilterDowntimeRemoved)
notification_period = "24x7" notification_period = "24x7"
} }
object NotificationCommand "mail-service-notification" { object NotificationCommand "mail-service-notification" {
import "plugin-notification-command", import "plugin-notification-command"
command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ], command = [ IcingaSysconfDir + "/icinga2/scripts/mail-notification.sh" ]
export_macros = [ export_macros = [
"NOTIFICATIONTYPE", "NOTIFICATIONTYPE",

View File

@ -4,37 +4,37 @@
*/ */
object TimePeriod "24x7" { object TimePeriod "24x7" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 24x7 TimePeriod", display_name = "Icinga 2 24x7 TimePeriod"
ranges = { ranges = {
"monday" = "00:00-24:00", "monday" = "00:00-24:00"
"tuesday" = "00:00-24:00", "tuesday" = "00:00-24:00"
"wednesday" = "00:00-24:00", "wednesday" = "00:00-24:00"
"thursday" = "00:00-24:00", "thursday" = "00:00-24:00"
"friday" = "00:00-24:00", "friday" = "00:00-24:00"
"saturday" = "00:00-24:00", "saturday" = "00:00-24:00"
"sunday" = "00:00-24:00", "sunday" = "00:00-24:00"
} }
} }
object TimePeriod "9to5" { object TimePeriod "9to5" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 9to5 TimePeriod", display_name = "Icinga 2 9to5 TimePeriod"
ranges = { ranges = {
"monday" = "09:00-17:00", "monday" = "09:00-17:00"
"tuesday" = "09:00-17:00", "tuesday" = "09:00-17:00"
"wednesday" = "09:00-17:00", "wednesday" = "09:00-17:00"
"thursday" = "09:00-17:00", "thursday" = "09:00-17:00"
"friday" = "09:00-17:00", "friday" = "09:00-17:00"
} }
} }
object TimePeriod "never" { object TimePeriod "never" {
import "legacy-timeperiod", import "legacy-timeperiod"
display_name = "Icinga 2 never TimePeriod", display_name = "Icinga 2 never TimePeriod"
ranges = { ranges = {
} }
} }

View File

@ -4,19 +4,19 @@
*/ */
object User "icingaadmin" { object User "icingaadmin" {
import "generic-user", import "generic-user"
display_name = "Icinga 2 Admin", display_name = "Icinga 2 Admin"
groups = [ "icingaadmins" ], groups = [ "icingaadmins" ]
macros = { macros = {
"name" = "Icinga 2 Admin", "name" = "Icinga 2 Admin"
"email" = "icinga@localhost", "email" = "icinga@localhost"
"pager" = "icingaadmin@localhost.localdomain" "pager" = "icingaadmin@localhost.localdomain"
}, }
custom = { custom = {
notes = "This is the Icinga 2 Admin account.", notes = "This is the Icinga 2 Admin account."
} }
} }

View File

@ -29,7 +29,7 @@ include "features-enabled/*.conf"
/** /**
* Although in theory you could define all your objects in this file * Although in theory you could define all your objects in this file
* the preferred way is to create separate directories and files in the conf.d * the preferred way is to create separate directories and files in the conf.d
* directory. * directory. Each of these files must have the file extension ".conf".
*/ */
include_recursive "conf.d" "*.conf" include_recursive "conf.d"

View File

@ -45,6 +45,8 @@ do { \
result = yyextra->ReadInput(buf, max_size); \ result = yyextra->ReadInput(buf, max_size); \
} while (0) } while (0)
extern int ignore_newlines;
struct lex_buf { struct lex_buf {
char *buf; char *buf;
size_t size; size_t size;
@ -194,7 +196,7 @@ static char *lb_steal(lex_buf *lb)
\/\/[^\n]* /* ignore C++-style comments */ \/\/[^\n]* /* ignore C++-style comments */
[ \t\r\n] /* ignore whitespace */ [ \t] /* ignore whitespace */
<INITIAL>{ <INITIAL>{
%type return T_TYPE; %type return T_TYPE;
@ -259,6 +261,7 @@ in { yylval->op = &AExpression::OpIn; return T_IN; }
\> { yylval->op = &AExpression::OpLessThan; return T_GREATER_THAN; } \> { yylval->op = &AExpression::OpLessThan; return T_GREATER_THAN; }
} }
[\r\n]+ { if (!ignore_newlines) return T_NEWLINE; }
. return yytext[0]; . return yytext[0];
%% %%

View File

@ -69,6 +69,8 @@ do { \
using namespace icinga; using namespace icinga;
int ignore_newlines = 0;
static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *left, Value *right, DebugInfo& diLeft, DebugInfo& diRight) static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *left, Value *right, DebugInfo& diLeft, DebugInfo& diRight)
{ {
*result = new Value(make_shared<AExpression>(op, static_cast<AExpression::Ptr>(*left), static_cast<AExpression::Ptr>(*right), DebugInfoRange(diLeft, diRight))); *result = new Value(make_shared<AExpression>(op, static_cast<AExpression::Ptr>(*left), static_cast<AExpression::Ptr>(*right), DebugInfoRange(diLeft, diRight)));
@ -97,6 +99,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
Array *array; Array *array;
} }
%token T_NEWLINE "new-line"
%token <text> T_STRING %token <text> T_STRING
%token <text> T_STRING_ANGLE %token <text> T_STRING_ANGLE
%token <num> T_NUMBER %token <num> T_NUMBER
@ -185,6 +188,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
%left T_MULTIPLY T_DIVIDE_OP %left T_MULTIPLY T_DIVIDE_OP
%right '!' '~' %right '!' '~'
%left '.' '(' '[' %left '.' '(' '['
%right ':'
%{ %{
int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
@ -232,7 +236,7 @@ statements: /* empty */
| statements statement | statements statement
; ;
statement: type | include | include_recursive | library | constant statement: type | include | include_recursive | library | constant | newlines
{ } { }
| lterm | lterm
{ {
@ -242,7 +246,7 @@ statement: type | include | include_recursive | library | constant
} }
; ;
include: T_INCLUDE rterm include: T_INCLUDE rterm sep
{ {
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$2); AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$2);
delete $2; delete $2;
@ -263,26 +267,26 @@ include_recursive: T_INCLUDE_RECURSIVE rterm
context->HandleIncludeRecursive(aexpr->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2)); context->HandleIncludeRecursive(aexpr->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2));
} }
| T_INCLUDE_RECURSIVE rterm rterm | T_INCLUDE_RECURSIVE rterm ',' rterm
{ {
AExpression::Ptr aexpr1 = static_cast<AExpression::Ptr>(*$2); AExpression::Ptr aexpr1 = static_cast<AExpression::Ptr>(*$2);
delete $2; delete $2;
AExpression::Ptr aexpr2 = static_cast<AExpression::Ptr>(*$3); AExpression::Ptr aexpr2 = static_cast<AExpression::Ptr>(*$4);
delete $3; delete $4;
context->HandleIncludeRecursive(aexpr1->Evaluate(m_ModuleScope), aexpr2->Evaluate(m_ModuleScope), DebugInfoRange(@1, @3)); context->HandleIncludeRecursive(aexpr1->Evaluate(m_ModuleScope), aexpr2->Evaluate(m_ModuleScope), DebugInfoRange(@1, @4));
} }
; ;
library: T_LIBRARY T_STRING library: T_LIBRARY T_STRING sep
{ {
context->HandleLibrary($2); context->HandleLibrary($2);
free($2); free($2);
} }
; ;
constant: T_CONST identifier T_SET rterm constant: T_CONST identifier T_SET rterm sep
{ {
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$4); AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$4);
delete $4; delete $4;
@ -316,7 +320,7 @@ type: partial_specifier T_TYPE identifier
m_Type->Register(); m_Type->Register();
} }
} }
type_inherits_specifier typerulelist type_inherits_specifier typerulelist sep
{ {
TypeRuleList::Ptr ruleList = *$6; TypeRuleList::Ptr ruleList = *$6;
m_Type->GetRuleList()->AddRules(ruleList); m_Type->GetRuleList()->AddRules(ruleList);
@ -353,11 +357,11 @@ typerulelist: '{'
; ;
typerules: typerules_inner typerules: typerules_inner
| typerules_inner ',' | typerules_inner sep
typerules_inner: /* empty */ typerules_inner: /* empty */
| typerule | typerule
| typerules_inner ',' typerule | typerules_inner sep typerule
; ;
typerule: T_REQUIRE T_STRING typerule: T_REQUIRE T_STRING
@ -418,7 +422,7 @@ object:
{ {
m_Abstract = false; m_Abstract = false;
} }
object_declaration identifier rterm rterm_scope object_declaration identifier rterm rterm_scope sep
{ {
Array::Ptr args = make_shared<Array>(); Array::Ptr args = make_shared<Array>();
@ -486,14 +490,11 @@ lbinary_op: T_SET
} }
; ;
comma_or_semicolon: ',' | ';'
;
lterm_items: lterm_items_inner lterm_items: lterm_items_inner
{ {
$$ = $1; $$ = $1;
} }
| lterm_items_inner comma_or_semicolon | lterm_items_inner sep
{ {
$$ = $1; $$ = $1;
} }
@ -508,7 +509,7 @@ lterm_items_inner: /* empty */
$$->Add(*$1); $$->Add(*$1);
delete $1; delete $1;
} }
| lterm_items_inner comma_or_semicolon lterm | lterm_items_inner sep lterm
{ {
if ($1) if ($1)
$$ = $1; $$ = $1;
@ -624,17 +625,31 @@ rterm_items_inner: /* empty */
} }
| rterm_items_inner ',' rterm | rterm_items_inner ',' rterm
{ {
if ($1) $$ = $1;
$$ = $1;
else
$$ = new Array();
$$->Add(*$3); $$->Add(*$3);
delete $3; delete $3;
} }
| rterm_items_inner ',' newlines rterm
{
$$ = $1;
$$->Add(*$4);
delete $4;
}
; ;
rterm_scope: '{' lterm_items '}' rterm_scope: '{' newlines lterm_items newlines '}'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($3), DebugInfoRange(@1, @5)));
}
| '{' newlines lterm_items '}'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($3), DebugInfoRange(@1, @4)));
}
| '{' lterm_items newlines '}'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @4)));
}
| '{' lterm_items '}'
{ {
$$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @3))); $$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @3)));
} }
@ -686,6 +701,18 @@ rterm: T_STRING
delete $1; delete $1;
free($3); free($3);
} }
| '[' newlines rterm_items newlines ']'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($3), DebugInfoRange(@1, @5)));
}
| '[' rterm_items newlines ']'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @4)));
}
| '[' newlines rterm_items ']'
{
$$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($3), DebugInfoRange(@1, @4)));
}
| '[' rterm_items ']' | '[' rterm_items ']'
{ {
$$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3))); $$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3)));
@ -694,9 +721,14 @@ rterm: T_STRING
{ {
$$ = $1; $$ = $1;
} }
| '(' rterm ')' | '('
{ {
$$ = $2; ignore_newlines++;
}
rterm ')'
{
ignore_newlines--;
$$ = $3;
} }
| rterm T_LOGICAL_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LOGICAL_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); }
| rterm T_LOGICAL_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LOGICAL_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); }
@ -793,4 +825,18 @@ apply:
m_Assign.reset(); m_Assign.reset();
m_Ignore.reset(); m_Ignore.reset();
} }
;
newlines: T_NEWLINE
| newlines T_NEWLINE
;
/* required separator */
sep: ',' newlines
| ','
| ';' newlines
| ';'
| newlines
;
%% %%