Skip to content

Commit

Permalink
Puppet 1.21
Browse files Browse the repository at this point in the history
git-svn-id: http://zenpacks.zenoss.org/svn/zenpacks@564 db08cffe-75b9-45d1-af1a-46ad9ef135f6
  • Loading branch information
Matt Ray committed Mar 8, 2010
0 parents commit b7b9634
Show file tree
Hide file tree
Showing 24 changed files with 549 additions and 0 deletions.
16 changes: 16 additions & 0 deletions COPYRIGHT.txt
@@ -0,0 +1,16 @@
All files in this directory and below are:

Copyright (c) 2010 Zenoss, Inc. All rights reserved.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as published
by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1 change: 1 addition & 0 deletions MANIFEST.in
@@ -0,0 +1 @@
graft ZenPacks
1 change: 1 addition & 0 deletions ZenPacks/__init__.py
@@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
1 change: 1 addition & 0 deletions ZenPacks/community/__init__.py
@@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
66 changes: 66 additions & 0 deletions ZenPacks/community/puppet/PuppetClient.py
@@ -0,0 +1,66 @@
from Globals import InitializeClass
from Products.ZenRelations.RelSchema import *
from Products.ZenModel.DeviceComponent import DeviceComponent
from Products.ZenModel.ManagedEntity import ManagedEntity
from Products.ZenModel.ZenossSecurity import ZEN_VIEW, ZEN_CHANGE_SETTINGS

_kw = dict(mode='w')

class PuppetClient(DeviceComponent, ManagedEntity):
"Puppet Client Information"

portal_type = meta_type = 'PuppetClient'

pcDisplayName = ""
pcSigned = -1
pcState = 1
pcLastUpdateTime = ""

_properties = (
dict(id='pcDisplayName', type='string', **_kw),
dict(id='pcSigned', type='int', **_kw),
dict(id='pcState', type='int', **_kw),
dict(id='pcLastUpdateTime', type='string', **_kw),
)

_relations = (
('puppetmaster', ToOne(ToManyCont, 'ZenPacks.community.puppet.PuppetMaster', 'puppetclients')),
)

factory_type_information = (
{
'id' : 'PuppetClient',
'meta_type' : 'Puppet Client',
'description' : 'Puppet Client Description',
'icon' : 'Device_icon.gif',
'product' : 'PuppetClients',
'factory' : 'manage_addPuppetClient',
'immediate_view' : 'puppetclientDetail',
'actions' :
(
{ 'id' : 'perf'
, 'name' : 'perf'
, 'action' : 'puppetclientDetail'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'templates'
, 'name' : 'Templates'
, 'action' : 'objTemplates'
, 'permissions' : (ZEN_CHANGE_SETTINGS, )
},
)
},
)

def device(self):
return self.puppetmaster()

def managedDeviceLink(self):
from Products.ZenModel.ZenModelRM import ZenModelRM
d = self.getDmdRoot("Devices").findDevice(self.pcDisplayName)
if d:
return ZenModelRM.urlLink(d, 'link')
return None

InitializeClass(PuppetClient)

59 changes: 59 additions & 0 deletions ZenPacks/community/puppet/PuppetMaster.py
@@ -0,0 +1,59 @@
from Globals import InitializeClass
from Products.ZenModel.Device import Device
from Products.ZenModel.ZenossSecurity import ZEN_VIEW
from Products.ZenRelations.RelSchema import *

import copy

class PuppetMaster(Device):
"Puppet Master Device"

_relations = Device._relations + (
('puppetclients', ToManyCont(ToOne, "ZenPacks.community.puppet.PuppetClient", "puppetmaster")),
)

factory_type_information = (
{
'immediate_view' : 'deviceStatus',
'actions' : (
{ 'id' : 'status'
, 'name' : 'Status'
, 'action' : 'deviceStatus'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'osdetail'
, 'name' : 'OS'
, 'action' : 'deviceOsDetail'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'puppetclientData'
, 'name' : 'Clients'
, 'action' : 'puppetclientData'
, 'permissions' : (ZEN_VIEW,)
},
{ 'id' : 'hwdetail'
, 'name' : 'Hardware'
, 'action' : 'deviceHardwareDetail'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'events'
, 'name' : 'Events'
, 'action' : 'viewEvents'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'perfServer'
, 'name' : 'Perf'
, 'action' : 'viewDevicePerformance'
, 'permissions' : (ZEN_VIEW, )
},
{ 'id' : 'edit'
, 'name' : 'Edit'
, 'action' : 'editDevice'
, 'permissions' : ("Change Device",)
},
)
},
)

