diff --git a/etalon_clone b/etalon_clone index 5dc44a0..2aa51c2 100755 --- a/etalon_clone +++ b/etalon_clone @@ -165,9 +165,9 @@ def main(): #pprint(site) si = pyVim.connect.SmartConnect( - host = site["vsphere"], - user = site["user"], - pwd = site["passwd"], + host = site["vcenter"], + user = site["vcenter_user"], + pwd = site["vcenter_passwd"], disableSslCertValidation = True ) diff --git a/vmw_off_relocate_on b/vmw_off_relocate_on new file mode 100755 index 0000000..aaffcec --- /dev/null +++ b/vmw_off_relocate_on @@ -0,0 +1,124 @@ +#!/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.SmartConnectNoSSL( + host = host, + user = user, + pwd = passwd + ) + 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: diff --git a/vmw_rename_vm b/vmw_rename_vm new file mode 100755 index 0000000..c5119da --- /dev/null +++ b/vmw_rename_vm @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +from pyVmomi import vim +import pyVim.connect +import atexit +import argparse +import siteconf + +site_conf = siteconf.read() + + +def get_args(): + parser = argparse.ArgumentParser( + description='Rename 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('-n', '--newname', + required=True, + action='store', + help='new name') + + 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.SmartConnectNoSSL( + host = host, + user = user, + pwd = passwd + ) + atexit.register(pyVim.connect.Disconnect, si) + content = si.RetrieveContent() + + vm = get_obj(content, [vim.VirtualMachine], args.vm) + if not vm: + print("vm not found") + exit(1) + + vm.Rename(args.newname) + +if __name__ == "__main__": + main() + +# vim: set tabstop=4 shiftwidth=4 expandtab smarttab: diff --git a/vmw_snapshot_list b/vmw_snapshot_list new file mode 100755 index 0000000..7894b99 --- /dev/null +++ b/vmw_snapshot_list @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +from pyVmomi import vim +import pyVim.connect +import atexit +import argparse +from pprint import pprint +import re +from datetime import datetime +from dateutil.tz import tzlocal +import siteconf + +site_conf = siteconf.read() + + +def get_args(): + parser = argparse.ArgumentParser( + description='Clone VM from template') + + parser.add_argument('-s', '--site', + required=False, + action='store', + help='name of the site to connect to') + + parser.add_argument('-H', '--host', + required=False, + action='store', + help='vcenter host name (override site)') + + parser.add_argument('-u', '--user', + required=False, + action='store', + help='user name') + + parser.add_argument('-p', '--passwd', + required=False, + action='store', + help='password') + + parser.add_argument('-a', '--age', + required=False, + type=int, + default=5, + action='store', + help='[days] miniumum snapshot age to list') + + args = parser.parse_args() + return args + + +def get_vms(content): + obj_view = content.viewManager.CreateContainerView( + content.rootFolder, [vim.VirtualMachine], True) + vms_list = obj_view.view + obj_view.Destroy() + return vms_list + + +def snapshots(snaplist, min_days, depth=0): + now = datetime.now(tzlocal()) + snapshot_data = [] + for s in snaplist: + dt = now - s.createTime + if dt.days >= min_days: + text = ". " * depth + "(%s) %s / %i days (%s)" % (s.state, s.name, dt.days, s.createTime) + snapshot_data.append(text) + snapshot_data = snapshot_data + snapshots(s.childSnapshotList, min_days, depth + 1) + return snapshot_data + + +def main(): + args = get_args() + + host, user, passwd = None, None, None + if args.site: + 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'] + if args.host: + host = args.host + if args.user: + host = args.user + if args.passwd: + host = args.passwd + + if not host or not user or not passwd: + print("Missing site / host, user, passwd.") + exit(1) + #print(f"host {host} user {user} passwd {passwd}") + + si = pyVim.connect.SmartConnectNoSSL( + host = host, + user = user, + pwd = passwd + ) + atexit.register(pyVim.connect.Disconnect, si) + content = si.RetrieveContent() + + vms = get_vms(content) + for vm in vms: + if vm.snapshot is None: + continue + + snaplist = snapshots(vm.snapshot.rootSnapshotList, args.age) + if re.search('_R$', vm.name): + continue; + for s in snaplist: + print("%s: %s" % (vm.name, s)) + + +if __name__ == "__main__": + main() + +# vim: set tabstop=4 shiftwidth=4 expandtab smarttab: diff --git a/vmw_snapshot_remove_all b/vmw_snapshot_remove_all new file mode 100755 index 0000000..e613005 --- /dev/null +++ b/vmw_snapshot_remove_all @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +from pyVmomi import vim +import pyVim.connect +import atexit +import argparse +from pprint import pprint +import sys +import siteconf + +site_conf = siteconf.read() + + +def get_args(): + parser = argparse.ArgumentParser( + description='Reads vm names from stdin, removes all snapshots.') + + parser.add_argument('-s', '--site', + required=True, + action='store', + help='name of the site to connect 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 wait_for_task(task): + """ wait for a vCenter task to finish """ + task_done = False + while not task_done: + if task.info.state == 'success': + return task.info.result + + if task.info.state == 'error': + print("there was an error") + task_done = True + +def snapshots(snaplist, depth=0): + snapshot_data = [] + for s in snaplist: + text = ". " * depth + "(%s) %s / %s" % (s.state, s.name, s.createTime) + snapshot_data.append(text) + snapshot_data = snapshot_data + snapshots(s.childSnapshotList, depth + 1) + return snapshot_data + + +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.SmartConnectNoSSL( + host = host, + user = user, + pwd = passwd + ) + atexit.register(pyVim.connect.Disconnect, si) + content = si.RetrieveContent() + + while True: + vmname = sys.stdin.readline() + if vmname == '': break # EOF + vmname = vmname.rstrip() + if vmname == '': continue # empty line + vm = get_obj(content, [vim.VirtualMachine], vmname) + if vm == None: + print("vm not found: "+ vmname) + continue + if vm.snapshot is None: + print("vm has no snapshots: "+ vmname) + continue + print("removing all snapshots of: "+ vmname) + snaplist = snapshots(vm.snapshot.rootSnapshotList) + for s in snaplist: + print(" "+ s) + + wait_for_task(vm.RemoveAllSnapshots()) + if vm.snapshot is None: + print("done.") + else: + print("warning: vm has still snapshots!") + + +if __name__ == "__main__": + main() + +# vim: set tabstop=4 shiftwidth=4 expandtab smarttab: diff --git a/vmw_vm_set_network b/vmw_vm_set_network new file mode 100755 index 0000000..358142a --- /dev/null +++ b/vmw_vm_set_network @@ -0,0 +1,108 @@ +#!/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='Set VM network') + + 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 configure') + + parser.add_argument('-n', '--network', + required=True, + action='store', + help='new network') + + 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.SmartConnectNoSSL( + host = host, + user = user, + pwd = passwd + ) + atexit.register(pyVim.connect.Disconnect, si) + content = si.RetrieveContent() + + vm = get_obj(content, [vim.VirtualMachine], args.vm) + if not vm: + print("vm not found") + exit(1) + net = get_obj(content, [vim.Network], args.network) + if not net: + print("network not found") + exit(1) + + device_change = [] + for dev in vm.config.hardware.device: + if isinstance(dev, vim.vm.device.VirtualEthernetCard): + nicspec = vim.vm.device.VirtualDeviceSpec() + nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit + nicspec.device = dev + nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() + nicspec.device.backing.network = net + nicspec.device.backing.deviceName = args.network + nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() + nicspec.device.connectable.startConnected = True + nicspec.device.connectable.allowGuestControl = True + nicspec.device.connectable.connected = True + device_change.append(nicspec) + break + + config_spec = vim.vm.ConfigSpec(deviceChange=device_change) + task = vm.ReconfigVM_Task(config_spec) + while task.info.state == vim.TaskInfo.State.running: + time.sleep(1) + print("network changed") + + +if __name__ == "__main__": + main() + +# vim: set tabstop=4 shiftwidth=4 expandtab smarttab: