Archived community.zenoss.org | full text search
Skip navigation
2807 Views 3 Replies Latest reply: Aug 29, 2013 1:32 AM by Andrey Telepin RSS
daveh Rank: White Belt 9 posts since
Aug 16, 2011
Currently Being Moderated

Oct 27, 2011 5:14 PM

How to get a reference to dmd root from within a modeler plugin

Can anyone tell me how to do the following from within a modeler plugin (i.e. SnmpPlugin) within a Zenpack?  My goal is to find a device in the dmd database with a given attribute (in this case a specific MAC address) and create a zLink to that device on my Overview page.

 

1. Obtain a reference to the dmd root.  The purpose is to be able to get or set properties of other devices in the database.

 

For example, the following code fragment runs fine from within zendmd:

 

    for dev in dmd.Devices.Server.getSubDevices():

    print "Device: %s, IP: %s, MAC: %s at:%s" % (dev.getDeviceName(),dev.getDeviceIpAddress(),dev.getDeviceMacaddress(),dev.getDeviceUrl())

 

But if I try to implement that from within my modeler plugin I get something like:

 

    2011-10-22 19:40:56,740 ERROR zen.ZenModeler: Problem while executing plugin community.snmp.IBMIMMDeviceMap

    2011-10-22 19:40:56,743 ERROR zen.ZenModeler: Traceback (most recent call last):

    File "/opt/zenoss/Products/DataCollector/zenmodeler.py", line 613, in processClient

    datamaps = plugin.process(device, results, self.log)

    File "/opt/zenoss/local/ZenPacks.community.IBMSystemxIMM/ZenPacks/community/IBMSystemxIMM/modeler/plugins/community/snmp/IBMIMMDeviceMap.py", line 128, in process

    for dev in dmd.Devices.Server.getSubDevices():

    NameError: global name 'dmd' is not defined

 

Is there a simple import I'm missing?  Are there any priviledge issues WRT setting vs. getting device parameters?

 

 

2. Obtain a reference to myself (i.e. the current instance of my device Object Class).  The purpose is to be able to get or set properties of the current device, by operating on methods supported by the device.

 

For example, I can do the following from within zendmd, and this will update the zLink on the device's Overview page.

 

    device=find('some.device.by.id')

    zenLink = "Some URL corresponding to the thing I want to create a link to."

    device.manage_changeProperties(zLinks=zenLink)

    commit()

 

But if I try to implement that from within my modeler plugin, using the 'device' variable available from within my modeler class, I get something like:

 

    2011-10-22 18:50:44,057 ERROR zen.ZenModeler: Problem while executing plugin community.snmp.IBMIMMDeviceMap

    2011-10-22 18:50:44,060 ERROR zen.ZenModeler: Traceback (most recent call last):

    File "/opt/zenoss/Products/DataCollector/zenmodeler.py", line 613, in processClient

    datamaps = plugin.process(device, results, self.log)

    File "/opt/zenoss/local/ZenPacks.community.IBMSystemxIMM/ZenPacks/community/IBMSystemxIMM/modeler/plugins/community/snmp/IBMIMMDeviceMap.py", line 138, in process

    device.manage_changeProperties(zLinks=zenLink)

    AttributeError: DeviceProxy instance has no attribute 'manage_changeProperties'

 

Apparently, 'device' here is an instance of class: DeviceProxy, not class: Device.  And the methods directly supported by class DeviceProxy are very limited.

 

Is there some way I can "walk back" from the DeviceProxy class to the Device class from which it was created?  And then operation on my device (i.e myself) directly?

 

NOTE: If I had 1. but not 2. I could still do what need by looking myself up in the database, assuming find() would work within the modeler plugin:

 

    myDevice = find('device.id')

 

I used the following excellent reference to do the above withing zendmd.  But there is no mention of how to do the same from within a running Zenpack:

 

http://www.nickyeates.com/technology/zenoss/dmd

 

Thanks!

  • kkearney ZenossEmployee 118 posts since
    Sep 23, 2008

    The short version is that you don't want to try to access the dmd from in a modeler plugin as only madness lies this way.

     

    If you have a custom device class, add a setXXX method to the device class (along with a getXXX method) and then set the object map with that method name and assign it the thing you want to pass.  Look in DataCollector/ApplyDataMap.py (sp?) for the code that implements the logic if you dare (it's close enough to Halloween for a little fear :) )

     

    If you don't have a custom device class then you'll need to monkey patch in the  setXXX/getXX methods from a new zenpack.  Look for the monkeypatch decorator for examples, and in ZenUtils/Util.py for the source to the monkeypatch decorator.

     

    The daemons talk to zenhub and zenhub has access to the dmd.

     

    Having said all of that, if you just want to set the zLink properties, you may just want to create a new device class from the GUI, and then update the zLink property with a TALES expression to customize it for each device.  I'm assuming that the expression would be very simple, but if for whatever reason it doesn't fit your needs then you'll have to try another method.

     

    Good luck!

     

    kells

  • jcurry ZenossMaster 1,021 posts since
    Apr 15, 2008

    Just to re-iterate Kells's comment -

     

    "you don't want to try to access the dmd from in a modeler plugin as only madness lies this way".

     

    I did this using the following in a modeler plugin in my ZenPack:

     

    # Don't even think of uncommenting these 2 lines - here lies madness!!!!

    #from Products.ZenUtils.ZenScriptBase import ZenScriptBase

    #dmd = ZenScriptBase(connect=True, noopts=True).dmd

     

    Everything appeared to be OK and the ZenPack worked fine, but......

     

    The standard modelling of processes stopped working - just for processes with in a process suborganizer - top-level processes worked fine.  Needless to say, we didn't immediately spot this issue.  Removing the lines resolved the issue immediately.  There may have been other weirdos that we never spotted.

     

    So.....

     

    "you don't want to try to access the dmd from in a modeler plugin as only madness lies this way".

     

    Cheers,

    Jane

  • Andrey Telepin Rank: White Belt 70 posts since
    May 13, 2010

    I long time not write to Zenoss and if i remeber corectly you can transfer control of creation class from plugin to you module. Just leave "id" field blank in datamap. You can explore source code of ApplyDataMap what happend if id blank. In addition i can send you my source where this trick work.

More Like This

  • Retrieving data ...

Legend

  • Correct Answers - 4 points
  • Helpful Answers - 2 points