Hi all
I'd like to donate the attached script to the community.
---
apply_errata
-a - all errata - implies -b -e -s
-b - bug fix errata
-d <date> - date (in m-d-yy format) - defaults to today's date
-e - enhancement errata
-s - security errata
-r - do it for real - required to make the script actually do
updates
-v - be verbose, implied if -r is not supplied
-n - call /usr/sbin/rhn_check rather than waiting for the next
scheduled checkin
-u <username> - username for connecting to RHN hosted or the Satellite server
-p <password> - password for connecting to RHN hosted or the Satellite server
-P <proxy> - the proxy server to use
-z <search> - only apply errata matching this regular expression
-h - this help message
Notes:
1) Errata are scheduled only if they have a date of <date> or older
2) -u and -p can be ommitted if the environment variables RHN_USER and RHN_PASS
are defined. If -u/-p are provided and RHN_USER and RHN_PASS are also
defined, the -u/-p switches have preference.
If the password is '-' then the user is asked to enter the password via stdin
3) the search is case insensitive and looks in the errata synopsis. An
example use is:
'apply_errata -s -d 2-12-2009 -z "critical|important"'
-P <proxy> is needed to define the proxy server (and port) to use and overrides
the environment variable RHN_PROXY
---
This script works against RHN Hosted (the client probably needs a
provisioning entitlement though, haven't checked) and
Satellite/Spacewalk.
The point of the script is to make it easy to apply only particular
errata (i.e. just security errata) but only up to a specific date.
This is useful for people who have to draw a line in the sand
regarding the errata they are allowed to install.
Thanks
CC
--
RHCE#805007969328369
#!/usr/bin/python
"""
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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.
Copyright 2009 Colin Coe <[email protected]>
Portions of code reused from the Satellite/Spacewalk documentation and
'Mastering Regular Expressions (2nd Edition)' and various sources on
the Internet
"""
import getopt, sys, time, os, re
import xmlrpclib, httplib
from time import localtime
from sys import argv
import getpass
prog = sys.argv[0]
today = "%d-%d-%d" % (localtime()[2], localtime()[1], localtime()[0])
erratum = []
opt = dict()
opt['test'] = True
opt['user'] = ""
opt['passwd'] = ""
opt['sat_host'] = ""
opt['date'] = time.localtime(time.time())
opt['proxy'] = ""
def usage(code):
offset = time.time() - (45 * 86400)
today = "%d-%d-%d" % (localtime(offset)[2], localtime(offset)[1],
localtime(offset)[0])
if code is not None:
try:
code = int(code)
except:
code = 0
else:
code = 0
print "-a - all errata - implies -b -e -s"
print "-b - bug fix errata"
print "-d <date> - date (in m-d-yy format) - defaults to today's date"
print "-e - enhancement errata"
print "-s - security errata"
print "-r - do it for real - required to make the script actually
do"
print " updates"
print "-v - be verbose, implied if -r is not supplied"
print "-n - call /usr/sbin/rhn_check rather than waiting for the
next"
print " scheduled checkin"
print "-u <username> - username for connecting to RHN hosted or the
Satellite server"
print "-p <password> - password for connecting to RHN hosted or the
Satellite server"
print "-P <proxy> - the proxy server to use"
print "-z <search> - only apply errata matching this regular expression"
print "-h - this help message"
print "Notes:"
print "1) Errata are scheduled only if they have a date of <date> or older"
print "2) -u and -p can be ommitted if the environment variables RHN_USER
and RHN_PASS"
print " are defined. If -u/-p are provided and RHN_USER and RHN_PASS are
also"
print " defined, the -u/-p switches have preference."
print " If the password is '-' then the user is asked to enter the
password via stdin"
print "3) the search is case insensitive and looks in the errata synopsis.
An"
print " example use is:"
print " '%s -u admin -p - -P squid:3128 -s -d %s -z \"critical|important\"'"
% (prog, today)
print "-P <proxy> is needed to define the proxy server (and port) to use and
overrides"
print " the environment variable RHN_PROXY"
sys.exit(code)
def testEnvVar(ev):
try:
var = os.environ[ev]
except:
return False
return True
def getSysId():
infile = open("/etc/sysconfig/rhn/systemid","r")
text = infile.read()
pattern = re.compile("[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]")
result = pattern.search(text)
infile.close()
if result is None:
print "No system ID found, please register the node with RHN or your
local Satellite/"
print "Spacewalk server using rhn_register or another appropriate tool"
sys.exit(3)
return int(result.group(0))
def getServer():
infile = open("/etc/sysconfig/rhn/up2date","r")
text = infile.read()
pattern = re.compile("(serverURL=).*")
result = pattern.search(text)
infile.close()
if result is None:
print "No server details found. This should not happen as RHN hosted is"
print "present by default. Resolve and re-run."
sys.exit(3)
return result.group(0).split("/")[2]
class ProxiedTransport(xmlrpclib.Transport):
def set_proxy(self, proxy):
self.proxy = opt['proxy']
def make_connection(self, host):
self.realhost = host
h = httplib.HTTP(self.proxy)
return h
def send_request(self, connection, handler, request_body):
connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
def send_host(self, connection, host):
connection.putheader('Host', self.realhost)
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "abd:esrvhu:p:P:z:n")
except getopt.GetoptError:
# print help information and exit:
usage(2)
type = dict()
EI = dict()
EN = dict()
ED = dict()
type['b'] = False
type['e'] = False
type['s'] = False
if len(argv) == 1:
usage(1)
if testEnvVar('RHN_USER'):
opt['user'] = os.environ['RHN_USER']
if testEnvVar('RHN_PASS'):
opt['passwd'] = os.environ['RHN_PASS']
if testEnvVar('RHN_PROXY'):
opt['proxy'] = os.environ['RHN_PROXY']
opt['verbose'] = False
for o, a in opts:
if o == "-v":
opt['verbose'] = True
if o in ("-h"):
usage(0)
if o in ("-p"):
if opt['passwd'] == "":
opt['passwd'] = a
if o in ("-u"):
if opt['user'] == "":
opt['user'] = a
if o in ("-P"):
if opt['proxy'] == "":
opt['proxy'] = a
if o in ("-d"):
opt['date'] = a
if o in ("-b") or o in ("-a"):
type['b'] = True
if o in ("-e") or o in ("-a"):
type['e'] = True
if o in ("-s") or o in ("-a"):
type['s'] = True
if o in ("-r"):
opt['test'] = False
if o in ("-z"):
opt['search'] = a
if opt['passwd'] == '-':
opt['passwd'] = getpass.getpass()
try:
if opt['search'] == "":
opt['search'] = ".*"
except:
opt['search'] = ".*"
if not type['b'] and not type['e'] and not type['s']:
# Nothing selected, assuming all
type['b'] = True
type['e'] = True
type['s'] = True
if opt['test'] == True:
opt['verbose'] = True
if opt['user'] == "":
print "-u <username> not supplied and environment variable RHN_USER not
set"
sys.exit(4)
if opt['passwd'] == "":
print "-p <password> not supplied and environment variable RHN_PASS not
set"
sys.exit(5)
if opt['sat_host'] == "":
opt['sat_host'] = getServer()
sid = getSysId()
SATELLITE_URL = "http://%s/rpc/api" % opt['sat_host']
# If no proxy is defined, assume no proxy needed
if opt['proxy'] != "":
p = ProxiedTransport()
p.set_proxy(opt['proxy']);
client = xmlrpclib.Server(SATELLITE_URL, verbose=0, transport=p)
else:
client = xmlrpclib.Server(SATELLITE_URL, verbose=0)
session = client.auth.login(opt['user'], opt['passwd'])
ue = client.system.getUnscheduledErrata(session, sid)
for e in ue:
year = int(e['date'].split("/")[2]) + 2000
month = int(e['date'].split("/")[0])
day = int(e['date'].split("/")[1])
e_epoch = int(time.mktime(time.strptime('%d-%d-%d 00:00:00' % (year,
month, day), '%Y-%m-%d %H:%M:%S')))
try:
year = int(opt['date'].split('-')[2])
month = int(opt['date'].split('-')[0])
day = int(opt['date'].split('-')[1])
except:
year = int(opt['date'][0])
month = int(opt['date'][1])
day = int(opt['date'][2])
d_epoch = int(time.mktime(time.strptime('%d-%d-%d 00:00:00' % (year,
month, day), '%Y-%m-%d %H:%M:%S')))
ED[e['id']] = time.strftime("%a, %d %b %Y %H:%M:%S +0000",
time.localtime(e_epoch))
if e_epoch < d_epoch:
EI[e['id']] = e['advisory_synopsis']
EN[e['id']] = e['advisory_name']
pattern = re.compile(opt['search'], re.I)
result = pattern.search(e['advisory_synopsis'])
if result is not None:
if type['b'] and e['advisory_name'].find("RHBA") == 0:
erratum.append(e['id'])
if type['e'] and e['advisory_name'].find("RHEA") == 0:
erratum.append(e['id'])
if type['s'] and e['advisory_name'].find("RHSA") == 0:
erratum.append(e['id'])
if opt['verbose']:
print "Notes:"
print "\tUsing: %s" % opt['sat_host']
if opt['test']:
print "\tRunning in test mode, updates will not be scheduled"
else:
print "\tUpdates *will* be scheduled"
if type['b']:
print "\tBug fix errata selected"
if type['e']:
print "\tEnhancement errata selected"
if type['s']:
print "\tSecurity errata selected"
print "\t%d errata selected" % len(erratum)
print ""
if opt['verbose']:
for errata in erratum:
print "(Errata ID: %04d, Errata Name: %s, Released: %s) %s" % (errata,
EN[errata], ED[errata], EI[errata])
if not opt['test']:
client.system.applyErrata(session, sid, erratum)
client.auth.logout(session)
if __name__ == "__main__":
main()
_______________________________________________
Spacewalk-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/spacewalk-devel