def SHOW_CLUSTER_CONTROLLER_SERVICES(connection, ccs=None, print_method=None, print_table=True): print_method = print_method or connection._show_method hostname_hdr = ('HOSTNAME', 24) name_hdr = ('NAME', 24) cluster_hdr = ('CLUSTER', 24) state_hdr = ('STATE', 16) pt = PrettyTable( [hostname_hdr[0], name_hdr[0], cluster_hdr[0], state_hdr[0]]) pt.max_width[hostname_hdr[0]] = hostname_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.max_width[cluster_hdr[0]] = cluster_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.align = 'l' pt.padding_width = 0 if ccs is None: ccs = connection.get_all_cluster_controller_services() if not isinstance(ccs, list): ccs = [ccs] for cc in ccs: if cc.state == 'ENABLED': state = markup(cc.state, [1, 92]) else: state = markup(cc.state, [1, 91]) pt.add_row( [markup(cc.hostname, [1, 94]), cc.name, cc.partition, state]) if print_table: print_method('\n' + pt.get_string(sortby=cluster_hdr[0]) + '\n') else: return pt
def show_all_accounts(self, account=None, account_name=None, account_id=None, search=False, print_method=None, print_table=True): """ Debug Method to print an account list based on given filter criteria :param account_name: regex - to use for account_name :param account_id: regex - to use for account_id :param search: boolean - specify whether to use match or search when filtering the returned list """ print_method = print_method or self.log.info pt = PrettyTable([markup('ACCOUNT_NAME'), markup('ACCOUNT_ID')]) pt.hrules = 1 pt.align = 'l' if account: if isinstance(account, IamAccount): alist = [account] else: alist = [self.get_account(account)] else: alist = self.get_all_accounts(account_name=account_name, account_id=account_id, search=search) for account in alist: pt.add_row([account.name, account.id]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def SHOW_PROPERTIES_NARROW(connection, properties=None, verbose=True, print_method=None, print_table=True, *prop_names): """ Narrow formatted table used to summarize Eucalyptus properties :param connection: EucaAdmin connection :param properties: list of EucaProperty objs or string names of properties :param verbose: show debug information during table creation :param print_table: bool, if True will print table using connection.debug_method() if False will return the table object :param prop_names: property names used to filter query response """ if not verbose: return connection.show_properties(properties=properties, description=False, print_method=print_method, print_table=print_table) print_method = print_method or connection._show_method info_len = 60 desc_len = 40 markup_size = len(markup('\n')) properties = properties or connection.get_properties(prop_names) pt = PrettyTable(['PROPERTY INFO', 'DESCRIPTION']) pt.max_width['PROPERTY INFO'] = info_len pt.max_width['DESCRIPTION'] = desc_len pt.align = 'l' pt.padding_width = 0 pt.hrules = 1 if not isinstance(properties, list): properties = [properties] for prop in properties: if not isinstance(prop, EucaProperty) and isinstance(prop, basestring): props = connection.get_properties(prop) if not props: continue else: props = [prop] for p in props: info_buf = "NAME: " prefix = "" line_len = info_len - markup_size - len('NAME: ') for i in xrange(0, len(p.name), line_len): if i: prefix = " " info_buf += (str(prefix + markup(p.name[i:i+line_len], [1, 94])) .ljust(info_len-2) + "\n") info_buf += 'VALUE: ' prefix = "" line_len = info_len - markup_size - len('VALUE: ') for i in xrange(0, len(p.value), line_len): if i: prefix = " " info_buf += (prefix + markup(p.value[i:i+line_len]) + "\n") desc_buf = markup('DESCRIPTION:').ljust(desc_len) + str(p.description).ljust(desc_len) pt.add_row([info_buf, desc_buf]) if not pt._rows: pt.add_row([markup('NO PROPERTIES RETURNED', [1, 91]), ""]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def show_all_groups(self, account_name=None, account_id=None, path=None, group_name=None, group_id=None, search=False, print_method=None, print_table=True): """ Print all groups in an account :param account_name: regex - to use for account_name :param account_id: regex - to use for :param path: regex - to match for path :param group_name: regex - to match for user_name :param group_id: regex - to match for user_id :param search: boolean - specify whether to use match or search when filtering the returned list """ print_method = print_method or self.log.info pt = PrettyTable([markup('ACCOUNT:'), markup('GROUPNAME:'), markup('GROUP_ID:')]) pt.hrules = 1 pt.align = 'l' glist = self.get_all_groups(account_name=account_name, account_id=account_id, path=path, group_name=group_name, group_id=group_id, search=search) for group in glist: pt.add_row([group['account_name'], group['group_name'], group['group_id']]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def SHOW_CLUSTER_CONTROLLER_SERVICES(connection, ccs=None, print_method=None, print_table=True): print_method = print_method or connection._show_method hostname_hdr = ('HOSTNAME', 24) name_hdr = ('NAME', 24) cluster_hdr = ('CLUSTER', 24) state_hdr = ('STATE', 16) pt = PrettyTable([hostname_hdr[0], name_hdr[0], cluster_hdr[0], state_hdr[0]]) pt.max_width[hostname_hdr[0]] = hostname_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.max_width[cluster_hdr[0]] = cluster_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.align = 'l' pt.padding_width = 0 if ccs is None: ccs = connection.get_all_cluster_controller_services() if not isinstance(ccs, list): ccs = [ccs] for cc in ccs: if cc.state == 'ENABLED': state = markup(cc.state, [1, 92]) else: state = markup(cc.state, [1, 91]) pt.add_row([markup(cc.hostname, [1, 94]), cc.name, cc.partition, state]) if print_table: print_method('\n' + pt.get_string(sortby=cluster_hdr[0]) + '\n') else: return pt
def get_val_from_host(ip, host, lookup=lookup): # Traverse attrs to retrieve the end value... if host_attr_chain: obj = host with hostlock: for attr in host_attr_chain: try: obj = getattr(obj, attr) except AttributeError as AE: obj = None errmsg = markup('{0}:{1}'.format(host, str(AE)), [1, 31]) debug(errmsg, host, err=True) value = obj # Use the host method... elif host_method_name: method = getattr(host, host_method_name, None) if method: value = method(**host_method_kwargs) with hostlock: debug(markup('Got value for host: "{0}.{1}" = "{2}"' .format(ip, lookup, value), [1, 94]), host) if value_dict.get(value) is not None: value_dict[value].append(ip) else: value_dict[value] = [ip]
def menu_summary(self, args): """Prints Summary of commands and sub-menu items""" menu_color = [1, 4, 34] # bold, underlined, blue prevname = None names = self.get_names() menu_items = [] maxlen = 0 main_pt = pt = PrettyTable(['MAIN']) main_pt.header = False main_pt.border = False main_pt.align = 'l' sub_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) base_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) current_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) for table in [sub_pt, base_pt, current_pt]: table.header = False table.border = False table.align = 'l' #Sort out methods that begin with 'do_' as menu items... for name in names: if name[:3] == 'do_': if name == prevname: continue prevname = name if len(name[3:]) > maxlen: maxlen = len(name[3:]) menu_items.append(name) #Sort out menu items into: submenus, local commands, and globals for name in menu_items: cmd = str(name[3:]) cmd_method = getattr(self, name) doc = str(cmd_method.__doc__) or '' doc = doc.lstrip().splitlines()[0].strip() if hasattr(cmd_method,'__submenu__'): if hasattr(BaseMenu, name): base_pt.add_row(["\t{0}".format(markup(cmd, markups=menu_color)), markup(doc, markups=menu_color)]) else: current_pt.add_row(["\t{0}".format(markup(cmd, markups=menu_color)), markup(doc, markups=menu_color)]) else: if hasattr(BaseMenu, name): base_pt.add_row(["\t{0}".format(yellow(cmd, bold=True)), doc]) else: current_pt.add_row(["\t{0}".format(yellow(cmd, bold=True)), doc]) buf = "{0}\n".format(cyan('*** ' + self.name.upper() + ' OPTIONS ***', bold=True)) if current_pt._rows: # Add blank line for formatting, separate menu items from commands #current_pt.add_row(["\t{0}".format(yellow(" ", bold=True)), ""]) buf += "{0}\n".format(current_pt.get_string(sortby='COMMAND')) if sub_pt._rows: buf += "{0}\n".format(sub_pt) if base_pt._rows: buf += "{0}\n{1}\n".format(cyan('*** BASE COMMANDS ***', bold=True), base_pt) main_pt.add_row([buf]) self.oprint("{0}".format(main_pt))
def show_all_users(self, users=None, account_name=None, account_id=None, path=None, user_name=None, user_id=None, search=False, print_method=None, print_table=True): """ Debug Method to print a user list based on given filter criteria :param account_name: regex - to use for account_name :param account_id: regex - to use for :param path: regex - to match for path :param user_name: regex - to match for user_name :param user_id: regex - to match for user_id :param search: boolean - specify whether to use match or search when filtering the returned list """ print_method = print_method or self.log.info pt = PrettyTable([ markup('ACCOUNT:'), markup('USERNAME:'******'USER_ID'), markup('ACCT_ID') ]) pt.hrules = 1 pt.align = 'l' if users: if not isinstance(users, list): ulist = [users] else: ulist = users for user in ulist: if not isinstance(user, IamUser): raise ValueError( 'show_all_users got non IAMUser type: "{0}/{1}"'. format(user, type(user))) else: ulist = self.get_all_users(account_name=account_name, account_id=account_id, path=path, user_name=user_name, user_id=user_id, search=search) for user in ulist: pt.add_row( [user.account_name, user.name, user.id, user.account_id]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def SHOW_COMPONENTS(connection, components=None, get_method=None, print_method=None, print_table=True): """ Base method for summarizing Eucalyptus components in a table format :param connection: EucaAdmin connection :param components: EucaServiceComponent objs :param get_method: method used to retrieve a list of components to summarize (ie get_all_cluster_controller_services) :param print_table: bool, if True will attempt to print the table to connection.debug_method, if False will return the table obj """ print_method = print_method or connection._show_method if not components: if not get_method: raise ValueError( '_show_component(). Components or get_method must be populated' ) components = get_method() if not isinstance(components, list): components = [components] hostname_hdr = ('HOSTNAME', 24) name_hdr = ('NAME', 50) cluster_hdr = ('PARTITION', 24) state_hdr = ('STATE', 16) type_hdr = ('TYPE', 16) pt = PrettyTable([ hostname_hdr[0], name_hdr[0], cluster_hdr[0], state_hdr[0], type_hdr[0] ]) pt.max_width[hostname_hdr[0]] = hostname_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.max_width[cluster_hdr[0]] = cluster_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.max_width[type_hdr[0]] = type_hdr[1] pt.align = 'l' pt.padding_width = 0 for component in components: if component.state == 'ENABLED': state = markup(component.state, [1, 92]) else: state = markup(component.state, [1, 91]) pt.add_row([ markup(component.hostname, [1, 94]), component.name, component.partition, state, component.type ]) if print_table: print_method('\n' + pt.get_string(sortby=cluster_hdr[0]) + '\n') else: return pt
def show_summary(self, printmethod=None, print_table=True): printmethod = printmethod or self.connection._show_method pt = self.show_machine_mapping(print_table=False) if print_table: printmethod('\n\t{0}"{1}"\n{2}'.format(markup('\nCLUSTER:'), self.name, str(pt))) else: return pt
def get_repo_file_by_baseurl(self, url, repopath=None, cleanurl=True, filters=None): """ Attempts to find a file containing repo info at 'repopath' by matching the provided 'url' to the 'baseurl' entries, and return a namespace obj with info of the key=value info found. :param url: string, baseurl to search repo files for :param repopath: dir to search for files :param cleanurl: bool, attempts to format an url to a typical baseurl :param filters: list of strings. Will match a subset of the keys found and only return those keys matching a filter. :returns namespace with repo info or None upon error, file not found, etc.. """ if repopath is None: repopath = '/etc/yum.repos.d/*' if cleanurl: try: match = re.match('^(http://\S+/x86_64)', url) if match: url = match.group(1) except: pass try: out = self.machine.sys('grep "{0}" {1} -l'.format(url, repopath), code=0) except CommandExitCodeException as CE: self.machine.log.error(markup('Could not find repo for url:"{0}", err:"{1}"' .format(url, str(CE)), markups=[1, 31])) return None if out: filepath = out[0] if re.search('^{0}'.format(repopath), filepath): return self.get_repo_file(filepath, filters=filters) return None
def status_log(self, msg): return self.log.info( markup(msg, markups=[ ForegroundColor.WHITE, BackGroundColor.BG_GREEN, TextStyle.BOLD ]))
def show_packet_test_results(self, results_dict, header=None, printmethod=None, printme=True): if not results_dict: self.log.warning("Empty results dict passed to show_packet_test_results") return protocol = results_dict.get("protocol", "???") header = header or "PACKET_TEST_RESULTS" main_pt = PrettyTable([header]) main_pt.align = "l" main_pt.padding_width = 0 main_pt.add_row(["{0}".format(results_dict.get("name"))]) main_pt.add_row( ["Elapsed:{0}, Packet Count:{1}".format(results_dict.get("elapsed"), results_dict.get("count"))] ) if results_dict.get("error"): main_pt.add_row(["ERROR: {0}".format(markup(results_dict.get("error"), [1, 91]))]) pt = PrettyTable(["pkt_src_addr", "pkt_dst_addr", "protocol", "port", "pkt_count"]) for src_addr, s_dict in results_dict.get("packets", {}).iteritems(): for dst_addr, d_dict in s_dict.iteritems(): for port, count in d_dict.iteritems(): pt.add_row([src_addr, dst_addr, protocol, port, count]) main_pt.add_row(["{0}".format(pt)]) if not printme: return main_pt printmethod = printmethod or self.log.info printmethod("\n{0}\n".format(main_pt))
def get_repo_file(self, filepath, filters=None): """ Read in repo key=value info from a file at 'filepath'. :param filepath: string, filepath containing repo info on remote machine :param filters: list of strings. Will match a subset of the keys found and only return those keys matching a filter. :returns namespace obj with repo info or None. """ filter_values = filters or [] values = {'filepath': filepath} try: out = self.machine.sys('cat {0}'.format(filepath), code=0) except CommandExitCodeException as CE: self.machine.log.error( markup('Failed to read repo_file at:"{0}", err:"{1}"'.format( filepath, str(CE)), markups=[1, 31])) return None for line in out: valname = None value = None if not line: continue valmatch = re.search('\s*(\w.*)\s*=\s*(\w.*)\s*$', line) if valmatch: valname = valmatch.group(1) value = valmatch.group(2) else: namematch = re.search('^\s*\[\s*(\S*)\s*\]\s*$', line) if namematch: valname = 'repo_name' value = namematch.group(1) if valname and value is not None: values[valname] = value if not values: self.machine.log.error( markup('No values parsed from:"{0}"'.format(filepath), markups=[1, 31])) return None if not filters: return RepoFile(**values) ret = RepoFile() for name in filters: if name in values: setattr(ret, name, values[name]) setattr(ret, 'filepath', str(filepath or "")) return ret
def get_repo_file(self, filepath, filters=None): """ Read in repo key=value info from a file at 'filepath'. :param filepath: string, filepath containing repo info on remote machine :param filters: list of strings. Will match a subset of the keys found and only return those keys matching a filter. :returns namespace obj with repo info or None. """ filter_values = filters or [] values = {'filepath': filepath} try: out = self.machine.sys('cat {0}'.format(filepath), code=0) except CommandExitCodeException as CE: self.machine.log.error(markup('Failed to read repo_file at:"{0}", err:"{1}"' .format(filepath, str(CE)), markups=[1, 31])) return None for line in out: valname = None value = None if not line: continue valmatch = re.search('\s*(\w.*)\s*=\s*(\w.*)\s*$', line) if valmatch: valname = valmatch.group(1) value = valmatch.group(2) else: namematch = re.search('^\s*\[\s*(\S*)\s*\]\s*$', line) if namematch: valname = 'repo_name' value = namematch.group(1) if valname and value is not None: values[valname] = value if not values: self.machine.log.error(markup('No values parsed from:"{0}"' .format(filepath), markups=[1, 31])) return None if not filters: return RepoFile(**values) ret = RepoFile() for name in filters: if name in values: setattr(ret, name, values[name]) setattr(ret, 'filepath', str(filepath or "")) return ret
def SHOW_COMPONENTS(connection, components=None, get_method=None, print_method=None, print_table=True): """ Base method for summarizing Eucalyptus components in a table format :param connection: EucaAdmin connection :param components: EucaServiceComponent objs :param get_method: method used to retrieve a list of components to summarize (ie get_all_cluster_controller_services) :param print_table: bool, if True will attempt to print the table to connection.debug_method, if False will return the table obj """ print_method = print_method or connection._show_method if not components: if not get_method: raise ValueError('_show_component(). Components or get_method must be populated') components = get_method() if not isinstance(components, list): components = [components] hostname_hdr = ('HOSTNAME', 24) name_hdr = ('NAME', 50) cluster_hdr = ('PARTITION', 24) state_hdr = ('STATE', 16) type_hdr = ('TYPE', 16) pt = PrettyTable([hostname_hdr[0], name_hdr[0], cluster_hdr[0], state_hdr[0], type_hdr[0]]) pt.max_width[hostname_hdr[0]] = hostname_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.max_width[cluster_hdr[0]] = cluster_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.max_width[type_hdr[0]] = type_hdr[1] pt.align = 'l' pt.padding_width = 0 for component in components: if component.state == 'ENABLED': state = markup(component.state, [1, 92]) else: state = markup(component.state, [1, 91]) pt.add_row([markup(component.hostname, [1, 94]), component.name, component.partition, state, component.type]) if print_table: print_method('\n' + pt.get_string(sortby=cluster_hdr[0]) + '\n') else: return pt
def show_cluster(connection, cluster, printmethod=None, print_table=True): printmethod = printmethod or connection._show_method maintpt = PrettyTable([markup('CLUSTER: {0}'.format(cluster.name))]) machpt = connection.show_machine_mappings(machine_dict=cluster.machines, print_table=False) maintpt.add_row([machpt.get_string(sortby=machpt.field_names[1], reversesort=True)]) proppt = connection.show_properties(cluster.properties, print_table=False) maintpt.add_row([proppt.get_string()]) if print_table: printmethod("\n{0}\n".format(maintpt)) else: return maintpt
def show_all_groups(self, account_name=None, account_id=None, path=None, group_name=None, group_id=None, search=False, print_method=None, print_table=True): """ Print all groups in an account :param account_name: regex - to use for account_name :param account_id: regex - to use for :param path: regex - to match for path :param group_name: regex - to match for user_name :param group_id: regex - to match for user_id :param search: boolean - specify whether to use match or search when filtering the returned list """ print_method = print_method or self.log.info pt = PrettyTable( [markup('ACCOUNT:'), markup('GROUPNAME:'), markup('GROUP_ID:')]) pt.hrules = 1 pt.align = 'l' glist = self.get_all_groups(account_name=account_name, account_id=account_id, path=path, group_name=group_name, group_id=group_id, search=search) for group in glist: pt.add_row([ group['account_name'], group['group_name'], group['group_id'] ]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def show_euca_process_summary(self, printmethod=None, print_table=True): printmethod = printmethod or self.log.info ps_sum = self.get_euca_process_summary() serv_hdr = markup('HOST SERVICE', [1, 4]) pt = PrettyTable([ serv_hdr, markup('COMMAND', [1, 4]), markup('%CPU', [1, 4]), markup('%MEM', [1, 4]), markup('PS_UPTIME', [1, 4]) ]) pt.align = 'l' pt.align[serv_hdr] = 'r' pt.border = 0 for service, command_dict in ps_sum.iteritems(): pt.add_row([markup(service + ":", [1, 32]), "", "", "", ""]) for command, info in command_dict.iteritems(): pt.add_row([ " --->", command, info.get('%CPU', None), info.get('%MEM', None), info.get('ELAPSED', None) ]) if print_table: printmethod("\n{0}\n".format(pt)) else: return pt
def show_availability_for_node(self, printmethod=None, print_table=True): printmethod = printmethod or self.eucahost.log.info vmtypes = self.get_vm_availability() cap = self.get_last_capacity_status() main_pt = PrettyTable( [markup('("{0}"\'s VM AVAILABILITY @ {1})').format(self.eucahost.hostname, cap.get('timestamp'))]) main_pt.border = 0 main_pt.align = 'l' cpu_hdr = markup('CPU({0}/{1})'.format(cap.get('cores'), cap.get('cores_total'))) mem_hdr = markup('MEM({0}/{1})'.format(cap.get('mem'), cap.get('mem_total'))) disk_hdr = markup('DISK({0}/{1})'.format(cap.get('disk'), cap.get('disk_total'))) vm_hdr = markup('VMTYPE') av_hdr = markup('AVAIL') pt = PrettyTable([vm_hdr, av_hdr, cpu_hdr, mem_hdr, disk_hdr]) pt.align = 'l' pt.align[cpu_hdr] = 'c' pt.align[av_hdr] = 'c' pt.border = 1 pt.vrules = 2 pt.hrules = 0 pt.padding_width = 0 for t in vmtypes: pt.add_row([t.name, "{0} / {1}".format(t.current, t.total), t.cores, t.memory, t.disk]) main_pt.add_row([pt]) if print_table: printmethod("\n{0}\n".format(main_pt)) else: return main_pt
def SHOW_NODES(connection, nodes=None, print_method=None, print_table=True): ''' Prints table summary of nodes. :params nodes: Can be a single, or list of EucaNodeService objects. Can be a single, or list of node names (strings). :param print_table: bool, if true will write table to self.debug_method, if false, will return the table object w/o printing it. ''' print_method = print_method or connection._show_method if not nodes: nodes_list = connection.get_all_node_controller_services() else: nodes_list = [] if not isinstance(nodes, list): nodes = [nodes] for node in nodes: if isinstance(node, EucaNodeService): nodes_list.append(node) elif isinstance(node, basestring): nodes_list.append(connection.get_node_controller_service(name=str(node))) else: raise ValueError('show_nodes: Unknown type for node: "{0}:{1}"' .format(node, type(node))) ins_id_len = 10 ins_type_len = 13 ins_dev_len = 16 ins_st_len = 15 zone_hdr = (markup('ZONE'), 20) name_hdr = (markup('NODE NAME'), 30) state_hdr = (markup('STATE'), 20) inst_hdr = (markup('INSTANCES'), (ins_id_len + ins_dev_len + ins_type_len + ins_st_len) + 5) pt = PrettyTable([zone_hdr[0], name_hdr[0], state_hdr[0], inst_hdr[0]]) pt.max_width[zone_hdr[0]] = zone_hdr[1] pt.max_width[inst_hdr[0]] = inst_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.padding_width = 0 pt.hrules = 1 for node in nodes_list: instances = "".join("{0}({1}{2}{3})" .format(str(x.id).ljust(ins_id_len), str(x.state + ",").ljust(ins_st_len), str(x.instance_type + ",").ljust(ins_type_len), str(x.root_device_type).ljust(ins_dev_len)) .ljust(inst_hdr[1]) for x in node.instances) instances.strip() if node.state == 'ENABLED': markups = [1, 92] else: markups = [1, 91] pt.add_row([node.partition, markup(node.name), markup(node.state, markups), instances]) if print_table: print_method('\n' + pt.get_string(sortby=zone_hdr[0]) + '\n') else: return pt
def get_url_for_package(self, package_name): if package_name in self.repo_url_cache: if (time.time() - self.repo_url_cache[package_name]['updated']) <= 10: return self.repo_url_cache[package_name]['url'] out = self.machine.sys('yumdownloader --urls eucalyptus -q', code=0) for line in out: match = re.match("^(http*.*.rpm)$", line) if match: line = match.group(1) self.repo_url_cache[package_name] = {'updated': time.time(), 'url': line} return line self.machine.log.error(markup('URL not found for local package:"{0}"' .format(package_name), markups=[1, 31]))
def show_all_users(self, users=None, account_name=None, account_id=None, path=None, user_name=None, user_id=None, search=False, print_method=None, print_table=True): """ Debug Method to print a user list based on given filter criteria :param account_name: regex - to use for account_name :param account_id: regex - to use for :param path: regex - to match for path :param user_name: regex - to match for user_name :param user_id: regex - to match for user_id :param search: boolean - specify whether to use match or search when filtering the returned list """ print_method = print_method or self.log.info pt = PrettyTable([markup('ACCOUNT:'), markup('USERNAME:'******'USER_ID'), markup('ACCT_ID')]) pt.hrules = 1 pt.align = 'l' if users: if not isinstance(users, list): ulist = [users] else: ulist = users for user in ulist: if not isinstance(user, IamUser): raise ValueError('show_all_users got non IAMUser type: "{0}/{1}"' .format(user, type(user))) else: ulist = self.get_all_users(account_name=account_name, account_id=account_id, path=path, user_name=user_name, user_id=user_id, search=search) for user in ulist: pt.add_row([user.account_name, user.name, user.id, user.account_id]) if print_table: print_method("\n" + str(pt) + "\n") else: return pt
def test3_download(self): """ Attempts to download the SOS reports from each host in the cloud and store in a local directory """ error_msg = "" count = 0 err_count = 0 host_count = len(self.ip_list) for ip in self.ip_list: if self.tc: if ip in self.tc.sysadmin.eucahosts.keys(): host = self.tc.sysadmin.eucahosts.get(ip) ssh = host.ssh else: ssh = SshConnection(host=ip, password=self.args.password) try: remote_tarball_path = ssh.sys( "ls -1 {0}/*.xz | grep {1}".format(self.remote_dir, self.ticket_number), code=0)[0] tarball_name = os.path.basename(remote_tarball_path) local_name = "sosreport-{0}.{1}{2}".format( ip, self.ticket_number, tarball_name.split(str(self.ticket_number))[1]) local_tarball_path = os.path.join(self.args.local_dir, local_name) self.log.debug("Downloading file to: " + local_tarball_path) ssh.sftp_get(localfilepath=local_tarball_path, remotefilepath=remote_tarball_path) except Exception, e: err_count += 1 msg = '\nError Downloading from: {0}. Error:"{0}"\n'.format( ip, e) self.log.error("{0}\n{1}".format(get_traceback(), msg)) error_msg += msg else: count += 1 self.log.info( markup('Downloaded SOS report {0}/{1} to:{2}'.format( count, host_count, local_tarball_path), markups=[ ForegroundColor.WHITE, BackGroundColor.BG_GREEN ]))
def get_url_for_package(self, package_name): if package_name in self.repo_url_cache: if (time.time() - self.repo_url_cache[package_name]['updated']) <= 10: return self.repo_url_cache[package_name]['url'] out = self.machine.sys( 'yumdownloader --urls {0} -q'.format(package_name), code=0) for line in out: match = re.match("^(http*.*.rpm)$", line) if match: line = match.group(1) self.repo_url_cache[package_name] = { 'updated': time.time(), 'url': line } return line self.machine.log.error( markup( 'URL not found for local package:"{0}"'.format(package_name), markups=[1, 31]))
def get_repo_file_by_baseurl(self, url, repopath=None, cleanurl=True, filters=None): """ Attempts to find a file containing repo info at 'repopath' by matching the provided 'url' to the 'baseurl' entries, and return a namespace obj with info of the key=value info found. :param url: string, baseurl to search repo files for :param repopath: dir to search for files :param cleanurl: bool, attempts to format an url to a typical baseurl :param filters: list of strings. Will match a subset of the keys found and only return those keys matching a filter. :returns namespace with repo info or None upon error, file not found, etc.. """ if repopath is None: repopath = '/etc/yum.repos.d/*' if cleanurl: try: match = re.match('^(http://\S+/x86_64)', url) if match: url = match.group(1) except: pass try: out = self.machine.sys('grep "{0}" {1} -l'.format(url, repopath), code=0) except CommandExitCodeException as CE: self.machine.log.error( markup('Could not find repo for url:"{0}", err:"{1}"'.format( url, str(CE)), markups=[1, 31])) return None if out: filepath = out[0] if re.search('^{0}'.format(repopath), filepath): return self.get_repo_file(filepath, filters=filters) return None
def clean_all_test_resources(self): fault_buf = "" for resource_name, resource_list in self.test_resources.iteritems(): clean_method = self.test_resources_clean_methods.get(resource_name, None) if clean_method: try: try: clean_method_name = clean_method.__func__.__name__ except: clean_method_name = str(clean_method) self.log.debug('Attempting to clean test resources of type:"{0}", ' 'method:"{1}", artifacts:"{2}"' .format(resource_name, clean_method_name, resource_list)) clean_method(resource_list) except Exception as E: fault_buf += "{0}\n{1}\n".format(get_traceback(), markup('Error while attempting to remove ' 'test resource type:"{0}", ' 'error:"{1}"' .format(resource_name, E))) if fault_buf: raise CleanTestResourcesException(fault_buf)
def test3_download(self): """ Attempts to download the SOS reports from each host in the cloud and store in a local directory """ error_msg = "" count = 0 err_count = 0 host_count = len(self.ip_list) for ip in self.ip_list: if self.tc: if ip in self.tc.sysadmin.eucahosts.keys(): host = self.tc.sysadmin.eucahosts.get(ip) ssh = host.ssh else: ssh = SshConnection(host=ip, password=self.args.password) try: remote_tarball_path = ssh.sys("ls -1 {0}/*.xz | grep {1}" .format(self.remote_dir, self.ticket_number), code=0)[0] tarball_name = os.path.basename(remote_tarball_path) local_name = "sosreport-{0}.{1}{2}".format(ip, self.ticket_number, tarball_name.split(str(self.ticket_number))[1]) local_tarball_path = os.path.join(self.args.local_dir, local_name) self.log.debug("Downloading file to: " + local_tarball_path) ssh.sftp_get(localfilepath=local_tarball_path, remotefilepath=remote_tarball_path) except Exception, e: err_count += 1 msg = '\nError Downloading from: {0}. Error:"{0}"\n'.format(ip, e) self.log.error("{0}\n{1}".format(get_traceback(), msg)) error_msg += msg else: count += 1 self.log.info(markup('Downloaded SOS report {0}/{1} to:{2}' .format(count, host_count, local_tarball_path), markups=[ForegroundColor.WHITE, BackGroundColor.BG_GREEN]))
def show_packet_test_results(self, results_dict, header=None, printmethod=None, printme=True): if not results_dict: self.log.warning('Empty results dict passed to show_packet_test_results') return protocol = results_dict.get('protocol', "???") header = header or 'PACKET_TEST_RESULTS' main_pt = PrettyTable([header]) main_pt.align = 'l' main_pt.padding_width = 0 main_pt.add_row(["{0}".format(results_dict.get('name'))]) main_pt.add_row(["Elapsed:{0}, Packet Count:{1}".format(results_dict.get('elapsed'), results_dict.get('count'))]) if results_dict.get('error'): main_pt.add_row(["ERROR: {0}".format(markup(results_dict.get('error'), [1, 91]))]) pt = PrettyTable(['pkt_src_addr', 'pkt_dst_addr', 'protocol', 'port', 'pkt_count']) for src_addr, s_dict in results_dict.get('packets', {}).iteritems(): for dst_addr, d_dict in s_dict.iteritems(): for port, count in d_dict.iteritems(): pt.add_row([src_addr, dst_addr, protocol, port, count]) main_pt.add_row(["{0}".format(pt)]) if not printme: return main_pt printmethod = printmethod or self.log.info printmethod("\n{0}\n".format(main_pt))
def clean_all_test_resources(self): fault_buf = "" for resource_name, resource_list in self.test_resources.iteritems(): clean_method = self.test_resources_clean_methods.get( resource_name, None) if clean_method: try: try: clean_method_name = clean_method.__func__.__name__ except: clean_method_name = str(clean_method) self.log.debug( 'Attempting to clean test resources of type:"{0}", ' 'method:"{1}", artifacts:"{2}"'.format( resource_name, clean_method_name, resource_list)) clean_method(resource_list) except Exception as E: fault_buf += "{0}\n{1}\n".format( get_traceback(), markup('Error while attempting to remove ' 'test resource type:"{0}", ' 'error:"{1}"'.format(resource_name, E))) if fault_buf: raise CleanTestResourcesException(fault_buf)
def show_euca_process_summary(self, printmethod=None, print_table=True): printmethod = printmethod or self.log.info ps_sum = self.get_euca_process_summary() serv_hdr = markup('HOST SERVICE', [1, 4]) pt = PrettyTable([serv_hdr, markup('COMMAND', [1, 4]), markup('%CPU', [1, 4]), markup('%MEM', [1, 4]), markup('PS_UPTIME', [1, 4])]) pt.align = 'l' pt.align[serv_hdr] = 'r' pt.border = 0 for service, command_dict in ps_sum.iteritems(): pt.add_row([markup(service + ":", [1, 32]), "", "", "", ""]) for command, info in command_dict.iteritems(): pt.add_row([" --->", command, info.get('%CPU', None), info.get('%MEM', None), info.get('ELAPSED', None)]) if print_table: printmethod("\n{0}\n".format(pt)) else: return pt
def show_availability_for_node(self, printmethod=None, print_table=True): printmethod = printmethod or self.eucahost.log.info vmtypes = self.get_vm_availability() cap = self.get_last_capacity_status() main_pt = PrettyTable([ markup('("{0}"\'s VM AVAILABILITY @ {1})').format( self.eucahost.hostname, cap.get('timestamp')) ]) main_pt.border = 0 main_pt.align = 'l' cpu_hdr = markup('CPU({0}/{1})'.format(cap.get('cores'), cap.get('cores_total'))) mem_hdr = markup('MEM({0}/{1})'.format(cap.get('mem'), cap.get('mem_total'))) disk_hdr = markup('DISK({0}/{1})'.format(cap.get('disk'), cap.get('disk_total'))) vm_hdr = markup('VMTYPE') av_hdr = markup('AVAIL') pt = PrettyTable([vm_hdr, av_hdr, cpu_hdr, mem_hdr, disk_hdr]) pt.align = 'l' pt.align[cpu_hdr] = 'c' pt.align[av_hdr] = 'c' pt.border = 1 pt.vrules = 2 pt.hrules = 0 pt.padding_width = 0 for t in vmtypes: pt.add_row([ t.name, "{0} / {1}".format(t.current, t.total), t.cores, t.memory, t.disk ]) main_pt.add_row([pt]) if print_table: printmethod("\n{0}\n".format(main_pt)) else: return main_pt
def run_instance_with_user(user): my_error = {} err_string = "" instance_str = "" setattr(user, "results", {}) instances = [] vpc_ids = [] subnet_ids = [] my_md_times = {} my_clc_times = None try: emi = user.ec2.get_emi( root_device_type="instance-store", filters={"virtualization-type": "hvm"}, basic_image=True ) key = user.ec2.create_keypair_and_localcert( "key_{0}_{1}_{2}".format(user.account_name, user.user_name, int(time.time())) ) if not key: raise RuntimeError( "Could not find or create key for account/user:{0}/{1}".format(user.account_name, user.user_name) ) group = user.ec2.add_group("group_{0}_{1}".format(user.account_name, user.user_name)) user.ec2.authorize_group(group=group, port=22, protocol="tcp") user.ec2.authorize_group(group=group, port=-1, protocol="icmp") start = time.time() for zone, count in zones.iteritems(): instances += user.ec2.run_image( image=emi, keypair=key, group=group, min=count, max=count, zone=zone, timeout=instance_timeout, monitor_to_running=False, clean_on_fail=False, auto_connect=True, ) for i in instances: if not i.vpc_id in vpc_ids: vpc_ids.append(i.vpc_id) if not i.subnet_id in subnet_ids: subnet_ids.append(i.subnet_id) elapsed = int(time.time() - start) my_clc_times = get_clc_artifacts_for_vpc(user, vpc_ids, subnet_ids, addtime=elapsed) elapsed = int(time.time() - start) my_md_times = wait_for_mido_metadata_nat_rule(instances, addtime=elapsed) user.ec2.monitor_euinstances_to_running(instances, timeout=instance_timeout) instance_str = "\n".join("{0}:{1}".format(x.id, x.placement) for x in instances) my_results = {"user": str(user), "result": "PASSED", "instances": instance_str} except Exception as E: user.log.debug("{0}\nError:{1}".format(get_traceback(), E)) err_string += "{0}\nError:{1}".format(get_traceback(), E) my_results = {"user": str(user), "result": markup("FAILED", [1, 91]), "instances": instance_str} try: for vpc_id in vpc_ids: cmd = "ps aux | grep {0}".format(vpc_id) err_string += "\nCLC CMD#: {0}\n".format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error("Failed to get vpc process info from clc:" + str(E)) finally: err_string += "(CMD DONE)\n" try: for vpc_id in vpc_ids: cmd = "ifconfig | grep {0}".format(str(vpc_id).lstrip("vpc-")) err_string += "\nCLC CMD#: {0}\n".format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error("Failed to get vpc ifconfig info from clc:" + str(E)) finally: err_string += "(CMD DONE)\n" try: for subnet_id in subnet_ids: cmd = "ifconfig | grep {0}".format(str(subnet_id).lstrip("subnet-")) err_string += "\nCLC CMD#: {0}\n".format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error("Failed to get subnet ifconfig info from clc:" + str(E)) finally: err_string += "(CMD DONE)\n" for i in instances: try: cmd = "grep {0} /var/run/eucalyptus/eucanetd_vpc_instance_ip_map".format(i.id) err_string += "\nCLC CMD#: {0}\n".format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error("Failed to get vpc nginx map info from clc:" + str(E)) finally: err_string += "(CMD DONE)\n" err_string += i.get_cloud_init_info_from_console() + "\n" finally: try: for ins in instances: if ins and ins.ssh: ins.ssh.close() ins = None instances = None except Exception as E: err_string += "{0}\nError:{1}".format(get_traceback(), E) user.log.warn("") user.results = my_results with userlock: if err_string: my_error = {"user": str(user), "error": err_string} errors.append(my_error) if my_clc_times: for key, value in my_clc_times.iteritems(): clc_times[key] = value if my_md_times: for key, value in my_md_times.iteritems(): mido_md_times[key] = value
def run_instance_with_user(user): my_error = {} err_string = "" instance_str = "" setattr(user, 'results', {}) instances = [] vpc_ids = [] subnet_ids = [] my_md_times = {} my_clc_times = None try: emi = user.ec2.get_emi(root_device_type='instance-store', filters={'virtualization-type': 'hvm'}, basic_image=True) key = user.ec2.create_keypair_and_localcert('key_{0}_{1}_{2}' .format(user.account_name, user.user_name, int(time.time()))) if not key: raise RuntimeError('Could not find or create key for account/user:{0}/{1}' .format(user.account_name, user.user_name)) group = user.ec2.add_group('group_{0}_{1}'.format(user.account_name, user.user_name)) user.ec2.authorize_group(group=group, port=22, protocol='tcp') user.ec2.authorize_group(group=group, port=-1, protocol='icmp') start = time.time() for zone, count in zones.iteritems(): instances += user.ec2.run_image(image=emi, keypair = key, group=group, min=count, max=count, zone=zone, timeout=instance_timeout, monitor_to_running=False, clean_on_fail=False, auto_connect=True) for i in instances: if not i.vpc_id in vpc_ids: vpc_ids.append(i.vpc_id) if not i.subnet_id in subnet_ids: subnet_ids.append(i.subnet_id) elapsed = int(time.time() - start) my_clc_times = get_clc_artifacts_for_vpc(user, vpc_ids, subnet_ids, addtime=elapsed) elapsed = int(time.time() - start) my_md_times = wait_for_mido_metadata_nat_rule(instances, addtime=elapsed) user.ec2.monitor_euinstances_to_running(instances, timeout=instance_timeout) instance_str = "\n".join("{0}:{1}".format(x.id, x.placement) for x in instances) my_results = {'user':str(user), 'result':'PASSED', 'instances':instance_str} except Exception as E: user.log.debug('{0}\nError:{1}'.format(get_traceback(), E)) err_string += '{0}\nError:{1}'.format(get_traceback(), E) my_results = {'user':str(user), 'result': markup('FAILED', [1, 91]), 'instances':instance_str} try: for vpc_id in vpc_ids: cmd = 'ps aux | grep {0}'.format(vpc_id) err_string += '\nCLC CMD#: {0}\n'.format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error('Failed to get vpc process info from clc:' + str(E)) finally: err_string += "(CMD DONE)\n" try: for vpc_id in vpc_ids: cmd = 'ifconfig | grep {0}'.format(str(vpc_id).lstrip('vpc-')) err_string += '\nCLC CMD#: {0}\n'.format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error('Failed to get vpc ifconfig info from clc:' + str(E)) finally: err_string += "(CMD DONE)\n" try: for subnet_id in subnet_ids: cmd = 'ifconfig | grep {0}'.format(str(subnet_id).lstrip('subnet-')) err_string += '\nCLC CMD#: {0}\n'.format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error('Failed to get subnet ifconfig info from clc:' + str(E)) finally: err_string += "(CMD DONE)\n" for i in instances: try: cmd = "grep {0} /var/run/eucalyptus/eucanetd_vpc_instance_ip_map".format(i.id) err_string += '\nCLC CMD#: {0}\n'.format(cmd) err_string += tc.sysadmin.clc_machine.sys(cmd, listformat=False) except Exception as E: tc.log.error('Failed to get vpc nginx map info from clc:' + str(E)) finally: err_string += "(CMD DONE)\n" err_string += i.get_cloud_init_info_from_console() + "\n" finally: try: for ins in instances: if ins and ins.ssh: ins.ssh.close() ins = None instances = None except Exception as E: err_string += '{0}\nError:{1}'.format(get_traceback(), E) user.log.warn('') user.results = my_results with userlock: if err_string: my_error = {'user':str(user), 'error':err_string} errors.append(my_error) if my_clc_times: for key, value in my_clc_times.iteritems(): clc_times[key] = value if my_md_times: for key, value in my_md_times.iteritems(): mido_md_times[key] = value
def SHOW_NODES(connection, nodes=None, print_method=None, print_table=True): ''' Prints table summary of nodes. :params nodes: Can be a single, or list of EucaNodeService objects. Can be a single, or list of node names (strings). :param print_table: bool, if true will write table to self.debug_method, if false, will return the table object w/o printing it. ''' print_method = print_method or connection._show_method if not nodes: nodes_list = connection.get_all_node_controller_services() else: nodes_list = [] if not isinstance(nodes, list): nodes = [nodes] for node in nodes: if isinstance(node, EucaNodeService): nodes_list.append(node) elif isinstance(node, basestring): nodes_list.append( connection.get_node_controller_service(name=str(node))) else: raise ValueError( 'show_nodes: Unknown type for node: "{0}:{1}"'.format( node, type(node))) ins_id_len = 10 ins_type_len = 13 ins_dev_len = 16 ins_st_len = 15 zone_hdr = (markup('ZONE'), 20) name_hdr = (markup('NODE NAME'), 30) state_hdr = (markup('STATE'), 20) inst_hdr = (markup('INSTANCES'), (ins_id_len + ins_dev_len + ins_type_len + ins_st_len) + 5) pt = PrettyTable([zone_hdr[0], name_hdr[0], state_hdr[0], inst_hdr[0]]) pt.max_width[zone_hdr[0]] = zone_hdr[1] pt.max_width[inst_hdr[0]] = inst_hdr[1] pt.max_width[state_hdr[0]] = state_hdr[1] pt.max_width[name_hdr[0]] = name_hdr[1] pt.padding_width = 0 pt.hrules = 1 for node in nodes_list: instances = "".join("{0}({1}{2}{3})".format( str(x.id).ljust(ins_id_len), str(x.state + ",").ljust(ins_st_len), str(x.instance_type + ",").ljust(ins_type_len), str(x.root_device_type).ljust(ins_dev_len)).ljust(inst_hdr[1]) for x in node.instances) instances.strip() if node.state == 'ENABLED': markups = [1, 92] else: markups = [1, 91] pt.add_row([ node.partition, markup(node.name), markup(node.state, markups), instances ]) if print_table: print_method('\n' + pt.get_string(sortby=zone_hdr[0]) + '\n') else: return pt
def n_markup(*args, **kwargs): kwargs['do_html'] = do_html kwargs['html_open'] = html_open kwargs['html_close'] = html_close return markup(*args, **kwargs)
def add_host(hostip, host, self=self): assert isinstance(host, EucaHost) servbuf = header + "\n" mservices = [] # Get the child services (ie for UFS) for serv in host.services: mservices.append(serv) mservices.extend(serv.child_services) for serv in mservices: for line in serv_lines: # Remove the ansi markup for parsing purposes, but leave it in the # displayed line clean_line = ansi_escape.sub('', line) splitline = clean_line.split() if len(splitline) < 2: continue line_type = splitline[0] line_name = splitline[1] # Pull matching lines out of the pre-formatted service table... if (splitline and re.match("^{0}$".format(serv.type), line_type) and re.match("^{0}$".format(serv.name), line_name)): # Add this line to the services to be displayed for this machine if line_name not in servbuf: servbuf += line + "\n" if serv.type == 'node': if getattr(serv, 'instances', None): if serv.instances: vm_pt = PrettyTable([ markup('INSTANCES', [1, 4]), markup('STATE:', [1, 4]), markup('VMTYPE:', [1, 4]), markup('ROOT_DEV:', [1, 4]) ]) vm_pt.align = 'l' vm_pt.border = 1 vm_pt.vrules = 2 vm_pt.hrules = 0 for x in serv.instances: vm_pt.add_row([ x.id, markup(x.state, self.vm_state_markup(x.state)), x.instance_type, x.root_device_type ]) servbuf += "{0}\n".format(vm_pt) av_pt = host.helpers.node_controller.show_availability_for_node( print_table=False) servbuf += av_pt.get_string() ps_sum_pt = host.show_euca_process_summary(print_table=False) servbuf += "\n" + ps_sum_pt.get_string( border=1, vrules=2, hrules=0) host_info = markup('Euca Versions:').ljust(machine_hdr[1]) host_info += "Cloud: {0}".format( host.get_eucalyptus_version()).ljust(machine_hdr[1]) host_info += "2ools: {0}".format( host.get_euca2ools_version()).ljust(machine_hdr[1]) host_info += markup("Hostname:").ljust(machine_hdr[1]) host_info += str(host.hostname).ljust(machine_hdr[1]) sys_pt = host.show_sys_info(print_table=False) host_info += "{0}".format(sys_pt) with hostlock: pt.add_row([ markup("HOST:") + markup(hostip, [1, 94]), markup('EUCALYPTUS SERVICES:') + markup( '[ {0} ]'.format(" ".join( str(x) for x in host.euca_service_codes)), [1, 34]) ]) pt.add_row([host_info, servbuf])
def show_hosts(self, hosts=None, partition=None, service_type=None, serv_columns=None, update=True, print_method=None, print_table=True, save_file=None): print_method = print_method or self._show_method ins_id_len = 10 ins_type_len = 13 ins_dev_len = 16 ins_st_len = 15 ins_total = (ins_id_len + ins_dev_len + ins_type_len + ins_st_len) + 5 machine_hdr = (markup('MACHINE INFO'), 30) service_hdr = (markup('EUCALYPTUS SERVICES'), 90) pt = PrettyTable([machine_hdr[0], service_hdr[0]]) pt.header = False pt.align = 'l' pt.hrules = 1 pt.max_width[machine_hdr[0]] = machine_hdr[1] total = [] eucahosts = {} if hosts is None: eucahosts = self.eucahosts elif isinstance(hosts, list): for host in hosts: eucahosts[host.hostname] = host elif isinstance(hosts, EucaHost): eucahosts[hosts.hostname] = hosts if not isinstance(eucahosts, dict): raise ValueError('show_machine_mappings requires dict example: ' '{"host ip":[host objs]}, got:"{0}/{1}"'.format( eucahosts, type(eucahosts))) # To format the tables services, print them all at once and then sort the table # rows string into the machines columns try: sorted_ips = sorted( list(eucahosts), key=lambda ip: struct.unpack("!L", socket.inet_aton(ip))[0]) except Exception as SE: self.log.warning( '"Failed to sort host list by IP, error:"{0}"'.format(SE)) sorted_ips = sorted(list(eucahosts)) for hostip in sorted_ips: host = eucahosts[hostip] for serv in host.services: if update: serv.update() total.append(serv) if serv.child_services: total.extend(serv.child_services) # Create a table showing the service states, grab the first 3 columns # for type, name, state, and zone servpt = self.show_services(total, print_table=False) # Get a subset of the show services fields... if serv_columns is None: fields = servpt._field_names[0:4] else: fields = servpt._fields_names[serv_columns] serv_lines = servpt.get_string(border=0, padding_width=2, fields=fields).splitlines() header = serv_lines[0] ansi_escape = re.compile(r'\x1b[^m]*m') # Now build the machine table... threads = [] hostlock = threading.Lock() # Method to allow host info to be gathered concurrently def add_host(hostip, host, self=self): assert isinstance(host, EucaHost) servbuf = header + "\n" mservices = [] # Get the child services (ie for UFS) for serv in host.services: mservices.append(serv) mservices.extend(serv.child_services) for serv in mservices: for line in serv_lines: # Remove the ansi markup for parsing purposes, but leave it in the # displayed line clean_line = ansi_escape.sub('', line) splitline = clean_line.split() if len(splitline) < 2: continue line_type = splitline[0] line_name = splitline[1] # Pull matching lines out of the pre-formatted service table... if (splitline and re.match("^{0}$".format(serv.type), line_type) and re.match("^{0}$".format(serv.name), line_name)): # Add this line to the services to be displayed for this machine if line_name not in servbuf: servbuf += line + "\n" if serv.type == 'node': if getattr(serv, 'instances', None): if serv.instances: vm_pt = PrettyTable([ markup('INSTANCES', [1, 4]), markup('STATE:', [1, 4]), markup('VMTYPE:', [1, 4]), markup('ROOT_DEV:', [1, 4]) ]) vm_pt.align = 'l' vm_pt.border = 1 vm_pt.vrules = 2 vm_pt.hrules = 0 for x in serv.instances: vm_pt.add_row([ x.id, markup(x.state, self.vm_state_markup(x.state)), x.instance_type, x.root_device_type ]) servbuf += "{0}\n".format(vm_pt) av_pt = host.helpers.node_controller.show_availability_for_node( print_table=False) servbuf += av_pt.get_string() ps_sum_pt = host.show_euca_process_summary(print_table=False) servbuf += "\n" + ps_sum_pt.get_string( border=1, vrules=2, hrules=0) host_info = markup('Euca Versions:').ljust(machine_hdr[1]) host_info += "Cloud: {0}".format( host.get_eucalyptus_version()).ljust(machine_hdr[1]) host_info += "2ools: {0}".format( host.get_euca2ools_version()).ljust(machine_hdr[1]) host_info += markup("Hostname:").ljust(machine_hdr[1]) host_info += str(host.hostname).ljust(machine_hdr[1]) sys_pt = host.show_sys_info(print_table=False) host_info += "{0}".format(sys_pt) with hostlock: pt.add_row([ markup("HOST:") + markup(hostip, [1, 94]), markup('EUCALYPTUS SERVICES:') + markup( '[ {0} ]'.format(" ".join( str(x) for x in host.euca_service_codes)), [1, 34]) ]) pt.add_row([host_info, servbuf]) for hostip, host in eucahosts.iteritems(): t = threading.Thread(target=add_host, args=(hostip, host)) t.start() threads.append(t) for t in threads: t.join() if save_file: with open(save_file, 'w') as sf: sf.write("\n{0}\n".format(pt.get_string())) if print_table: # print_method("\n{0}\n".format(pt.get_string(sortby=pt.field_names[1]))) print_method("\n{0}\n".format(pt.get_string())) else: return pt
def SHOW_PROPERTIES(connection, properties=None, description=True, defaults=True, readonly=True, grid=ALL, print_method=None, print_table=True, search=None, *nameprefix): """ Summarize Eucalyptus properties in table format :param connection: EucaAdmin connection :param properties: list of property names, or Eucaproperties to summarize :param description: bool, show property descriptions :param grid: bool, show table in grid format :param readonly: bool, show readonly flag :param defaults: bool, show property defaults in table :param print_table: bool, if True will print table using connection.debug_method() if False will return the table object :param search: string, to use as filter for name of properties :param nameprefix: property names used to filter query response """ print_method = print_method or connection._show_method name_hdr = markup('PROPERTY NAME', [1, 94]) def_hdr = markup('DEFAULT', [1, 94]) value_hdr = markup('PROPERTY VALUE', [1, 94]) desc_hdr = markup('DESCRIPTION', [1, 94]) ro_hdr = markup('RO', [1, 94]) pt = PrettyTable([name_hdr, value_hdr]) pt.max_width[name_hdr] = 70 pt.max_width[value_hdr] = 40 if defaults: pt.add_column(fieldname=def_hdr, column=[]) pt.max_width[def_hdr] = 40 if readonly: pt.add_column(fieldname=ro_hdr, column=[]) if description: pt.add_column(fieldname=desc_hdr, column=[]) pt.max_width[desc_hdr] = 40 # Reduce the default width to accommodate the description pt.max_width[def_hdr] = 20 pt.padding_width = 0 pt.align = 'l' pt.hrules = grid or 0 if not isinstance(properties, list): properties = properties or connection.get_properties(search=search, *nameprefix) if not isinstance(properties, list): properties = [properties] for prop in properties: if not isinstance(prop, EucaProperty) and isinstance(prop, basestring): props = connection.get_properties(prop) if not props: continue else: props = [prop] for p in props: row = [markup(p.name, [94]), p.value] if defaults: row.append(getattr(p, 'defaultvalue', None)) if readonly: ro = getattr(p, 'readonly', "?") if ro != "?": if 'rue' in ro: ro = 'T' if 'alse' in ro: ro = 'F' row.append(ro) if description: row.append(p.description) pt.add_row(row) if not pt._rows: err_row = [markup('NO PROPERTIES RETURNED', [1, 91])] for x in xrange(1, len(pt._field_names)): err_row.append("") pt.add_row(err_row) if print_table: print_method('\n' + str(pt) + '\n') else: return pt
def n_markup(*args, **kwargs): kwargs["do_html"] = do_html kwargs["html_open"] = html_open kwargs["html_close"] = html_close return markup(*args, **kwargs)
def add_host(hostip, host, self=self): assert isinstance(host, EucaHost) servbuf = header + "\n" mservices = [] # Get the child services (ie for UFS) for serv in host.services: mservices.append(serv) mservices.extend(serv.child_services) for serv in mservices: for line in serv_lines: # Remove the ansi markup for parsing purposes, but leave it in the # displayed line clean_line = ansi_escape.sub("", line) splitline = clean_line.split() if len(splitline) < 2: continue line_type = splitline[0] line_name = splitline[1] # Pull matching lines out of the pre-formatted service table... if ( splitline and re.match("^{0}$".format(serv.type), line_type) and re.match("^{0}$".format(serv.name), line_name) ): # Add this line to the services to be displayed for this machine if line_name not in servbuf: servbuf += line + "\n" if serv.type == "node": if getattr(serv, "instances", None): if serv.instances: vm_pt = PrettyTable( [ markup("INSTANCES", [1, 4]), markup("STATE:", [1, 4]), markup("VMTYPE:", [1, 4]), markup("ROOT_DEV:", [1, 4]), ] ) vm_pt.align = "l" vm_pt.border = 1 vm_pt.vrules = 2 vm_pt.hrules = 0 for x in serv.instances: vm_pt.add_row( [ x.id, markup(x.state, self.vm_state_markup(x.state)), x.instance_type, x.root_device_type, ] ) servbuf += "{0}\n".format(vm_pt) av_pt = host.helpers.node_controller.show_availability_for_node(print_table=False) servbuf += av_pt.get_string() ps_sum_pt = host.show_euca_process_summary(print_table=False) servbuf += "\n" + ps_sum_pt.get_string(border=1, vrules=2, hrules=0) host_info = markup("Euca Versions:").ljust(machine_hdr[1]) host_info += "Cloud: {0}".format(host.get_eucalyptus_version()).ljust(machine_hdr[1]) host_info += "2ools: {0}".format(host.get_euca2ools_version()).ljust(machine_hdr[1]) host_info += markup("Hostname:").ljust(machine_hdr[1]) host_info += str(host.hostname).ljust(machine_hdr[1]) sys_pt = host.show_sys_info(print_table=False) host_info += "{0}".format(sys_pt) with hostlock: pt.add_row( [ markup("HOST:") + markup(hostip, [1, 94]), markup("EUCALYPTUS SERVICES:") + markup("[ {0} ]".format(" ".join(str(x) for x in host.euca_service_codes)), [1, 34]), ] ) pt.add_row([host_info, servbuf])
def show_hosts( self, hosts=None, partition=None, service_type=None, serv_columns=None, update=True, print_method=None, print_table=True, save_file=None, ): print_method = print_method or self._show_method ins_id_len = 10 ins_type_len = 13 ins_dev_len = 16 ins_st_len = 15 ins_total = (ins_id_len + ins_dev_len + ins_type_len + ins_st_len) + 5 machine_hdr = (markup("MACHINE INFO"), 30) service_hdr = (markup("EUCALYPTUS SERVICES"), 90) pt = PrettyTable([machine_hdr[0], service_hdr[0]]) pt.header = False pt.align = "l" pt.hrules = 1 pt.max_width[machine_hdr[0]] = machine_hdr[1] total = [] eucahosts = {} if hosts is None: eucahosts = self.eucahosts elif isinstance(hosts, list): for host in hosts: eucahosts[host.hostname] = host elif isinstance(hosts, EucaHost): eucahosts[hosts.hostname] = hosts if not isinstance(eucahosts, dict): raise ValueError( "show_machine_mappings requires dict example: " '{"host ip":[host objs]}, got:"{0}/{1}"'.format(eucahosts, type(eucahosts)) ) # To format the tables services, print them all at once and then sort the table # rows string into the machines columns for hostip, host in eucahosts.iteritems(): for serv in host.services: if update: serv.update() total.append(serv) if serv.child_services: total.extend(serv.child_services) # Create a table showing the service states, grab the first 3 columns # for type, name, state, and zone servpt = self.show_services(total, print_table=False) # Get a subset of the show services fields... if serv_columns is None: fields = servpt._field_names[0:4] else: fields = servpt._fields_names[serv_columns] serv_lines = servpt.get_string(border=0, padding_width=2, fields=fields).splitlines() header = serv_lines[0] ansi_escape = re.compile(r"\x1b[^m]*m") # Now build the machine table... threads = [] hostlock = threading.Lock() # Method to allow host info to be gathered concurrently def add_host(hostip, host, self=self): assert isinstance(host, EucaHost) servbuf = header + "\n" mservices = [] # Get the child services (ie for UFS) for serv in host.services: mservices.append(serv) mservices.extend(serv.child_services) for serv in mservices: for line in serv_lines: # Remove the ansi markup for parsing purposes, but leave it in the # displayed line clean_line = ansi_escape.sub("", line) splitline = clean_line.split() if len(splitline) < 2: continue line_type = splitline[0] line_name = splitline[1] # Pull matching lines out of the pre-formatted service table... if ( splitline and re.match("^{0}$".format(serv.type), line_type) and re.match("^{0}$".format(serv.name), line_name) ): # Add this line to the services to be displayed for this machine if line_name not in servbuf: servbuf += line + "\n" if serv.type == "node": if getattr(serv, "instances", None): if serv.instances: vm_pt = PrettyTable( [ markup("INSTANCES", [1, 4]), markup("STATE:", [1, 4]), markup("VMTYPE:", [1, 4]), markup("ROOT_DEV:", [1, 4]), ] ) vm_pt.align = "l" vm_pt.border = 1 vm_pt.vrules = 2 vm_pt.hrules = 0 for x in serv.instances: vm_pt.add_row( [ x.id, markup(x.state, self.vm_state_markup(x.state)), x.instance_type, x.root_device_type, ] ) servbuf += "{0}\n".format(vm_pt) av_pt = host.helpers.node_controller.show_availability_for_node(print_table=False) servbuf += av_pt.get_string() ps_sum_pt = host.show_euca_process_summary(print_table=False) servbuf += "\n" + ps_sum_pt.get_string(border=1, vrules=2, hrules=0) host_info = markup("Euca Versions:").ljust(machine_hdr[1]) host_info += "Cloud: {0}".format(host.get_eucalyptus_version()).ljust(machine_hdr[1]) host_info += "2ools: {0}".format(host.get_euca2ools_version()).ljust(machine_hdr[1]) host_info += markup("Hostname:").ljust(machine_hdr[1]) host_info += str(host.hostname).ljust(machine_hdr[1]) sys_pt = host.show_sys_info(print_table=False) host_info += "{0}".format(sys_pt) with hostlock: pt.add_row( [ markup("HOST:") + markup(hostip, [1, 94]), markup("EUCALYPTUS SERVICES:") + markup("[ {0} ]".format(" ".join(str(x) for x in host.euca_service_codes)), [1, 34]), ] ) pt.add_row([host_info, servbuf]) for hostip, host in eucahosts.iteritems(): t = threading.Thread(target=add_host, args=(hostip, host)) t.start() threads.append(t) for t in threads: t.join() if save_file: with open(save_file, "w") as sf: sf.write("\n{0}\n".format(pt.get_string())) if print_table: # print_method("\n{0}\n".format(pt.get_string(sortby=pt.field_names[1]))) print_method("\n{0}\n".format(pt.get_string())) else: return pt
def status_log(self, msg): return self.log.info(markup(msg, markups=[ForegroundColor.WHITE, BackGroundColor.BG_GREEN, TextStyle.BOLD]))
def menu_summary(self, args): """Prints Summary of commands and sub-menu items""" menu_color = [1, 4, 34] # bold, underlined, blue prevname = None names = self.get_names() menu_items = [] maxlen = 0 main_pt = pt = PrettyTable(['MAIN']) main_pt.header = False main_pt.border = False main_pt.align = 'l' sub_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) base_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) current_pt = PrettyTable(['COMMAND', 'DESCRIPTION']) for table in [sub_pt, base_pt, current_pt]: table.header = False table.border = False table.align = 'l' #Sort out methods that begin with 'do_' as menu items... for name in names: if name[:3] == 'do_': if name == prevname: continue prevname = name if len(name[3:]) > maxlen: maxlen = len(name[3:]) menu_items.append(name) #Sort out menu items into: submenus, local commands, and globals for name in menu_items: cmd = str(name[3:]) cmd_method = getattr(self, name) doc = str(cmd_method.__doc__) or '' doc = doc.lstrip().splitlines()[0].strip() if hasattr(cmd_method, '__submenu__'): if hasattr(BaseMenu, name): base_pt.add_row([ "\t{0}".format(markup(cmd, markups=menu_color)), markup(doc, markups=menu_color) ]) else: current_pt.add_row([ "\t{0}".format(markup(cmd, markups=menu_color)), markup(doc, markups=menu_color) ]) else: if hasattr(BaseMenu, name): base_pt.add_row( ["\t{0}".format(yellow(cmd, bold=True)), doc]) else: current_pt.add_row( ["\t{0}".format(yellow(cmd, bold=True)), doc]) buf = "{0}\n".format( cyan('*** ' + self.name.upper() + ' OPTIONS ***', bold=True)) if current_pt._rows: # Add blank line for formatting, separate menu items from commands #current_pt.add_row(["\t{0}".format(yellow(" ", bold=True)), ""]) buf += "{0}\n".format(current_pt.get_string(sortby='COMMAND')) if sub_pt._rows: buf += "{0}\n".format(sub_pt) if base_pt._rows: buf += "{0}\n{1}\n".format( cyan('*** BASE COMMANDS ***', bold=True), base_pt) main_pt.add_row([buf]) self.oprint("{0}".format(main_pt))