I'm tying to build the arguments dictionary dynamically from values in a host dictionary object called hosts.vars.meta and not having a lot of success. I did find the section in the docs that does something similar to what I'm doing (http://docs.icinga.org/icinga2/latest/doc/module/icinga2/chapter/advanced-topics#!/icinga2/latest/doc/module/icinga2/chapter/advanced-topics#use-functions-command-attribute). I've tried a lot of different permutations and can't seem to get this to work. I wonder of some of the issues I am having are related to the fact that host.vars.meta is a dictionary object and not a string. Or is it a case that I am trying to reach too far back. Should I just assign a local vars.meta in the Notification object from the host object?

host.vars.meta looks like:
* vars
    * meta
      * chassis = "CHMODEL_DEVICE"
% = modified in '/etc/icinga2/conf.d/fb/generated/cic1-00-off-wgw1.conf', lines 13:4-13:49
      * entity = "Entity.Value"
% = modified in '/etc/icinga2/conf.d/fb/templates/host.conf', lines 18:4-18:52
      * key = "ODS.Key"
% = modified in '/etc/icinga2/conf.d/fb/templates/host.conf', lines 19:4-19:45
      * os = "ios-xr"
% = modified in '/etc/icinga2/conf.d/fb/generated/cic1-00-off-wgw1.conf', lines 15:4-15:29
      * region = "amer"
% = modified in '/etc/icinga2/conf.d/fb/generated/cic1-00-off-wgw1.conf', lines 9:4-9:36
      * role = "edge-gateway"
% = modified in '/etc/icinga2/conf.d/fb/generated/cic1-00-off-wgw1.conf', lines 11:4-11:43
      * vendor = "network-vendor"
% = modified in '/etc/icinga2/conf.d/fb/generated/cic1-00-off-wgw1.conf', lines 7:4-7:32

And here is the NotificationCommand on my last attempt:
object NotificationCommand "fb-notification-host" {
   import "plugin-notification-command"
   command = [ FBPluginDir + "/icinga2-notify.pl" ]

   env = {
      NOTIFICATIONTYPE = "$notification.type$"
      HOSTALIAS = "$host.display_name$"
      HOSTADDRESS = "$address$"
      HOSTSTATE = "$host.state$"
      LONGDATETIME = "$icinga.short_date_time$"
      CHECKOUTPUT = "$host.output$"
      NOTIFICATIONAUTHORNAME = "$notification.author$"
      NOTIFICATIONCOMMENT = "$notification.comment$"
      USEREMAIL = "$user.email$"
      LEVEL = "$level$"
      }

   var host_meta = {{
         log(LogInformation, "Getting MetaData", encode(host.vars.meta))
         return encode(host.vars.meta)
      }}
   arguments = {
      "--metadata" = this.host_meta
      }
   }

So my last attempt before I gave up I tried to convert the whole dictionary to a JSON string. All I would get from GetOptions in icinga2-notify.pl is an empty string for --metadata.

SIDE NOTE: I couldn't get anything to log anywhere. My guess is that I don't have logging setup correctly. I do have mainlog enabled and the log level is set to information. I might be able to figure this out if I could get logging enabled.

Some of the permutations I've tried:

var host_meta = {{
         for( key => value in host.vars.meta ) {
            arguments["--" + key] = value
            }
      }}

The idea here is to use a function to get at host.vars.meta and manipulate arguments inside that function. I did try just calling a bare function but I couldn't get away with that. Arguments is still empty. I think in this case it is a scope issue. I set arguments inside the function but the scope of Arguments is local to the function. I tried global.arguments but no success.

arguments = {{
      var service_args
      for( key => value in service.vars.meta ) {
         service_args["--" + key] = value
         return service_args
         }

      }}

The idea here is to use a function and set arguments base on the return, returning a Dictionary object. I try to return just the Dictionary object and return using the clone function ie return clone(service_args). Doing that gives me a stack trace ( see below ), but basically its std::bad_cast. I try to return from the function to a temp variable and then assign that to arguments. I get 2 different errors depending on if I use clone or not on the RHS of the assignment. The bad_cast error seems failry obvious. Trying to assign one type to another and it won't let me. Is the function not returning a dictionary object?

var service_meta = {{
      var service_args
      for( key => value in service.vars.meta ) {
         service_args["--" + key] = value
         return service_args
         }

      }}
   arguments = service_meta

gives a std::bad_cast

   var service_meta = {{
      var service_args
      for( key => value in service.vars.meta ) {
         service_args["--" + key] = value
         return service_args
         }

      }}
   arguments = clone(service_meta)

   }


