#!/usr/bin/python3
#
# om-wizard.py
# Opengear Solution Engineering, 4 April 2023
# 
# OM Initial Configuration Wizard
# NOTE: Version only for OM release 23.03.1 and later [SLE-226].


import requests
import json
import subprocess
import os
import crypt
import getpass
import ipaddress
import time
from os.path import expanduser
from ogshared.raml_api import overrides


TOKENFILE = expanduser("~/.token")

uri = "https://localhost/api/v2/"


# Create local API token
def createToken():

    # minimal, fast-loading requests alternative
    import ogshared.requests_lite as requests

    # use current cli session to fetch an api token
    cli_session_binary = getattr(overrides, "CLI_SESSION_BINARY", "/usr/libexec/cli-session")

    token = subprocess.run([cli_session_binary], stdout=subprocess.PIPE).stdout.decode("utf-8")

	# write token to file
    with open(TOKENFILE, "w") as f:
          f.write(token)

	# store token in var header
    headers = { "Authorization" : "Token " + token }

    return headers

# TODO: Add function to fetch IP address info for net1 & net2

# Check if IP address entries are in the valid format (ex: 10.0.0.1)
def checkIp():

    while True:
        try:
            address = ipaddress.ip_address(input("IP address: "))
            print(address)
            return address
        except ValueError:
            print("IP address is not a valid format (example: 10.0.0.1). Try again.")      
            continue


# Configure root password
def rootPw(headers):

    # Warn user about changing the root password [SLE-161]
    print("\nWARNING: You are about to change the systems 'root' password.")
    while True:
        ok = input("\nProceed with changing the 'root' password (y/n)? ")
        if ok == "y":
            break
        elif ok == "n":
            print("\nOK...returning to the Main Menu...")
            menu(headers)
            break   
        else: 
            print("Please enter y or n.")
            continue
        
        

    # Loop to check and prompt user if password left empty [SLE-161]
    password = ""
    while True:
        password = getpass.getpass(prompt="\nNew Root Password: ")
        if password:
            pwCheck = getpass.getpass(prompt="Enter new password again: ")
            break
        else:
            print("\nPassword cannot be blank! Try again...")
            continue

    if pwCheck == password:
        print("Passwords match! Setting root password...")
        hashed = crypt.crypt(password)

        # Dictionary to contruct json
        root = {
                "user": {
                    "username": "root",
                    "enabled": True,
                    "no_password": False,
                    "ssh_password_enabled": True,
                    "hashed_password": hashed,
                    "groups": [
                        "groups-1"
                        ]
                    }
                }
        
        r = requests.put(f"{uri}users/users-1", headers=headers, data=json.dumps(root), verify=False)
        if r.ok:
            print("\nRoot password successfully changed!\n")
            menu(headers)
        else:
            print("\nSomething went wrong. Try again.\n")
            print("Returning to the main menu.\n")
            menu(headers)

    else:
        print("Password did not match. Try again.")
        rootPw(headers)


# Configure static IP address for the selected network interface
def setStatic(headers, iface):

    while True:
        try:
            ifaddr = ipaddress.IPv4Interface(input("\nEnter IPv4 Address w/ cidr (e.g. 192.168.0.1/24): "))
            break
        except ValueError:
            print("Invalid format. Try again.")
            continue

    address = ifaddr.ip
    netmask = ifaddr.netmask

    while True:
        ok = input("\nEnter Gateway (y/n)?")
        if ok == "y":
            while True:
                try:
                    gateway = ipaddress.ip_address(input("Gateway: "))             
                    break
                except ValueError:
                    print("Invalid format. Try again.")
                    continue
            break
        elif ok == "n":
            gateway = "0.0.0.0"
            break  
        else: 
            print("Please enter y or n.")

    while True:
        ok = input("\nEnter DNS (y/n)?")
        if ok == "y":
            while True:
                try:
                    dns = ipaddress.ip_address(input("DNS: "))           
                    break
                except ValueError:
                    print("Invalid format. Try again.")
                    continue
            break
        elif ok == "n":
            dns = "0.0.0.0"
            break  
        else: 
            print("Please enter y or n.")

    # User 
    print(f"\nInterface: {iface}")
    print(f"IP Address: {address}")
    print(f"Netmask: {netmask}")
    print(f"Gateway: {gateway}")
    print(f"DNS: {dns}")
    while True:
        ok = input("\nAre these values this ok (y/n)? ")
        if ok == "y":
            print(f"OK, pushing static IP configuration for {iface}. This will take a moment...")
            break
        elif ok == "n":
            setStatic(headers, iface)   
        else: 
            print("Please enter y or n.")    

    # Dictionary to contruct json
    static = {
    "conn": {
        "ipv4_static_settings": {
        "netmask": str(netmask),
        "address": str(address),
        "gateway": str(gateway),
        "dns1": str(dns)
        },
        "mode": "static",
        "physif": iface
        }
    }

    r = requests.post(uri + "conns", data=json.dumps(static), headers=headers, verify=False)
    if r.ok:
        print(f"\nIP settings for {iface} successfully configured!\n")
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        menu(headers)


# Configure DHCP for the selected network interfaces
def setDhcp(headers, iface):

    # Dictionary to contruct json
    dhcp = {
    "conn": {
        "mode": "dhcp",
        "physif": iface,
        }
    }

    print("OK, pushing DHCP configuration to {iface}. This will take a moment...\n")

    r = requests.post(f"{uri}conns", data=json.dumps(dhcp), headers=headers, verify=False)
    if r.ok:
        print(f"DHCP successfully configured for {iface}.\n")
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        menu(headers)


# Set the network interface IP mode (dhcp or static)
def setMode(headers, iface):

    print("""

    1. Set static address
    2. Set DHCP
    3. Show current IP settings
    4. Back to Main Menu
        
    """)

    while True:
        opt = input("Choose an option [1-3]: ")
        if opt == "1":
            print(f"Configure static IP settings for {iface}...")
            setStatic(headers, iface)
        elif opt == "2":
            print(f"Configure DHCP for {iface}...")
            setDhcp(headers, iface)
        elif opt == "3":
            # TODO: Move these vars to a new "getIp()" function
            getNet1 = os.popen("ip address | grep net1 | awk ' / inet / { print $7,$2 }'")
            getNet2 = os.popen("ip address | grep net2 | awk ' / inet / { print $7,$2 }'")
            net1Data = getNet1.read()
            net2Data = getNet2.read()
            net1Output = net1Data.rstrip()
            net2Output = net2Data.rstrip()
            print(f"\nCurrent IP settings for {iface}...\n")
            if iface == "net1":
                print(f"{net1Output}\n")
                setMode(headers, iface)
            else:
                print(f"{net2Output}\n")
                setMode(headers, iface)
        elif opt == "4":
            menu(headers)
        else:
            opt != ""
            print("\nInvalid choice, try again...")
            setMode(headers, iface)
        break


# Choose which auth mode to configure
def authMode(headers):

    # Choose auth mode
    print("""

    1. RADIUS
    2. TACACS
    3. LDAP
    4. Local
    5. Main Menu
        
    """)

    while True:
        opt = input("Choose an option [1-4]: ")
        if opt == "1":
            radius(headers)
            break
        elif opt == "2":
            tacacs(headers)
            break
        elif opt == "3":
            ldap(headers)
            break
        elif opt == "4":
            localAuth(headers)
            break
        elif opt == "5":
            menu(headers)
            break
        else:
            opt != ""
            print("\nInvalid choice, try again...")
            authMode(headers)
        break


# Configure RADIUS
def radius(headers):

    while True:
        try:
            radIp = ipaddress.ip_address(input("\nRADIUS server IP: "))
            break
        except ValueError:
            print("IP address is not a valid format (example: 10.0.0.1). Try again.")      
            continue
    
    while True:
        ok = input("\nWould you like to configure a RADIUS accounting server (y/n)")
        if ok == "y":
            while True:
                try:
                    acIp = ipaddress.ip_address(input("Enter a RADIUS accounting server IP or hostname: "))
                    break
                except ValueError:
                    print("IP address is not a valid format (example: 10.0.0.1). Try again.")      
                    continue
        elif ok == "n":
            acIp = "0.0.0.0"
            
            break
        else:
            print("Please enter y or n.")

    while True:
        rpw = getpass.getpass(prompt="\nEnter RADIUS password (password input hidden): ")
        rpwCheck = getpass.getpass(prompt="Enter RADIUS password again: ")
        if rpw == rpwCheck:
            print("Password match!")
            break
        else:
            print("\nPassword did not match, try again.")

    # User confirmation [SLE-158]
    # If Accouting Server not configured, don"t show 0.0.0.0 (user experience feedback)
    print(f"\nRADIUS Server IP: {radIp}")
    if acIp == "0.0.0.0":
        print(f"RADIUS Accounting Server IP: not configured")
    else:
        print(f"RADIUS Accounting Server IP: {acIp}")
    while True:
        ok = input("\nAre these values this ok (y/n)? ")
        if ok == "y":
            print("\nOK, pushing RADIUS configuration. This will take a moment...")
            break
        elif ok == "n":
            menu(headers)    
        else: 
            print("Please enter y or n.")    

    # Dictionary to contruct json
    aaa = {
    "auth": {
        "ldapAuthenticationServers": [],
        "tacacsAuthenticationServers": [],
        "mode": "radius",
        "policy": "remotedownlocal",
        "radiusPassword": rpw,
        "radiusAuthenticationServers": [
        {
            "hostname": str(radIp)
        }
        ],
        "radiusAccountingServers": [
        {
            "hostname": acIp
        }
        ],
        }
    }

    r = requests.put(f"{uri}auth", data=json.dumps(aaa), headers=headers, verify=False)
    if r.ok:
        print("\nRADIUS successfully configured!")
        time.sleep(2)
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        time.sleep(2)
        menu(headers)

# Configure TACACS
def tacacs(headers):

    while True:
        try:
            tacIp = ipaddress.ip_address(input("\nTACACS server IP or hostname: "))            
            break
        except ValueError:
            print("IP address is not a valid format (example: 10.0.0.1). Try again.")
    
    print("""
    Choose a TACACS login method:
    1. PAP
    2. CHAP
    3. Login (DES)
    """)
    while True:
        opt = input("Choose an option (1-3): ")
        if opt == "1":
            tacMethod = "pap"
        elif opt == "2":
            tacMethod = "chap"
        elif opt == "3":
            tacMethod = "login"
        else:
            opt != ""
            print("\nInvalid choice, try again...")
            tacacs(headers)
        break

    tacService = input("\nTACACS Service (defaults to 'raccess' if left blank): ")

    while True:
        tpw = getpass.getpass(prompt="\nEnter TACACS password (password input hidden): ")
        tpwCheck = getpass.getpass(prompt="Enter TACACS password again: ")
        if tpw == tpwCheck:
            print("Password match!\n")
            break
        else:
            print("Password did not match, try again.")

    # User confirmation [SLE-159]
    print(f"\nTACACS Server IP: {tacIp}")
    print(f"TACACS Login Method: {tacMethod}")
    if tacService == "":
        print(f"TACACS Service: raccess")
    else:
        print(f"TACACS Service: {tacService}")
    while True:
        ok = input("\nAre these values this ok (y/n)? ")
        if ok == "y":
            print("\nOK, pushing TACACS configuration. This will take a moment...")
            break
        elif ok == "n":
            menu(headers)    
        else: 
            print("Please enter y or n.")    

    # Dictionary to contruct json
    aaa = {
    "auth": {
        "ldapAuthenticationServers": [],
        "radiusAuthenticationServers": [],
        "radiusAccountingServers": [],
        "mode": "tacacs",
        "policy": "remotedownlocal",
        "tacacsService": tacService,
        "tacacsMethod": tacMethod,
        "tacacsPassword": tpw,
        "tacacsAuthenticationServers": [
            {
            "hostname": str(tacIp)
            }
        ]
        }
    }

    r = requests.put(f"{uri}auth", data=json.dumps(aaa), headers=headers, verify=False)
    if r.ok:
        print("\nLDAP successfully configured!")
        time.sleep(2)
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        time.sleep(2)
        menu(headers)

