class TempOps: def __init__(self): self.connect = Connect() self.c = self.connect.connect() def temp_list(self, args): templates_service = self.c.system_service().templates_service() try: if args.prefix is not None: search_prefix = 'name=' + args.prefix + '*' else: search_prefix = '*' templates = templates_service.list(search=search_prefix) rows = [] for template in templates: cores = template.cpu.topology.cores * template.cpu.topology.sockets * template.cpu.topology.threads memory = template.memory / 1024 / 1024 description = "" if template.description is not None: description = template.description rows.append([ template.id, template.name, str(memory) + ' M', cores, str(description) ]) output = Output(["ID", "Name", "Mem", "CPU", "Description"], rows) output.print_table() self.c.close() except sdk.Error as err: print "Failed to list templates, %s" % str(err)
class StorageDomainOps: def __init__(self): self.connect = Connect() self.c = self.connect.connect() def sd_list(self, args): try: sds_service = self.c.system_service().storage_domains_service() rows = [] for sd in sds_service.list(): if sd.available is not None and sd.used is not None: rows.append([ sd.id, sd.name, sd.storage.type, str((sd.available + sd.used) / 1024 / 1024 / 1024) + 'G', str(sd.available / 1024 / 1024 / 1024) + 'G' ]) else: rows.append( [sd.id, sd.name, sd.storage.type, "N/A", "N/A"]) output = Output(["ID", "Name", "Type", "Total", "Free"], rows) output.print_table() except sdk.Error as err: print "Failed to list disks, %s" % str(err) def sd_optimize(self, args): # TODO: Compare args.request_size and free size for each SD # TODO: return: First SD id that meets args.request_size pass
def vm_stop(self, args): c_obj = Connect() c = c_obj.connect() vms_service = c.system_service().vms_service() search_prefix = 'name=' + args.vm_name try: vm = vms_service.list(search=search_prefix)[0] vm_service = vms_service.vm_service(vm.id) vm_service.stop() self.c.close() except sdk.Error as err: print("Failed to stop %s, %s" % (args.vm_name, str(err))) except IndexError: print "Error: No such VM %s" % args.vm_name else: print "The request of stopping %s has been sent" % vm.name
def __init__(self): """Initialize some variables""" cmd.Cmd.__init__(self) self.server = '' self.username = os.getlogin() self.ssh = Connect() self.connection = '' self.Sanitizer = Sanitizer() self.sanitize = self.Sanitizer.sanitize self.log = self.Sanitizer.log
class DiskOps: def __init__(self): self.connect = Connect() self.c = self.connect.connect() def disk_add(self, args): vms_service = self.c.system_service().vms_service() vm = vms_service.list(search=args.vm_name)[0] disk_attachments_service = vms_service.vm_service( vm.id).disk_attachments_service() disk_attachments_service.add( types.DiskAttachment( disk=types.Disk( name='mydisk', description='Created by titamu', format=types.DiskFormat.COW, provisioned_size=args.size * 2**30, storage_domains=[ types.StorageDomain(name=storagedomain, ), ], ), interface=types.DiskInterface.VIRTIO, bootable=False, active=True, ), ) def disk_list(self, args): try: vms_service = self.c.system_service().vms_service() vm = vms_service.list(search=args.vm_name)[0] vm_service = vms_service.vm_service(vm.id) disk_attachments_service = vm_service.disk_attachments_service() disk_attachments = disk_attachments_service.list() rows = [] for disk_attachment in disk_attachments: disk = self.c.follow_link(disk_attachment.disk) rows.append([ disk.id, disk.name, str(disk.provisioned_size / 1024 / 1024 / 1024) + "G", str(disk.status).upper() ]) output = Output(["ID", "Name", "Size", "Status"], rows) output.print_table() self.c.close() except sdk.Error as err: print "Failed to list disks, %s" % str(err)
class Commands(cmd.Cmd): """Cmd provides the way to create a pseudo-shell environment. Any command must be first defined here.""" def __init__(self): """Initialize some variables""" cmd.Cmd.__init__(self) self.server = '' self.username = os.getlogin() self.ssh = Connect() self.connection = '' self.Sanitizer = Sanitizer() self.sanitize = self.Sanitizer.sanitize self.log = self.Sanitizer.log intro = '*' * 50 + '\n' + '*' + ' ' * 20 + 'L1 Tool' + ' ' * 21 + '*' + \ '\n' + '*' * 50 + '\n' doc_header = 'Commands:' undoc_header = 'Other:' def preloop(self): """This will prompt user for credentials. Eventually they will be used for LDAP auth. For now it will be for logging.""" self.server = self.sanitize(raw_input('Server IP: '), '\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s?') while not self.server: self.server = self.sanitize(raw_input('Server IP: '), '\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s?') self.prompt = self.username + '@' + self.server + '>> ' self.log.info(self.prompt + 'Login') def emptyline(self): """This prevents the previous command from being run again if the user hits 'enter' on an empty line""" print '' def precmd(self, line): sline = self.sanitize(line) if sline is None: sline = '\n' return cmd.Cmd.precmd(self, sline) def postcmd(self, stop, line): """After the command is run make sure the SSH connection has been closed""" if self.connection: self.connection.close() return cmd.Cmd.postcmd(self, stop, line) def postloop(self): """Make sure the connection is closed again when the script is exiting.""" self.log.info(self.prompt + 'Logout') if self.connection: self.connection.close() def _comm(self, command): stdin, stdout, stderr = self.connection.exec_command(command) for err in stderr.readlines(): print err[:-1] for out in stdout.readlines(): print out[:-1] def command(self, key=None, command=''): """It's easier to pass this function around than the exec_command""" self.connection = self.ssh.connect(server=self.server, key=key) stdin, stdout, stderr = self.connection.exec_command(command) error = stderr.readlines() if error: self.log.error('%s%s %s' % (self.prompt, key.split('/')[-1], command)) print 'ERROR:' for err in error: print err[:-1] self.log.info('%s%s %s' % (self.prompt, key.split('/')[-1], command)) for out in stdout.readlines(): print out[:-1] if self.connection: self.connection.close() def multioutcommand(self, key=None, command=None, interval=1): """Same as the command method, but it supports multiple runs""" self.connection = self.ssh.connect(server=self.server, key=key) self.log.info(self.prompt + command) for i in range(interval): self._comm(command) print '' time.sleep(1) self.connection.close() #TODO: This is gonna be special and big. It's not going to work in dev the way it will in prod. # Not to sure how to accomplish this yet. It may be the very last thing I do. def do_swappers(self, line): """swappers Print swap use for linux slices""" del line print 'No swapping script in dev yet. Sorry...' # This is an example function to follow when adding new commands. # The function name must start with 'do_' with no other special chars. # # def do_example(self, line): # sline = self.sanitize(line, req='', bad='') # self.command(sline) def do_goto(self, line): """goto Change the target host. This will update your prompt so you know which host you're poking. Does not accept host names. goto <IP>""" sline = self.sanitize(line, req='\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s?') if not sline: print 'goto <IP>' else: self.server = sline self.prompt = self.username + '@' + self.server + '>> ' self.log.info(self.prompt + 'Change server') # def do_date(self, line): # """date # Prints current server time.""" # del line # self.command('date') # def do_grep(self, line): # """grep # grep [options] pattern /var/log/<file> # Works the same as it does in a normal linux environment. # --help will return help documentation from the host server.""" # sline = sanitize(line, req='\/var\/log\/', bad='\.\.\/|-R|-r|--mmap|-f') # if not sline: # print 'grep [options] <pattern> /var/log/<file>' # else: # self.command('grep ' + sline) def do_uptime(self, line): """uptime Print the remote system's running time, users and load avgerage.""" del line self.command(key='/opt/scripts/keys/uptime') def do_ps(self, line): """ps ps [options] ps with no options will run 'ps aux' Same as the ps command you know and love.""" key = '/opt/scripts/keys/ps' if not line: line = 'aux' self.command(key, line) def do_ifconfig(self, line): """ifconfig Print all interfaces on host. No args are supported. Sorry.""" sline = self.sanitize(line, req='$eth[0-9]|$vif[0-9]+\.[01]') key = '/opt/scripts/keys/ifconfig' self.command(key, line) def do_link(self, line): """link Prints link status for eth0 or eth1 plus some stats.""" sline = self.sanitize(line, req='\s?eth[0-9]') key = '/opt/scripts/keys/ethtool' if sline: self.command(key, sline) else: print 'link <eth[0-9]>' def do_iostat(self, line): """iostat List device usage by tapdisk/physical disk. Runs one time with no arguments. A single integer after the command will run the command that many times up to 100. iostat <single integer>""" sline = self.sanitize(line) key = '/opt/scripts/keys/iostat' if not sline: sline = 'xmd' self.command(key, sline) # else: # try: # if int(sline) <=1 or int(sline) > 100: # sline = 2 # self.multioutcommand('iostat -xmd', int(sline)) # except ValueError: # print 'iostat <single integer>' def do_top(self, line): """top Secure 'top'. This provides the top 20 high cpu processes. It will run 5 times in 1 second intervals.""" key = '/opt/scripts/keys/top' command = 'uptime && ps -eo pcpu,pid,user,args | sort -k 1 -r | head -20' del line self.multioutcommand(key=key, command=command, interval=5) # def do_free(self, line): # """free # Print memory statistics. '-s' and '-c' will be filtered from input. # free [options]""" # sline = self.sanitize(line, bad='-s|-c') # if not sline: # self.command('free -m') # else: # self.command('free ' + sline) # def do_xentop(self, line): # """xentop # Print out stats on VMs in a 'Running' power-state.""" # del line # self.command('sudo /usr/sbin/xentop -b -i1') ##TODO: Restrict users to /var/log/. Looks like a job for regex! # def do_logs(self, line): # """list # lists log files in /var/log/""" # sline = self.sanitize(line, bad='\.\.\/') # if sline: # self.command('ls -l /var/log/' + sline) # else: # self.command('ls -l /var/log/') ##TODO: Restrict users to /var/log/! # def do_tail(self, line): # """tail # Returns the last 50 lines of a file in /var/log/""" # sline = self.sanitize(line, bad='\.\.\/') # if not sline: # print 'tail <file>' # else: # self.command('sudo tail -50 /var/log/' + sline) # def do_bwm(self, line): # """bwm # Prints all interfaces current through-put in Kb/s at 1 sec intervals # 5 times with no arguments. '-D' and '-F' will be filtered from input # You can specify a interface with -I <interface>.""" # sline = self.sanitize(line, bad='-D|-F') # if not sline: # self.multioutcommand('bwm-ng -c1 -o plain', 5) # else: # self.multioutcommand('bwm-ng -c1 -o plain ' + sline, 5) # def do_packets(self, line): # """packets # Prints all interfaces current packet per second count at 1 sec # intervals 5 times with no arguments. You can specify an interface # with -I <interface>.""" # sline = self.sanitize(line) # if not sline: # self.multioutcommand('bwm-ng -c1 -o plain -u packets', 5) # else: # self.multioutcommand('bwm-ng -c1 -o plain -u packets ' + sline, 5) ##TODO: Add usage documentation. TCPdump is a really powerful tool that could be malicious in a scripted format. May remove or only allow a few options!!! # def do_tcpdump(self, line): # """tcpdump # Runs tcpdump on the remote host. For this to work quickly, there # needs to be traffic. If the host is having network problems, you # may find that this takes a long time to return output. However, # normal traffic (mostly TCP) should come back relitively quickly. # tcpdump -i <interface> """ # sline = self.sanitize(line) # if not sline: # print 'Using interface 0...' # self.command('sudo /usr/sbin/tcpdump -lU -c100 -nn -i eth0') # else: # self.command('sudo /usr/sbin/tcpdump -l -c100 -nn ' + sline) # def do_list(self, line): # """list # List all VMs on the Hypervisor. xe vm-list options are supported. # list <slice ID> [params=<param>]""" # sline = self.sanitize(line, bad='Control\s[\w\s\W]+') # if not sline: # self.command('sudo xe vm-list') # else: # self.command('sudo xe vm-list name-label=' + sline) # def do_start(self, line): # """start # Start a VM # start <slice####>""" # sline = self.sanitize(line) # if not sline: # print 'start <slice ID>' # else: # self.command('sudo xe vm-start name-label=' + sline) ##TODO: filter compute info so compute can't be rebooted! # def do_reboot(self, line): # """reboot # Reboot a slice. # reboot <slice####>""" # sline = self.sanitize(line, bad='Control\s[\w\s\W]+') # if not sline: # print 'reboot <slice ID>' # else: # self.command('sudo xe vm-reboot --force name-label=' + sline) # def do_tasks(self, line): # """tasks # Print tasks returned by xe task-list.""" # del line # self.command('sudo xe task-list') # def do_cancel(self, line): # """cancel # Cancel a pending task. # cancel <task UUID>""" # sline = self.sanitize(line) # if not sline: # print 'cancel <task UUID>' # else: # self.command('sudo xe task-cancel uuid=' + sline) # def do_disks(self, line): # """disks # List all vm disks. This will list every vdi and vbd for every slice. # xe vm-disk-list options are supported. # disks <slice ID> [params=<params>]""" # sline = self.sanitize(line) # if not sline: # self.command('sudo xe vm-disk-list --multiple') # else: # self.command('sudo xe vm-disk-list name-label=' + sline) # def do_df(self, line): # """df # Print disk usage statistics.""" # sline = self.sanitize(line) # if not sline: # self.command('df -h') # else: # self.command('df ' + sline) def do_exit(self, line): """exit Exit the tool cleanly.""" del line return True
def __init__(self): self.connect = Connect() self.c = self.connect.connect()
class VmOps: def __init__(self): self.connect = Connect() self.c = self.connect.connect() def test(self): print self.c def vm_list(self, args): # Call ovirtsdk to get vms_service vms_service = self.c.system_service().vms_service() # We check whether prefix has been given or not if args.prefix is not None: search_prefix = 'name=' + args.prefix + '*' else: search_prefix = 'name=' + environ.get('TITAMU_VM_PREFIX') + '*' try: # Get vm list by using vms_service vms = vms_service.list( search=search_prefix, case_sensitive=False, ) rows = [] for vm in vms: addr = "" comment = "" if vm.comment is not None: comment = vm.comment vm_service = vms_service.vm_service(vm.id) # We use reported_devices_service method to get all the # NICs that have IP address assigned for device in vm_service.reported_devices_service().list(): if device.ips is not None and vm.status.value == 'up': for ip in device.ips: # cchen: ip.version is a enum so we have to use "value" to # get its real value we are assuming that only the IP which # starts with '10' is something that we are interested in if ip.version.value == 'v4' and ip.address.startswith( '10'): addr += ip.address + ' ' rows.append( [vm.id, vm.name, vm.status.value.upper(), addr, comment]) output = Output(["ID", "Name", "Status", "Networks", "Comment"], rows) output.print_table() self.c.close() except sdk.Error as err: print "Failed to list VMs, %s" % str(err) def vm_start(self, args): vms_services = self.c.system_service().vms_service() search_prefix = 'name=' + args.vm_name try: vm = vms_services.list(search=search_prefix)[0] vm_service = vms_services.vm_service(vm.id) vm_service.start() self.c.close() except sdk.Error as err: print("Failed to start %s, %s" % (args.vm_name, str(err))) except IndexError: print "Error: No such VM %s" % args.vm_name else: print "The request of starting %s has been sent" % vm.name def vm_stop(self, args): c_obj = Connect() c = c_obj.connect() vms_service = c.system_service().vms_service() search_prefix = 'name=' + args.vm_name try: vm = vms_service.list(search=search_prefix)[0] vm_service = vms_service.vm_service(vm.id) vm_service.stop() self.c.close() except sdk.Error as err: print("Failed to stop %s, %s" % (args.vm_name, str(err))) except IndexError: print "Error: No such VM %s" % args.vm_name else: print "The request of stopping %s has been sent" % vm.name def vm_delete(self, args): vms_service = self.c.system_service().vms_service() search_prefix = 'name=' + args.vm_name try: vm = vms_service.list(search=search_prefix)[0] vm_service = vms_service.vm_service(vm.id) vm_service.remove() self.c.close() except sdk.Error as err: print("Failed to delete %s, %s" % (args.vm_name, str(err))) except IndexError: print "Error: No such VM %s" % args.vm_name else: print "The request of deleting %s has been sent" % vm.name def vm_boot(self, args): vms_service = self.c.system_service().vms_service() if args.vm_raw == '1': template_used = 'Blank' else: template_used = args.temp try: vm = vms_service.add( types.Vm( name=args.vm_name, cluster=types.Cluster( # A little bit dangerous as we hardcoded the cluster name as 'Default' name='Default', ), template=types.Template(name=template_used, ), comment=args.vm_comment, ), ) self.c.close() except sdk.Error as err: print("%s creation failed, %s" % (args.vm_name, str(err))) else: print "The request of creating %s has been sent." % vm.name def vm_console(self, args): vms_service = self.c.system_service().vms_service() search_prefix = 'name=' + args.vm_name try: vm = vms_service.list(search=search_prefix)[0] vm_service = vms_service.vm_service(vm.id) consoles_service = vm_service.graphics_consoles_service() consoles = consoles_service.list(current=True) console = next( (c for c in consoles if c.protocol == types.GraphicsType.VNC), None) if console is not None: # cchen: VNC found and usually we use VNC for our VM display because spice doesn't # work sometimes console_service = consoles_service.console_service(console.id) # cchen: If the password contains "/" then the console can not be opened. while 1: ticket = console_service.ticket() if "/" not in ticket.value: break try: vnc_url = "vnc://:%s@%s:%d" % ( ticket.value, console.address, console.port) if environ.get('TITAMU_DIST') == 'MacOS': # For MacOS we simply let OS open the VNC url. # TODO: Linux to be implemented subprocess.call(["/usr/bin/open", vnc_url]) except IOError as ioerr: print "Can not open console.vv %s" % str(ioerr) elif console is None: # VNC didn't find so the console might be spice console = next((c for c in consoles if c.protocol == types.GraphicsType.SPICE), None) if console is not None: console_service = consoles_service.console_service( console.id) # cchen: Simply call the remote_viewer_connection_file function to get console.vv console_vv = console_service.remote_viewer_connection_file( ) path = "/tmp/console.vv" with open(path, "w") as f: f.write(console_vv) try: if environ.get('TITAMU_DIST') == 'MacOS': # TODO: Linux to be implemented the same as VNC subprocess.call( 'remote-viewer /tmp/console.vv 2>/dev/null', shell=True) except OSError as err: print "Unable to locate remote-viewer application: %s" % err self.c.close() except sdk.Error as err: print str(err) except IndexError: print "Error: No such VM %s" % args.vm_name def vm_show(self, args): vms_service = self.c.system_service().vms_service() try: rows = [] vm = vms_service.list(search=args.vm_name)[0] vm_service = vms_service.vm_service(vm.id) # Print basic information rows.append(["Name", vm.name]) rows.append(["ID", vm.id]) rows.append(["Status", str(vm.status).upper()]) rows.append(["Memory", str(vm.memory / 1024 / 1024) + 'M']) rows.append([ "CPU", vm.cpu.topology.cores * vm.cpu.topology.sockets * vm.cpu.topology.threads ]) # Print Disk information disk_attachments_service = vm_service.disk_attachments_service() disk_attachments = disk_attachments_service.list() for disk_attachment in disk_attachments: disk = self.c.follow_link(disk_attachment.disk) rows.append([ "Disks", [ disk.name, disk.id, str(disk.provisioned_size / 1024 / 1024 / 1024) + 'G' ] ]) # We use nics_service() instead of reported_devices_service() # because we need to get NIC id and name nics_service = vm_service.nics_service().list() for nic in nics_service: for device in nic.reported_devices: if device.ips is not None: for ip in device.ips: if ip.version.value == 'v4': rows.append([ "Active Nics", [ nic.name, nic.mac.address, nic.id, ip.address ] ]) if device.ips is None: rows.append([ "Inactive Nics", [nic.name, nic.mac.address, nic.id] ]) output = Output(["Item", "Value"], rows) output.print_table() except sdk.Error as err: print str(err) except IndexError: print "Error: No such VM %s" % args.vm_name
class NetOps: def __init__(self): self.connect = Connect() self.c = self.connect.connect() def net_list(self, args): networks_service = self.c.system_service().networks_service() try: networks = networks_service.list() rows = [] for network in networks: comment = "" description = "" if network.description is not None: description = network.description if network.comment is not None: comment = network.comment rows.append([network.id, network.name, comment, description]) output = Output(["ID", "Name", "Comment", "Description"], rows) output.print_table() self.c.close() except sdk.Error as err: print "Failed to list networks, %s" % str(err) def net_add(self, args): vms_service = self.c.system_service().vms_service() vm = vms_service.list(search=args.vm_name)[0] nics_service = vms_service.vm_service(vm.id).nics_service() index = len(nics_service.list()) # nics_service.add method takes vnic profile id as the variable, # not the network id. So we have to find out the vnic profile id # by using network id # https://lab-rhevm.gsslab.pek2.redhat.com/ovirt-engine/api/vnicprofiles/00e3cad9-5383-494c-9524-f353b5e2c8be profiles_service = self.c.system_service().vnic_profiles_service() profile_id = None for profile in profiles_service.list(): if profile.network.id == args.net_id: profile_id = profile.id break nic_name = 'nic'+str(index) try: nics_service.add( types.Nic( name=nic_name, description='My network interface card', vnic_profile=types.VnicProfile( id=profile_id, ), ), ) self.c.close() except sdk.Error as err: print "Failed to add NICs to %s, %s" % (args.vm_name, str(err)) def net_rm(self, args): vms_service = self.c.system_service().vms_service() vm = vms_service.list(search=args.vm_name)[0] nic_service = vms_service.vm_service(vm.id).nics_service().nic_service(args.port_id) #nics_service = vms_service.vm_service(vm.id).nics_service() #VmNicService got remove function # http://ovirt.github.io/ovirt-engine-sdk/master/services.m.html#ovirtsdk4.services.HostService.nics_service # nics_service.add method takes vnic profile id as the variable, # not the network id. So we have to find out the vnic profile id # by using network id # https://lab-rhevm.gsslab.pek2.redhat.com/ovirt-engine/api/vnicprofiles/00e3cad9-5383-494c-9524-f353b5e2c8be try: nic_service.remove( types.Nic( name=nic_name, description='My network interface card', vnic_profile=types.VnicProfile( id=profile_id, ), ), ) self.c.close() except sdk.Error as err: print "Failed to add NICs to %s, %s" % (args.vm_name, str(err))