zenoss / ZenPacks.zenoss.ZenPackLib

This is a helper library for zenpacks.
http://zenpacklib.zenoss.com/
GNU General Public License v2.0
15 stars 17 forks source link

Multiple ZenPacks affecting same device class #151

Closed aalvrz closed 8 years ago

aalvrz commented 8 years ago

Hello

I am currently running into an issue where I install the OpenStack Infrastructure ZenPack, which consequently creates the /Server/SSH/Linux/NovaHost device class. The ZenPack also assigns some modeler plugins to this device class.

The problem is, I am developing a new ZenPack using zenpacklib which aims to add some modeler plugins to this device class. However, when I specify these new modeler plugins in my zenpack.yaml file for this device class, all the previous modeler plugins (and possibly other configurations?) are replaced by the ones from my new ZenPack.

Is there any way around this problem so that the new modeler plugins are added to the list of existing plugins instead of replacing them? I could not find anything regarding this in the zenpacklib documentation.

Help is greatly appreciated...

cluther commented 8 years ago

@BigChief45: You can't augment the existing plugins directly from zenpack.yaml, but you can do it by providing a custom installer. See the following example of how to do this in the init.py in the same directory as your zenpack.yaml file.

from . import zenpacklib

CFG = zenpacklib.load_yaml()

from . import schema

class ZenPack(schema.ZenPack):
    def install(self, app):
        try:
            dc = self.dmd.Devices.getOrganizer("/Server/SSH/Linux/NovaHost")
        except Exception:
            # Device class doesn't exist.
            pass
        else:
            zCollectorPlugins = list(dc.zCollectorPlugins) + ["MyPluginName1"]
            self.device_classes["/My/Device/Class"].zProperties["zCollectorPlugins"] = zCollectorPlugins

        # Call super last to perform the rest of installation.        
        super(ZenPack, self).install(app)
aalvrz commented 8 years ago

@cluther Thanks for the solution, works nicely. I guess with this approach there is no need to declare the modeler plugins in zenpack.yaml?

cluther commented 8 years ago

@BigChief45: That's right. You don't want to set zCollectorPlugins in zenpack.yaml when using this approach because it will overwrite what's there instead of more gently augmenting it.

I'm also going to leave this issue open and tag it as enhancement to see if we can add special support for appending modeler plugins instead of replacing them. It's a fairly common case that ideally shouldn't require writing custom installation code like I suggested.

aalvrz commented 7 years ago

@cluther

Was this feature implemented in ZenPackLib 2? From the docs:

Beginning with ZenPackLib 2.0, this behavior has changed. zProperties will no longer be overwritten if a target device class already exists (i.e. during an upgrade or if the YAML affects a preexisting class such as /Devices/Server. Instead, a warning will be displayed to the user during installation, and the target zProperty will be left alone.

By "left alone" does it mean that the new plugins are not appended?

cluther commented 7 years ago

@BigChief45: Sorry for the delay in response. Yes, by "left alone" I meant that the new plugins will not be appended. Any changes to zProperties (including zCollectorPlugins for modeler plugins) of existing device classes must be performed using the ZenPack.install() method as I described above. This has been done to make preservation of user's customizations the default behavior.