Skip to content
This repository has been archived by the owner on Oct 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #34 from stdevel/nightly
Browse files Browse the repository at this point in the history
Release 0.3.2 - minor enhancements and fixes
  • Loading branch information
stdevel committed Mar 30, 2015
2 parents 94e006f + 741af07 commit 29dad7d
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 21 deletions.
33 changes: 25 additions & 8 deletions satprep_prepare_maintenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from satprep_shared import schedule_downtime, get_credentials, create_snapshot, is_downtime, has_snapshot
import time
import os
from fnmatch import fnmatch

#set logger
LOGGER = logging.getLogger('satprep_prepare_maintenance')
Expand All @@ -33,7 +34,17 @@



def is_blacklisted(name, list):
#check whether system is blacklisted
for entry in list:
LOGGER.debug("Checking whether {name} is blacklisted by *{entry}*".format(name=name, entry=entry))
if fnmatch(name.lower(), "*{seek}*".format(seek=entry.lower()) ): return True
return False



def verify():
#verify snapshots and downtimes
global downtimeHosts
global snapshotHosts
global myPrefix
Expand Down Expand Up @@ -124,7 +135,7 @@ def verify():


def setDowntimes():
#some globale variables
#set downtimes
global defaultMonUser
global defaultMonPass

Expand Down Expand Up @@ -185,7 +196,7 @@ def setDowntimes():


def createSnapshots():
#some globale variables
#create snapshots
global defaultVirtUser
global defaultVirtPass

Expand Down Expand Up @@ -281,7 +292,7 @@ def readFile(file):
if (row[repcols["system_prod"]] == "1" and options.nonprodOnly == False) \
or (row[repcols["system_prod"]] != "1" and options.prodOnly == False) \
or (options.prodOnly == False and options.nonprodOnly == False):
if row[repcols["hostname"]].lower() not in options.exclude: downtimeHosts.append(this_name)
if is_blacklisted(row[repcols["hostname"]], options.exclude) == False: downtimeHosts.append(this_name)
LOGGER.debug("Downtime will be scheduled for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")

#virtualization, add custom name if defined
Expand All @@ -292,7 +303,7 @@ def readFile(file):
if (row[repcols["system_prod"]] == "1" and options.nonprodOnly == False) \
or (row[repcols["system_prod"]] != "1" and options.prodOnly == False) \
or (options.prodOnly == False and options.nonprodOnly == False):
if row[repcols["hostname"]].lower() not in options.exclude: snapshotHosts.append(this_name)
if is_blacklisted(row[repcols["hostname"]], options.exclude) == False: snapshotHosts.append(this_name)
LOGGER.debug("Snapshot will be created for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")
else:
LOGGER.debug("Script parameters are avoiding creating snapshot for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")
Expand All @@ -307,7 +318,7 @@ def readFile(file):
if (row[repcols["system_prod"]] == "1" and options.nonprodOnly == False) \
or (row[repcols["system_prod"]] != "1" and options.prodOnly == False) \
or (options.prodOnly == False and options.nonprodOnly == False):
if row[repcols["hostname"]].lower() not in options.exclude: downtimeHosts.append(this_name)
if is_blacklisted(row[repcols["hostname"]], options.exclude) == False: downtimeHosts.append(this_name)
LOGGER.debug("Downtime will be scheduled for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")
else: LOGGER.debug("Script parameters are avoiding scheduling downtime for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")

Expand All @@ -321,7 +332,7 @@ def readFile(file):
if (row[repcols["system_prod"]] == "1" and options.nonprodOnly == False) \
or (row[repcols["system_prod"]] != "1" and options.prodOnly == False) \
or (options.prodOnly == False and options.nonprodOnly == False):
if row[repcols["hostname"]].lower() not in options.exclude: snapshotHosts.append(this_name)
if is_blacklisted(row[repcols["hostname"]], options.exclude) == False: snapshotHosts.append(this_name)
LOGGER.debug("Snapshot will be created for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")
else:
LOGGER.debug("Script parameters are avoiding creating snapshot for '" + this_name + "' (P:" + row[repcols["system_prod"]] + ")")
Expand Down Expand Up @@ -353,14 +364,18 @@ def main(options):
#schedule downtimes and create snapshots
if options.skipMonitoring == False: setDowntimes()
if options.skipSnapshot == False: createSnapshots()
#also verify
if options.dryrun == False:
LOGGER.info("Verifying preparation...")
verify()



