Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dev.icinga.com #7564] Access object runtime attributes in custom vars & command arguments #2186

Closed
icinga-migration opened this issue Nov 3, 2014 · 27 comments
Labels
area/configuration DSL, parser, compiler, error handling blocker Blocks a release or needs immediate attention enhancement New feature or request
Milestone

Comments

@icinga-migration
Copy link

This issue has been migrated from Redmine: https://dev.icinga.com/issues/7564

Created by rcgreenw on 2014-11-03 20:32:19 +00:00

Assignee: gbeutner
Status: Resolved (closed on 2015-02-11 13:15:03 +00:00)
Target Version: 2.3.0
Last Update: 2016-12-06 10:46:34 +00:00 (in Redmine)


Requirement

Find a possibility similar to Icinga 1.x On-Demand Macros for runtime access to object attributes.

Proposal

https://dev.icinga.org/issues/7564#note-6

Implementation

Original Request

Implement On-Demand Macros, or document if they are already implemented. They are needed for check_cluster.

http://docs.icinga.org/latest/en/macros.html#ondemand

Changesets

2015-01-27 12:40:05 +00:00 by (unknown) fb44744

Implement support for using functions in custom attributes

refs #7564

2015-01-28 07:36:17 +00:00 by (unknown) eb2f2dd

Implement get_object() and get_objects()

fixes #7564

2015-01-28 13:14:48 +00:00 by (unknown) 4ad4c31

Implement the 'macro' function for dynamic custom vars

refs #7564

2015-01-28 13:18:27 +00:00 by (unknown) 235c734

Implement accessor functions for hosts, services, etc.

refs #7564

2015-01-28 14:48:08 +00:00 by (unknown) ea3c3e0

Fix incorrectly resolved macros

refs #7564

2015-01-29 09:09:53 +00:00 by (unknown) 7b4f1e2

Implement support for functions in set_if

refs #7564

2015-01-29 09:30:02 +00:00 by (unknown) dd4a7ab

Update validators for command arguments

refs #7564

2015-01-29 15:52:04 +00:00 by (unknown) c01fb97

Don't escape macros for the macro() function

refs #7564

2015-01-30 08:49:57 +00:00 by (unknown) aeb579d

Implement another syntax for nullary lambdas

refs #7564

2015-02-04 10:23:48 +00:00 by (unknown) e3137a7

Implement support for using functions in custom attributes

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) 290a5c2

Implement get_object() and get_objects()

fixes #7564

2015-02-04 10:23:49 +00:00 by (unknown) d6a01fe

Implement the 'macro' function for dynamic custom vars

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) 4082f57

Implement accessor functions for hosts, services, etc.

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) db70fac

Fix incorrectly resolved macros

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) f191b12

Implement support for functions in set_if

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) eca3e4e

Update validators for command arguments

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) f2f99b1

Don't escape macros for the macro() function

refs #7564

2015-02-04 10:23:49 +00:00 by (unknown) 32cb638

Implement another syntax for nullary lambdas

refs #7564

2015-02-09 07:50:17 +00:00 by (unknown) 97fc5bb

Implement additional attributes for the Host class

refs #7564

2015-02-09 10:04:28 +00:00 by (unknown) 2792933

Build fix for Windows

refs #7564

2015-02-09 11:37:29 +00:00 by (unknown) a8ec777

Make sure all fields in the Field class are initialized

refs #7564

2015-02-09 12:12:28 +00:00 by (unknown) 5a0fbfd

Add documentation for runtime attributes

refs #7564

2015-02-10 09:59:08 +00:00 by (unknown) 2de89fe

Allow funcs in the 'env' dictionary

refs #7564

2015-02-10 14:21:48 +00:00 by (unknown) 0f39750

Add documentation for the object accessor functions

refs #7564

2015-02-11 13:10:21 +00:00 by (unknown) 46f7397

Update documentation

fixes #7564