gives critical/config: Error: Invalid field access (for value of type 'NotificationCommand'): 'clone'

At this point I've gone so far down the rabbit hole and can't think straight anymore. Can somebody offer a second opinion or a solution?


critical/config: Error: std::bad_cast
(0) libbase.so: void boost::throw_exception<boost::exception_detail::error_info_injector<std::bad_cast> >(boost::exception_detail::error_info_injector<std::bad_cast> const&) (+0xb8) [0x3a316eec68] (1) libbase.so: _ZNK6icinga5ValuecvN5boost13intrusive_ptrIT_EEINS_10DictionaryEEEv (+0x264) [0x3a316f5924] (2) libicinga.so: icinga::Command::ValidateArguments(icinga::String const&, boost::intrusive_ptr<icinga::Command> const&) (+0x55) [0x7ff8d7bec4e5] (3) libicinga.so: icinga::Value icinga::FunctionWrapperV<icinga::String const&, boost::intrusive_ptr<icinga::Command> const&>(void (*)(icinga::String const&, boost::intrusive_ptr<icinga::Command> const&), std::vector<icinga::Value, std::allocator<icinga::Value> > const&) (+0x77) [0x7ff8d7c7d917] (4) libicinga.so: boost::detail::function::function_obj_invoker1<boost::_bi::bind_t<icinga::Value, icinga::Value (*)(void (*)(icinga::String const&, boost::intrusive_ptr<icinga::Command> const&), std::vector<icinga::Value, std::allocator<icinga::Value> > const&), boost::_bi::list2<boost::_bi::value<void (*)(icinga::String const&, boost::intrusive_ptr<icinga::Command> const&)>, boost::arg<1> > >, icinga::Value, std::vector<icinga::Value, std::allocator<icinga::Value> > const&>::invoke(boost::detail::function::function_buffer&, std::vector<icinga::Value, std::allocator<icinga::Value> > const&) (+0xd) [0x7ff8d7c57f4d] (5) libbase.so: icinga::Function::Invoke(std::vector<icinga::Value, std::allocator<icinga::Value> > const&) (+0x1d) [0x3a316a0a7d] (6) libconfig.so: icinga::ConfigType::ValidateObject(boost::intrusive_ptr<icinga::Object> const&, std::vector<boost::intrusive_ptr<icinga::TypeRuleList>, std::allocator<boost::intrusive_ptr<icinga::TypeRuleList> > > const&, std::vector<icinga::String, std::allocator<icinga::String> >&, icinga::TypeRuleUtilities const*) (+0x42b) [0x3a31e75fbb] (7) libconfig.so: icinga::ConfigType::ValidateItem(icinga::String const&, boost::intrusive_ptr<icinga::Object> const&, icinga::DebugInfo const&, icinga::TypeRuleUtilities const*) (+0x2d9) [0x3a31e786e9] (8) libconfig.so: icinga::ConfigItem::Commit(bool) (+0x9ea) [0x3a31e7932a] (9) libconfig.so: boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<boost::intrusive_ptr<icinga::DynamicObject>, boost::_mfi::mf1<boost::intrusive_ptr<icinga::DynamicObject>, icinga::ConfigItem, bool>, boost::_bi::list2<boost::_bi::value<boost::intrusive_ptr<icinga::ConfigItem> >, boost::_bi::value<bool> > >, void>::invoke(boost::detail::function::function_buffer&) (+0x28) [0x3a31e81618] (10) libbase.so: icinga::WorkQueue::WorkerThreadProc() (+0x25d) [0x3a316b7f6d]
        (11) libboost_thread-mt.so.5: thread_proxy (+0x77) [0x3fd100ad47]
        (12) /lib64/libpthread.so.0() [0x3fccc079d1]
        (13) libc.so.6: clone (+0x6d) [0x3fcc4e88fd]






_______________________________________________
icinga-users mailing list
icinga-users@lists.icinga.org
https://lists.icinga.org/mailman/listinfo/icinga-users

Reply via email to