#!/usr/bin/env python
#
print("""
################################################################################
# The goal of this script is to patch the remote F5 running configuration,
#   by merging it with F5 running configuration file.
#
################################################################################
# Version: 0.3, Date: August 28 2018
# Author: Sam Li 
# Usage:
#         $ f5-put --node xxx --file abc
###############################################################################
# Prerequisite:
# a. F5 remote SSH access service are setup.
# b. You have privileged access to the F5 TMOS configuration.
###############################################################################
""")
import f5_admin
from f5_admin.util import *
import argparse
import getpass
import sys
import os
import re

# command argument switch setup
parser = argparse.ArgumentParser(description='This program will patch the running configuration. ')
parser.add_argument('-n','--node', help='Remote F5 hostname or IP address',required=False)
parser.add_argument('-l','--list', help='File with F5 nodes one entry per line',required=False)
parser.add_argument('-u','--user', help='(Optional) F5 box logon user ID. Default to root. ',required=False)
parser.add_argument('-p','--password', nargs='+', help='(Optional) F5 box root password',required=True)
parser.add_argument('-v','--verbose', help='(Optional) Verbose mode',action='store_true', default=False, required=False)
parser.add_argument('-r','--verify',help='(Optional) Verify mode only. No running configuration change. ', action='store_true', default=False, required=False)
parser.add_argument('-f','--file',help='File path to the patch configuration in the local file system. ', required=True)
args = parser.parse_args()

################################################################################
#      Main Program
################################################################################
if __name__ == '__main__':
    # simple program argument check
    if not args.node and not args.list:
        print("Usage: ", __file__, " -h")
        exit(1)
    elif args.node and args.list:
        print("Usage: ", __file__, " -h")
        exit(1)
    #else:
        # do nothing. program proceeding
    # Setup F5 connection string
    if args.password:
        credential = set_credential_1(args.user, *args.password)
    else:
        credential = set_credential_2(args.user)

    if args.list:
        nodes=file_to_list(args.list)
    else:
        nodes=[args.node]
    #  Initialize a F5 instance
    with f5_admin.F5Client(credential, 7, args.verbose) as my_f5:
        for node in nodes:
            print("\nPatching F5 node: ",node, "...","\n")
            my_f5.load(node)
            # Evaluate the local merge file - upload a copy to F5 if exist
            if not os.path.isfile(args.file):
                print("Please check your file path again: ",args.file)
                sys.exit(1)
            else:
                if "/" in args.file:
                    f_dest = "/var/tmp/" + args.file.split("/")[-1]
                else:
                    f_dest = "/var/tmp/" + args.file
                if args.user:
                    cmd_01 = "sshpass -p " + "\"" + my_f5.credential["user_pass"] + "\"" " scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q " + args.file + " " + args.user + "@" + node + ":" + f_dest
                else:
                    cmd_01 = "sshpass -p " + "\"" + my_f5.credential["user_pass"] + "\"" + " scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q " + args.file + " root@" + node + ":" + f_dest
                print("Execute shell command: ", cmd_01)
                os.system(cmd_01)
            if my_f5.credential["user_name"] == "root":
                cmd_prefix = "tmsh "
            else:
                cmd_prefix = ""
            cmd_02 = cmd_prefix + "load sys config merge file " + f_dest
            cmd_03 = cmd_prefix + "save /sys config partitions all"
            # sync to slave failover device
            cmd_06 = cmd_prefix + "run /cm config-sync to-group device-group-failover"
            cmd_05 = cmd_prefix + "load sys config verify file " + f_dest
            cmd_04 = "rm -rf " + f_dest
            conn = my_f5.ssh_connect()
            # if verify bit is on
            if args.verify:
                for x in [cmd_05, cmd_04]:
                    out = my_f5.ssh_command(conn, x, "")
                    if len(out) > 0:
                        for z in out:
                            print(z)
            else:
                for y in[cmd_02,cmd_06,cmd_03,cmd_04]:
                    out = my_f5.ssh_command(conn,y,"")
                    if len(out) > 0:
                        print("Here is the command execution result: ")
                        for z in out:
                            print(z)
            conn.close()
    # Step 5: Print the confirmation
    print("""
All done. Bye!""")
