Skip to content

Instantly share code, notes, and snippets.

@Morrolan
Created February 27, 2015 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Morrolan/d99cb3059f5be6ef30d9 to your computer and use it in GitHub Desktop.
Save Morrolan/d99cb3059f5be6ef30d9 to your computer and use it in GitHub Desktop.
Zabbix Deployment Script
__author__ = 'ihavelock'
# system modules
import logging
import json
import argparse
import os
import shutil
import fileinput
# custom modules
import afcsupport3
# third-party modules
# particular imports
################### CONSTANTS ####################
SETTINGS = r"config/config.json"
################### VARIABLES ####################
#
################### FUNCTIONS ####################
def begin():
"""
As always, lets start at the beginning!
"""
# load our settings into a dict
settings = get_settings()
logging.basicConfig(filename=settings['log_file'], level=logging.DEBUG,
format='%(asctime)s %(levelname)s: %(message)s')
logging.info("\n\n\n")
logging.info("#########################################################################")
logging.info("#")
logging.info("# Zabbix Agent Config & Script Deployment Manager v0.1")
logging.info("# Written by Ian Havelock")
logging.info("#")
logging.info("#########################################################################")
# read commandline arguments
logging.info("Parsing commandline arguments.")
args = parse_arguments()
# stitch together the filename from the commandline parameter and the directory, and add file extension.
filename = args + ".json"
logging.info("User has specified '{0}' environment file as a parameter.")
file_path = os.path.join(settings['environment_dir'], filename)
# pass the filename to the JSON parser so that we (hopefully!) have a list containing a dict per server.
logging.info("Attempting to read server list.")
servers_list = parse_json(file_path)
logging.info("Checking that server list is correctly formed.")
check_integrity(servers_list)
logging.info("Attempting to process servers in list.")
process_server_list(servers_list)
# TODO: Check to see if RDP available, if so mount network share, if not stick file on holding area (TBD)
def get_settings():
"""
Import settings from the JSON settings file!
:return: dict
"""
imported_settings = json.load(open(os.path.normpath(SETTINGS)))
#print(imported_settings)
settings_dict = imported_settings['config'][0]
return settings_dict
def parse_arguments():
"""
Here we will parse the commandline arguments and switches
:return: list
"""
parser = argparse.ArgumentParser()
# tell our parser what to look for and a description of what it does.
parser.add_argument("--environment", "-e",
help="Please enter the environment that you wish to update, i.e. 'ST4'.")
# parse them to see if any were specified
argo = parser.parse_args()
# set our argdata variable to point to the environment parameter (perfectly fine if nothing is specified)
# By doing it this way, and adding another layer before the return, it allows us to easily expand the args later
# if required.
argdata = argo.environment
logging.info("Arguments passed: {0}".format(argdata))
return argdata
def parse_json(env):
"""
Here we will first check to see if the file exists, and if so open it as a JSON object.
:param env: string representing the filepath of the settings file to open.
:return: list
"""
servers_list = None
# little bit of error handling in case the concatenated filename doesn't actually exist.
logging.info("Checking to see if specified JSON file exists.")
try:
imported_servers = json.load(open(os.path.normpath(env)))
servers_list = imported_servers['servers']
except IOError:
e = "The environment file you have specified at '{0}' does not exist. Please try again.".format(env)
logging.error(e)
print(e)
exit(1)
return servers_list
def check_integrity(servers_list):
"""
What we'll do here is to check as we go that we get the expected object type, i.e. a dict where we expect a dict.
:param servers_list:
"""
try:
logging.info("Asserting that server list is actually a 'list' object.")
assert(isinstance(servers_list, list))
except AssertionError:
e = "Type assertion failed - expected a list."
logging.error(e)
print(e)
exit(1)
logging.info("Asserting that all list entries are 'dict' object types.")
for server in servers_list:
try:
assert(isinstance(server, dict))
except AssertionError:
e = "Type assertion failed - expected a dict."
logging.error(e)
print(e)
exit(1)
def process_server_list(servers_list):
"""
What we'll do here is to iterate through our list of servers, and do our processing as we go!
:param servers_list:
"""
settings = get_settings()
master_dir = settings['master_dir']
temp_dir = settings['temp_dir']
zabbix_conf = os.path.join(temp_dir, settings['zabbix_conf'])
for server in servers_list:
if os.path.exists(temp_dir):
logging.info("temp dir exists - deleting...")
shutil.rmtree(temp_dir)
if os.path.exists(master_dir):
logging.info("Copying master directory to temp directory.")
shutil.copytree(master_dir, temp_dir)
else:
e = "The directory '{0}' does not exist.".format(master_dir)
logging.error(e)
print(e)
# now that we have our temp_dir, lets go replace the hostname?
for line in fileinput.input(zabbix_conf, inplace=True):
print(line.replace('#HOSTNAME#', server['hostname']), end='')
copy_to_destination(server)
def copy_to_destination(server):
"""
:param server:
"""
settings = get_settings()
temp_dir = settings['temp_dir']
if server['rdp'] == "True":
share = "\\\\" + server['ip'] + "\\" + server['path']
logging.info("Share directory: {0}".format(str(os.path.normpath(share))))
else:
share = settings['holding_area'] + "\\" + server['ip']
logging.info("Share directory: {0}".format(str(os.path.normpath(share))))
if not os.path.isdir(share):
os.makedirs(share)
username = server['domain'] + "\\" + server['username']
password = server['password']
logging.info("Attempting to mount share...")
afcsupport3.mount_share(share, username, password)
logging.info("Share mounted successfully.")
logging.info("Copying files to destination...")
recursive_overwrite(temp_dir, share)
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
if ignore is not None:
ignored = ignore(src, files)
else:
ignored = set()
for f in files:
if f not in ignored:
if not f.endswith('.exe'): # hack because I can't get the ignore shit to work!
logging.info("Copying '{0}' to '{1}'".format(str(f), dest))
recursive_overwrite(os.path.join(src, f),
os.path.join(dest, f),
ignore)
else:
shutil.copyfile(src, dest)
def main():
begin()
###############################################
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment