#!/opt/vmware/bin/python

"""
This file exposes the command line interface to the PnidManager()
class (defined in pnid-impl.py), which contains methods for
updating and querying the system Principal Network Identifier (PNID)
and for generating (via VMCA) and installing (via AFD) the machine
SSL certificate containing the appropriate PNID.

Note that this utility must run under an administrator account.
"""

import argparse
import logging
import os
import sys

if os.name == 'posix':
    vmware_python_path = os.environ['VMWARE_PYTHON_PATH'].split(':')
else:
    vmware_python_path = os.environ['VMWARE_PYTHON_PATH'].split(';')

sys.path.extend(vmware_python_path)

from appliance.pnid import PnidManager

logDir = os.environ['VMWARE_LOG_DIR']

logFormat = '%(asctime)-15s: %(message)s'
logFile = os.path.join(logDir, 'pnid-manager.log')
logging.basicConfig(format=logFormat,
                    level=logging.DEBUG,
                    filename=logFile,
                    filemode='a')

def parseArguments():
    """
    Parse command line arguments.
    """
    parser = argparse.ArgumentParser(description="Tool for manipulating the "
                                     "Principal Network Identifier (PNID).",
                                     epilog="Returns: 0 (success), "
                                     "1 (failure), 2 (cert not generated or "
                                     "no PNID defined)""")
    parser.add_argument("--get-pnid", help="Get PNID",
                        action="store_true")
    parser.add_argument("--get-current-pnid", help="Get current PNID",
                        action="store_true")
    parser.add_argument("--set-pnid", help="Set PNID")
    parser.add_argument("--gen-cert",
                        help="Generate machine SSL certificate (if necessary)",
                        action="store_true")
    parser.add_argument("--get-cert",
                        help="Get current machine SSL certificate",
	                action="store_true")
    parser.add_argument("--wait",
                        help="Wait specified seconds for VMCA/AFD services (0 => don't wait)",
                        type=int)
    parser.add_argument("--dry-run",
                        help="Print actions to be performed without actually "
                        "doing them", action="store_true")

    args = parser.parse_args()

    # Check: exactly one of --gen-cert, --set-pnid, --get-pnid, or
    # --get-current-pnid must be provided
    if (1 if args.gen_cert else 0) + \
       (1 if args.get_cert else 0) + \
       (1 if args.set_pnid else 0) + \
       (1 if args.get_pnid else 0) + \
       (1 if args.get_current_pnid else 0) != 1:
        print "Error: Exactly one of --gen-cert, --set-pnid, " \
              "--get-pnid, or --get-current-pnid is allowed"
        exit(1)

    # Check: --wait can only be used with --gen-cert
    if args.wait is not None and not args.gen_cert:
        print "Error: --wait can only be used with --gen-cert"
        exit(1)

    if args.wait == 0:
        args.wait = None

    return args

def main():
    args = parseArguments()

    exitStatus = 0
    try:
        if args.get_pnid:
            result = PnidManager.getPnid(args.dry_run)
            if result:
                print result
            else:
                print "No next PNID defined"
                exitStatus = 2
        elif args.get_current_pnid:
            result = PnidManager.getCurrentPnid(args.dry_run)
            if result:
                print result
            else:
                print "No current PNID defined"
                exitStatus = 2
        elif args.set_pnid:
            PnidManager.setPnid(args.set_pnid, args.dry_run)
        elif args.gen_cert:
            result = PnidManager.genMachineSSLCert(args.dry_run, args.wait)
            if not result:
                print "Certificate generation not necessary"
                exitStatus = 2
        elif args.get_cert:
            cert,key = PnidManager._getCert()
            print "%s\n%s" % (cert,key)
    except IOError:
        e = sys.exc_info()[0]
        logging.error("Operation failed: %s" % str(e))
        print "Operation failed: %s" % str(e)
        exit(1)
    exit(exitStatus)

if __name__=="__main__":
    main()