InitializeClass(PuppetMaster)

18 changes: 18 additions & 0 deletions ZenPacks/community/puppet/README.txt
@@ -0,0 +1,18 @@

Puppet zenpack:

- Enable forwarding of syslog messages on puppet client to foward to zenoss
*.warn @zenossserver
- Add something in puppet which triggers logger to run like so:
logger -p warn -t puppetd "Zenoss addserver myservername"
Example:
class addtozenoss {
exec { "add to zenoss":
command => "logger -p warn -t puppetd \"Zenoss addserver $hostname\"",
path => "/usr/bin"
}
}
For busy zenoss servers, you probably want to add some conditions around this so it does not run every single time, e.g. perhaps do an on boot or on kick check

- You can change which server class this defaults to or other items in Events/App/puppetd/puppetd_zenoss_commands

8 changes: 8 additions & 0 deletions ZenPacks/community/puppet/__init__.py
@@ -0,0 +1,8 @@

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())
2 changes: 2 additions & 0 deletions ZenPacks/community/puppet/datasources/__init__.py
@@ -0,0 +1,2 @@
# __init__.py

1 change: 1 addition & 0 deletions ZenPacks/community/puppet/lib/__init__.py
@@ -0,0 +1 @@
# __init__.py
1 change: 1 addition & 0 deletions ZenPacks/community/puppet/migrate/__init__.py
@@ -0,0 +1 @@
# __init__.py
Empty file.
44 changes: 44 additions & 0 deletions ZenPacks/community/puppet/modeler/plugins/PuppetModeler.py
@@ -0,0 +1,44 @@

from Products.DataCollector.plugins.CollectorPlugin import CommandPlugin

class PuppetModeler(CommandPlugin):
"""
Run puppetca on remote host to get list of managed hosts
"""
relname = "puppetclients"
modname = 'ZenPacks.community.puppet.PuppetClient'
command = '/usr/sbin/puppetca --list --all'

def process(self, device, results, log):
log.info('Collecting puppet client list for device %s' % device.id)
rm = self.relMap()
rlines = results.split("\n")
for line in rlines:
om = self.objectMap()
if line.startswith("+ "):
om.pcSigned = 1
else:
om.pcSigned = 0
om.pcDisplayName = line.lstrip("+ ")
if om.pcDisplayName == '':
continue
log.info('Collecting puppet client list for device %s: Found client = %s' % (device.id,om.pcDisplayName))
om.id = self.prepId(om.pcDisplayName)
rm.append(om)
return [rm]

#root@ubuntu1:/var/lib/puppet# puppetca --list --all
#ubuntu4
#+ ubuntu1
#+ ubuntu2
#+ ubuntu3
#root@ubuntu1:/var/lib/puppet# puppetlast
#ubuntu1 checked in 2 minutes ago
#ubuntu2 checked in 2 minutes ago
#ubuntu3 checked in 2 minutes ago

# from puppetlist....
### puts "#{node.name} #{node.expired? ? 'cached expired, ' : ''}checked in #{((Time.now - node.values[:_timestamp]) / 60).floor} minutes ago"



Empty file.
99 changes: 99 additions & 0 deletions ZenPacks/community/puppet/objects/objects.xml
@@ -0,0 +1,99 @@
<?xml version="1.0"?>
<objects>
<object id='/zport/dmd/Devices/Server/PuppetMaster' module='Products.ZenModel.DeviceClass' class='DeviceClass'>
<property type="string" id="description" mode="w" >
ssh based puppet client status checker.

