#!/usr/bin/python
#nicholas_nachefski@hotmail.com

#init
import func.overlord.client as fc
import getopt, sys, datetime, re, os

#subroutines
def usage():
    print "Usage: %s <host mask>"%sys.argv[0]
    sys.exit(2)

#get options
if len(sys.argv) < 2:
    usage()

#check if file exists and is +x
def is_exe(fpath):
    return os.path.exists(fpath) and os.access(fpath, os.X_OK)

#define our remote exec function
def exec_command(hostMask, threads, exec_command):
    client = fc.Client(hostMask,nforks=threads)
    if client.command.exists(exec_command):
        returnD = client.command.run(exec_command)
	return returnD
    else:
        print "func 'command' module not found on remote machine"
        return 1

from optparse import OptionParser
parser = OptionParser()
parser.add_option("-r", "--return",
                action="store", type="int", dest="returncode",
                help="only report on a specific return code")
parser.add_option("-t", "--threads", 
		action="store", type="int", dest="threads", default=10,
		help="number of treads to use (-t 10)" )
parser.add_option("-e", "--exe",
                action="store", type="string", dest="command",
                help="command to execute (-e 'echo test')")
parser.add_option("-f", "--file",
                action="store", type="string", dest="xfile",
                help="execute local script (-f script.sh)" )

#parse remaining args, including hostMask		
(options, args) = parser.parse_args()
hostdata = args[0]

#argument santiy checking
if (not options.xfile) and (not options.command):
    print "You need to tell me something to do ie: -e or -f"
    sys.exit(2)

if (options.xfile) and (options.command):
    print "You cannot have both -e and -f options set"
    sys.exit(2)


#Start Main##############################################
def main():
    hostMask = ''
    hosts = []

    if os.path.isfile(hostdata):
	file = open(hostdata,"r")
	while file:
	    line = file.readline()
	    if not line:
		break
	    host = line.strip('\n')
	    hostMask = hostMask + host + ';'
        file.close()
    else:
	hostMask = hostdata

    if re.match ('.+;$', hostMask):
	hostMask = hostMask.strip(';')

#if we are using xfile, transfer it now.
    if options.xfile:
        if is_exe(options.xfile) == True:
	    if re.match ('^\/.+', options.xfile):
                m = re.match('.*\/(.+)$', options.xfile)
		rPath = m.group(1)
	    else:
		rPath = options.xfile

	    remotePath = "/tmp/" + rPath
            fc.Client(hostMask,nforks=options.threads).local.copyfile.send(options.xfile, remotePath)

	    #set the command to be the exec file uploaded
	    options.command = remotePath + ' &'

#get data for report
    t = datetime.datetime.now()
    print "Starting run:", t.strftime("%m/%d/%Y %H:%M:%S"),

    returnD = exec_command(hostMask, options.threads, options.command)

    if type(returnD) == type(int()):
	print "exec_command function failed!"
	sys.exit(1)

    if options.xfile:
	delComm = "rm -rf " + remotePath
	tempD = exec_command(hostMask, options.threads, delComm)

#start printing the report
    print "\nHostmask '%s' returns '%d' host(s)" % (hostMask, len(returnD))

    sortedD = returnD.keys()
    sortedD.sort()

    report_count = 0	
    for key in sortedD:
	if type(options.returncode) == type(int()):
	    if returnD[key][0] == options.returncode:
	        report_count += 1

    if type(options.returncode) == type(int()):
        print "Showing '%s' results\n" % (report_count)

    for key in sortedD:
	if type(options.returncode) == type(int()): 
	    if returnD[key][0] == options.returncode:
		print "(%s)" % key
	        print returnD[key][0]
                print returnD[key][1]
                print
	    else:
	        continue
	else:
	    print "(%s)" % key
            print returnD[key][0]
            print returnD[key][1]
            print

    #exit cleanly
    sys.exit(0)

if __name__ == "__main__":
    main()