# Configure LDAP [SLE-160]
def ldap(headers):
    
    # Prompt user for LDAP inputs
    while True:
        try:
            ldapBaseDn = input("\nLDAP Base DN: ")            
            break
        except ValueError:
            print("Cannot be blank. Try again.")
            continue

    ldapBindDn = input("\nLDAP Bind DN (defaults to anonymous if left blank): ")

    while True:
        try:
            ldapUser = input("\nLDAP username: ")            
            break
        except ValueError:
            print("Cannot be blank. Try again.")
            continue

    ldapGroup = input("\nLDAP Group Membership (leave blank for OpenLDAP or if not required): ")

    while True:
        try:
            ldapIp = input("\nLDAP server IP or hostname: ")            
            break
        except ValueError:
            print("Cannot be blank. Try again.")
            continue

    while True:
        lpw = getpass.getpass(prompt="\nEnter LDAP password: ")
        lpwCheck = getpass.getpass(prompt="Enter LDAP password again: ")
        if lpw == lpwCheck:
            print("Password match!")
            break
        else:
            print("Password did not match, try again.")
            continue

    # User confirmation
    print(f"\nLDAP Base DN: {ldapBaseDn}")
    if ldapBindDn == "":
        pass
    else:
        print(f"LDAP Bind DN: {ldapBindDn}")
    print(f"LDAP username: {ldapUser}")
    if ldapGroup == "":
        pass
    else:
        print(f"LDAP Group Membership: {ldapGroup}")
    print(f"LDAP Server IP: {ldapIp}")
    while True:
        ok = input("\nAre these values this ok (y/n)? ")
        if ok == "y":
            print("\nOK, pushing LDAP configuration. This will take a moment...")
            break
        elif ok == "n":
            ldap(headers)    
        else: 
            print("Please enter y or n.")    

    # Dictionary to contruct json
    aaa = {
    "auth": {
        "radiusAuthenticationServers": [],
        "radiusAccountingServers": [],
        "tacacsAuthenticationServers": [],
        "ldapBaseDN": ldapBaseDn,
        "ldapBindDN": ldapBindDn,
        "ldapUsernameAttribute": ldapUser,
        "ldapGroupMembershipAttribute": ldapGroup,
        "ldapBindPassword": lpw,
        "ldapAuthenticationServers": [
            {
            "hostname": str(ldapIp)
        }
        ],
        "mode": "ldap",
        "policy": "remotedownlocal",
        }
    }    

    r = requests.put(f"{uri}auth", data=json.dumps(aaa), headers=headers, verify=False)
    if r.ok:
        print("\nTACACS successfully configured!")
        time.sleep(2)
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        menu(headers)

# Configure Local Authentication
def localAuth(headers):

    # Check if local auth already configured
    getAuth = requests.get(f"{uri}auth", headers=headers, verify=False)
    a = json.loads(getAuth.text)
    if a['auth']['mode'] == 'local':
        print("Local user auth already configured.")
        authMode(headers)
    else:
        print("\nSetting system to local user auth...")
    
    aaa = {
    "auth": {
        "ldapAuthenticationServers": [],
        "radiusAuthenticationServers": [],
        "radiusAccountingServers": [],
        "tacacsAuthenticationServers": [],
        "mode": "local",
        }
    }

    r = requests.put(f"{uri}auth", data=json.dumps(aaa), headers=headers, verify=False)
    if r.ok:
        print("\nLocal user auth successfully configured!")
        time.sleep(2)
        menu(headers)
    else:
        print("\nSomething went wrong. Try again.\n")
        print("Returning to the main menu.\n")
        time.sleep(2)
        menu(headers)
    

# Configure NTP
def ntp(headers):

    # Prompt user for NTP server
    timeServer = input("\nEnter the NTP server: ")

    # Dictionary to contruct json
    ntpData = {
    "ntp": {
        "enabled": True,
        "servers": [
            {
            "value": timeServer
            },
        ]
        }
    }

    # User confirmation
    while True:
        ok = input(f"\nYou entered {timeServer}. Is this ok (y/n)?")
        if ok == "y":
            print(f"\nAdding NTP server {timeServer}. This will take a moment...\n")
            r = requests.put(f"{uri}services/ntp", data=json.dumps(ntpData), headers=headers, verify=False)
            if r.ok:
                print("\nNTP server successfully added!")
                menu(headers)
            else:
                print("\nSomething went wrong.\n")
                print("Returning to the main menu.\n")
                menu(headers)
        elif ok == "n":
            menu(headers)
        else:
            print("Please enter y or n.")
        break
    
# Configure hostname
def hostname(headers):

    # Prompt user for hostname input
    hostName = input("\nEnter hostname: ")

    # Dictionary to contruct json
    hostNameData = {
    "system_hostname": {
        "hostname": hostName
        }
    }

    while True:
        ok = input(f"\nYou entered {hostName}. Is this ok (y/n)?")
        if ok == "y":
            print("\nConfiguring system hostname. This will take a moment...\n")
            r = requests.put(f"{uri}system/hostname", data=json.dumps(hostNameData), headers=headers, verify=False)
            if r.ok:
                print("\nHostname successfully configured!")
                menu(headers)
            else:
                print("\nSomething went wrong.\n")
                print("Returning to the main menu.\n")
                menu(headers)
        elif ok == "n":
            hostname(headers)
        else:
            print("Please enter y or n.")
        break


# Configure Lighthouse enrollment
def lhEnroll(headers):

    # Prompt user for lighthouse server info
    print("\nEnter the Lighthouse IP Address: ")
    address = checkIp()

    lhPw = getpass.getpass(prompt="Lighthouse Enrollment Token: ")
    lhBundle = input("Lighthouse Enrollment Bundle: ")

    # Check for default port so users can leave blank [SLE-166]
    while True:
        ok = input("Would you like to enter a custom Lighthouse Enrollment port number (y/n)? (Optional. Default is port 443.) ")
        if ok == "y":
            lhPort = input("Enter the Lighthouse Enrollment port number: ")
            if lhPort.isnumeric():
                break
            else:
                print("\nInvalid entry. Please enter a port number.\n")
        elif ok == "n":
            lhPort = 443
            break
        else:
            print("Please enter y or n.")

    # Dictionary to contruct json
    lhData = {
    "lighthouse_enrollment": {
        "address": str(address), 
        "token": lhPw,
        "bundle": lhBundle,
        "port": int(lhPort)
        }
    }

    # User confirmation
    while True:
        print("\nYou entered the below info...\n")
        print(f"Lighthouse IP: {address}")
        print(f"Lighthouse Token: {lhPw}")
        print(f"Lighthouse Bundle: {lhBundle}")
        print(f"Lighthouse Port: {int(lhPort)}")  
        ok = input("\nAre the above Lighthouse enrollment parameters above correct? (y/n)")
        if ok == "y":
            print("\nConfiguring Lighthouse enrollment parameters. This will take a moment...\n")
            r = requests.post(f"{uri}lighthouse_enrollments", data=json.dumps(lhData), headers=headers, verify=False)
            if r.ok:
                print("\nLighthouse enrollment parameters successfully configured!")
                menu(headers)
            else:
                print("\nSomething went wrong.\n")
                print("Returning to the main menu.\n")
                menu(headers)
        elif ok == "n":
            lhEnroll(headers)
        else:
            print("Please enter y or n.")
        break

