Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: alienth/ZenPacks.community.HAProxy
base: master
...
head fork: alienth/ZenPacks.community.HAProxy
compare: topic.initialdev
Checking mergeability… Don't worry, you can still create the pull request.
  • 17 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
View
43 ZenPacks/community/HAProxy/HAProxyComponent.py
@@ -0,0 +1,43 @@
+###########################################################################
+#
+# Copyright (C) 2012, Jason Harvey
+# Based on code by Zenoss, Inc. -- Copyright (C) 2011, Zenoss Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 or (at your
+# option) any later version as published by the Free Software Foundation.
+#
+###########################################################################
+
+from Products.ZenModel.DeviceComponent import DeviceComponent
+from Products.ZenModel.ManagedEntity import ManagedEntity
+from Products.ZenModel.ZenossSecurity import ZEN_CHANGE_DEVICE
+
+
+class HAProxyComponent(DeviceComponent, ManagedEntity):
+ """
+ Abstract base class to avoid repeating boilerplate code in all of the
+ DeviceComponent subclasses in this ZenPack.
+ """
+
+ # Disambiguate multi-inheritence.
+ _properties = ManagedEntity._properties
+ _relations = ManagedEntity._relations
+
+ # This makes the "Templates" component display available.
+ factory_type_information = ({
+ 'actions': ({
+ 'id': 'perfConf',
+ 'name': 'Template',
+ 'action': 'objTemplates',
+ 'permissions': (ZEN_CHANGE_DEVICE,),
+ },),
+ },)
+
+ # Query for events by id instead of name.
+ # This is needed in-case any of our components have a duplicate name.
+ event_key = "ComponentId"
+
+ # Commands are run via SSH and should not be specified absolutely.
+ zCommandPath = ''
+
View
52 ZenPacks/community/HAProxy/HAProxyServer.py
@@ -0,0 +1,52 @@
+###########################################################################
+#
+# Copyright (C) 2012, Jason Harvey
+# Based on code by Zenoss, Inc. -- Copyright (C) 2011, Zenoss Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 or (at your
+# option) any later version as published by the Free Software Foundation.
+#
+###########################################################################
+
+from Products.ZenRelations.RelSchema import ToManyCont, ToOne
+
+from .HAProxyComponent import HAProxyComponent
+
+
+
+#3###########3
+## Instance should just contain 'servers'
+## Servers can be of the type BACKEND, FRONTEND, or SERVER
+## but they all track similar attributes.
+## The component list should sort by type, so that FRONTEND and BACKEND are at the top
+
+class HAProxyServers(HAProxyComponent):
+ meta_type = portal_type = "HAProxyServers"
+
+ # Modeled attributes.
+ #durable = None
+ #auto_delete = None
+ #arguments = None
+ servertype = None
+
+ # Managed attributes.
+ threshold_session_rate = None
+ threshold_session_active = None
+
+ _properties = HAProxyComponent._properties + (
+ {'id': 'threshold_session_rate', 'type': 'int', 'mode': 'w'},
+ {'id': 'threshold_session_active', 'type': 'int', 'mode': 'w'},
+ )
+
+
+ _relations = HAProxyComponent._relations + (
+ ('haproxy_host', ToOne(ToManyCont,
+ 'Products.ZenModel.Device.Device',
+ 'haproxy_servers',
+ ),),
+ )
+
+ def device(self):
+ return self.haproxy_host()
+
View
77 ZenPacks/community/HAProxy/__init__.py
@@ -1,8 +1,75 @@
+###########################################################################
+#
+# Copyright (C) 2012, Jason Harvey
+# Based on code by Zenoss, Inc. -- Copyright (C) 2011, Zenoss Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 or (at your
+# option) any later version as published by the Free Software Foundation.
+#
+###########################################################################
+
+"""
+Custom ZenPack initialization code. All code defined in this module will be
+executed at startup time in all Zope clients.
+"""
+
+import logging
+log = logging.getLogger('zen.HAProxy')
import Globals
-import os.path
-skinsDir = os.path.join(os.path.dirname(__file__), 'skins')
-from Products.CMFCore.DirectoryView import registerDirectory
-if os.path.isdir(skinsDir):
- registerDirectory(skinsDir, globals())
+from Products.ZenEvents.EventManagerBase import EventManagerBase
+from Products.ZenModel.Device import Device
+from Products.ZenModel.ZenPack import ZenPack as ZenPackBase
+from Products.ZenRelations.RelSchema import ToManyCont, ToOne
+from Products.ZenUtils.Utils import unused
+
+unused(Globals)
+
+
+ZENPACK_NAME = 'ZenPacks.community.HAProxy'
+
+# Define new device relations.
+NEW_DEVICE_RELATIONS = (
+ ('haproxy_instances', 'HAProxyInstance'),
+ )
+
+# Add new relationships to Device if they don't already exist.
+for relname, modname in NEW_DEVICE_RELATIONS:
+ if relname not in (x[0] for x in Device._relations):
+ Device._relations += (
+ (relname, ToManyCont(ToOne,
+ '.'.join((ZENPACK_NAME, modname)), 'haproxy_host')),
+ )
+
+
+class ZenPack(ZenPackBase):
+ """
+ ZenPack loader that handles custom installation and removal tasks.
+ """
+
+ def install(self, app):
+ super(ZenPack, self).install(app)
+ self._buildDeviceRelations()
+
+ def remove(self, app, leaveObjects=False):
+ if not leaveObjects:
+ # Remove our Device relations additions.
+ Device._relations = tuple(
+ [x for x in Device._relations \
+ if x[0] not in NEW_DEVICE_RELATIONS])
+
+ self._buildDeviceRelations()
+
+ def _buildDeviceRelations(self):
+ log.info("Rebuilding relations for existing devices")
+ for d in self.dmd.Devices.getSubDevicesGen():
+ d.buildRelations()
+
+
+# We need to filter HAProxy components by id instead of name.
+EventManagerBase.ComponentIdWhere = (
+ "\"(device = '%s' and component = '%s')\""
+ " % (me.device().getDmdKey(), me.id)")
+
View
145 ZenPacks/community/HAProxy/datasources/HAProxyDataSource.py
@@ -0,0 +1,145 @@
+###########################################################################
+#
+# Copyright (C) 2012, Jason Harvey
+# Based on code by Zenoss, Inc. -- Copyright (C) 2008, Zenoss Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 or (at your
+# option) any later version as published by the Free Software Foundation.
+#
+###########################################################################
+
+__doc__='''HAProxyDataSource.py
+
+Defines datasource for HAProxy
+'''
+
+import Products.ZenModel.BasicDataSource as BasicDataSource
+from Products.ZenModel.ZenPackPersistence import ZenPackPersistence
+from AccessControl import ClassSecurityInfo, Permissions
+from Products.ZenUtils.ZenTales import talesCompile, getEngine
+
+import os
+
+class HAProxyDataSource(ZenPackPersistence,
+ BasicDataSource.BasicDataSource):
+ SOURCETYPE = 'HAProxy'
+
+ ZENPACKID = 'ZenPacks.community.HAProxy'
+
+ # Mostly for my info; can probably be removed
+ DATAPOINTS = ('pxname', 'svname', 'qcur', 'qmax', 'scur', 'smax', 'slim', 'stot', 'bin', 'bout',
+ 'dreq', 'dresp', 'ereq', 'econ', 'eresp', 'wretr', 'wredis', 'status', 'weight', 'act',
+ 'bck', 'chkfail', 'chkdown', 'lastchg', 'downtime', 'qlimit', 'pid', 'iid', 'sid',
+ 'throttle', 'lbtot', 'tracked', 'type', 'rate', 'rate_lim', 'rate_max', 'check_status',
+ 'check_code', 'check_duration', 'hrsp_1xx', 'hrsp_2xx', 'hrsp_3xx', 'hrsp_4xx', 'hrsp_5xx',
+ 'hrsp_other', 'hanafail', 'req_rate', 'req_rate_max', 'req_tot', 'cli_abrt', 'srv_abrt')
+
+ sourcetypes = (SOURCETYPE,)
+ sourcetype = SOURCETYPE
+
+ timeout = 15
+ eventClass = '/Status/Web'
+
+ hostname = '${dev/manageIp}'
+ server = '${dev/componentId}'
+ servertype = 'BACKEND'
+ port = '80'
+ ssl = False
+ url = '/haproxy_stats;csv'
+
+ _properties = BasicDataSource.BasicDataSource._properties + (
+ {'id':'timeout', 'type':'int', 'mode':'w'},
+ {'id':'eventClass', 'type':'string', 'mode':'w'},
+ {'id':'hostname', 'type':'string', 'mode':'w'},
+ {'id':'port', 'type':'string', 'mode':'w'},
+ {'id':'ssl', 'type':'boolean', 'mode':'w'},
+ {'id':'url', 'type':'string', 'mode':'w'},
+ {'id':'server', 'type':'string', 'mode':'w'},
+ {'id':'servertype', 'type':'string', 'mode':'w'},
+ )
+
+ _relations = BasicDataSource.BasicDataSource._relations + (
+ )
+
+ factory_type_information = (
+ {
+ 'immediate_view': 'editHAProxyDataSource',
+ 'actions':
+ (
+ { 'id': 'edit',
+ 'name': 'Data Source',
+ 'action': 'editHAProxyDataSource',
+ 'permissions': ( Permissions.view ),
+ },
+ )
+ },
+ )
+
+ security = ClassSecurityInfo()
+
+
+ def __init__(self, id, title=None, buildRelations=True):
+ BasicDataSource.BasicDataSource.__init__(self, id, title,
+ buildRelations)
+
+
+ def getDescription(self):
+ if self.sourcetype == self.SOURCETYPE:
+ return self.hostname
+ return BasicDataSource.BasicDataSource.getDescription(self)
+
+
+ def useZenCommand(self):
+ return True
+
+
+ def getCommand(self, context):
+ parts = ['check_haproxy.py']
+ if self.hostname:
+ parts.append('-H %s' % self.hostname)
+ if self.port:
+ parts.append('-p %s' % self.port)
+ if self.ssl:
+ parts.append('-s')
+ if self.url:
+ parts.append("-u '%s'" % self.url)
+ if self.server:
+ parts.append("-S '%s'" % self.url)
+ if self.servertype:
+ parts.append("-T '%s'" % self.url)
+ cmd = ' '.join(parts)
+ cmd = BasicDataSource.BasicDataSource.getCommand(self, context, cmd)
+ return cmd
+
+ def checkCommandPrefix(self, context, cmd):
+ if self.usessh:
+ return os.path.join(context.zCommandPath, cmd)
+ zp = self.getZenPack(context)
+ return zp.path('libexec', cmd)
+
+
+ def addDataPoints(self):
+ for dpname in ('totalAccesses', 'totalKBytes'):
+ dp = self.manage_addRRDDataPoint(dpname)
+ dp.rrdtype = 'DERIVE'
+ dp.rrdmin = 0
+
+ for dpname in ('bytesPerReq', 'cpuLoad', 'slotDNSLookup',
+ 'slotKeepAlive', 'slotLogging', 'slotOpen', 'slotReadingRequest',
+ 'slotSendingReply', 'slotWaiting'):
+
+ dp = self.manage_addRRDDataPoint(dpname)
+ dp.rrdtype = 'GAUGE'
+ dp.rrdmin = 0
+
+
+ def zmanage_editProperties(self, REQUEST=None):
+ '''validation, etc'''
+ if REQUEST:
+ self.addDataPoints()
+ if not REQUEST.form.get('eventClass', None):
+ REQUEST.form['eventClass'] = self.__class__.eventClass
+ return BasicDataSource.BasicDataSource.zmanage_editProperties(self,
+ REQUEST)
+
View
2  setup.py
@@ -4,7 +4,7 @@
# NB: PACKAGES is deprecated
NAME = "ZenPacks.community.HAProxy"
VERSION = "0.1"
-AUTHOR = "alienth"
+AUTHOR = "Jason Harvey <alienth@gmail.com>"
LICENSE = ""
NAMESPACE_PACKAGES = ['ZenPacks', 'ZenPacks.community']
PACKAGES = ['ZenPacks', 'ZenPacks.community', 'ZenPacks.community.HAProxy']

No commit comments for this range

Something went wrong with that request. Please try again.