def __init__(self, vport, tci = None, tpid = None, **kwargs): """ Creates a namespace key, defines a namespace in emulation server. .. code-block:: python # creating a namespace key with no vlans ns_key = EMUNamespaceKey(vport = 0) # creating a namespace key with vlan using default tpid(0x8100) ns_key = EMUNamespaceKey(vport = 0, tci = 1) # creating a namespace key with 2 vlans using tpid ns_key = EMUNamespaceKey(vport = 0, tci = [1, 2], tpid = [0x8100, 0x8100]) :parameters: vport: int (Mandatory) Port for the namespace. tci: int or list of 2 ints. (Optional) Tag Control Information/s for the namespace (up to 2), defaults to None means no Vlan. tpid: int or 2 ints. (Optional) Tag Protocol Identifier/s for the tci/s (up to 2), defaults to None means no vlan. If tci supplied without tpid, it will set tpid to 0x8100 by default. :raises: + :exe:'TRexError': In any case of wrong parameters. """ if tci is None: tci = [0, 0] tci = listify(tci) if tpid is None: tpid = [0 for _ in tci] tpid = listify(tpid) ver_args = [ {'name': 'vport', 'arg': vport, 't': 'vport'}, {'name': 'tci', 'arg': tci, 't': 'tci'}, {'name': 'tpid', 'arg': tpid, 't': 'tpid'}, ] EMUValidator.verify(ver_args) if tpid != [0, 0] and tci == [0, 0]: raise TRexError('Cannot supply tpid without tci to namespace!') if tpid != [0, 0] and tci != [0, 0]: if len(tpid) != len(tci): raise TRexError('tci & tpid length must be equal!') elif any([tc == 0 and tp !=0 for tc, tp in zip(tci, tpid)]): raise TRexError('Cannot supply tpid with non zero value to zero value vlan tag!') self.vport = vport self.tci = tci self.tpid = tpid
def mdns_show_hosts_line(self, line): """Show hosts of mDNS client.\n""" parser = parsing_opts.gen_parser( self, "mdns_show_hosts", self.mdns_show_hosts_line.__doc__, parsing_opts.EMU_NS_GROUP, parsing_opts.MAC_ADDRESS, ) opts = parser.parse_args(line.split()) ns_key = EMUNamespaceKey(opts.port, opts.vlan, opts.tpid) c_key = EMUClientKey(ns_key, opts.mac) hosts = self.get_client_hosts(c_key=c_key) if hosts: hosts = listify(hosts) keys_to_headers = [ { 'key': 'number', 'header': 'Number' }, { 'key': 'hostname', 'header': 'Hostname' }, ] res = [{ 'number': i + 1, 'hostname': host } for i, host in enumerate(hosts)] self.print_table_by_keys(res, keys_to_headers, title="Hostnames") else: text_tables.print_colored_line( "The client doesn't own any hostname.", "yellow")
def dns_show_domains_line(self, line): """Show domains a Name Server holds.\n""" parser = parsing_opts.gen_parser(self, "dns_show_domains", self.dns_show_domains_line.__doc__, parsing_opts.EMU_NS_GROUP, parsing_opts.MAC_ADDRESS) opts = parser.parse_args(line.split()) ns_key = EMUNamespaceKey(opts.port, opts.vlan, opts.tpid) c_key = EMUClientKey(ns_key, opts.mac) domains = self.get_domains(c_key=c_key) if domains: domains = listify(domains) keys_to_headers = [ { 'key': 'number', 'header': 'Number' }, { 'key': 'domain', 'header': 'Domain' }, ] res = [{ 'number': i + 1, 'domain': domain } for i, domain in enumerate(domains)] self.print_table_by_keys(res, keys_to_headers, title="Domains") else: text_tables.print_colored_line( "The Name Server doesn't recognize any domains.", "yellow")
def _translate_names_to_ids(self, tg_names, pid_input = DEFAULT_PROFILE_ID): list_of_tg_names = listify(tg_names) tg_ids = [] if not list_of_tg_names: raise ASTFErrorBadTG("List of tg_names can't be empty") for tg_name in list_of_tg_names: if tg_name not in self.tg_names_dict[pid_input]['tg_names']: raise ASTFErrorBadTG("Template name %s isn't defined in this profile" % tg_name) else: tg_ids.append(self.tg_names_dict[pid_input]['tg_names_dic'][tg_name]) return tg_ids
def _translate_names_to_ids(self, tg_names): list_of_tg_names = listify(tg_names) tg_ids = [] if not list_of_tg_names: raise ASTFErrorBadTG("List of tg_names can't be empty") for tg_name in list_of_tg_names: if tg_name not in self.tg_names_dict: raise ASTFErrorBadTG( "Template name %s isn't defined in this profile" % tg_name) else: tg_ids.append(self.tg_names_dict[tg_name]) return tg_ids
def mdns_remove_hosts_line(self, line): """Remove hosts from mDNS client.\n""" parser = parsing_opts.gen_parser(self, "mdns_remove_hosts", self.mdns_remove_hosts_line.__doc__, parsing_opts.EMU_NS_GROUP, parsing_opts.MAC_ADDRESS, parsing_opts.MDNS_HOSTS_LIST) opts = parser.parse_args(line.split()) ns_key = EMUNamespaceKey(opts.port, opts.vlan, opts.tpid) c_key = EMUClientKey(ns_key, opts.mac) non_existing_hosts = self.add_remove_hosts(c_key=c_key, op=True, hosts=opts.hosts) if non_existing_hosts: msg = "Hosts: {} didn't exist.".format(listify(non_existing_hosts)) text_tables.print_colored_line(msg, "yellow") self.logger.post_cmd(True) # If we got here, it was successful
def dns_show_domain_entries_line(self, line): """Show entries of Dns Domain in the Name Server.\n""" parser = parsing_opts.gen_parser( self, "dns_show_domain_entries", self.dns_show_domain_entries_line.__doc__, parsing_opts.EMU_NS_GROUP, parsing_opts.MAC_ADDRESS, parsing_opts.DNS_DOMAIN_NAME, ) opts = parser.parse_args(line.split()) ns_key = EMUNamespaceKey(opts.port, opts.vlan, opts.tpid) c_key = EMUClientKey(ns_key, opts.mac) entries = listify( self.get_domain_entries(c_key=c_key, domain=opts.domain)) # We filter out TXTs because the table should be kept compact. entries = [entry for entry in entries if entry["type"] != "TXT"] keys_to_headers = [ { 'key': 'answer', 'header': 'Answer' }, { 'key': 'type', 'header': 'Type' }, { 'key': 'class', 'header': 'Class' }, ] args = { 'title': '{} entries'.format(opts.domain), 'empty_msg': 'No entries for {}'.format(opts.domain), 'keys_to_headers': keys_to_headers } self.print_table_by_keys(data=entries, **args)
def verify(list_of_args): """ Check if list_of_args is valid. :parameters: list_of_args: list List of dictionary with data about the arguments. | list_of_args = [{'name': 'ipv4_mc_arg', 'value': ipv4_mc_arg, 'type': 'ipv4_mc', must: 'False', 'allow_list': True}] | the example above will verify: None, '224.0.0.0', ['224.0.0.0'] but raise exception for: 42, 'FF00::', ['224.0.0.0', 'FF00::'] | name: string (Mandatory) | Name of the argument(for error messages). | arg: Anything (Mandatory) | The actual variable to validate. | type: string or class instance (Mandatory) | Might be a string from `EMU_VAL_DICT`('mac', 'ipv4'..) or just the wanted class instance. | `type` might also be a list of types and `value` should be 1 one them. | must: bool | True will validate value is not None, defaults to True. | allow_list: bool | True will allow `value` to be a list of anything from `types`. :raises: + :exe:'TRexError': In any case of wrong parameters. """ def _check_types_for_val(types, arg_name, arg_val): for t in types: if not isinstance(t, str): # type is a class if isinstance(arg_val, t): break else: # type is a string, look for it in database test_func = database.get(t, None) if test_func is None: err(arg_name, arg_val, 'Unknown type to EMUValidator "{0}"'.format(t)) else: if not test_func(arg_val): err(arg_name, arg_val, 'Argument is not valid for "{0}" type'.format(t)) break else: # got here if code did not break err(arg_name, arg_val, 'Not matching type, got: "{0}"'.format(type(arg_val))) def err(name, val, reason): raise TRexError('Validation error, argument "{name}" with value "{val}"\nReason: {reason}'.format(name=name, val=val, reason=reason)) for arg in list_of_args: database = EMUValidator.EMU_VAL_DICT arg_name = arg.get('name') arg_val = arg.get('arg') arg_type = arg.get('t') is_must = arg.get('must', True) allow_list = arg.get('allow_list', False) # check if arg is None if arg_val is None: if is_must: err(arg_name, arg_val, 'Cannot be None') else: continue arg_types = listify(arg_type) if allow_list and isinstance(arg_val, list): for val in arg_val: _check_types_for_val(arg_types, arg_name, val) else: _check_types_for_val(arg_types, arg_name, arg_val)