If you're administering a number of machines and each account on these machines has a number of cronjobs this recipe can be used to generate an HTML report listing all crontabs on all your machines. You can use this script in a cronjob to regenerate this report periodically.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | #!python
# -*- coding: iso-8859-1 -*-
import datetime
import py
from ll.xist import xsc
from ll.xist.ns import xml, html, meta
codetemplate = """
import os
base = %r
crontabs = os.listdir(base)
channel.send(len(crontabs))
for file in crontabs:
channel.send((file, os.popen('crontab -u %%s -l' %% file).read()))
"""
class Host(object):
def __init__(self, name, dir="/var/spool/cron/crontabs", python="python2.4"):
self.name = name
self.dir = dir
self.python = python
def getcrontabs(self):
code = py.code.Source(codetemplate % self.dir)
gateway = py.execnet.SshGateway("root@%s" % self.name, remotepython=self.python)
channel = gateway.remote_exec(code)
count = channel.receive()
for i in xrange(count):
yield channel.receive()
gateway.exit()
hosts = [
Host("host1.example.com"),
Host("host2.example.org"),
Host("host3.example.net"),
]
style = """
body {
margin: 0;
padding: 0;
background-color: #fff;
color: #000;
}
.note
{
font-size: 13px;
}
h1, h2, h3
{
color: #0063a8;
font-family: "Trebuchet MS", sans-serif;
font-weight: normal;
}
h1
{
font-size: 30px;
color: #fff;
background-color: #0063a8;
padding: 8px 30px;
}
h2
{
font-size: 20px;
margin: 30px 30px -10px 30px;
}
h3
{
font-size: 14px;
margin: 20px 30px 2px 30px;
}
pre
{
margin: 0px 30px 10px 30px;
font-size: 11px;
line-height: 18px;
border: 1px solid #eee;
background-color: #fafafa;
padding: 1px 5px 2px 5px;
overflow: auto;
}
"""
now = datetime.datetime.now()
node = xsc.Frag(html.h1("Cronjobs ", html.span("(generated at %s)" % now.strftime("%d.%m.%Y %H:%M"), class_="note")))
for host in hosts:
node.append(html.h2(host.name))
for (user, crontab) in sorted(host.getcrontabs()):
node.append(html.h3(user, "@", host.name))
node.append(html.pre(crontab.decode("latin-1").strip()))
node = xsc.Frag(
xml.XML10(), "\n",
html.head(
meta.contenttype(),
html.title("Cronjobs"),
html.style(style, type="text/css"),
),
html.body(node)
)
print e.asBytes(encoding="iso-8859-1")
|
This recipe requires the py library (http://codespeak.net/py/current/doc/). It uses py.execnet to communicate with each host and get back the crontab for each user. Furthermore XIST (http://www.livinglogic.de/Python/xist/) is used for generating HTML.
For this to work non-interactively, you need to setup each host so that you can log into the machine via ssh without requiring a password. The remote host must provide Python for py.execnet to work.
Recently, py lib and execnet were separated so you need to drag in the "execnet" package and use it instead of "py.execnet". Also execnet.SshGateway is deprecated in favour of "execnet.makegateway('ssh=HOST')". cheers, holger