You will need to setup the ssh user in order to connect to a user who can query data via
puppetca and puppetlast on the puppet master. There is a report in Device Reports which
gives the status of all puppet clients
</property>
<property visible="True" type="lines" id="zCollectorPlugins" >
['zenoss.snmp.NewDeviceMap', 'zenoss.snmp.DeviceMap', 'zenoss.snmp.HPDeviceMap', 'zenoss.snmp.InterfaceMap', 'zenoss.snmp.RouteMap', 'zenoss.snmp.IpServiceMap', 'zenoss.snmp.HRSWInstalledMap', 'zenoss.snmp.HRSWRunMap', 'zenoss.snmp.CpuMap', 'zenoss.snmp.HPCPUMap', 'PuppetModeler']
</property>
<property visible="True" type="string" id="zPythonClass" >
ZenPacks.community.puppet.PuppetMaster
</property>
<tomanycont id='rrdTemplates'>
<object id='PuppetClient' module='Products.ZenModel.RRDTemplate' class='RRDTemplate'>
<property type="text" id="description" mode="w" >
Template for monitoring puppet client status
</property>
<property type="string" id="targetPythonClass" mode="w" >
ZenPacks.community.puppet.PuppetClient
</property>
<tomanycont id='datasources'>
<object id='puppetlast' 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="eventClass" mode="w" >
/Cmd/Fail
</property>
<property type="int" id="severity" mode="w" >
3
</property>
<property type="string" id="commandTemplate" mode="w" >
/usr/bin/puppetlast
</property>
<property type="int" id="cycletime" mode="w" >
300
</property>
<property type="boolean" id="usessh" mode="w" >
True
</property>
<property type="string" id="parser" mode="w" >
ZenPacks.community.puppet.parsers.linux.puppetlast
</property>
<tomanycont id='datapoints'>
<object id='pcState' 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>
<object id='pcLastUpdateTime' 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>
</object>
</tomanycont>
</object>
<!-- ('', 'zport', 'dmd', 'Events', 'App', 'puppetd') -->
<object id='/zport/dmd/Events/App/puppetd' module='Products.ZenEvents.EventClass' class='EventClass'>
<tomanycont id='instances'>
<object id='puppetd_zenoss_commands' module='Products.ZenEvents.EventClassInst' class='EventClassInst'>
<property type="text" id="transform" mode="w" >
if evt.zenosscommand == 'addserver':
dmd.DeviceLoader.loadDevice(evt.zenossargs, '/Server/Linux')



</property>
<property type="string" id="eventClassKey" mode="w" >
puppetd
</property>
<property type="int" id="sequence" mode="w" >
7
</property>
<property type="string" id="regex" mode="w" >
Zenoss (?P&lt;zenosscommand&gt;\S+) (?P&lt;zenossargs&gt;.*)
</property>
</object>
</tomanycont>
</object>
<object id='/zport/dmd/Reports/Device Reports/PuppetClientList' module='Products.ZenModel.Report' class='Report'>
</object>
</objects>
Empty file.
Empty file.
55 changes: 55 additions & 0 deletions ZenPacks/community/puppet/parsers/linux/puppetlast.py
@@ -0,0 +1,55 @@
from Products.ZenRRD.ComponentCommandParser import ComponentCommandParser
import re
from pprint import pformat
import logging
from Products.ZenUtils.Utils import prepId as globalPrepId

log = logging.getLogger("zen.ComponentCommandParser")

class puppetlast(ComponentCommandParser):
componentSplit = '\n'
componentScanner = '^(?P<component>\S+)'
componentScanValue = 'id'
scanners = [
r'^\S+ checked in (?P<pcLastUpdateTime>[0-9]+) minutes ago',
r'^\S+ cached expired, checked in (?P<pcLastUpdateTime>[0-9]+) minutes ago',
]

# def dataForParser(self, context, dp):
# return dict(componentScanValue = getattr(context, self.componentScanValue))
#
# def processResults(self, cmd, result):
#
# # Map datapoints by data you can find in the command output
# ifs = {}
# for dp in cmd.points:
# points = ifs.setdefault(dp.data['componentScanValue'], {})
# points[dp.id] = dp
#
# # split data into component blocks
# parts = cmd.result.output.split(self.componentSplit)
#
# for part in parts:
# # find the component match
# match = re.search(self.componentScanner, part)
# if not match: continue
# component = match.groupdict()['component'].strip()
# if self.componentScanValue == 'id': component = self.prepId(component)
# points = ifs.get(component, None)
# if not points: continue
#
# # find any datapoints
# for search in self.scanners:
# match = re.search(search, part)
# if match:
# for name, value in match.groupdict().items():
# dp = points.get(name, None)
# if dp is not None:
# if value in ('-', ''): value = 0
# result.values.append( (dp, value ) )
# #log.debug('value='+value+' float(value)='+float(value))
#
# log.debug('Finished with result set')
# log.debug(pformat(result))
# return result

0 comments on commit b7b9634

Please sign in to comment.