#!/usr/bin/env python3
from pyVmomi import vim
import pyVim.connect
import atexit
import argparse
import time
import siteconf

site_conf = siteconf.read()

def get_args():
    parser = argparse.ArgumentParser(
        description='Turn off - relocate - turn on VM')

    parser.add_argument('-s', '--site',
                        required=True,
                        action='store',
                        help='name of the site to connect to')

    parser.add_argument('-v', '--vm',
                        required=True,
                        action='store',
                        help='vm to rename')

    parser.add_argument('-d', '--desthost',
                        required=False,
                        action='store',
                        help='host to relocate to')

    parser.add_argument('-D', '--destcluster',
                        required=False,
                        action='store',
                        help='cluster to relocate to')

    args = parser.parse_args()
    return args


def get_obj(content, vimtype, name):
    """
    Return an object by name, if name is None the
    first found object is returned
    """
    obj = None
    container = content.viewManager.CreateContainerView(
        content.rootFolder, vimtype, True)
    for c in container.view:
        if name:
            if c.name == name:
                obj = c
                break
        else:
            obj = c
            break

    return obj


def main():
    args = get_args()

    if not args.site in site_conf:
        print(f"site not found: {args.site}")
        exit(1)
    host = site_conf[args.site]['vcenter']
    user = site_conf[args.site]['vcenter_user']
    passwd = site_conf[args.site]['vcenter_passwd']

    si = pyVim.connect.SmartConnect(
        host = host,
        user = user,
        pwd = passwd,
        disableSslCertValidation = True
        )
    atexit.register(pyVim.connect.Disconnect, si)
    content = si.RetrieveContent()

    spec = vim.VirtualMachineRelocateSpec()
    vm = get_obj(content, [vim.VirtualMachine], args.vm)
    if not vm:
        print("vm not found")
        exit(1)

    if args.destcluster:
        cluster = get_obj(content, [vim.ClusterComputeResource], args.destcluster)
        spec.pool = cluster.resourcePool
    elif args.desthost:
        host = get_obj(content, [vim.HostSystem], args.desthost)
        if not host:
            print("host not found")
            exit(1)
        if host == vm.runtime.host:
            print("vm already runs on destination host")
            exit(0)
        spec.host = host
        spec.pool = host.parent.resourcePool
    else:
        print("no cluster or host given")
        exit(1)

    print("shutdown")
    vm.ShutdownGuest()
    while vm.runtime.powerState != vim.VirtualMachine.PowerState.poweredOff:
        time.sleep(1);

    print("relocate")
    try:
        task = vm.RelocateVM_Task(spec)
        while task.info.state == vim.TaskInfo.State.running:
            time.sleep(1)
    except Exception as e:
        print("error: "+ str(e))

    print("power on")
    task = vm.PowerOnVM_Task()
    while task.info.state == vim.TaskInfo.State.running:
        time.sleep(1)
    print("waiting for powerstate on")
    while vm.runtime.powerState != vim.VirtualMachine.PowerState.poweredOn:
        time.sleep(1);

if __name__ == "__main__":
    main()

# vim: set tabstop=4 shiftwidth=4 expandtab smarttab:
