def create_acl_table(dut, skip_verify=True, **kwargs): """ Create the ACL table Author: Chaitanya Vella ([email protected]) :param dut: :param kwargs: :param skip_verify: True(Default) / False :return: Ex: Create_acl_table(1, name="DATAACL", stage = "INGRESS", type="L3", description="Testing", ports=["Ethernet0", "Ethernet2"]) """ cli_type = kwargs.get("cli_type", "click") table_name = kwargs.get("table_name", None) if cli_type == "click": st.log("Creating ACL table ...") acl_data = kwargs if not acl_data: st.error("ACL table creation failed because of invalid data ..") acl_table_data = dict() acl_table = dict() acl_table[acl_data["name"]] = dict() acl_table[acl_data["name"]][ "type"] = acl_data["type"] if 'type' in acl_data else '' acl_table[acl_data["name"]]["policy_desc"] = acl_data[ "description"] if 'description' in acl_data else '' acl_table[acl_data["name"]][ "ports"] = acl_data["ports"] if 'ports' in acl_data else [] acl_table[acl_data["name"]][ "stage"] = acl_data["stage"] if 'stage' in acl_data else '' acl_table_data["ACL_TABLE"] = acl_table acl_table_data = json.dumps(acl_table_data) json.loads(acl_table_data) st.apply_json2(dut, acl_table_data) # reboot.config_save(dut) if not skip_verify: if not verify_acl_table(dut, acl_data["name"]): return False else: if not table_name: st.log("Mandatory parameter table name not passed") return False commands = list() commands.append("ip access-list {}".format(table_name)) commands.append("exit") st.config(dut, commands, type=cli_type, skip_error_check=skip_verify) return True
def config_spanning_tree_rpvst_intf(dut, skip_verify=True, **kwargs): """ :param dut: :param kwargs: :param skip_verify: True(Default) / False :return: Ex: config_spanning_tree_rpvst(1, ifname, field='edge_port', cfg_value='true') """ st.log("Configuring RPVST interface parameters...") rpvst_data = kwargs stp_cfg = dict() # if STP is already configured on the DUT, just update the given field # rest of the fields should not be affected current_stp = sconf_obj.get_running_config(dut, "STP_PORT") stp_cfg['STP_PORT'] = current_stp if current_stp: if rpvst_data['ifname'] in current_stp: #if rpvst_data['field'] in current_stp[rpvst_data['ifname']]: #any existing field is updated. New field will get added to the config_db stp_cfg['STP_PORT'][rpvst_data['ifname']][rpvst_data['field']] = rpvst_data['cfg_value'] #else: # st.error("field {} does not exist".format(rpvst_data['field'])) # return False else: st.error("interface {} does not exist".format(rpvst_data['ifname'])) return False else: st.error("STP interface configuration does not exist") return False json_cfg = json.dumps(stp_cfg) json.loads(json_cfg) st.apply_json2(dut, json_cfg) return True
def config_spanning_tree_rpvst(dut, skip_verify=True, **kwargs): """ :param dut: :param kwargs: :param skip_verify: True(Default) / False :return: Ex: config_spanning_tree_rpvst(1, field='mode', cfg_value='rpvst') """ st.log("Configuring RPVST...") rpvst_data = kwargs # if STP is already configured on the DUT, just update the given field # rest of the fields should not be affected current_stp = sconf_obj.get_running_config(dut, "STP") if current_stp: stp_cfg = default_stp_global_cfg # current_value = sconf_obj.get_running_config(dut,"STP","GLOBAL",rpvst_data['field']) if rpvst_data['field'] in current_stp['GLOBAL']: stp_cfg['STP']['GLOBAL'][rpvst_data['field']] = rpvst_data['cfg_value'] excluded_keys = rpvst_data['field'] for key, _ in current_stp['GLOBAL'].items(): if key not in excluded_keys: stp_cfg['STP']['GLOBAL'][key] = current_stp['GLOBAL'][key] else: stp_cfg = default_stp_global_cfg json_cfg = json.dumps(stp_cfg) json.loads(json_cfg) st.apply_json2(dut, json_cfg) return True
def apply_wred_ecn_config(dut, config): st.log("loading wred and ecn config from wred_ecn_config_json.py") json_config = json.dumps(config) json.loads(json_config) st.apply_json2(dut, json_config)
def create_acl_rule(dut, skip_verify=True, type1=None, type2=None, **kwargs): """ Create the ACL rule Author: Chaitanya Vella ([email protected]) :param dut: :param kwargs: :param skip_verify: True(Default) / False :return: create_acl_rule(1, table_name="DATAACL",rule_name = "DATARULE", <REST OF THE PARAMETERS CHECK REF LINK>) REF: https://github.com/Azure/SONiC/wiki/ACL-High-Level-Design -- Follow the rule attributes names from this link """ cli_type = kwargs.get("cli_type", "click") table_name = kwargs.get("table_name", None) rule_name = kwargs.get("rule_name", None) packet_action = kwargs.get("packet_action", "deny") l4_protocol = kwargs.get("l4_protocol", None) src_ip = kwargs.get("SRC_IP", "any") dst_ip = kwargs.get("DST_IP", "any") dscp_value = kwargs.get("dscp_value") tcp_flag = kwargs.get("tcp_flag", None) st.log("Creating ACL rule ...") if cli_type == "click": acl_rule_data = kwargs if not acl_rule_data: st.error("ACL rule creation failed because of invalid data") return False acl_table_rules = dict() acl_rules = dict() excluded_keys = ["table_name", "rule_name"] acl_rules["{}|{}".format(acl_rule_data["table_name"], acl_rule_data["rule_name"])] = dict() for key, value in acl_rule_data.items(): if key not in excluded_keys: acl_rules["{}|{}".format( acl_rule_data["table_name"], acl_rule_data["rule_name"])][key.upper()] = value acl_table_rules["ACL_RULE"] = acl_rules acl_table_rules = json.dumps(acl_table_rules) json.loads(acl_table_rules) st.apply_json2(dut, acl_table_rules) # reboot.config_save(dut) if not skip_verify: if not verify_acl_table_rule(dut, acl_rule_data["table_name"], acl_rule_data["rule_name"]): return False else: if not (table_name and l4_protocol): st.log( "Mandatory parameters like table name and/or rule name and/or l4 protocol not passed" ) return False commands = list() commands.append("ip access-list {}".format(table_name)) if rule_name: rule_seq = int(re.findall(r'\d+', rule_name)[0]) if type1 and type2: command = "seq {} {} {} {} {} {} {}".format( rule_seq, packet_action, l4_protocol, type1, src_ip, type2, dst_ip) elif type1: command = "seq {} {} {} {} {} {}".format( rule_seq, packet_action, l4_protocol, type1, src_ip, dst_ip) elif type2: command = "seq {} {} {} {} {} {}".format( rule_seq, packet_action, l4_protocol, src_ip, type2, dst_ip) else: command = "seq {} {} {} {} {}".format(rule_seq, packet_action, l4_protocol, src_ip, dst_ip) if tcp_flag: if not l4_protocol == "tcp": st.log("l4 protocol should be tcp") return False command += " tcp_flag".format(tcp_flag) if dscp_value: command += " dscp {}".format(dscp_value) commands.append(command) commands.append('exit') st.config(dut, commands, type=cli_type, skip_error_check=skip_verify) return True
def apply_wred_ecn_config(dut, config, cli_type=''): """ Author: Jagadish Chatrasi ([email protected]) :param dut: :type dut: :param config: :type config: :param cli_type: :type cli_type: :return: :rtype: """ if not 'WRED_PROFILE' in config: st.debug('Invalid config data: {}'.format(config)) return False cli_type = st.get_ui_type(dut, cli_type=cli_type) if cli_type == 'click': json_config = json.dumps(config) json.loads(json_config) st.apply_json2(dut, json_config) elif cli_type in ['klish', 'rest-patch', 'rest-put']: wred_data = config['WRED_PROFILE'] port_data = config.get('QUEUE', None) for profile, wred_config in wred_data.items(): ecn = wred_config.get('ecn', None) green_min_threshold = wred_config.get('green_min_threshold', None) green_max_threshold = wred_config.get('green_max_threshold', None) green_dp = wred_config.get('green_drop_probability', None) green_enable = wred_config.get('wred_green_enable', None) commands = list() if cli_type == 'klish': commands.append('qos wred-policy {}'.format(profile)) if ecn: commands.append('ecn {}'.format(ecn.replace('ecn_', ''))) if all([green_max_threshold, green_min_threshold, green_dp]): commands.append( 'green minimum-threshold {} maximum-threshold {} drop-probability {}' .format(get_klish_rate(green_min_threshold), get_klish_rate(green_max_threshold), green_dp)) commands.append('exit') else: rest_urls = st.get_datastore(dut, 'rest_urls') if ecn: url = rest_urls['wred_params_config'].format(profile) config_json = { "openconfig-qos-ext:wred-profile": [{ "name": profile, "config": { "name": profile, "ecn": ecn.upper() } }] } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_json): st.error( 'Failed to configure ECN: {} for WRED_PROFILE: {}'. format(ecn, profile)) return False if green_min_threshold: url = rest_urls['wred_green_min_threshold_config'].format( profile) config_json = { "openconfig-qos-ext:green-min-threshold": str(green_min_threshold) } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_json): st.error( 'Failed to configure the green_min_threshold: {} for WRED_PROFILE: {}' .format(green_min_threshold, profile)) return False if green_max_threshold: url = rest_urls['wred_green_max_threshold_config'].format( profile) config_json = { "openconfig-qos-ext:green-max-threshold": str(green_max_threshold) } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_json): st.error( 'Failed to configure the green_max_threshold: {} for WRED_PROFILE: {}' .format(green_max_threshold, profile)) return False if green_dp: url = rest_urls[ 'wred_green_drop_probability_config'].format(profile) config_json = { "openconfig-qos-ext:green-drop-probability": str(green_dp) } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_json): st.error( 'Failed to configure the green_drop_probability: {} for WRED_PROFILE: {}' .format(green_dp, profile)) return False if green_enable: url = rest_urls['wred_green_enable_config'].format(profile) config_json = { "openconfig-qos-ext:wred-green-enable": True } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_json): st.error( 'Failed to configure the wred_green_enable for WRED_PROFILE: {}' .format(profile)) return False if port_data: config_apply_list = list() for port, wred_map in port_data.items(): temp = dict() p, q = port.split('|') temp['port'] = p.split(',') if '-' in q: queue1, queue2 = q.split('-') temp['queue'] = list(range(int(queue1), int(queue2) + 1)) else: temp['queue'] = q.split(',') temp['wred_profile'] = wred_map['wred_profile'] config_apply_list.append(temp) st.debug('port map data is: {}'.format(config_apply_list)) for entry in config_apply_list: for port in entry['port']: if cli_type == 'klish': intf_data = get_interface_number_from_name(port) commands.append('interface {} {}'.format( intf_data['type'], intf_data['number'])) commands.extend([ 'queue {} wred-policy {}'.format( queue, entry['wred_profile']) for queue in entry['queue'] ]) commands.append('exit') else: urls = [ rest_urls['wred_profile_apply_config'].format( port, queue) for queue in entry['queue'] ] config_json = { "openconfig-qos:config": { "openconfig-qos-ext:wred-profile": entry['wred_profile'] } } for url in urls: if not config_rest(dut, http_method=cli_type, rest_url=url, json_data=config_json): st.error( 'Failed to apply WRED_PROFILE: {} to port: {}' .format(entry['wred_profile'], port)) return False if commands: response = st.config(dut, commands, type=cli_type) if any(error in response.lower() for error in errors_list): st.error("The response is: {}".format(response)) return False else: st.error("Unsupported CLI TYPE {}".format(cli_type)) return False return True
def apply_acl_config(dut, config): json_config = json.dumps(config) json.loads(json_config) st.apply_json2(dut, json_config)
def apply_queue_shcheduling_config(dut, scheduler_data, **kwargs): """ API to configure scheduler parameters :param dut: :type dut: :param scheduler_data: :type scheduler_data: :param cli_type: :type cli_type: :return: :rtype: """ cli_type = st.get_ui_type(dut, **kwargs) skip_error = kwargs.get('skip_error', False) cli_type = 'klish' if skip_error and cli_type == 'click' else cli_type st.debug("Provided scheduler configuration is: {}".format(scheduler_data)) ports = list() if scheduler_data.get('port'): ports = make_list(scheduler_data['port']) if not scheduler_data.get("policy_name"): st.error("policy_name is not provided") return False if cli_type == 'click': config_data = {"QUEUE": {}, "SCHEDULER": {}} scheduler_info = make_list(scheduler_data['scheduler_data']) for ent in scheduler_info: temp = dict() queue_map = dict() policy = "{}@{}".format(scheduler_data['policy_name'], ent['queue']) temp[policy] = dict() if 'weight' in ent: temp[policy].update(weight=str(ent['weight'])) if ent.get('type'): temp[policy].update(type=ent['type'].upper()) if ports: queue_map = { "{}|{}".format(port, ent['queue']): { "scheduler": "{}".format(policy) } for port in ports } if temp[policy]: config_data['SCHEDULER'].update(temp) if queue_map: config_data['QUEUE'].update(queue_map) if not config_data['QUEUE']: config_data.pop('QUEUE') if not config_data['SCHEDULER']: config_data.pop('SCHEDULER') json_config = json.dumps(config_data) json.loads(json_config) st.apply_json2(dut, json_config) elif cli_type == 'klish': commands = list() commands.append("qos scheduler-policy {}".format( scheduler_data['policy_name'])) scheduler_info = make_list(scheduler_data['scheduler_data']) for ent in scheduler_info: commands.append("queue {}".format(ent['queue'])) if ent.get('type'): commands.append("type {}".format(ent['type'].lower())) if 'weight' in ent: commands.append("weight {}".format(ent['weight'])) commands.append("exit") commands.append("exit") if ports: for port in ports: intf_data = get_interface_number_from_name(port) commands.append("interface {} {}".format( intf_data['type'], intf_data['number'])) commands.append("scheduler-policy {}".format( scheduler_data['policy_name'])) commands.append("exit") response = st.config(dut, commands, type=cli_type, skip_error_check=skip_error) if any(error in response.lower() for error in errors_list): st.error("The response is: {}".format(response)) return False elif cli_type in ['rest-patch', 'rest-put']: rest_urls = st.get_datastore(dut, 'rest_urls') scheduler_info = make_list(scheduler_data['scheduler_data']) for ent in scheduler_info: if ent.get('type') or 'weight' in ent: url = rest_urls['shaper_create_config'] params_config = {"sequence": int(ent['queue'])} if ent.get('type'): params_config.update(priority=ent['type'].upper()) if 'weight' in ent: params_config.update( {"openconfig-qos-ext:weight": int(ent['weight'])}) config_data = { "openconfig-qos:scheduler-policies": { "scheduler-policy": [{ "name": scheduler_data['policy_name'], "config": { "name": scheduler_data['policy_name'] }, "schedulers": { "scheduler": [{ "sequence": int(ent['queue']), "config": params_config }] } }] } } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( 'Failed to create scheduler with data: {}'.format(ent)) return False if ports: for port in ports: url = rest_urls['apply_shaper_config'].format(port) config_data = { "openconfig-qos:config": { "name": scheduler_data['policy_name'] } } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( "Failed to attach queue-shaper configuration to port: {}" .format(port)) return False else: st.error("Unsupported CLI Type: {}".format(cli_type)) return False return True
def apply_port_shaping_config(dut, shaper_data, **kwargs): """ API to configure Port-Level shaper :param dut: :type dut: :param shaper_data: :type shaper_data: :param cli_type: :type cli_type: :return: :rtype: """ cli_type = st.get_ui_type(dut, **kwargs) skip_error = kwargs.get('skip_error', False) cli_type = 'klish' if skip_error and cli_type == 'click' else cli_type st.debug("Provided port-shaper configuration is: {}".format(shaper_data)) if not shaper_data.get("policy_name"): st.error("policy_name is not provided") return False if cli_type == 'click': policy_name = "{}@255".format(shaper_data["policy_name"]) json_data = {"PORT_QOS_MAP": {}, "SCHEDULER": {policy_name: {}}} if shaper_data.get("port"): ports = make_list(shaper_data["port"]) json_data["PORT_QOS_MAP"] = { port: { "scheduler": "{}".format(policy_name) } for port in ports } else: json_data.pop("PORT_QOS_MAP") if ("pir" in shaper_data) or ( "pbs" in shaper_data) or shaper_data.get("meter_type"): if shaper_data.get("meter_type"): json_data["SCHEDULER"][policy_name].update( meter_type=shaper_data['meter_type']) if "pir" in shaper_data: json_data["SCHEDULER"][policy_name].update( pir=str(shaper_data['pir'])) if "pbs" in shaper_data: json_data["SCHEDULER"][policy_name].update( pbs=str(shaper_data['pbs'])) else: json_data.pop("SCHEDULER") json_config = json.dumps(json_data) json.loads(json_config) st.apply_json2(dut, json_config) elif cli_type == 'klish': commands = list() if ("pir" in shaper_data) or ("pbs" in shaper_data): commands.append("qos scheduler-policy {}".format( shaper_data['policy_name'])) commands.append("port") if "pir" in shaper_data: commands.append("pir {}".format( get_klish_rate(shaper_data['pir']))) if "pbs" in shaper_data: commands.append("pbs {}".format(shaper_data['pbs'])) commands.extend(["exit", "exit"]) if shaper_data.get("port"): ports = make_list(shaper_data["port"]) for port in ports: intf_data = get_interface_number_from_name(port) commands.append("interface {} {}".format( intf_data['type'], intf_data['number'])) commands.append("scheduler-policy {}".format( shaper_data['policy_name'])) commands.append("exit") response = st.config(dut, commands, type=cli_type, skip_error_check=skip_error) if any(error in response.lower() for error in errors_list): st.error("The response is: {}".format(response)) return False elif cli_type in ['rest-patch', 'rest-put']: rest_urls = st.get_datastore(dut, 'rest_urls') if ("pir" in shaper_data) or ("pbs" in shaper_data): url = rest_urls['shaper_create_config'] params_config = dict() if "pir" in shaper_data: params_config.update( pir=str(get_rest_rate(shaper_data['pir']))) if "pbs" in shaper_data: params_config.update(be=int(shaper_data['pbs'])) config_data = { "openconfig-qos:scheduler-policies": { "scheduler-policy": [{ "name": shaper_data['policy_name'], "config": { "name": shaper_data['policy_name'] }, "schedulers": { "scheduler": [{ "sequence": 255, "config": { "sequence": 255 }, "two-rate-three-color": { "config": params_config } }] } }] } } if not config_rest( dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( "Failed to create port-level shaper with shaper-data: {}". format(shaper_data)) return False if shaper_data.get("port"): ports = make_list(shaper_data["port"]) for port in ports: url = rest_urls['apply_shaper_config'].format(port) config_data = { "openconfig-qos:config": { "name": shaper_data['policy_name'] } } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( "Failed to attach shaper configuration to port: {}". format(port)) return False else: st.error("Unsupported CLI Type: {}".format(cli_type)) return False return True
def apply_queue_shaping_config(dut, shaper_data, **kwargs): """ API to configure Queue-Level shaper :param dut: :type dut: :param shaper_data: :type shaper_data: :param cli_type: :type cli_type: :return: :rtype: """ cli_type = st.get_ui_type(dut, **kwargs) skip_error = kwargs.get('skip_error', False) cli_type = 'klish' if skip_error and cli_type == 'click' else cli_type st.debug("Provided queue-shaper configuration is: {}".format(shaper_data)) ports = list() if shaper_data.get('port'): ports = make_list(shaper_data['port']) if not shaper_data.get("policy_name"): st.error("policy_name is not provided") return False if cli_type == 'click': config_data = {"QUEUE": {}, "SCHEDULER": {}} if shaper_data.get('shaper_data'): shaper_info = make_list(shaper_data['shaper_data']) for ent in shaper_info: policy = "{}@{}".format(shaper_data['policy_name'], ent['queue']) if ('cir' in ent) or ('cbs' in ent) or ('pir' in ent) or ('pbs' in ent): temp = dict() temp[policy] = {} if 'meter_type' in ent: temp[policy].update(meter_type=ent['meter_type']) if 'cir' in ent: temp[policy].update(cir=str(ent['cir'])) if 'cbs' in ent: temp[policy].update(cbs=str(ent['cbs'])) if 'pir' in ent: temp[policy].update(pir=str(ent['pir'])) if 'pbs' in ent: temp[policy].update(pbs=str(ent['pbs'])) config_data["SCHEDULER"].update(temp) if ports: queue_map = dict() queue_map = { "{}|{}".format(port, ent['queue']): { "scheduler": "{}".format(policy) } for port in ports } config_data["QUEUE"].update(queue_map) config_data2 = {key: value for key, value in config_data.items()} for key, value in config_data2.items(): if not value: config_data.pop(key) json_config = json.dumps(config_data) json.loads(json_config) st.apply_json2(dut, json_config) elif cli_type == 'klish': shaper_info = make_list(shaper_data['shaper_data']) commands = list() commands.append("qos scheduler-policy {}".format( shaper_data['policy_name'])) for ent in shaper_info: if ('cir' in ent) or ('cbs' in ent) or ('pir' in ent) or ('pbs' in ent): commands.append("queue {}".format(ent['queue'])) if 'cir' in ent: commands.append("cir {}".format(get_klish_rate( ent['cir']))) if 'cbs' in ent: commands.append("cbs {}".format(ent['cbs'])) if 'pir' in ent: commands.append("pir {}".format(get_klish_rate( ent['pir']))) if 'pbs' in ent: commands.append("pbs {}".format(ent['pbs'])) commands.append("exit") commands.append("exit") if ports: for port in ports: intf_data = get_interface_number_from_name(port) commands.append("interface {} {}".format( intf_data['type'], intf_data['number'])) commands.append("scheduler-policy {}".format( shaper_data['policy_name'])) commands.append("exit") response = st.config(dut, commands, type=cli_type, skip_error_check=skip_error) if any(error in response.lower() for error in errors_list): st.error("The response is: {}".format(response)) return False elif cli_type in ['rest-patch', 'rest-put']: rest_urls = st.get_datastore(dut, 'rest_urls') shaper_info = make_list(shaper_data['shaper_data']) for ent in shaper_info: if ('cir' in ent) or ('cbs' in ent) or ('pir' in ent) or ('pbs' in ent): url = rest_urls['shaper_create_config'] params_config = dict() if 'cir' in ent: params_config.update(cir=str(get_rest_rate(ent['cir']))) if 'cbs' in ent: params_config.update(bc=int(ent['cbs'])) if 'pir' in ent: params_config.update(pir=str(get_rest_rate(ent['pir']))) if 'pbs' in ent: params_config.update(be=int(ent['pbs'])) config_data = { "openconfig-qos:scheduler-policies": { "scheduler-policy": [{ "name": shaper_data['policy_name'], "config": { "name": shaper_data['policy_name'] }, "schedulers": { "scheduler": [{ "sequence": int(ent['queue']), "config": { "sequence": int(ent['queue']) }, "two-rate-three-color": { "config": params_config } }] } }] } } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( "Failed to create queue-level shaper with shaper-data: {}" .format(ent)) return False if ports: for port in ports: url = rest_urls['apply_shaper_config'].format(port) config_data = { "openconfig-qos:config": { "name": shaper_data['policy_name'] } } if not config_rest(dut, rest_url=url, http_method=cli_type, json_data=config_data): st.error( "Failed to attach queue-shaper configuration to port: {}" .format(port)) return False else: st.error("Unsupported CLI Type: {}".format(cli_type)) return False return True