# Show the current configuration [SLE-197]
# NOTE: Currently showing only items that are configurable by the wizard
def getInfo(headers):

    # get net1 & net2 IP addresses
    # Note: There"s no clean way to friggin" do this...
    getNet1 = os.popen("ip address | grep net1 | awk ' / inet / { print $7,$2 }'")
    getNet2 = os.popen("ip address | grep net2 | awk ' / inet / { print $7,$2 }'")
    net1Data = getNet1.read()
    net2Data = getNet2.read()
    net1Output = net1Data.rstrip()
    net2Output = net2Data.rstrip()
    
    # Set up api gets
    getHostname = requests.get(f"{uri}system/hostname", headers=headers, verify=False)
    getSerial = requests.get(f"{uri}system/serial_number", headers=headers, verify=False)
    getModel = requests.get(f"{uri}system/model_name", headers=headers, verify=False)
    getVersion = requests.get(f"{uri}system/version", headers=headers, verify=False)
    getAuth = requests.get(f"{uri}auth", headers=headers, verify=False)
    getNtp = requests.get(f"{uri}services/ntp", headers=headers, verify=False)
    getLh = requests.get(f"{uri}lighthouse_enrollments", headers=headers, verify=False)

    # Convert json into dictionaries
    h = json.loads(getHostname.text)["system_hostname"]["hostname"]
    s = json.loads(getSerial.text)["system_serial_number"]["serial_number"]
    m = json.loads(getModel.text)["system_model_name"]["model_name"]
    v = json.loads(getVersion.text)["system_version"]["firmware_version"]
    a = json.loads(getAuth.text)
    n = json.loads(getNtp.text)
    l = json.loads(getLh.text)
    
    # Check if network interfaces are configured
    if net1Output == "":
        net1 = "net1:   not configured\n"
    else:
        net1 = net1Output
    if net2Output == "":
        net2 = "\nnet2: not configured\n"
    else:
        net2 = net2Output

    # Check if AAA is configured
    authMode = a["auth"]["mode"]
    if "local" in a["auth"]["mode"]:
        pass 
    elif "radius" in a["auth"]["mode"]:
        authServer = a["auth"]["radiusAuthenticationServers"][0]["hostname"]
        authPort = a["auth"]["radiusAuthenticationServers"][0]["port"]
        if a["auth"]["radiusAccountingServers"][0]["hostname"] == "0.0.0.0":
            authAccounting = "not configured" 
            authAccPort = "not configured" 
        else:
            authAccounting = a["auth"]["radiusAccountingServers"][0]["hostname"]
            authAccPort = a["auth"]["radiusAccountingServers"][0]["port"] 
    elif "tacacs" in a["auth"]["mode"]:
        tacacsServer = a["auth"]["tacacsAuthenticationServers"][0]["hostname"]
        tacacsMethod = a["auth"]["tacacsMethod"]
        tacacsService = a["auth"]["tacacsService"]
    elif "ldap" in a["auth"]["mode"]:
        ldapServer = a["auth"]["ldapAuthenticationServers"][0]["hostname"]
        ldapBaseDn = a["auth"]["ldapBaseDN"]
        if a["auth"]["ldapBindDN"] == "":
            ldapBindDn = "anonymous"
        else:
            ldapBindDn = a["auth"]["ldapBindDN"]
        ldapUser = a["auth"]["ldapUsernameAttribute"]
        if "ldapGroupMembershipAttribute" in a["auth"]:
            ldapGroup = a["auth"]["ldapGroupMembershipAttribute"]
        else:
            ldapGroup = "not configured"
    
    # Check if NTP is configured
    if n["ntp"]["servers"] == []:
        ntp = "not configured"
    else:
        ntp = n["ntp"]["servers"][0]["value"]

    # Check if configured to enrolled with Lighthouse
    if l["lighthouse-enrollments"] == []:
        address = "not configured"
        port = "not configured"
        bundle = "not configured"
        status = "not configured"
    else:
        address = l["lighthouse-enrollments"][0]["address"]
        port = l["lighthouse-enrollments"][0]["port"]
        bundle = l["lighthouse-enrollments"][0]["bundle"]
        status = l["lighthouse-enrollments"][0]["status"]
 
    # Print config output
    print("\n")
    print(f"Hostname:   {h}")
    print(f"Serial:     {s}")
    print(f"Model:      {m}")
    print(f"Version:    {v}\n\n")
    
    print(f"{net1}")
    print(f"{net2}")
    print(f"NTP Server: {ntp}\n\n")

    # Check which authMode and output accordingly
    print(f"User Auth Mode: {authMode}")
    if authMode == "radius":
        print(f"RADIUS Server:    {authServer}")
        print(f"RADIUS Port:      {authPort}")
        print(f"RADIUS Server:    {authAccounting}")   
        print(f"RADIUS Port:      {authAccPort}\n\n")
    elif authMode =="tacacs":
        print(f"TACACS Server:    {tacacsServer}")
        print(f"TACACS Method:    {tacacsMethod}")
        print(f"TACACS Service:   {tacacsService}")
    elif authMode == "ldap":
        print(f"LDAP Base DN:   {ldapBaseDn}")
        print(f"LDAP Bind DN:   {ldapBindDn}")
        print(f"LDAP User:      {ldapUser}")
        print(f"LDAP Group:     {ldapGroup}")
        print(f"LDAP Server:    {ldapServer}")

    print(f"\n\nLighthouse Server:  {address}")
    print(f"Lighthouse Port:    {port}")
    print(f"Lighthouse Bundle:  {bundle}")
    print(f"Lighthouse Status:  {status}\n\n")

    # Pause and wait for user to hit ENTER 
    try:
        input("Press ENTER to continue...")
        menu(headers)
    except SyntaxError:
        pass


# Wizard main menu
def menu(headers):

    os.system("clear")

    print("\nOperations Manager CLI Configuration Wizard")

    print("""
    \nMain Menu\n
    1. Configure Net1
    2. Configure Net2
    3. Change root password 
    4. Configure Authentication (RADIUS,TACACS,LDAP)
    5. Configure NTP
    6. Configure Hostname
    7. Lighthouse Enrollment
    8. Show Current Configuration
    9. Exit
    """)

    while True:
        opt = input("Choose an option [1-9]: ")
        if opt == "1":
            print("\nConfigure Net1...")
            iface = "net1"
            setMode(headers, iface)
        elif opt == "2":
            print("\nConfigure Net2...")
            iface = "net2"
            setMode(headers, iface)
        elif opt == "3":
            print("\nConfigure root password...")
            rootPw(headers)
        elif opt == "4":
            print("\nConfigure authentication...")
            authMode(headers)
        elif opt == "5":
            print("\nConfigure NTP..")
            ntp(headers)
        elif opt == "6":
            print("\nConfigure hostname..")
            hostname(headers)
        elif opt == "7":
            print("\nLighthouse Enrollment..")
            lhEnroll(headers)
        elif opt == "8":
            getInfo(headers)
        elif opt == "9":
            print("\n\nOK...exiting...\n\n")
        else:
            opt != ""
            print("\nInvalid choice, try again...")
            menu(headers)
        break


if __name__ == "__main__":

    # Fetch api token when script starts
    headers = createToken()

    # Call main menu after fetching the api toke
    menu(headers)