def parse_options(args=None):
if args is None:
args = sys.argv

# define usage, description, version and load parser
#define usage, description, version and load parser
usage = "usage: %prog [options] snapshot.csv"
desc = '''%prog is used to prepare maintenance for systems managed with Spacewalk, Red Hat Satellite or SUSE Manager. This includes (un)scheduling downtimes in Nagios, Icinga and Shinken and creating/removing snapshots of virtual machines. As this script uses libvirt multiple hypervisors are supported (see GitHub and libvirt documenation). Login credentials are assigned using the following shell variables:
SATELLITE_LOGIN username for Satellite
Expand Down Expand Up @@ -436,9 +451,11 @@ def parse_options(args=None):

#tell user that he's a funny guy
if (
(options.skipSnapshot and options.skipMonitoring)
(options.skipSnapshot == True and options.skipMonitoring == True)
or
(options.prodOnly == True and options.nonprodOnly == True)
or
(options.dryrun == True and options.verifyOnly == True)
):
print "Haha, you're funny."
exit(1)
Expand Down
68 changes: 55 additions & 13 deletions satprep_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import xmlrpclib
from optparse import OptionParser, OptionGroup
from satprep_shared import check_if_api_is_supported, get_credentials
from unidecode import unidecode



Expand Down Expand Up @@ -76,6 +77,8 @@ def parse_options(args=None):
#snapOpts.add_option("-f", "--field", action="append", type="choice", dest="fields", choices=POSSIBLE_FIELDS, metavar="FIELDS", help="defines which fields should be integrated in the report (default: all available)")
#-p / --include-patches
snapOpts.add_option("-p", "--include-patches", action="store_true", default=False, dest="includePatches", help="defines whether package updates that are not part of an erratum shall be included (default: no)")
#-l / --include-locked
snapOpts.add_option("-l", "--include-locked", action="store_true", default=False, dest="includeLocked", help="also includes locked systems (default: no)")

(options, args) = parser.parse_args(args)

Expand All @@ -98,8 +101,9 @@ def main(options):
sattelite_url = "http://{0}/rpc/api".format(options.server)
client = xmlrpclib.Server(sattelite_url, verbose=options.debug)
key = client.auth.login(username, password)

check_if_api_is_supported(client)

if options.includeLocked: LOGGER.warning("Snapshot report will also include information about locked systems")

#check whether the output directory/file is writable
if os.access(os.path.dirname(options.output), os.W_OK) or os.access(os.getcwd(), os.W_OK):
Expand All @@ -110,7 +114,6 @@ def main(options):
writer = csv.writer(open(options.output, "w"), 'default')

#create header and scan _all_ the systems
#writer.writerow(options.fields)
writer.writerow(DEFAULT_FIELDS)
systems = client.system.listSystems(key)
#counter variable for XMLRPC timeout workaround (https://github.com/stdevel/satprep/issues/5)
Expand Down Expand Up @@ -156,29 +159,45 @@ def process_errata(client, key, writer, system):
"errata_date": "update_date"
}

#break if system locked
details = client.system.getDetails(key, system["id"])
if details["lock_status"] != False and options.includeLocked == False:
LOGGER.info("Skipping errata for locked host "
"{system[name]} (SID {system[id]})...".format(
system=system
)
)
return

#TODO: errata_* not working! Implemented a workaround (looking for a "nicer" way to do this)

errata = client.system.getRelevantErrata(key, system["id"])
if not errata:
LOGGER.info("Host {0[name]} (SID {0[id]}) has no relevant errata.".format(system))
LOGGER.debug("Host {0[name]} (SID {0[id]}) has no relevant errata.".format(system))
return
else:
LOGGER.info("Looking at relevant errata for host "
"{system[name]} (SID {system[id]})...".format(
system=system
)
)

for i, erratum in enumerate(errata, start=1):
LOGGER.info("Having a look at relevant errata #{errata} "
LOGGER.debug("Having a look at relevant errata #{errata} "
"for host {system[name]} (SID {system[id]})...".format(
errata=i,
system=system
)
)

valueSet = []
for column in DEFAULT_FIELDS:
try:
valueSet.append(system[columnErrataMapping[column]])
LOGGER.debug("Translated column '" + column + "' in '" + columnErrataMapping[column] + "'")
continue
except KeyError:
# Key not found - probably needs more logic.
#Key not found - probably needs more logic.
LOGGER.debug("Could not find column '" + column + "' in columnErrataMapping")
pass

Expand Down Expand Up @@ -286,7 +305,7 @@ def process_errata(client, key, writer, system):
and temp["SYSTEM_MONITORING_HOST"] != "" and
"SYSTEM_MONITORING_HOST_AUTH" in temp and
temp["SYSTEM_MONITORING_HOST_AUTH"] != ""):
temp_vmname = temp_vmname + "@" + temp["SYSTEM_MONITORING_HOST"] + ":" + temp["SYSTEM_MONITORING_HOST_AUTH"]
temp_monname = temp_monname + "@" + temp["SYSTEM_MONITORING_HOST"] + ":" + temp["SYSTEM_MONITORING_HOST_AUTH"]
valueSet.append(temp_monname)
else:
valueSet.append("")
Expand Down Expand Up @@ -323,37 +342,60 @@ def process_errata(client, key, writer, system):
else:
valueSet.append("")

#replace unicodes
for i,field in enumerate(valueSet):
if type(field) is unicode:
LOGGER.debug("Converted to ascii: {ascii}".format(
ascii=unidecode(field)
))
valueSet[i] = str(unidecode(field))

writer.writerow(valueSet)



def process_patches(client, key, writer, system):
updates = client.system.listLatestUpgradablePackages(key, system["id"])

#break if system locked
details = client.system.getDetails(key, system["id"])
if details["lock_status"] != False and options.includeLocked == False:
LOGGER.info("Skipping patches for locked host "
"{system[name]} (SID {system[id]})...".format(
system=system
)
)
return

if not updates:
LOGGER.debug("Host {0[name]} (SID {0[id]}) has no relevant updates.".format(system))
return
else:
LOGGER.info("Looking at relevant package updates for host "
"{system[name]} (SID {system[id]})...".format(
system=system
)
)

for i, update in enumerate(updates, start=1):
LOGGER.info("Having a look at relevant package update "
LOGGER.debug("Having a look at relevant package update "
"#{update} for host {system[name]} "
"(SID {system[id]})...".format(
update=i,
system=system
)
)

if client.packages.listProvidingErrata(key, update["to_package_id"]):
# We only add update information if it is not not
# already displayed as part of an erratum
#We only add update information if it is not not
#already displayed as part of an erratum
LOGGER.debug("Dropping update {0[name]} "
"({0[to_package_id]}) as it's already part of "
"an erratum.".format(update)
)
continue

valueSet = []
#for column in options.fields:
for column in DEFAULT_FIELDS:
if column == "hostname":
valueSet.append(system["name"])
Expand Down Expand Up @@ -438,7 +480,7 @@ def process_patches(client, key, writer, system):
and temp["SYSTEM_MONITORING_HOST"] != "" and
"SYSTEM_MONITORING_HOST_AUTH" in temp and
temp["SYSTEM_MONITORING_HOST_AUTH"] != ""):
temp_vmname = temp_vmname + "@" + temp["SYSTEM_MONITORING_HOST"] + ":" + temp["SYSTEM_MONITORING_HOST_AUTH"]
temp_monname = temp_monname + "@" + temp["SYSTEM_MONITORING_HOST"] + ":" + temp["SYSTEM_MONITORING_HOST_AUTH"]
valueSet.append(temp_monname)
else:
valueSet.append("")
Expand Down

0 comments on commit 29dad7d

Please sign in to comment.