Permalink
Browse files

* Example of extending the base Device class and adding your own com…

…ponents.

git-svn-id: http://zenpacks.zenoss.org/svn/zenpacks@156 db08cffe-75b9-45d1-af1a-46ad9ef135f6
  • Loading branch information...
1 parent 4413103 commit 961b00b8dc0f592f3b4fddc039c813e33327902c @cluther cluther committed Apr 7, 2009
View
@@ -0,0 +1,34 @@
+ZenPacks.example.Techniques
+---------------------------
+This ZenPack is not to be used for any real purpose. It is a sandbox used to
+demonstrate techniques that can be used when developing your own ZenPacks. Each
+version of the ZenPack will have a new technique added to it, and this
+README.txt file will be updated with some notes about the technique.
+
+1.0.0: Adding a new top-level object to the DMD (Device Management Database)
+-------------------------------------------------------------------------------
+There may be a reason for you to create your own top-level construct in the
+dmd. This would be considered if your concept doesn't fit into any of the
+existing top-level contructs such as Devices, Services, Processes, etc.
+
+1.1.0: Adding a new property to an existing object type
+-------------------------------------------------------------------------------
+This example demonstrates how you can extend existing object types to include
+custom information.
+
+1.2.0: Adding a custom graph report
+-------------------------------------------------------------------------------
+This version adds a complex custom graph report that aggregates information
+across an particular group of devices.
+
+1.3.0: Adding a new tab to all devices
+-------------------------------------------------------------------------------
+This version adds a new tab to all devices in the system. You can use the new
+tab to display anything you want. This only demonstrates how to install the new
+tab.
+
+1.4.0: Extending the Device object and creating your own type of components
+-------------------------------------------------------------------------------
+In this version we show how you can extend the base Device class to create a
+new type of device that has its own special kind of components attached to it.
+
@@ -0,0 +1,42 @@
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+from Products.ZenRelations.RelSchema import *
+from Products.ZenModel.ZenossSecurity import *
+from Products.ZenModel.Device import Device
+
+from ZenPacks.example.Techniques.WebSite import WebSite
+
+class WebServerDevice(Device):
+ "A device that contains zero or more websites"
+
+ _relations = Device._relations + (
+ ('websites', ToManyCont(ToOne,
+ 'ZenPacks.example.Techniques.WebSite', 'webserver')),
+ )
+
+ security = ClassSecurityInfo()
+
+ def __init__(self, *args, **kwargs):
+ Device.__init__(self, *args, **kw)
+ self.buildRelations()
+
+ security.declareProtected(ZEN_MANAGE_DMD, 'manage_addWebSite')
+ def manage_addWebSite(self, id, url, REQUEST=None):
+ """Add a web site to this web server"""
+ if not id: return self.callZenScreen(REQUEST)
+ website = WebSite(id)
+ self.websites._setObject(id, website)
+ website = self.websites._getOb(id)
+ website.url = url
+ website.index_object()
+ if REQUEST:
+ if website:
+ REQUEST['message'] = "WebSite %s added" % website.id
+ url = "%s/websites/%s" % (self.getPrimaryUrlPath(), website.id)
+ return REQUEST['RESPONSE'].redirect(url)
+ else:
+ return self.callZenScreen(REQUEST)
+ return website
+
+
+InitializeClass(WebServerDevice)
@@ -0,0 +1,56 @@
+from Globals import InitializeClass
+from Products.ZenModel.DeviceComponent import DeviceComponent
+from Products.ZenModel.ManagedEntity import ManagedEntity
+from Products.ZenRelations.RelSchema import *
+from Products.ZenModel.ZenossSecurity import *
+
+class WebSite(DeviceComponent, ManagedEntity):
+ "Individual website on a webserver"
+
+ portal_type = meta_type = "WebSite"
+
+ url = ""
+
+ _properties = (
+ {'id':'url', 'type':'string', 'mode':''},
+ )
+
+ _relations = (
+ ('webserver', ToOne(ToManyCont,
+ 'ZenPacks.example.Techniques.WebServerDevice', 'websites')),
+ )
+
+ factory_type_information = ({
+ 'id' : 'WebSite',
+ 'meta_type' : 'WebSite',
+ 'description' : """Individual website on a webserver""",
+ 'icon' : 'WebSite_icon.gif',
+ 'product' : 'Techniques',
+ 'factory' : 'manage_addWebSite',
+ 'immediate_view' : 'viewWebSite',
+ 'actions' : (
+ { 'id' : 'status'
+ , 'name' : 'Status'
+ , 'action' : 'viewWebSite'
+ , 'permissions' : (ZEN_VIEW, )
+ },
+ { 'id' : 'perfConf'
+ , 'name' : 'Template'
+ , 'action' : 'objTemplates'
+ , 'permissions' : (ZEN_CHANGE_SETTINGS, )
+ },
+ { 'id' : 'viewHistory'
+ , 'name' : 'Modifications'
+ , 'action' : 'viewHistory'
+ , 'permissions' : (ZEN_VIEW, )
+ },),
+ },)
+
+ def viewName(self):
+ return self.id
+ name = primarySortKey = viewName
+
+ def device(self):
+ return self.webserver()
+
+InitializeClass(WebSite)
@@ -10,6 +10,55 @@
if os.path.isdir(skinsDir):
registerDirectory(skinsDir, globals())
+from Products.ZenModel.ZenPack import ZenPackBase
+from Products.ZenModel.ZenMenu import ZenMenu
+
+class ZenPack(ZenPackBase):
+ def install(self, app):
+ ZenPackBase.install(self, app)
+ self.installMenuItems(app.zport.dmd)
+
+ def upgrade(self, app):
+ ZenPackBase.upgrade(self, app)
+ self.installMenuItems(app.zport.dmd)
+
+ def remote(self, app, leaveObjects=False):
+ self.removeMenuItems(app.zport.dmd)
+ ZenPackBase.remove(self, app, leaveObjects)
+
+ def installMenuItems(self, dmd):
+ self.removeMenuItems(dmd)
+ dmd.zenMenus.More.manage_addZenMenuItem(
+ "webServerDeviceDetail",
+ action="webServerDeviceDetail",
+ description="Web Server Details",
+ allowed_classes=("WebServerDevice",),
+ ordering=5.0)
+
+ menu = ZenMenu('WebSites')
+ dmd.zenMenus._setObject(menu.id, menu)
+ menu = dmd.zenMenus._getOb(menu.id)
+ menu.manage_addZenMenuItem(
+ 'addWebSite',
+ action='dialog_addWebSite',
+ description='Add Web Sites...',
+ allowed_classes=('WebServerDevice',),
+ ordering=5.0,
+ isdialog=True)
+
+ def removeMenuItems(self, dmd):
+ id = "webSererDeviceDetail"
+ try:
+ dmd.zenMenus.More.manage_deleteZenMenuItem((
+ "webServerDeviceDetail",))
+ except (KeyError, AttributeError):
+ pass
+
+ try:
+ dmd.zenMenus._delObject('WebSites')
+ except AttributeError:
+ pass
+
@monkeypatch('Products.ZenModel.IpInterface.IpInterface')
def setCustomerInfo(self, customerInfo):
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<objects>
+<!-- ('', 'zport', 'dmd', 'Devices', 'Server', 'rrdTemplates', 'WebSite') -->
+<object id='/zport/dmd/Devices/Server/rrdTemplates/WebSite' module='Products.ZenModel.RRDTemplate' class='RRDTemplate'>
+<property type="text" id="description" mode="w" >
+Per-website template for web server devices.
+</property>
+<property type="string" id="targetPythonClass" mode="w" >
+Products.ZenModel.Device
+</property>
+<tomanycont id='datasources'>
+<object id='web' module='Products.ZenModel.BasicDataSource' class='BasicDataSource'>
+<property select_variable="sourcetypes" type="selection" id="sourcetype" mode="w" >
+COMMAND
+</property>
+<property type="boolean" id="enabled" mode="w" >
+True
+</property>
+<property type="string" id="component" mode="w" >
+${here/id}
+</property>
+<property type="string" id="eventClass" mode="w" >
+/Status
+</property>
+<property type="int" id="severity" mode="w" >
+3
+</property>
+<property type="string" id="commandTemplate" mode="w" >
+check_http -H ${here/manageIp} -u ${here/url}
+</property>
+<property type="int" id="cycletime" mode="w" >
+300
+</property>
+<property type="boolean" id="usessh" mode="w" >
+False
+</property>
+<property type="string" id="parser" mode="w" >
+Nagios
+</property>
+<tomanycont id='datapoints'>
+<object id='time' module='Products.ZenModel.RRDDataPoint' class='RRDDataPoint'>
+<property select_variable="rrdtypes" type="selection" id="rrdtype" mode="w" >
+GAUGE
+</property>
+<property type="boolean" id="isrow" mode="w" >
+True
+</property>
+</object>
+</tomanycont>
+</object>
+</tomanycont>
+<tomanycont id='thresholds'>
+<object id='slow response' module='Products.ZenModel.MinMaxThreshold' class='MinMaxThreshold'>
+<property type="lines" id="dsnames" mode="w" >
+['web_time']
+</property>
+<property type="boolean" id="enabled" mode="w" >
+True
+</property>
+<property type="string" id="maxval" mode="w" >
+8
+</property>
+<property type="string" id="eventClass" mode="w" >
+/Perf/Web
+</property>
+<property type="int" id="severity" mode="w" >
+3
+</property>
+<property type="int" id="escalateCount" mode="w" >
+0
+</property>
+</object>
+</tomanycont>
+<tomanycont id='graphDefs'>
+<object id='Response Time' module='Products.ZenModel.GraphDefinition' class='GraphDefinition'>
+<property type="int" id="height" mode="w" >
+100
+</property>
+<property type="int" id="width" mode="w" >
+500
+</property>
+<property type="string" id="units" mode="w" >
+seconds
+</property>
+<property type="boolean" id="log" mode="w" >
+False
+</property>
+<property type="boolean" id="base" mode="w" >
+False
+</property>
+<property type="int" id="miny" mode="w" >
+0
+</property>
+<property type="int" id="maxy" mode="w" >
+-1
+</property>
+<property type="boolean" id="hasSummary" mode="w" >
+True
+</property>
+<tomanycont id='graphPoints'>
+<object id='slow response' module='Products.ZenModel.ThresholdGraphPoint' class='ThresholdGraphPoint'>
+<property type="string" id="threshId" mode="w" >
+slow response
+</property>
+<property type="string" id="legend" mode="w" >
+${graphPoint/id}
+</property>
+</object>
+<object id='time' module='Products.ZenModel.DataPointGraphPoint' class='DataPointGraphPoint'>
+<property type="long" id="sequence" mode="w" >
+1
+</property>
+<property select_variable="lineTypes" type="selection" id="lineType" mode="w" >
+LINE
+</property>
+<property type="long" id="lineWidth" mode="w" >
+1
+</property>
+<property type="boolean" id="stacked" mode="w" >
+False
+</property>
+<property type="string" id="format" mode="w" >
+%8.3lf
+</property>
+<property type="string" id="legend" mode="w" >
+Response Time
+</property>
+<property type="long" id="limit" mode="w" >
+-1
+</property>
+<property type="string" id="dpName" mode="w" >
+web_time
+</property>
+<property type="string" id="cFunc" mode="w" >
+AVERAGE
+</property>
+</object>
+</tomanycont>
+</object>
+</tomanycont>
+</object>
+<!-- ('', 'zport', 'dmd', 'Reports', 'Example Reports', 'Cluster Requests') -->
+<object id='/zport/dmd/Reports/Example Reports/Cluster Requests' module='Products.ZenModel.Report' class='Report'>
+</object>
+</objects>
@@ -0,0 +1,21 @@
+<h2>Add Web Site</h2>
+<span id="errmsg" style="color:red;"></span>
+<br/>
+<p style="text-align:right;">
+Name:&nbsp;<input name="id" size="15">
+<br/><br/>
+URL:&nbsp;<input name="url" size="32">
+<br/><br/>
+</p>
+<div id="dialog_buttons">
+<input tal:attributes="id string:dialog_submit;
+ type string:submit;
+ value string:OK;
+ onclick string:return $$('dialog').submit_form('${here/absolute_url}',
+ '', 1)"
+ name="manage_addWebSite:method" />
+<input tal:attributes="id string:dialog_cancel;
+ type string:button;
+ value string:Cancel;
+ onclick string:$$('dialog').hide()" />
+</div>
@@ -0,0 +1,32 @@
+<tal:block metal:use-macro="here/templates/macros/page2">
+<tal:block metal:fill-slot="contentPane">
+
+<form method=post
+ tal:define="manager here/isManager"
+ tal:attributes="action string:${here/absolute_url_path}">
+ <input type="hidden" name="zenScreenName"
+ tal:attributes="value template/id" />
+
+<tal:block metal:define-macro="objectperf" tal:define="
+ tabletitle string:Web Site">
+<tal:block metal:use-macro="here/zenuimacros/macros/zentable">
+
+<tal:block metal:fill-slot="zentablecontents">
+ <tr>
+ <td class="tableheader" align=left>Name</td>
+ <td class="tablevalues" tal:content="here/id">Home Page</td>
+ <td class="tableheader" align=left>URL</td>
+ <td class="tablevalues" tal:content="here/url">http://example.com/</td>
+ </tr>
+</tal:block>
+</tal:block>
+</tal:block>
+
+</form>
+<br/>
+<tal:block tal:condition="here/monitored" >
+<table metal:use-macro="here/viewPerformanceDetail/macros/objectperf" />
+</tal:block>
+</tal:block>
+</tal:block>
+
Oops, something went wrong.

0 comments on commit 961b00b

Please sign in to comment.