#!/usr/bin/env python
#
print("""
################################################################################
# The goal of this program is to pull F5 running configuration. Then print out
# a list of VIPs that do not meet our basic configuration standard:
#    a. Missing logging profile splunk-logging, splunk-logging-local
#    b. Missing ip-intelligence-policy
################################################################################
# Version: 0.1, Date: August 23 2018
# Author: Sam Li, yangsec888@gmail.com, x.x.1972
# Usage:
#         $ gap-vip --node xxx
###############################################################################
# Prerequisite:
# a. F5 remote SSH access service are setup.
# b. You have privileged access to the F5 TMOS configuration.
###############################################################################
""")
#from client import F5Client
import f5_admin
from f5_admin.util import *
import argparse
import os
from os.path import isfile, join

# command argument switch setup
parser = argparse.ArgumentParser(description='This program will retrieve F5 VIP audit report for you. ')
parser.add_argument('-n','--node', help='Remote F5 hostname or IP address',required=True)
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=False)
parser.add_argument('-v','--verbose', help='(Optional) Verbose mode',action='store_true', default=False, required=False)
parser.add_argument('-r','--refresh',help='(Optional) Refresh the F5 running configuration in the local cache directory. ', action='store_true', default=False, required=False)
parser.add_argument('-l','--list',help='(Optional) List of F5 VIPs. ', action='store_true', default=False, required=False)
parser.add_argument('-s','--splunk',help='(Optional) List of F5 VIPs missing splunk logging profile ', action='store_true', default=False, required=False)
parser.add_argument('-i','--ip_intelligence',help='(Optional) List of F5 VIPs missing ip-intelligence policy. ', action='store_true', default=False, required=False)
args = parser.parse_args()

################################################################################
#      Main Program
################################################################################
if __name__ == '__main__':

    # simple command argument check
    if not (args.splunk or args.ip_intelligence or args.refresh):
        print("Command for help: ",__file__, " -h")
        exit(1)
    # Setup F5 connection string
    if args.password:
        credential = set_credential_1(args.user, *args.password)
    else:
        credential = set_credential_2(args.user)
    # Initialize a F5 instance
    with f5_admin.F5Client(credential, 7, args.verbose) as my_f5:
        my_f5.load(args.node)
        vs_objs = my_f5.filter_f5_objs(my_f5.top_objs, "ltm virtual ")
        print("Total Number of VIPs: ", len(list(vs_objs.keys())), "\n")

        if args.list:
            for f in list(vs_objs.keys()):
                print(f.replace('ltm virtual ',''))
            exit(1)
        # step 4. (optional) Refetch the running configuration
        if args.refresh:
            my_f5.fetch()
            exit(1)
        # Step 5:  (optional) Filter the VIP(s) missing profile
        if args.splunk:
            # filter out vs objects with splunk logging profiles
            objs_0 = my_f5.filter_f5_objs(vs_objs, "splunk-logging")
            splunk_objs = my_f5.filter_f5_objs(objs_0, "splunk-logging_local")
            # identify the gap vs objects
            gap_objs = {k:v for k,v in list(vs_objs.items()) if k not in splunk_objs}
            # remove entry with 'exchange'
            objs_final = {k: v for k, v in gap_objs.items() if 'exchange' not in k.lower()}
            #   Filter the VIP(s) missing ip-intelligence profile
        elif args.ip_intelligence:
            # filter out vs objects with splunk logging profiles
            objs_0 = my_f5.filter_f5_objs(vs_objs, "ip-intelligence-policy")
            # identify the gap vs objects
            gap_objs = {k:v for k,v in list(vs_objs.items()) if k not in objs_0}
            # remove entry with 'exchange'
            objs_final = {k: v for k, v in gap_objs.items() if 'exchange' not in k.lower()}
    # print out the F5 configuration object
    print("Total mis-configured VIPs: ", len(objs_final), "\n")
    if os.path.isfile("vs_gap.inc"):
        os.unlink("vs_gap.inc")
    for key,val in objs_final.items():
        print(key.replace("ltm virtual ",""))
        my_f5.write_obj(key,val,"vs_gap.inc")
    # Print the confirmation
    print("""
Details of the F5 objects can be found in local directory: vs_gap.inc
All done. Bye!""")