Relations:

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2014-11-03 20:36:28 +00:00

  • Relates set to 5938

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2014-11-03 20:37:32 +00:00

If you really need 'check_cluster' you'd rather want it implemented as Icinga 2 check task, and that goes into the direction of cloning and combining states like discussed with #5938

@icinga-migration
Copy link
Author

Updated by mfrosch on 2015-01-12 08:17:25 +00:00

  • Category set to Configuration
  • Status changed from New to Assigned
  • Assigned to set to gbeutner
  • Target Version set to 2.3.0

Please evaluate for 2.3

We need to find a proper syntax for Icinga2 macros...

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-01-16 08:39:41 +00:00

Just a quick refresher for the current macro semantics:

Icinga 2 generates a list of macro "resolvers" when looking up macros - for example, for a service check the following ordered resolver list is set up:

("host", )
("service", )
("command", )

$address$ - This checks the resolver objects in the specified order and picks the first "match" (i.e. the first object that either has a custom attribute with this name - or a built-in attribute).

$service.address$ - This uses the "address" attribute from the service object (which fails in this case because Service objects don't have an "address" attribute: A warning is logged and an empty string is used for the macro)

Markus' idea:

$service[http].address$ (1)
$service[host!http].address$ (2)

Users who are familiar with the existing macro semantics would assume that the "address" attribute for the service "http" (on the same host) is used for case 1. In case 2 the "address" attribute for the service "http" on host "host" is used.

My idea:

$host=localhost!address$ (1)
$service=http!address$ (2)
$host=localhostaddress$ (3)

(1) would substitute the "host" macro resolver in the resolver list with the host "localhost". Also, assuming that the service resolver is set and that the substituted host has a service with the same name it will use the new host's service instead (e.g. if service previously referred to the service "http" on host "oldhost" it will now refer to the "http" service on the host "localhost"; if there's no matching service the service resolver is removed).

(2) works similarly to (1) however it substitutes the service resolver with the service "http" on the same host.

(3) replaces the host resolver with the "localhost" host and the service resolver with the service "http" on that host.

Pros:

-This would be fairly extensible (if we care we could also let users override other resolvers, e.g. user, command, etc.).
-The syntax isn't ambiguous (with regards to $service.address$).

Cons:

-The syntax is fairly ugly :P

@icinga-migration
Copy link
Author

Updated by mfrosch on 2015-01-23 09:56:28 +00:00

Ah few thought bringing visible logic, might cause a bit longer macros though:

$service.state$
$service[http].state$
$host[otherhost].service[http].state$

$host.state$
$host[otherhost].state$

$vars.os$
$host[foobar].service[http].vars.os$

$address$
$host[otherhost].address$

Still to review: Group Macros (http://docs.icinga.org/latest/en/macros.html#ondemandgroup)

old: $HOSTSTATEID:hostgroup1:,$ -> 0,2,1,1,0
$hostgroup[hostgroup1].state$
$hostgroup[hostgroup1].state(,)$

Questions:

  • Is there a problem still inheriting vars from a host, when we call it like:

    $host[foobar].service[http].vars.os$

  • Will we ever expect this to work:

    $host[otherhost].service[blubb].address$ -> $host[otherhost].address$

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-24 13:37:51 +00:00

I have been thinking about this issue and the syntax quite a lot in the past months, independent from the proposals already posted.

I generally don't like the approach of parsing macro strings and obfuscating a key value into something which then generates a value. While this is totally reasonable when you just have a string (command line, as Icinga 1.x) it does not really fit into Icinga 2 and its command arguments.

Status Quo

Consider a check_cluster example from Icinga 1.x:

command_line /usr/local/icinga/libexec/check_cluster --service -l $ARG1$ -w $ARG2$ -c $ARG3$ -d $ARG4$ 

check_command check_service_cluster!"Alive"!1!2!$SERVICESTATEID:host1:PING$, $SERVICESTATEID:host2:PING$

Which would be written as the following in Icinga 2:

object CheckCommand "check_cluster" {
  import "plugin-check-command"

  command = [ PluginDir + "/check_cluster" ]

  arguments = {
    "-l" = "$check_cluster_label$"
    "-w" = "$check_cluster_warning$"
    "-c" = "$check_cluster_critical$"
    "-d" = ONDEMAND(host1!PING, service.state_id) + ", " + ONDEMAND(host2!PING, service.state_id)
  }
}

object Service "my-cluster-check" {
  host_name = "localhost"

  check_command = "check_cluster"
  vars.check_cluster_label = "Alive"
  vars.check_cluster_warning = 1
  vars.check_cluster_critical = 2
  //vars.check_cluster_data = 
}

Proposal

Imho there should be a more elegant way to access object's runtime attributes when executing a command.

My idea originates from the newly added functions and expressions in 2.3 whereas it's also possible to access an object (during config parsing stage).

If we imagine, that such expression ONDEMAND would be called

get_runtime("localhost!ping4", "state")

get_runtime(objectname, attributename)

which is not evaluated by the config parser, but actually at runtime when the caller (the CheckCommand execute method) says so. Similar to resolving the macro strings.

Functions are registered globally as far as I know, so accessing them later at runtime would be a reasonable idea. Maybe it's also similar to how the new 'icinga2 console' cli command works.

I'm also going into the "write a function inside the config and execute it at runtime in-memory" direction here. Which obviously comes to mind with the new feature set of 2.3 :-)

Possible Problems

It might be a problem when passing these functions as command arguments (from the host/service), ensuring that the function expression still exists then on command execution. Something like

  vars.check_cluster_data = get_runtime("host1!PING", "state_id") + ", " + get_runtime("host2!PING", "state_id")

  arguments = {
...
    "-d" = "$check_cluster_data$"
  }

Not sure how we could keep this secured, other than allowing a new type for custom attributes (runtime expressions?), which implicitely gets a to_string() function for external interfaces.

I'm not sure how this would work out for group macros - even 1.x does some magic calculation here. Though accessing the runtime "state" of "groups" could just be handled with a special functionality (loop over all members).

Other Proposals

One thing against the other proposals - every syntax addition and exception for the macro processor leads to performance decreasements. Further I don't like the square brackets. That's confusing with the Array syntax already available with icinga2.

Conclusion

Generally speaking "on-demand macros" is the wrong attempt here - imho it's more like "accessing object attributes at event runtime".

We should carefully evaluate which solution fits best. Changing the macro syntax cannot be reverted later on. Neither can the runtime object access.

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-25 07:29:36 +00:00

One more thing during sleep...

Evaluate usage of function

In #8030 we're discussing where to use functions. One use case already found is the "set_if" attribute for command arguments in #6697.

  "-x" = {
     set_if = vmware_conditional_value(host.vars.vmware_type)
  }

That requirement is similar to a function accessing the runtime attributes of other objects, in simple assign cases as command argument value.

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-25 07:30:51 +00:00

  • Relates set to 8030

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-25 07:31:11 +00:00

  • Relates set to 6697

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-26 15:06:37 +00:00

  • Subject changed from Implement On-Demand Macros to Implement dynamic custom vars

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-01-27 09:52:47 +00:00

  • Relates set to 8291

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-01-27 12:44:43 +00:00

TODO:

  • support for set_if
  • documentation (examples)
  • Built-in attributes for Host, Service (i.e. get rid of MacroResolver)

@icinga-migration
Copy link
Author

Updated by Anonymous on 2015-01-28 07:37:00 +00:00

  • Status changed from Assigned to Resolved
  • Done % changed from 0 to 100

Applied in changeset eb2f2dd.

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-28 09:35:09 +00:00

  • Status changed from Resolved to Assigned
  • Done % changed from 100 to 80

@icinga-migration
Copy link
Author

Updated by mwaldmueller on 2015-01-28 14:10:36 +00:00

Here's an example of how On-Demand Macros are actually used with Icinga 1.x:

/some/custom/plugin.sh $SERVICESTATEID::win-disks$ $SERVICESTATEID::svc-nsclient$ $SERVICESTATETYPE::win-disks$ $SERVICEST
ATETYPE::svc-nsclient$ "$SERVICEOUTPUT::win-disks$" "$SERVICEOUTPUT::svc-nsclient$" "$SERVICEDESC::win-disks$" "$SERVICEDESC::svc-nsclient$"

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-01-28 14:33:59 +00:00

  • Subject changed from Implement dynamic custom vars to Access object runtime attributes in custom vars & command arguments
  • Description updated

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-02-02 10:36:27 +00:00

TODO:

  • User-accessible attributes for Host, Service, User, *Command
  • Documentation for user-accessible attributes

@icinga-migration
Copy link
Author

Updated by Anonymous on 2015-02-04 13:05:04 +00:00

  • Status changed from Assigned to Resolved
  • Done % changed from 80 to 100

Applied in changeset 290a5c2.

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-02-04 13:06:05 +00:00

  • Status changed from Resolved to Assigned
  • Done % changed from 100 to 80

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-02-09 09:41:08 +00:00

  • Duplicated set to 8094

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-02-09 12:18:59 +00:00

  • Priority changed from Normal to High

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-02-09 12:37:09 +00:00

  • Description updated

To-do:

  • Support for functions in env

@icinga-migration
Copy link
Author

Updated by gbeutner on 2015-02-10 13:16:10 +00:00

  • Status changed from Assigned to Resolved

This needs more testing. Apart from that I'm done here I guess.

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2015-02-10 15:31:58 +00:00

  • Status changed from Resolved to Assigned

I'd say we need one last thing besides testing - proper usage examples in the current "monitoring basics" documentation. A combination of accessing runtime attributes and getting these objects, but simplified for the reader, next to the runtime macro chapter.

@icinga-migration
Copy link
Author

Updated by Anonymous on 2015-02-11 13:15:03 +00:00

  • Status changed from Assigned to Resolved
  • Done % changed from 80 to 100

Applied in changeset 46f7397.

@icinga-migration
Copy link
Author

Updated by gvenka008c on 2016-12-06 03:38:01 +00:00

@here, i tried the below to check

object CheckCommand "check_cluster" {
import "plugin-check-command"

command = [ "/usr/lib64/nagios/plugins/check_cluster" ]

arguments = {
"-l" = "$check_cluster_label$"
"-w" = "$check_cluster_warning$"
"-c" = "$check_cluster_critical$"
"-d" = "$check_cluster_data$"
}
}

```

#services.conf

```
object Service "my-cluster-check" {
host_name = NodeName
check_command = "check_cluster"
vars.check_cluster_label = "PING"
vars.check_cluster_warning = 1
vars.check_cluster_critical = 2
vars.check_cluster_data = {{ get_service("host1", "PING").state_id + ", " + get_service("host2", "PING").state_id }}
}

When I bring down one of the node, it is still showing OK status. Didn't see any Warning message. Any thoughts how to have check_cluster working in icinga2?

@icinga-migration
Copy link
Author

Updated by mfriedrich on 2016-12-06 10:46:34 +00:00

Please ask on the community channels not some old issue already resolved. https://www.icinga.com/community/get-involved/

@icinga-migration icinga-migration added blocker Blocks a release or needs immediate attention enhancement New feature or request labels Jan 17, 2017
@icinga-migration icinga-migration added the area/configuration DSL, parser, compiler, error handling label Jan 17, 2017
@icinga-migration icinga-migration added this to the 2.3.0 milestone Jan 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/configuration DSL, parser, compiler, error handling blocker Blocks a release or needs immediate attention enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant