diff --git a/mdd/python/translation/common.py b/mdd/python/translation/common.py index 1fdc9e11..7c6e1699 100644 --- a/mdd/python/translation/common.py +++ b/mdd/python/translation/common.py @@ -77,3 +77,13 @@ def verify_ipv4(ip: str) -> bool: return False except ValueError: return False + + +def is_qos_configured(nso_props): + if (len(nso_props.service.oc_qos__qos.classifiers.classifier) > 0 or + len(nso_props.service.oc_qos__qos.forwarding_groups.forwarding_group) > 0 or + len(nso_props.service.oc_qos__qos.interfaces.interface) > 0 or + len(nso_props.service.oc_qos__qos.scheduler_policies.scheduler_policy)): + return True + + return False diff --git a/mdd/python/translation/openconfig_nx/nx_main.py b/mdd/python/translation/openconfig_nx/nx_main.py index e4f4e066..2d889113 100644 --- a/mdd/python/translation/openconfig_nx/nx_main.py +++ b/mdd/python/translation/openconfig_nx/nx_main.py @@ -1,6 +1,8 @@ # -*- mode: python; python-indent: 4 -*- from translation.common import is_oc_routing_policy_configured from translation.openconfig_nx.nx_system import nx_system_program_service +from translation.common import is_qos_configured + def check_nx_features(self, nso_props) -> None: """ @@ -33,3 +35,8 @@ def check_nx_features(self, nso_props) -> None: # OpenConfig System nx_system_program_service(self, nso_props) + + # Openconfig QoS + if is_qos_configured(nso_props): + raise NotImplementedError('openconfig-qos has not yet been implemented for XR') + diff --git a/mdd/python/translation/openconfig_xe/xe_main.py b/mdd/python/translation/openconfig_xe/xe_main.py index abf31434..8884c436 100644 --- a/mdd/python/translation/openconfig_xe/xe_main.py +++ b/mdd/python/translation/openconfig_xe/xe_main.py @@ -8,7 +8,7 @@ from translation.openconfig_xe.xe_routing_policy import xe_routing_policy_program_service from translation.openconfig_xe.xe_system import xe_system_program_service from translation.openconfig_xe.xe_stp import xe_stp_program_service - +from translation.openconfig_xe.xe_qos import xe_qos_program_service def check_xe_features(oc_self, nso_props) -> None: """ @@ -40,6 +40,9 @@ def check_xe_features(oc_self, nso_props) -> None: # OpenConfig System xe_system_program_service(oc_self, nso_props) + # OpenConfig QoS + if nso_props.service.oc_qos__qos: + xe_qos_program_service(oc_self, nso_props) def clean_xe_cdb(nso_props) -> None: """ @@ -78,3 +81,4 @@ def clean_xe_cdb(nso_props) -> None: device.ios__ntp.trusted_key.delete() device.ios__router.bgp.delete() device.ios__router.ospf.delete() + diff --git a/mdd/python/translation/openconfig_xe/xe_qos.py b/mdd/python/translation/openconfig_xe/xe_qos.py new file mode 100644 index 00000000..be835446 --- /dev/null +++ b/mdd/python/translation/openconfig_xe/xe_qos.py @@ -0,0 +1,279 @@ +# -*- mode: python; python-indent: 4 -*- +from translation.common import get_interface_type_and_number + +dscp_dict = {8:'cs1', 10:'af11', 12:'af12', 14:'af13', 16:'cs2', 18:'af21', 20:'af22', + 22:'af23', 24:'cs3', 26:'af31', 28:'af32', 30:'af33', 32:'cs4', 34:'af41', + 36:'af42', 38:'af43', 40:'cs5', 46:'ef', 48:'cs6', 56:'cs7', 0:'default'} + +def xe_qos_program_service(self, nso_props) -> None: + """ + Program service + """ + + device_cdb = nso_props.root.devices.device[nso_props.device_name].config + + # Forwarding-groups + """ + Configure forwarding-groups + """ + for fg in nso_props.service.oc_qos__qos.forwarding_groups.forwarding_group: + if device_cdb.ios__policy_map.exists(fg.name): + del device_cdb.ios__policy_map[fg.name] + device_cdb.ios__policy_map.create(fg.name) + + # Class-map + """ + Configure classifiers + """ + list_cmap = [] + for c_map in nso_props.service.oc_qos__qos.classifiers.classifier: + pmap_cmap = {} + # Configure class-map + if device_cdb.ios__class_map.exists(c_map.name) and c_map.name != 'class-default': + del device_cdb.ios__class_map[c_map.name] + elif c_map.name == 'class-default': + for t_map in c_map.terms.term: + pmap_cmap[t_map.actions.config.target_group] = c_map.name + else: + device_cdb.ios__class_map.create(c_map.name) + for t_map in c_map.terms.term: + pmap_cmap[t_map.actions.config.target_group] = c_map.name + # Configure "match ip dscp" + if t_map.conditions.ipv4.config.protocol == 4: + # Configure multiple dscp statements + if t_map.conditions.ipv4.config.dscp_set: + for new_ip_dscp in t_map.conditions.ipv4.config.dscp_set: + new_ip_dscp = modify_dscp(new_ip_dscp) + device_cdb.ios__class_map[c_map.name].prematch = 'match-all' + device_cdb.ios__class_map[c_map.name].match.ip.dscp.create(new_ip_dscp) + # Configure single dscp statements + elif t_map.conditions.ipv4.config.dscp: + new_ip_dscp = modify_dscp(t_map.conditions.ipv4.config.dscp) + device_cdb.ios__class_map[c_map.name].prematch = 'match-all' + device_cdb.ios__class_map[c_map.name].match.ip.dscp.create( + new_ip_dscp) + # Configure "match dscp" + else: + # Configure multiple dscp statements + if t_map.conditions.ipv4.config.dscp_set: + for new_dscp in t_map.conditions.ipv4.config.dscp_set: + new_dscp = modify_dscp(new_dscp) + device_cdb.ios__class_map[c_map.name].prematch = 'match-all' + device_cdb.ios__class_map[c_map.name].match.dscp.create(new_dscp) + # Configure single dscp statements + elif t_map.conditions.ipv4.config.dscp: + new_dscp = modify_dscp(t_map.conditions.ipv4.config.dscp) + device_cdb.ios__class_map[c_map.name].prematch = 'match-all' + device_cdb.ios__class_map[c_map.name].match.dscp.create( + new_dscp) + list_cmap.append(pmap_cmap) + + # Schedulers + """ + Configure schedulers + """ + for sched_pol in nso_props.service.oc_qos__qos.scheduler_policies.scheduler_policy: + for sequence in sched_pol.schedulers.scheduler: + # Configure policy-map + p_map = device_cdb.ios__policy_map.create(sequence.output.config.output_fwd_group) + for dict_pmap_cmap in list_cmap: + if p_map.name in dict_pmap_cmap.keys() and dict_pmap_cmap[p_map.name] in sched_pol.name: + c_map = dict_pmap_cmap[p_map.name] + # Configure policy-map class-map + device_cdb.ios__policy_map[p_map.name].ios__class.create(c_map) + if sequence.config.type == 'oc-qos-types:ONE_RATE_TWO_COLOR': + if sequence.one_rate_two_color.config.queuing_behavior == 'SHAPE': + conf_shape_params(device_cdb, sequence, c_map, p_map.name) + elif sequence.one_rate_two_color.config.queuing_behavior == 'POLICE': + conf_police_params(device_cdb, sequence, c_map, p_map.name) + elif sequence.config.type == 'oc-qos-types:TWO_RATE_THREE_COLOR': + conf_police_params(device_cdb, sequence, c_map, p_map.name) + + # Interfaces + """ + Configure interfaces + """ + for interface in nso_props.service.oc_qos__qos.interfaces.interface: + if interface.output.scheduler_policy.config.name == sched_pol.name: + conf_out_service_policy(device_cdb, interface, sequence) + elif interface.input.scheduler_policy.config.name == sched_pol.name: + conf_in_service_policy(device_cdb, interface, sequence) + +def conf_shape_params(device_cdb, sequence, c_map, p_map): + + # Configure class priority + if sequence.config.priority == 'STRICT': + class_priority = device_cdb.ios__policy_map[p_map].ios__class[c_map].priority + if sequence.one_rate_two_color.config.cir_pct: + class_priority.create() + class_priority.percent = sequence.one_rate_two_color.config.cir_pct + elif sequence.one_rate_two_color.config.cir: + class_priority.create() + class_priority.kilo_bits = int(sequence.one_rate_two_color.config.cir / 1000) + if sequence.one_rate_two_color.config.bc: + class_priority.burst = sequence.one_rate_two_color.config.bc + # Configure class bandwidth + else: + class_bandwidth = device_cdb.ios__policy_map[p_map].ios__class[c_map].bandwidth + if sequence.one_rate_two_color.config.cir_pct: + class_bandwidth.percent = sequence.one_rate_two_color.config.cir_pct + elif sequence.one_rate_two_color.config.cir: + class_bandwidth.bits = sequence.one_rate_two_color.config.cir + elif sequence.one_rate_two_color.config.cir_pct_remaining: + class_bandwidth.remaining.percent.percent = sequence.one_rate_two_color.config.cir_pct_remaining + +def conf_police_params(device_cdb, sequence, c_map, p_map): + + # Configure policing one-rate-two-color + if sequence.one_rate_two_color: + # Configure cir percentage + if sequence.one_rate_two_color.config.cir_pct: + police_cir_percent = device_cdb.ios__policy_map[p_map].ios__class[c_map].police_cir_percent.police.cir.percent + police_cir_percent.percentage = sequence.one_rate_two_color.config.cir_pct + if sequence.one_rate_two_color.config.bc: + # TODO convert bytes to ms + police_cir_percent.bc = sequence.one_rate_two_color.config.bc + police_cir_percent.bc_ms.ms.create() + # Configure conform action + if sequence.one_rate_two_color.conform_action.config.set_dscp: + dscp = modify_dscp(sequence.one_rate_two_color.conform_action.config.set_dscp) + police_cir_percent.actions.conform_set_dscp_transmit.conform_action.set_dscp_transmit = dscp + # Configure exceed action + if sequence.one_rate_two_color.exceed_action: + if sequence.one_rate_two_color.exceed_action.config.set_dscp: + dscp = modify_dscp(sequence.one_rate_two_color.exceed_action.config.set_dscp) + police_cir_percent.actions.exceed_set_dscp_transmit.exceed_action.set_dscp_transmit = dscp + elif sequence.one_rate_two_color.exceed_action.config.drop: + police_cir_percent.actions.exceed_drop.exceed_action.drop.create() + # Configure cir + elif sequence.one_rate_two_color.config.cir: + police_cir = device_cdb.ios__policy_map[p_map].ios__class[c_map].police_policy_map.police + police_cir.cir = sequence.one_rate_two_color.config.cir + if sequence.one_rate_two_color.config.bc: + police_cir.bc = sequence.one_rate_two_color.config.bc + # Configure conform action + if sequence.one_rate_two_color.conform_action.config.set_dscp: + dscp = modify_dscp(sequence.one_rate_two_color.conform_action.config.set_dscp) + police_cir.actions.conform_set_dscp_transmit.conform_action.set_dscp_transmit = dscp + # Configure exceed action + if sequence.one_rate_two_color.exceed_action: + if sequence.one_rate_two_color.exceed_action.config.set_dscp: + dscp = modify_dscp(sequence.one_rate_two_color.exceed_action.config.set_dscp) + police_cir.actions.exceed_set_dscp_transmit.exceed_action.set_dscp_transmit = dscp + elif sequence.one_rate_two_color.exceed_action.config.drop: + police_cir.actions.exceed_drop.exceed_action.drop.create() + # Configure policing two-rate-three-color + if sequence.two_rate_three_color: + # Configure cir percentage + if sequence.two_rate_three_color.config.cir_pct: + police_cir_percent = device_cdb.ios__policy_map[p_map].ios__class[c_map].police_cir_percent.police.cir.percent + police_cir_percent.percentage = sequence.two_rate_three_color.config.cir_pct + if sequence.two_rate_three_color.config.bc: + # TODO convert bytes to ms + police_cir_percent.bc = sequence.two_rate_three_color.config.bc + police_cir_percent.bc_ms.ms.create() + if sequence.two_rate_three_color.config.pir_pct: + police_cir_percent.pir.percent = sequence.two_rate_three_color.config.pir_pct + if sequence.two_rate_three_color.config.be: + # TODO convert bytes to ms + police_cir_percent.pir_be.be = sequence.two_rate_three_color.config.be + police_cir_percent.pir_be_ms.ms.create() + # Configure conform action + if sequence.two_rate_three_color.conform_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.conform_action.config.set_dscp) + police_cir_percent.actions.conform_set_dscp_transmit.conform_action.set_dscp_transmit = dscp + # Configure exceed action + if sequence.two_rate_three_color.exceed_action: + if sequence.two_rate_three_color.exceed_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.exceed_action.config.set_dscp) + police_cir_percent.actions.exceed_set_dscp_transmit.exceed_action.set_dscp_transmit = dscp + elif sequence.two_rate_three_color.exceed_action.config.drop: + police_cir_percent.actions.exceed_drop.exceed_action.drop.create() + # Configure violate action + if sequence.two_rate_three_color.violate_action: + if sequence.two_rate_three_color.violate_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.violate_action.config.set_dscp) + police_cir_percent.actions.violate_set_dscp_transmit.violate_action.set_dscp_transmit = dscp + elif sequence.two_rate_three_color.violate_action.config.drop: + police_cir_percent.actions.violate_drop.violate_action.drop.create() + # Configure cir + elif sequence.two_rate_three_color.config.cir: + police_cir = device_cdb.ios__policy_map[p_map].ios__class[c_map].police_policy_map.police + police_cir.cir = sequence.two_rate_three_color.config.cir + if sequence.two_rate_three_color.config.bc: + police_cir.bc = sequence.two_rate_three_color.config.bc + if sequence.two_rate_three_color.config.pir: + police_cir.pir = sequence.two_rate_three_color.config.pir + if sequence.two_rate_three_color.config.be: + police_cir.pir_be.be = sequence.two_rate_three_color.config.be + # Configure conform action + if sequence.two_rate_three_color.conform_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.conform_action.config.set_dscp) + police_cir.actions.conform_set_dscp_transmit.conform_action.set_dscp_transmit = dscp + # Configure exceed action + if sequence.two_rate_three_color.exceed_action: + if sequence.two_rate_three_color.exceed_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.exceed_action.config.set_dscp) + police_cir.actions.exceed_set_dscp_transmit.exceed_action.set_dscp_transmit = dscp + elif sequence.two_rate_three_color.exceed_action.config.drop: + police_cir.actions.exceed_drop.exceed_action.drop.create() + # Configure violate action + if sequence.two_rate_three_color.violate_action: + if sequence.two_rate_three_color.violate_action.config.set_dscp: + dscp = modify_dscp(sequence.two_rate_three_color.violate_action.config.set_dscp) + police_cir.actions.violate_set_dscp_transmit.violate_action.set_dscp_transmit = dscp + elif sequence.two_rate_three_color.exceed_action.config.drop: + police_cir.actions.violate_drop.violate_action.drop.create() + +def conf_out_service_policy(device_cdb, interface, sequence): + + interface_type, interface_number = get_interface_type_and_number(interface.config.interface_id) + + # Configure service-policy output + device_int = device_cdb.ios__interface + if interface_type == 'GigabitEthernet': + device_int.GigabitEthernet.create(interface_number) + device_int.GigabitEthernet[interface_number].service_policy.output = sequence.output.config.output_fwd_group + elif interface_type == 'Port_channel': + device_int.Port_channel.create(interface_number) + device_int.Port_channel[interface_number].service_policy.output = sequence.output.config.output_fwd_group + elif interface_type == 'Loopback': + device_int.Loopback.create(interface_number) + if sequence.one_rate_two_color.config.queuing_behavior == 'POLICE' or sequence.two_rate_three_color: + device_int.Loopback[interface_number].service_policy.output = sequence.output.config.output_fwd_group + elif interface_type == 'Tunnel': + device_int.Tunnel.create(interface_number) + device_int.Tunnel[interface_number].service_policy.output = sequence.output.config.output_fwd_group + else: + raise ValueError( + f'Interface type {interface_type} not supported by this NSO_OC_Services implementation. Please file an issue at https://github.com/model-driven-devops/nso-oc-services') + +def conf_in_service_policy(device_cdb, interface, sequence): + + interface_type, interface_number = get_interface_type_and_number(interface.config.interface_id) + + # Configure service-policy-input + device_int = device_cdb.ios__interface + if interface_type == 'GigabitEthernet': + device_int.GigabitEthernet.create(interface_number) + if sequence.one_rate_two_color.config.queuing_behavior == 'POLICE' or sequence.two_rate_three_color: + device_int.GigabitEthernet[interface_number].service_policy.input = sequence.output.config.output_fwd_group + elif interface_type == 'Port_channel': + device_int.Port_channel.create(interface_number) + device_int.Port_channel[interface_number].service_policy.input = sequence.output.config.output_fwd_group + elif interface_type == 'Loopback': + device_int.Loopback.create(interface_number) + if sequence.one_rate_two_color.config.queuing_behavior == 'POLICE' or sequence.two_rate_three_color: + device_int.Loopback[interface_number].service_policy.input = sequence.output.config.output_fwd_group + elif interface_type == 'Tunnel': + device_int.Tunnel.create(interface_number) + if sequence.one_rate_two_color.config.queuing_behavior == 'POLICE' or sequence.two_rate_three_color: + device_int.Tunnel[interface_number].service_policy.input = sequence.output.config.output_fwd_group + else: + raise ValueError( + f'Interface type {interface_type} not supported by this NSO_OC_Services implementation. Please file an issue at https://github.com/model-driven-devops/nso-oc-services') + +def modify_dscp(dscp): + if (dscp % 2) != 0: + return dscp + return dscp_dict.get(dscp, 'default') \ No newline at end of file diff --git a/mdd/python/translation/openconfig_xr/xr_main.py b/mdd/python/translation/openconfig_xr/xr_main.py index 4e9ba49f..09eab598 100644 --- a/mdd/python/translation/openconfig_xr/xr_main.py +++ b/mdd/python/translation/openconfig_xr/xr_main.py @@ -7,6 +7,7 @@ from translation.openconfig_xr.xr_acls import xr_acls_lines_program_service from translation.openconfig_xr.xr_acls import xr_acls_ntp_program_service from translation.openconfig_xr.xr_network_instances import xr_network_instances_program_service +from translation.common import is_qos_configured def check_xr_features(oc_self, nso_props) -> None: @@ -41,6 +42,10 @@ def check_xr_features(oc_self, nso_props) -> None: # OpenConfig System xr_system_program_service(oc_self, nso_props) + # OpenConfig QoS + if is_qos_configured(nso_props): + raise NotImplementedError('openconfig-qos has not yet been implemented for XR') + def clean_xr_cdb(nso_props) -> None: """ diff --git a/mdd/src/Makefile b/mdd/src/Makefile index fabb486f..fd5f552e 100644 --- a/mdd/src/Makefile +++ b/mdd/src/Makefile @@ -21,7 +21,8 @@ OC_MODELS = $(filter-out %aaa-tacacs.yang %aaa-radius.yang %grpc.yang, $(wildcar $(filter-out %if-8021X.yang %if-ethernet-ext.yang %if-ip-ext.yang %if-sdn-ext.yang, $(wildcard yang/openconfig/interfaces/*.yang)) \ $(wildcard yang/openconfig/vlan/*.yang) \ $(wildcard yang/openconfig/stp/*.yang) \ - $(wildcard yang/openconfig/multicast/*.yang) \ + $(filter-out %openconfig-qos-interfaces.yang %openconfig-qos-elements.yang, $(wildcard yang/openconfig/qos/*.yang)) \ + $(wildcard yang/openconfig/multicast/*.yang) \ $(filter-out %system-ext-sub-nat.yang, $(wildcard yang/extensions/*.yang)) # Not used diff --git a/mdd/src/yang/openconfig/qos/openconfig-qos-elements.yang b/mdd/src/yang/openconfig/qos/openconfig-qos-elements.yang index 08fe2c95..fb42137c 100644 --- a/mdd/src/yang/openconfig/qos/openconfig-qos-elements.yang +++ b/mdd/src/yang/openconfig/qos/openconfig-qos-elements.yang @@ -17,7 +17,7 @@ submodule openconfig-qos-elements { contact "OpenConfig working group - www.openconfig.net"; + netopenconfig@googlegroups.com"; description "This submodule defines configuration and operational state @@ -36,44 +36,7 @@ submodule openconfig-qos-elements { packets for transmission, including policer and shaper functions"; - oc-ext:openconfig-version "0.8.0"; - - revision "2023-02-17" { - description - "Add queue identifier."; - reference "0.8.0"; - } - - revision "2023-02-08" { - description - "Remove incorrect output placement of interface-ref"; - reference "0.7.0"; - } - - revision "2023-01-28" { - description - "Split groupings in interfaces for better leaf reuse."; - reference "0.6.1"; - } - - revision "2022-09-13" { - description - "Add queue octet drop counter."; - reference "0.6.0"; - } - - revision "2021-08-28" { - description - "Revision updating memory management profile WRED and RED configuration."; - reference "0.5.0"; - } - - revision "2021-04-28" { - description - "Revision updating buffer management and queue management - configuration."; - reference "0.3.0"; - } + oc-ext:openconfig-version "0.2.3"; revision "2019-11-28" { description @@ -372,33 +335,7 @@ submodule openconfig-qos-elements { path "../../../../queues/queue/config/name"; } description - "Output queue for packets in this forwarding group. - This leaf applies to both multicast and unicast - packets. Where a user or system requires separate - queueing for multicast and unicast the unicast-output-queue - and multicast-output-queue leaves should be specified."; - } - - leaf unicast-output-queue { - type leafref { - path "../../../../queues/queue/config/name"; - } - description - "Output queue for unicast packets within this - forwarding group. Where an operator or system does - not require separate queueing for multicast and - unicast this leaf is not specified."; - } - - leaf multicast-output-queue { - type leafref { - path "../../../../queues/queue/config/name"; - } - description - "Output queue for multicast packets within this - forwarding group. Where an operator or system does - not require separate queueing for multicast and - unicast this leaf is not specified."; + "Queue for packets in this forwarding group."; } } @@ -456,7 +393,7 @@ submodule openconfig-qos-elements { leaf enable-ecn { type boolean; - default false; + //default false; description "When set to true, the device should mark packets that are ECN-capable rather than dropping them. The receiver is @@ -579,11 +516,13 @@ submodule openconfig-qos-elements { description "User-defined name of the queue"; } - leaf queue-id { - type uint8; + + leaf queue-type { + type identityref { + base oc-qos-types:QOS_QUEUE_TYPE; + } description - "An optional identifier which may be required by some hardware to map - the named queue to a hardware queue"; + "Sets the type of the queue"; } } @@ -628,6 +567,21 @@ submodule openconfig-qos-elements { uses qos-queue-config; uses qos-queue-state; } + + uses qos-queue-red-top { + when "./config/queue-type = 'oc-qos-types:RED'" { + description + "RED configuration is valid when the queue-type + is set accordingly."; + } + } + uses qos-queue-wred-top { + when "./config/queue-type = 'oc-qos-types:WRED'" { + description + "WRED configuration is valid when the queue-type + is set accordingly."; + } + } } } } @@ -660,11 +614,6 @@ submodule openconfig-qos-elements { } leaf child-scheduler { - when "../output-type = 'SCHEDULER'" { - description - "The child-scheduler leaf is valid only when - the output type of the scheduler is a child scheduler"; - } // TODO: consider whether both child (output) and parent // (input) references are needed; consider whether child // reference should separate in-profile and out-of-profile @@ -675,6 +624,11 @@ submodule openconfig-qos-elements { path "../../../../../../../scheduler-policies/scheduler-policy/" + "config/name"; } + when "../output-type = 'SCHEDULER'" { + description + "The child-scheduler leaf is valid only when + the output type of the scheduler is a child scheduler"; + } description "When the scheduler output type is a child scheduler, this leaf provides a reference to the downstream @@ -682,16 +636,16 @@ submodule openconfig-qos-elements { } leaf output-fwd-group { + type leafref { + path "../../../../../../../forwarding-groups/forwarding-group" + + "/config/name"; + } when "../output-type = 'FWD_GROUP'" { description "The output-fwd-group leaf is valid only when the output type of the scheduler is a forwarding group"; } - type leafref { - path "../../../../../../../forwarding-groups/forwarding-group" + - "/config/name"; - } - description + description "When the scheduler output type is a forwarding group, this leaf provides a reference to the forwarding group."; } @@ -760,16 +714,16 @@ submodule openconfig-qos-elements { } leaf queue { - when "../input-type = 'QUEUE'" { - description - "The queue leaf is valid only when - the input type of the scheduler is a queue"; - } type leafref { // current loc: /qos/scheduler-policies/scheduler-policy/schedulers/ // scheduler/inputs/input/config/queue path "../../../../../../../../queues/queue/name"; } + when "../input-type = 'QUEUE'" { + description + "The queue leaf is valid only when + the input type of the scheduler is a queue"; + } description "Reference to a queue that is an input source for the scheduler"; diff --git a/mdd/src/yang/openconfig/qos/openconfig-qos-interfaces.yang b/mdd/src/yang/openconfig/qos/openconfig-qos-interfaces.yang index e6bc4ea4..821e8962 100644 --- a/mdd/src/yang/openconfig/qos/openconfig-qos-interfaces.yang +++ b/mdd/src/yang/openconfig/qos/openconfig-qos-interfaces.yang @@ -17,57 +17,14 @@ submodule openconfig-qos-interfaces { contact "OpenConfig working group - www.openconfig.net"; + netopenconfig@googlegroups.com"; description "This submodule defines data related to quality-of-service configuration and operational state associated with interfaces."; - oc-ext:openconfig-version "0.8.0"; - - revision "2023-02-17" { - description - "Add queue identifier."; - reference "0.8.0"; - } - - revision "2023-02-08" { - description - "Remove incorrect output placement of interface-ref"; - reference "0.7.0"; - } - - revision "2023-01-28" { - description - "Split groupings in interfaces for better leaf reuse."; - reference "0.6.1"; - } - - revision "2022-09-13" { - description - "Add queue octet drop counter."; - reference "0.6.0"; - } - - revision "2021-08-28" { - description - "Revision updating memory management profile WRED and RED configuration."; - reference "0.5.0"; - } - - revision "2021-04-28" { - description - "Updating memory management profile to queue management profile."; - reference "0.4.0"; - } - - revision "2021-04-28" { - description - "Revision updating buffer management and queue management - configuration."; - reference "0.3.0"; - } + oc-ext:openconfig-version "0.2.3"; revision "2019-11-28" { description @@ -99,9 +56,9 @@ submodule openconfig-qos-interfaces { reference "0.1.0"; } - grouping qos-interface-classifier-match-state { + grouping qos-interface-classifier-match-config { description - "Operational state data for match terms in the classifier + "Configuration data for match terms in the classifier associated with an interface"; leaf id { @@ -117,13 +74,12 @@ submodule openconfig-qos-interfaces { description "Reference to match terms in the classifier"; } - - uses qos-interface-classifier-match-counters-state; } - grouping qos-interface-classifier-match-counters-state { + grouping qos-interface-classifier-match-state { description - "Grouping for counters relating to QoS classifier match terms."; + "Operational state data for match terms in the classifier + associated with an interface"; leaf matched-packets { type oc-yang:counter64; @@ -153,25 +109,33 @@ submodule openconfig-qos-interfaces { list term { key "id"; - config false; description "List of match terms in the classifier associated with the interface"; leaf id { type leafref { - path "../state/id"; + path "../config/id"; } description "Reference to match term id list key"; } + container config { + description + "Configuration data for match terms in the classifier + associated with an interface"; + + uses qos-interface-classifier-match-config; + } + container state { config false; description "Operational state data for match terms in the classifier associated with an interface"; + uses qos-interface-classifier-match-config; uses qos-interface-classifier-match-state; } } @@ -237,27 +201,19 @@ submodule openconfig-qos-interfaces { leaf type { type enumeration { enum IPV4 { - value 4; description - "Classifier matches IPv4 Unicast packets."; + "Classifier matches IPv4 packets."; + value 4; } enum IPV6 { - value 6; description - "Classifier matches IPv6 Unicast packets."; + "Classifier matches IPv6 packets."; + value 6; } enum MPLS { description "Classifier matches MPLS packets."; } - enum IPV4_MULTICAST { - description - "Classifier matches IPv4 Multicast packets."; - } - enum IPV6_MULTICAST { - description - "Classifier matches IPv6 Multicast packets."; - } } description "Type of packets matched by the classifier."; @@ -266,8 +222,8 @@ submodule openconfig-qos-interfaces { grouping qos-interface-queue-config { description - "Configuration data for queues associated with the - interface, this is re-used across input/output queues."; + "Configuration data for the queue associated with the + interface"; leaf name { // TODO(robjs): Previously we proposed that the queue name here is @@ -286,33 +242,6 @@ submodule openconfig-qos-interfaces { } } - grouping qos-interface-queue-root-config { - description - "Configuration parameters for per-queue per-interface, applying - only to the root."; - - leaf queue-management-profile { - type leafref { - // we are at /qos/interfaces/interface/{input,output}/queues/queue/config/queue-management-profile - path "../../../../../../../queue-management-profiles/" + - "queue-management-profile/config/name"; - } - description - "The queue management profile that is to be used for the queue - on the interface. - - For example, the system may use a profile which specifies that - WRED curves are used for setting an ECN mark in the IP header - instead of dropping a packet in order to signal impending - congestion and for determining when there is sufficient - congestion to tail drop packets. - - A single profile is available per queue - which applies to all packets - that are enqueued to the specified queue, whether they are unicast or - multicast."; - } - } - grouping qos-interface-queue-state { description "Operational state data for the queue associated with the @@ -350,12 +279,6 @@ submodule openconfig-qos-interfaces { description "Number of packets dropped by the queue due to overrun"; } - - leaf dropped-octets { - type oc-yang:counter64; - description - "Number of octets dropped by the queue due to overrun"; - } } grouping qos-interface-queue-top { @@ -405,56 +328,6 @@ submodule openconfig-qos-interfaces { } } - grouping qos-interface-queue-root-top { - description - "Top-level grouping for the queue associated with the - interface - used only for /qos/interfaces/interface rather - than in multiple contexts."; - - container queues { - description - "Surrounding container for a list of queues that are - instantiated on an interface."; - - list queue { - key "name"; - - description - "Top-level container for the queue associated with this - interface"; - - leaf name { - type leafref { - path "../config/name"; - } - description - "Reference to the name of the queue - instantiated on the interface."; - } - - container config { - description - "Configuration data for the queue associated with the - interface"; - - uses qos-interface-queue-config; - uses qos-interface-queue-root-config; - } - - container state { - config false; - description - "Operational state data for the queue associated with the - interface"; - - uses qos-interface-queue-config; - uses qos-interface-queue-root-config; - uses qos-interface-queue-state; - } - } - } - } - grouping qos-interface-voqs-top { description "Structural grouping of virtual-output-queue operational state @@ -675,75 +548,6 @@ submodule openconfig-qos-interfaces { grouping qos-interface-input-config { description "Configuration data for QoS on ingress interface"; - - leaf buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/input/config/buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the input (rx) queueing. - - This leaf is used in deployment cases where the operator or system - requires common allocation profiles covering unicast and multicast - packets."; - } - - leaf multicast-buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/input/config/multicast-buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the output (tx) queueing. - - This buffer allocation profile applies to only multicast packets on - the interface - if specified, the unicast-buffer-allocation-profile - governs the allocation profile used for memory dedicated to unicast. - If a system does not support, or an operator does not require separate - buffer-allocation-profiles, this is specified by use of the - buffer-allocation-profile leaf."; - } - - leaf unicast-buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/input/config/unicast-buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the output (tx) queueing. - - This buffer allocation profile applies to only unicast packets on - the interface - if specified, the multicast-buffer-allocation-profile - governs the allocation profile used for memory dedicated to multicast. - If a system does not support, or an operator does not require separate - buffer-allocation-profiles, this is specified by use of the - buffer-allocation-profile leaf."; - } } grouping qos-interface-input-state { @@ -777,7 +581,7 @@ submodule openconfig-qos-interfaces { } uses qos-interface-classifier-top; - uses qos-interface-queue-root-top; + uses qos-interface-queue-top; uses qos-interface-scheduler-top; uses qos-interface-voqs-top; } @@ -786,75 +590,6 @@ submodule openconfig-qos-interfaces { grouping qos-interface-output-config { description "Configuration data for QoS on the egress interface"; - - leaf buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/output/config/buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the output (tx) queueing. - - This leaf is used in deployment cases where the operator or system - requires common allocation profiles covering unicast and multicast - packets."; - } - - leaf multicast-buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/output/config/buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the output (tx) queueing. - - This buffer allocation profile applies to only multicast packets on - the interface - if specified, the unicast-buffer-allocation-profile - governs the allocation profile used for memory dedicated to unicast. - If a system does not support, or an operator does not require separate - buffer-allocation-profiles, this is specified by use of the - buffer-allocation-profile leaf."; - } - - leaf unicast-buffer-allocation-profile { - type leafref { - // we are at - // /qos/interfaces/interface/output/config/buffer-allocation-profile - path "../../../../../buffer-allocation-profiles/" + - "buffer-allocation-profile/config/name"; - } - description - "The buffer allocation profile that is to be used for the interface. - This profile specifies how memory that is available to the interface - should be allocated amongst the queues that are instantiated on the - interface. - - This reference specifies the policy that should be used for memory - allocated to the output (tx) queueing. - - This buffer allocation profile applies to only unicast packets on - the interface - if specified, the multicast-buffer-allocation-profile - governs the allocation profile used for memory dedicated to multicast. - If a system does not support, or an operator does not require separate - buffer-allocation-profiles, this is specified by use of the - buffer-allocation-profile leaf."; - } } grouping qos-interface-output-state { @@ -887,8 +622,9 @@ submodule openconfig-qos-interfaces { uses qos-interface-output-state; } + uses oc-if:interface-ref; uses qos-interface-classifier-top; - uses qos-interface-queue-root-top; + uses qos-interface-queue-top; uses qos-interface-scheduler-top; } } @@ -934,8 +670,9 @@ submodule openconfig-qos-interfaces { uses oc-if:interface-ref; uses qos-interface-input-top; uses qos-interface-output-top; + } } } -} \ No newline at end of file +} diff --git a/mdd/src/yang/openconfig/qos/openconfig-qos-types.yang b/mdd/src/yang/openconfig/qos/openconfig-qos-types.yang index c178af89..c6ebde43 100644 --- a/mdd/src/yang/openconfig/qos/openconfig-qos-types.yang +++ b/mdd/src/yang/openconfig/qos/openconfig-qos-types.yang @@ -156,4 +156,4 @@ module openconfig-qos-types { // notification statements -} \ No newline at end of file +} diff --git a/mdd/src/yang/openconfig/qos/openconfig-qos.yang b/mdd/src/yang/openconfig/qos/openconfig-qos.yang index e472a95d..0bbdd7c3 100644 --- a/mdd/src/yang/openconfig/qos/openconfig-qos.yang +++ b/mdd/src/yang/openconfig/qos/openconfig-qos.yang @@ -28,51 +28,7 @@ module openconfig-qos { "This module defines configuration and operational state data related to network quality-of-service."; - oc-ext:openconfig-version "0.8.0"; - - revision "2023-02-17" { - description - "Add queue identifier."; - reference "0.8.0"; - } - - revision "2023-02-08" { - description - "Remove incorrect output placement of interface-ref"; - reference "0.7.0"; - } - - revision "2023-01-28" { - description - "Split groupings in interfaces for better leaf reuse."; - reference "0.6.1"; - } - - revision "2022-09-13" { - description - "Add queue octet drop counter."; - reference "0.6.0"; - } - - revision "2021-08-28" { - description - "Revision using latest revision of openconfig-qos-mem-mgmt submodule."; - reference "0.5.0"; - } - - revision "2021-06-28" { - description - "Revision to include buffer-allocation-profile-q-config - parameters in openconfig-qos-mem-mgmt submodule."; - reference "0.4.0"; - } - - revision "2021-04-28" { - description - "Revision updating buffer management and queue management - configuration."; - reference "0.3.0"; - } + oc-ext:openconfig-version "0.2.3"; revision "2019-11-28" { description @@ -143,7 +99,6 @@ module openconfig-qos { uses qos-forwarding-group-top; uses qos-queue-top; uses qos-scheduler-top; - uses qos-buffer-profile-top; } } diff --git a/package_nso_to_oc/main.py b/package_nso_to_oc/main.py old mode 100755 new mode 100644 diff --git a/package_nso_to_oc/xe/main_xe.py b/package_nso_to_oc/xe/main_xe.py index c7488971..0beff449 100644 --- a/package_nso_to_oc/xe/main_xe.py +++ b/package_nso_to_oc/xe/main_xe.py @@ -9,7 +9,7 @@ if (find_spec("package_nso_to_oc") is not None): from package_nso_to_oc import common - from package_nso_to_oc.xe import xe_network_instances, xe_vlans, xe_interfaces, xe_system, xe_stp, xe_acls, xe_routing_policy + from package_nso_to_oc.xe import xe_network_instances, xe_vlans, xe_interfaces, xe_system, xe_stp, xe_acls, xe_routing_policy, xe_qos else: import common from xe import xe_network_instances, xe_vlans, xe_interfaces, xe_system, xe_stp, xe_acls, xe_routing_policy @@ -27,12 +27,14 @@ def build_xe_to_oc(config_before_dict: dict, configs_leftover: dict, oc: dict, t "openconfig-network-instance:network-instance"][0]["openconfig-network-instance:vlans"]) openconfig_system = xe_system.main(config_before_dict, configs_leftover, interface_ip_name_dict, translation_notes) openconfig_stp = xe_stp.main(config_before_dict, configs_leftover, translation_notes) + openconfig_qos = xe_qos.main(config_before_dict, configs_leftover, translation_notes) oc['mdd:openconfig'].update(openconfig_stp) oc['mdd:openconfig'].update(openconfig_system) oc['mdd:openconfig'].update(openconfig_network_instances) oc['mdd:openconfig'].update(openconfig_interfaces) oc['mdd:openconfig'].update(openconfig_acls) oc['mdd:openconfig'].update(openconfig_routing_policy) + oc['mdd:openconfig'].update(openconfig_qos) # return added for direct calls from ansible-mdd return common.prune_configs(oc) diff --git a/package_nso_to_oc/xe/xe_acls.py b/package_nso_to_oc/xe/xe_acls.py old mode 100755 new mode 100644 diff --git a/package_nso_to_oc/xe/xe_qos.py b/package_nso_to_oc/xe/xe_qos.py new file mode 100644 index 00000000..c6595847 --- /dev/null +++ b/package_nso_to_oc/xe/xe_qos.py @@ -0,0 +1,1439 @@ +#! /usr/bin/env python3 +""" +Translate NSO Device config to MDD OpenConfig + +This script will pull a device's configuration from an NSO server, convert the NED structured configuration to +MDD OpenConfig, save the NSO configuration to a file named {device_name}_configuration.json, save the NSO device +configuration minus parts replaced by OpenConfig to a file named {device_name}_configuration_remaining.json, +and save the MDD OpenConfig configuration to a file named {nso_device}_openconfig_qos.json. + +The script requires the following environment variables: +NSO_URL - URL for the NSO server +NSO_USERNAME +NSO_PASSWORD +NSO_DEVICE - NSO device name for configuration translation +TEST - True or False. True enables sending the OpenConfig to the NSO server after generation +""" + +import sys +# from pathlib import Path +from importlib.util import find_spec +qos_notes = [] + +dscp_dict = {'cs1':8, 'af11':10, 'af12':12, 'af13':14, 'cs2':16, 'af21':18, 'af22':20, + 'af23':22, 'cs3':24, 'af31':26, 'af32':28, 'af33':30, 'cs4':32, 'af41':34, + 'af42':36, 'af43':38, 'cs5':40, 'ef':46, 'cs6':48, 'cs7':56, 'default':0} + +openconfig_qos = { + "openconfig-qos:qos": { + "openconfig-qos:forwarding-groups": { + "openconfig-qos:forwarding-group": [] + }, + "openconfig-qos:classifiers": { + "openconfig-qos:classifier": [] + }, + "openconfig-qos:scheduler-policies": { + "openconfig-qos:scheduler-policy": [] + }, + "openconfig-qos:interfaces": { + "openconfig-qos:interface": [] + } + } +} + + +def configure_xe_qos(config_before: dict, config_leftover: dict) -> None: + """ + Translates NSO XE NED to MDD OpenConfig QoS + """ + openconfig_policy_map = openconfig_qos["openconfig-qos:qos"]["openconfig-qos:forwarding-groups"]["openconfig-qos:forwarding-group"] + openconfig_class_map = openconfig_qos["openconfig-qos:qos"]["openconfig-qos:classifiers"]["openconfig-qos:classifier"] + openconfig_scheduler = openconfig_qos["openconfig-qos:qos"]["openconfig-qos:scheduler-policies"]["openconfig-qos:scheduler-policy"] + openconfig_interface = openconfig_qos["openconfig-qos:qos"]["openconfig-qos:interfaces"]["openconfig-qos:interface"] + policy_map_list = config_before.get("tailf-ned-cisco-ios:policy-map") + class_map_list = config_before.get("tailf-ned-cisco-ios:class-map") + interface_dict = config_before.get("tailf-ned-cisco-ios:interface") + + # Init variables: class default index, class map index + cd_index = c_index = 0 + # Init list: interface to scheduler list + intf_to_sched_list = [] + + # Configure OC Forwarding Groups and Schedulers + for policy_map_index, policy_map in enumerate(policy_map_list): + # Configure OC Forwarding Groups + set_qos_policy_map(policy_map, openconfig_policy_map) + # Configure OC Schedulers + # For Class Default + if "class-default" in policy_map: + cd_index += 1 + # Configure OC terms class-default + set_qos_class_default(cd_index, policy_map, openconfig_class_map) + # Priority percent and kilo-bits + if "priority" in policy_map["class-default"]["class"][0]: + if "percent" in policy_map["class-default"]["class"][0]["priority"]: + set_sched_class_default_priority_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + elif "kilo-bits" in policy_map["class-default"]["class"][0]["priority"]: + set_sched_class_default_priority_bits(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Bandwidth percent and bits + elif "bandwidth" in policy_map["class-default"]["class"][0]: + if "percent" in policy_map["class-default"]["class"][0]["bandwidth"]: + set_sched_class_default_bandwidth_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + elif "bits" in policy_map["class-default"]["class"][0]: + set_sched_class_default_bandwidth_bits(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Police CIR + elif "police-policy-map" in policy_map["class-default"]["class"][0]: + # Two Rate, Three Color + if "conform-set-dscp-transmit" in policy_map["class-default"]["class"][0]["police-policy-map"]["police"]["actions"] and ("exceed-set-dscp-transmit" in policy_map[ + "class-default"]["class"][0]["police-policy-map"]["police"]["actions"] or "exceed-drop" in policy_map["class-default"]["class"][0]["police-policy-map"]["police"]["actions"]) and ( + "violate-set-dscp-transmit" in policy_map["class-default"]["class"][0][ + "police-policy-map"]["police"]["actions"] or "violate-drop" in policy_map["class-default"]["class"][0]["police-policy-map"]["police"]["actions"]): + set_sched_class_default_policy_three_color(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + # One Rate, Two Color + elif "conform-set-dscp-transmit" in policy_map["class-default"]["class"][0]["police-policy-map"]["police"]["actions"] and ("exceed-set-dscp-transmit" in policy_map[ + "class-default"]["class"][0]["police-policy-map"]["police"]["actions"] or "exceed-drop" in policy_map["class-default"]["class"][0]["police-policy-map"]["police"]["actions"]): + set_sched_class_default_policy_two_color(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Police CIR Percent + elif "police-cir-percent" in policy_map["class-default"]["class"][0]: + # Two Rate, Three Color + if "conform-set-dscp-transmit" in policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"] and ("exceed-set-dscp-transmit" in policy_map[ + "class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"] or "exceed-drop" in policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"]) and ( + "violate-set-dscp-transmit" in policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"] or "violate-drop" in policy_map["class-default"][ + "class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"]): + set_sched_class_default_policy_three_color_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + # One Rate, Two Color + elif "conform-set-dscp-transmit" in policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"] and ("exceed-set-dscp-transmit" in policy_map[ + "class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"] or "exceed-drop" in policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"]["actions"]): + set_sched_class_default_policy_two_color_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + #For class-map + if "class" in policy_map: + for class_index, class_name in enumerate(policy_map["class"]): + c_index += 1 + # Priority percent and kilo-bits + if "priority" in class_name: + if "percent" in class_name["priority"]: + set_sched_priority_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + elif "kilo-bits" in class_name["priority"]: + set_sched_priority_bits(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Bandwidth percent and bits + elif "bandwidth" in class_name: + if "percent" in class_name["bandwidth"]: + set_sched_bandwidth_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + elif "bits" in class_name["bandwidth"]: + set_sched_bandwidth_bits(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Police CIR + elif "police-policy-map" in class_name: + # Two Rate, Three Color + if "conform-set-dscp-transmit" in class_name["police-policy-map"]["police"]["actions"] and ("exceed-set-dscp-transmit" in class_name[ + "police-policy-map"]["police"]["actions"] or "exceed-drop" in class_name["police-policy-map"]["police"]["actions"]) and ( + "violate-set-dscp-transmit" in class_name["police-policy-map"]["police"][ + "actions"] or "violate-drop" in class_name["police-policy-map"]["police"]["actions"]): + set_sched_policy_three_color(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + # One Rate, Two Color + elif "conform-set-dscp-transmit" in class_name["police-policy-map"]["police"]["actions"] and ("exceed-set-dscp-transmit" in class_name[ + "police-policy-map"]["police"]["actions"] or "exceed-drop" in class_name["police-policy-map"]["police"]["actions"]): + set_sched_policy_two_color(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + # Police CIR Percent + elif "police-cir-percent" in class_name: + # Two Rate, Three Color + if "conform-set-dscp-transmit" in class_name["police-cir-percent"]["police"]["cir"]["percent"]["actions"] and ("exceed-set-dscp-transmit" in class_name[ + "police-cir-percent"]["police"]["cir"]["percent"]["actions"] or "exceed-drop" in class_name["police-cir-percent"]["police"]["cir"]["percent"]["actions"]) and ( + "violate-set-dscp-transmit" in class_name["police-cir-percent"]["police"][ + "cir"]["percent"]["actions"] or "violate-drop" in class_name["police-cir-percent"]["police"]["cir"]["percent"]["actions"]): + set_sched_policy_three_color_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + # One Rate, Two Color + elif "conform-set-dscp-transmit" in class_name["police-cir-percent"]["police"]["cir"]["percent"]["actions"] and ("exceed-set-dscp-transmit" in class_name[ + "police-cir-percent"]["police"]["cir"]["percent"]["actions"] or "exceed-drop" in class_name["police-cir-percent"]["police"]["cir"]["percent"]["actions"]): + set_sched_policy_two_color_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler) + intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler) + + for class_map_index, class_map in enumerate(class_map_list): + # Set QoS class-maps + if "ip" in class_map["match"]: + # class-map with 'match ip' + set_qos_class_map_ip(config_leftover, class_map_index, class_map, openconfig_class_map, policy_map_list) + else: + set_qos_class_map(config_leftover, class_map_index, class_map, openconfig_class_map, policy_map_list) + + for interface in interface_dict: + if interface: + # Map OC interface and scheduler + set_qos_interface(config_leftover, openconfig_interface, interface, interface_dict[interface], intf_to_sched_list, openconfig_scheduler) + + +def intf_to_scheduler_map(config_leftover, policy_map, intf_to_sched_list, openconfig_scheduler): + + # Map policy-map and scheduler + intf_to_sched_list.append({policy_map["name"]: openconfig_scheduler[-1]['openconfig-qos:name']}) + return intf_to_sched_list + + +def set_qos_class_default(cd_index, policy_map, openconfig_class_map): + + openconfig_class_map.append({ + "openconfig-qos:name": "class-default", + "openconfig-qos:config": {"openconfig-qos:name:": "class-default"}, + "openconfig-qos:terms": {"openconfig-qos:term": [{"openconfig-qos:id": "term-default-" + f'{cd_index}', + "openconfig-qos:config": { + "openconfig-qos:id": "term-default-" + f'{cd_index}' + }, + "openconfig-qos:actions": { + "openconfig-qos:config": { + "openconfig-qos:target-group": policy_map["name"] + } + } + } + ] + } + }) + + +def set_qos_policy_map(policy_map, openconfig_policy_map): + + openconfig_policy_map.append({"openconfig-qos:name": policy_map["name"], + "openconfig-qos:config": { + "openconfig-qos:name": policy_map["name"] + }}) + + +def set_sched_class_default_priority_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:priority": "STRICT", + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": policy_map["class-default"]["class"][0]["priority"]["percent"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_priority_bits(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:priority": "STRICT", + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": policy_map["class-default"]["class"][0]["priority"]["kilo-bits"], + "openconfig-qos:bc": policy_map["class-default"]["class"][0]["priority"]["burst"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_bandwidth_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": policy_map["class-default"]["class"][0]["bandwidth"]["percent"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_bandwidth_bits(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": policy_map["class-default"]["class"][0]["bandwidth"]["bits"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_policy_three_color(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + cd_new_police = policy_map["class-default"]["class"][0]["police-policy-map"]["police"] + cd_new_actions = cd_new_police["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "TWO_RATE_THREE_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:two-rate-three-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": set_class_default_qos_cir(cd_new_police), + "openconfig-qos:bc": set_class_default_qos_bc(cd_new_police), + "openconfig-qos:pir": set_class_default_qos_pir(cd_new_police), + "openconfig-qos:be": set_class_default_qos_be(cd_new_police) + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_conform(cd_new_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_exceed(cd_new_actions)[0], + "openconfig-qos:drop": set_class_default_policy_exceed(cd_new_actions)[1] + } + }, + "openconfig-qos:violate-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_violate(cd_new_actions)[0], + "openconfig-qos:drop": set_class_default_policy_violate(cd_new_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_policy_two_color(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + cd_new_police = policy_map["class-default"]["class"][0]["police-policy-map"]["police"] + cd_new_actions = cd_new_police["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": set_class_default_qos_cir(cd_new_police), + "openconfig-qos:bc": set_class_default_qos_bc(cd_new_police), + "openconfig-qos:queuing-behavior": 'POLICE' + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_conform(cd_new_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_exceed(cd_new_actions)[0], + "openconfig-qos:drop": set_class_default_policy_exceed(cd_new_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_policy_three_color_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + cd_new_percent = policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"] + cd_new_percent_actions = cd_new_percent["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "TWO_RATE_THREE_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:two-rate-three-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": set_class_default_qos_cir_percent(cd_new_percent), + "openconfig-qos:bc": set_class_default_qos_bc_percent(cd_new_percent), + "openconfig-qos:pir-pct": set_class_default_qos_pir_percent(cd_new_percent), + "openconfig-qos:be": set_class_default_qos_be_percent(cd_new_percent) + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_conform_percent(cd_new_percent_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_exceed_percent(cd_new_percent_actions)[0], + "openconfig-qos:drop": set_class_default_policy_exceed_percent(cd_new_percent_actions)[1] + } + }, + "openconfig-qos:violate-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_violate_percent(cd_new_percent_actions)[0], + "openconfig-qos:drop": set_class_default_policy_violate_percent(cd_new_percent_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_class_default_policy_two_color_percent(config_leftover, cd_index, policy_map_index, policy_map, openconfig_scheduler): + + cd_new_percent = policy_map["class-default"]["class"][0]["police-cir-percent"]["police"]["cir"]["percent"] + cd_new_percent_actions = cd_new_percent["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default", + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{cd_index}-'"class-default" + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:priority": "STRICT", + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": set_class_default_qos_cir_percent(cd_new_percent), + "openconfig-qos:bc": set_class_default_qos_bc_percent(cd_new_percent), + "openconfig-qos:queuing-behavior": 'POLICE' + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_conform_percent(cd_new_percent_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_class_default_policy_exceed_percent(cd_new_percent_actions)[0], + "openconfig-qos:drop": set_class_default_policy_exceed_percent(cd_new_percent_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class-default"] = None + + +def set_sched_priority_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:priority": "STRICT", + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": class_name["priority"]["percent"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_priority_bits(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:priority": "STRICT", + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": class_name["priority"]["kilo-bits"], + "openconfig-qos:bc": class_name["priority"]["burst"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_bandwidth_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": class_name["bandwidth"]["percent"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_bandwidth_bits(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": class_name["bandwidth"]["bits"], + "openconfig-qos:queuing-behavior": "SHAPE" + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_policy_three_color(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + cm_new_police = class_name["police-policy-map"]["police"] + cm_new_actions = cm_new_police["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "TWO_RATE_THREE_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:two-rate-three-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": set_qos_cir(cm_new_police), + "openconfig-qos:bc": set_qos_bc(cm_new_police), + "openconfig-qos:pir": set_qos_pir(cm_new_police), + "openconfig-qos:be": set_qos_be(cm_new_police) + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_conform(cm_new_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_exceed(cm_new_actions)[0], + "openconfig-qos:drop": set_policy_exceed(cm_new_actions)[1] + } + }, + "openconfig-qos:violate-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_violate(cm_new_actions)[0], + "openconfig-qos:drop": set_policy_violate(cm_new_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_policy_two_color(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + cm_new_police = class_name["police-policy-map"]["police"] + cm_new_actions = cm_new_police["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": set_qos_cir(cm_new_police), + "openconfig-qos:bc": set_qos_bc(cm_new_police), + "openconfig-qos:queuing-behavior": "POLICE" + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_conform(cm_new_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_exceed(cm_new_actions)[0], + "openconfig-qos:drop": set_policy_exceed(cm_new_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_policy_three_color_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + cm_new_percent = class_name["police-cir-percent"]["police"]["cir"]["percent"] + cm_new_percent_actions = cm_new_percent["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "TWO_RATE_THREE_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:two-rate-three-color": { + "openconfig-qos:config": { + "openconfig-qos:cir": set_qos_cir_percent(cm_new_percent), + "openconfig-qos:bc": set_qos_bc_percent(cm_new_percent), + "openconfig-qos:pir": set_qos_pir_percent(cm_new_percent), + "openconfig-qos:be": set_qos_be_percent(cm_new_percent) + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_conform_percent(cm_new_percent_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_exceed_percent(cm_new_percent_actions)[0], + "openconfig-qos:drop": set_policy_exceed_percent(cm_new_percent_actions)[1] + } + }, + "openconfig-qos:violate-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_violate_percent(cm_new_percent_actions)[0], + "openconfig-qos:drop": set_policy_violate_percent(cm_new_percent_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_sched_policy_two_color_percent(config_leftover, class_index, policy_map_index, class_name, c_index, policy_map, openconfig_scheduler): + + cm_new_percent = class_name["police-cir-percent"]["police"]["cir"]["percent"] + cm_new_percent_actions = cm_new_percent["actions"] + openconfig_scheduler.append({ + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}', + "openconfig-qos:config": { + "openconfig-qos:name": "sched-"f'{c_index}-'f'{class_name["name"]}' + }, + "openconfig-qos:schedulers": { + "openconfig-qos:scheduler": [{ + "openconfig-qos:sequence": 10, + "openconfig-qos:config": { + "openconfig-qos:sequence": 10, + "openconfig-qos:type": "ONE_RATE_TWO_COLOR" + }, + "openconfig-qos:output": { + "openconfig-qos:config": { + "openconfig-qos:output-type": "FWD_GROUP", + "openconfig-qos:output-fwd-group": policy_map["name"] + } + }, + "openconfig-qos:one-rate-two-color": { + "openconfig-qos:config": { + "openconfig-qos:cir-pct": set_qos_cir_percent(cm_new_percent), + "openconfig-qos:bc": set_qos_bc_percent(cm_new_percent), + "openconfig-qos:queuing-behavior": "POLICE" + }, + "openconfig-qos:conform-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_conform_percent(cm_new_percent_actions) + } + }, + "openconfig-qos:exceed-action": { + "openconfig-qos:config": { + "openconfig-qos:set-dscp": set_policy_exceed_percent(cm_new_percent_actions)[0], + "openconfig-qos:drop": set_policy_exceed_percent(cm_new_percent_actions)[1] + } + } + } + }] + } + }) + + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["name"] = None + config_leftover["tailf-ned-cisco-ios:policy-map"][policy_map_index]["class"][class_index] = None + + +def set_class_default_qos_cir(cd_new_police): + + cir = None + if "cir" in cd_new_police: + cir = cd_new_police["cir"] + + return cir + + +def set_class_default_qos_bc(cd_new_police): + + bc = None + if "bc" in cd_new_police: + bc = cd_new_police["bc"] + + return bc + + +def set_class_default_qos_pir(cd_new_police): + + pir = None + if "pir" in cd_new_police: + pir = cd_new_police["pir"] + + return pir + + +def set_class_default_qos_be(cd_new_police): + + be = None + if "pir-be" in cd_new_police and "be" in cd_new_police["pir-be"]: + be = cd_new_police["pir-be"]["be"] + + return be + + +def set_class_default_qos_cir_percent(cd_new_percent): + + cir_percent = None + if "percentage" in cd_new_percent: + cir_percent = cd_new_percent["percentage"] + + return cir_percent + + +def set_class_default_qos_bc_percent(cd_new_percent): + + bc_percent = None + if "bc" in cd_new_percent: + bc_percent = cd_new_percent["bc"] + + return bc_percent + + +def set_class_default_qos_pir_percent(cd_new_percent): + + pir_percent = None + if "pir" in cd_new_percent and "percent" in cd_new_percent["pir"]: + pir_percent = cd_new_percent["pir"]["percent"] + + return pir_percent + + +def set_class_default_qos_be_percent(cd_new_percent): + + be_percent = None + if "pir-be" in cd_new_percent and "be" in cd_new_percent["pir-be"]: + be_percent = cd_new_percent["pir-be"]["be"] + + return be_percent + + +def set_qos_cir(cm_new_police): + + cir = None + if "cir" in cm_new_police: + cir = cm_new_police["cir"] + + return cir + +def set_qos_bc(cm_new_police): + + bc = None + if "bc" in cm_new_police: + bc = cm_new_police["bc"] + + return bc + +def set_qos_pir(cm_new_police): + + pir = None + if "pir" in cm_new_police: + pir = cm_new_police["pir"] + + return pir + +def set_qos_be(cm_new_police): + + be = None + if "pir-be" in cm_new_police and "be" in cm_new_police["pir-be"]: + be = cm_new_police["pir-be"]["be"] + + return be + + +def set_qos_cir_percent(cm_new_percent): + + cir_percent = None + if "percentage" in cm_new_percent: + cir_percent = cm_new_percent["percentage"] + + return cir_percent + + +def set_qos_bc_percent(cm_new_percent): + + bc_percent = None + if "bc" in cm_new_percent: + bc_percent = cm_new_percent["bc"] + + return bc_percent + + +def set_qos_pir_percent(cm_new_percent): + + pir_percent = None + if "pir" in cm_new_percent and "percent" in cm_new_percent["pir"]: + pir_percent = cm_new_percent["pir"]["percent"] + + return pir_percent + + +def set_qos_be_percent(cm_new_percent): + + be_percent = None + if "pir-be" in cm_new_percent and "be" in cm_new_percent["pir-be"]: + be_percent = cm_new_percent["pir-be"]["be"] + + return be_percent + + +def set_class_default_policy_conform(cd_new_actions): + + conform = None + if "set-dscp-transmit" in cd_new_actions["conform-set-dscp-transmit"]["conform-action"]: + conform = cd_new_actions["conform-set-dscp-transmit"]["conform-action"]["set-dscp-transmit"] + + if type(conform) is str: + conform = dscp_dict.get(conform, 'default') + + return conform + + +def set_class_default_policy_exceed(cd_new_actions): + + exceed = drop = None + if "exceed-set-dscp-transmit" in cd_new_actions: + exceed = cd_new_actions["exceed-set-dscp-transmit"]["exceed-action"]["set-dscp-transmit"] + elif "exceed-drop" in cd_new_actions: + drop = True + + if type(exceed) is str: + exceed = dscp_dict.get(exceed, 'default') + + return exceed, drop + + +def set_class_default_policy_violate(cd_new_actions): + + violate = drop = None + if "violate-set-dscp-transmit" in cd_new_actions: + violate = cd_new_actions["violate-set-dscp-transmit"]["violate-action"]["set-dscp-transmit"] + elif "violate-drop" in cd_new_actions: + drop = True + + if type(violate) is str: + violate = dscp_dict.get(violate, 'default') + + return violate, drop + + +def set_class_default_policy_conform_percent(cd_new_percent_actions): + + conform_percent = None + if "set-dscp-transmit" in cd_new_percent_actions["conform-set-dscp-transmit"]["conform-action"]: + conform_percent = cd_new_percent_actions["conform-set-dscp-transmit"]["conform-action"]["set-dscp-transmit"] + + if type(conform_percent) is str: + conform_percent = dscp_dict.get(conform_percent, 'default') + + return conform_percent + + +def set_class_default_policy_exceed_percent(cd_new_percent_actions): + + exceed_percent = drop = None + if "exceed-set-dscp-transmit" in cd_new_percent_actions: + exceed_percent = cd_new_percent_actions["exceed-set-dscp-transmit"]["exceed-action"]["set-dscp-transmit"] + elif "exceed-drop" in cd_new_percent_actions: + drop = True + + if type(exceed_percent) is str: + exceed_percent = dscp_dict.get(exceed_percent, 'default') + + return exceed_percent, drop + + +def set_class_default_policy_violate_percent(cd_new_percent_actions): + + violate_percent = drop = None + if "violate-set-dscp-transmit" in cd_new_percent_actions: + violate_percent = cd_new_percent_actions["violate-set-dscp-transmit"]["violate-action"]["set-dscp-transmit"] + elif "violate-drop" in cd_new_percent_actions: + drop = True + + if type(violate_percent) is str: + violate_percent = dscp_dict.get(violate_percent, 'default') + + return violate_percent, drop + + +def set_policy_conform(cm_new_actions): + + conform = None + if "set-dscp-transmit" in cm_new_actions["conform-set-dscp-transmit"]["conform-action"]: + conform = cm_new_actions["conform-set-dscp-transmit"]["conform-action"]["set-dscp-transmit"] + + if type(conform) is str: + conform = dscp_dict.get(conform, 'default') + + return conform + +def set_policy_exceed(cm_new_actions): + + exceed = drop = None + if "exceed-set-dscp-transmit" in cm_new_actions: + exceed = cm_new_actions["exceed-set-dscp-transmit"]["exceed-action"]["set-dscp-transmit"] + elif "exceed-drop" in cm_new_actions: + drop = True + + if type(exceed) is str: + exceed = dscp_dict.get(exceed, 'default') + + return exceed, drop + + +def set_policy_violate(cm_new_actions): + + violate = drop = None + if "violate-set-dscp-transmit" in cm_new_actions: + violate = cm_new_actions["violate-set-dscp-transmit"]["violate-action"]["set-dscp-transmit"] + elif "violate-drop" in cm_new_actions: + drop = True + + if type(violate) is str: + violate = dscp_dict.get(violate, 'default') + + return violate, drop + + +def set_policy_conform_percent(cm_new_percent_actions): + + conform_percent = None + if "set-dscp-transmit" in cm_new_percent_actions["conform-set-dscp-transmit"]["conform-action"]: + conform_percent = cm_new_percent_actions["conform-set-dscp-transmit"]["conform-action"]["set-dscp-transmit"] + + if type(conform_percent) is str: + conform_percent = dscp_dict.get(conform_percent, 'default') + + return conform_percent + + +def set_policy_exceed_percent(cm_new_percent_actions): + + exceed_percent = drop = None + if "exceed-set-dscp-transmit" in cm_new_percent_actions: + exceed_percent = cm_new_percent_actions["exceed-set-dscp-transmit"]["exceed-action"]["set-dscp-transmit"] + elif "exceed-drop" in cm_new_percent_actions: + drop = True + + if type(exceed_percent) is str: + exceed_percent = dscp_dict.get(exceed_percent, 'default') + + return exceed_percent, drop + + +def set_policy_violate_percent(cm_new_percent_actions): + + violate_percent = drop = None + if "violate-set-dscp-transmit" in cm_new_percent_actions: + violate_percent = cm_new_percent_actions["violate-set-dscp-transmit"]["violate-action"]["set-dscp-transmit"] + elif "violate-drop" in cm_new_percent_actions: + drop = True + + if type(violate_percent) is str: + violate_percent = dscp_dict.get(violate_percent, 'default') + + return violate_percent, drop + + +def set_qos_interface(config_leftover, openconfig_interface, interface, interface_list, intf_to_sched_list, openconfig_scheduler): + + for index, intf in enumerate(interface_list): + openconfig_interface.append({ + "openconfig-qos:interface-id": interface + str(intf.get("name")), + "openconfig-qos:config": { + "openconfig-qos:interface-id": interface + str(intf.get("name")) + }, + "openconfig-qos:input": { + "openconfig-qos:scheduler-policy": { + "openconfig-qos:config": { + "openconfig-qos:name": set_scheduler_policy_input( + config_leftover, openconfig_scheduler, interface, intf, intf_to_sched_list, index) + } + } + }, + "openconfig-qos:output": { + "openconfig-qos:scheduler-policy": { + "openconfig-qos:config": { + "openconfig-qos:name": set_scheduler_policy_output( + config_leftover, openconfig_scheduler, interface, intf, intf_to_sched_list, index) + } + } + } + }) + + +def set_scheduler_policy_output(config_leftover, openconfig_scheduler, interface, intf, intf_to_sched_list, index): + + scheduler_out = None + if "service-policy" in intf: + for int_index in intf_to_sched_list: + if "output" in intf["service-policy"] and intf["service-policy"]["output"] in int_index: + scheduler_out = int_index[intf['service-policy']['output']] + config_leftover["tailf-ned-cisco-ios:interface"][interface][index]["service-policy"]["output"] = None + + return scheduler_out + + +def set_scheduler_policy_input(config_leftover, openconfig_scheduler, interface, intf, intf_to_sched_list, index): + + scheduler_in = None + if "service-policy" in intf: + for intf_to_sched in intf_to_sched_list: + if "input" in intf["service-policy"] and intf["service-policy"]["input"] in intf_to_sched: + scheduler_in = intf_to_sched[intf['service-policy']['input']] + config_leftover["tailf-ned-cisco-ios:interface"][interface][index]["service-policy"]["input"] = None + + return scheduler_in + + +def set_qos_class_map_ip(config_leftover, class_map_index, class_map, openconfig_class_map, policy_map_list): + + if len(class_map["match"]["ip"]["dscp"]) == 1: + openconfig_class_map.append({ + "openconfig-qos:name": class_map["name"], + "openconfig-qos:config": {"openconfig-qos:name:": class_map["name"], + "openconfig-qos:type:": "IPV4"}, + "openconfig-qos:terms": {"openconfig-qos:term": [{"openconfig-qos:id": "term-" + f'{class_map_index + 1}', + "openconfig-qos:config": { + "openconfig-qos:id": "term-" + f'{class_map_index + 1}' + }, + "openconfig-qos:conditions": { + "openconfig-qos:ipv4": { + "openconfig-qos:config": { + "openconfig-qos:dscp": modify_dscp(class_map["match"]["ip"]["dscp"]), + "openconfig-qos:protocol": 4 + } + } + }, + "openconfig-qos:actions": { + "openconfig-qos:config": { + "openconfig-qos:target-group": get_policy_map_group(class_map_index, class_map, policy_map_list) + } + } + } + ] + } + }) + config_leftover["tailf-ned-cisco-ios:class-map"][class_map_index] = None + elif len(class_map["match"]["ip"]["dscp"]) > 1: + openconfig_class_map.append({ + "openconfig-qos:name": class_map["name"], + "openconfig-qos:config": {"openconfig-qos:name:": class_map["name"], + "openconfig-qos:type:": "IPV4"}, + "openconfig-qos:terms": {"openconfig-qos:term": [{"openconfig-qos:id": "term-" + f'{class_map_index + 1}', + "openconfig-qos:config": { + "openconfig-qos:id": "term-" + f'{class_map_index + 1}' + }, + "openconfig-qos:conditions": { + "openconfig-qos:ipv4": { + "openconfig-qos:config": { + "openconfig-qos:dscp-set": modify_dscp_list(class_map["match"]["ip"]["dscp"]), + "openconfig-qos:protocol": 4 + } + } + }, + "openconfig-qos:actions": { + "openconfig-qos:config": { + "openconfig-qos:target-group": get_policy_map_group(class_map_index, class_map, policy_map_list) + } + } + } + ] + } + }) + config_leftover["tailf-ned-cisco-ios:class-map"][class_map_index] = None + + +def set_qos_class_map(config_leftover, class_map_index, class_map, openconfig_class_map, policy_map_list): + + if len(class_map["match"]["dscp"]) == 1: + openconfig_class_map.append({ + "openconfig-qos:name": class_map["name"], + "openconfig-qos:config": {"openconfig-qos:name:": class_map["name"] + }, + "openconfig-qos:terms": {"openconfig-qos:term": [{"openconfig-qos:id": "term-" + f'{class_map_index + 1}', + "openconfig-qos:config": { + "openconfig-qos:id": "term-" + f'{class_map_index + 1}' + }, + "openconfig-qos:conditions": { + "openconfig-qos:ipv4": { + "openconfig-qos:config": { + "openconfig-qos:dscp": modify_dscp(class_map["match"]["dscp"]) + } + } + }, + "openconfig-qos:actions": { + "openconfig-qos:config": { + "openconfig-qos:target-group": get_policy_map_group(class_map_index, class_map, policy_map_list) + } + } + } + ] + } + }) + config_leftover["tailf-ned-cisco-ios:class-map"][class_map_index] = None + elif len(class_map["match"]["dscp"]) > 1: + openconfig_class_map.append({ + "openconfig-qos:name": class_map["name"], + "openconfig-qos:config": {"openconfig-qos:name:": class_map["name"] + }, + "openconfig-qos:terms": {"openconfig-qos:term": [{"openconfig-qos:id": "term-" + f'{class_map_index + 1}', + "openconfig-qos:config": { + "openconfig-qos:id": "term-" + f'{class_map_index + 1}' + }, + "openconfig-qos:conditions": { + "openconfig-qos:ipv4": { + "openconfig-qos:config": { + "openconfig-qos:dscp-set": modify_dscp_list(class_map["match"]["dscp"]) + } + } + }, + "openconfig-qos:actions": { + "openconfig-qos:config": { + "openconfig-qos:target-group": get_policy_map_group(class_map_index, class_map, policy_map_list) + } + } + } + ] + } + }) + config_leftover["tailf-ned-cisco-ios:class-map"][class_map_index] = None + + +def modify_dscp(dscp_list): + dscp = dscp_list[0] + if type(dscp) is int and (dscp % 2) != 0: + return dscp + return dscp_dict.get(dscp, 'default') + + +def modify_dscp_list(dscp_list): + new_dscp_list = [] + for dscp in dscp_list: + if type(dscp) is int and (dscp % 2) != 0: + new_dscp_list.append(dscp) + else: + new_dscp_list.append(dscp_dict.get(dscp, 'default')) + + return new_dscp_list + + +def get_policy_map_group(class_map_index, class_map, policy_map_list): + + policy = None + for policy_map in policy_map_list: + if "class-default" not in policy_map: + for pol in policy_map["class"]: + if pol["name"] == class_map["name"]: + policy = policy_map["name"] + return policy + + +def main(before: dict, leftover: dict, translation_notes: list = []) -> dict: + """ + Translates NSO Device configurations to MDD OpenConfig configurations. + + Requires environment variables: + NSO_HOST: str + NSO_USERNAME: str + NSO_PASSWORD: str + NSO_DEVICE: str + TEST - If True, sends generated OC configuration to NSO Server: str + + :param before: Original NSO Device configuration: dict + :param leftover: NSO Device configuration minus configs replaced with MDD OC: dict + :return: MDD Openconfig Network Instances configuration: dict + """ + + configure_xe_qos(before, leftover) + translation_notes += qos_notes + + return openconfig_qos + + +if __name__ == "__main__": + sys.path.append("../../") + sys.path.append("../../../") + + if (find_spec("package_nso_to_oc") is not None): + from package_nso_to_oc.xe import common_xe + from package_nso_to_oc import common + else: + import common_xe + import common + + (config_before_dict, config_leftover_dict, interface_ip_dict) = common_xe.init_xe_configs() + main(config_before_dict, config_leftover_dict) + config_name = "_qos" + config_remaining_name = "_remaining_qos" + oc_name = "_openconfig_qos" + common.print_and_test_configs( + "xe1", config_before_dict, config_leftover_dict, openconfig_qos, + config_name, config_remaining_name, oc_name, qos_notes) +else: + # This is needed for now due to top level __init__.py. We need to determine if contents in __init__.py is still necessary. + if (find_spec("package_nso_to_oc") is not None): + from package_nso_to_oc.xe import common_xe + from package_nso_to_oc import common + else: + from xe import common_xe + import common \ No newline at end of file diff --git a/package_nso_to_oc/xr/xr_acls.py b/package_nso_to_oc/xr/xr_acls.py old mode 100755 new mode 100644 diff --git a/test/tests/xe/xe_qos.yml b/test/tests/xe/xe_qos.yml new file mode 100644 index 00000000..f7b88d16 --- /dev/null +++ b/test/tests/xe/xe_qos.yml @@ -0,0 +1,792 @@ +--- +- hosts: nso + connection: local + gather_facts: no + roles: + - nso-rollback-save + run_once: true + vars: + rollback_file: "{{ lookup('env', 'PWD') }}/rollback.yaml" + +- name: test QOS + hosts: "{{ lookup('env', 'TEST_DEVICE_XEROUTER') | default('xe1', True) }}" + gather_facts: no + connection: network_cli + vars: + device: "{{ lookup('env', 'TEST_DEVICE_XEROUTER') | default('xe1', True) }}" + ansible_network_os: 'cisco.ios.ios' + tasks: + - name: test qos_policy_maps + tags: + - qos_policy_maps + import_role: + name: nso-openconfig-test + vars: + content: | + mdd:openconfig: + openconfig-qos:qos: + openconfig-qos:forwarding-groups: + openconfig-qos:forwarding-group: + - openconfig-qos:name: 'pm-ip-dscp-11' + openconfig-qos:config: + openconfig-qos:name: 'pm-ip-dscp-11' + - openconfig-qos:name: 'pm-ip-dscp-af11' + openconfig-qos:config: + openconfig-qos:name: 'pm-ip-dscp-af11' + - openconfig-qos:name: 'pm-dscp-13-15' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-13-15' + - openconfig-qos:name: 'pm-dscp-af12-af13' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-af12-af13' + - openconfig-qos:name: 'pm-dscp-19' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-19' + - openconfig-qos:name: 'pm-dscp-21' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-21' + - openconfig-qos:name: 'pm-dscp-23' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-23' + - openconfig-qos:name: 'pm-dscp-25' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-25' + - openconfig-qos:name: 'pm-dscp-31' + openconfig-qos:config: + openconfig-qos:name: 'pm-dscp-31' + - openconfig-qos:name: 'pm-class-default-01' + openconfig-qos:config: + openconfig-qos:name: 'pm-class-default-01' + - openconfig-qos:name: 'pm-class-default-02' + openconfig-qos:config: + openconfig-qos:name: 'pm-class-default-02' + openconfig-qos:classifiers: + openconfig-qos:classifier: + - openconfig-qos:name: 'class-default' + openconfig-qos:config: + openconfig-qos:name: 'class-default' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-default-01' + openconfig-qos:config: + openconfig-qos:id: 'term-default-01' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '1' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-class-default-01' + - openconfig-qos:id: 'term-default-02' + openconfig-qos:config: + openconfig-qos:id: 'term-default-02' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '1' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-class-default-02' + - openconfig-qos:id: 'term-default-03' + openconfig-qos:config: + openconfig-qos:id: 'term-default-03' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '1' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-ip-dscp-af11' + - openconfig-qos:name: 'cm-ip-dscp-11' + openconfig-qos:config: + openconfig-qos:name: 'cm-ip-dscp-11' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-ip-dscp-11' + openconfig-qos:config: + openconfig-qos:id: 'term-ip-dscp-11' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '11' + openconfig-qos:protocol: 4 # IPv4 + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-ip-dscp-11' + - openconfig-qos:name: 'cm-ip-dscp-af11' + openconfig-qos:config: + openconfig-qos:name: 'cm-ip-dscp-af11' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-ip-dscp-af11' + openconfig-qos:config: + openconfig-qos:id: 'term-ip-dscp-af11' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '10' + openconfig-qos:protocol: 4 # IPv4 + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-ip-dscp-af11' + - openconfig-qos:id: 'term-ip-dscp-11' + openconfig-qos:config: + openconfig-qos:id: 'term-ip-dscp-11' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '10' + openconfig-qos:protocol: 4 # IPv4 + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-ip-dscp-11' + - openconfig-qos:name: 'cm-dscp-13-15' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-13-15' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-13-15' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-13-15' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp-set: + - '13' + - '15' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-13-15' + - openconfig-qos:id: 'term-dscp-af12-af13' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-af12-af13' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp-set: + - '13' + - '15' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-af12-af13' + - openconfig-qos:name: 'cm-dscp-af12-af13' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-af12-af13' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-af12-af13' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-af12-af13' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp-set: + - '12' + - '14' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-af12-af13' + - openconfig-qos:name: 'cm-dscp-19' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-19' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-19' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-19' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '19' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-19' + - openconfig-qos:name: 'cm-dscp-21' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-21' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-21' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-21' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '21' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-21' + - openconfig-qos:name: 'cm-dscp-23' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-23' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-23' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-23' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '23' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-23' + - openconfig-qos:name: 'cm-dscp-25' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-25' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-25' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-25' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '25' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-25' + - openconfig-qos:name: 'cm-dscp-31' + openconfig-qos:config: + openconfig-qos:name: 'cm-dscp-31' + openconfig-qos:type: 'IPV4' + openconfig-qos:terms: + openconfig-qos:term: + - openconfig-qos:id: 'term-dscp-31' + openconfig-qos:config: + openconfig-qos:id: 'term-dscp-31' + openconfig-qos:conditions: + openconfig-qos:ipv4: + openconfig-qos:config: + openconfig-qos:dscp: '34' + openconfig-qos:actions: + openconfig-qos:config: + openconfig-qos:target-group: 'pm-dscp-31' + openconfig-qos:scheduler-policies: + openconfig-qos:scheduler-policy: + - openconfig-qos:name: 'sched-01-cm-ip-dscp-11' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-11' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-ip-dscp-11' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 10 # Percentage + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-01-cm-ip-dscp-af11' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-af11' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-ip-dscp-af11' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 200000 # Unit bits + openconfig-qos:bc: 1000 # Unit bytes + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-02-cm-ip-dscp-af11' + openconfig-qos:config: + openconfig-qos:name: 'sched-02-cm-ip-dscp-af11' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-ip-dscp-11' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 100000 # Unit bits + openconfig-qos:bc: 500 # Unit bytes + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-01-cm-dscp-13-15' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-13-15' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-13-15' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 20 # Percentage + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-02-cm-dscp-13-15' + openconfig-qos:config: + openconfig-qos:name: 'sched-02-cm-dscp-13-15' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-af12-af13' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 300000 # Unit bps + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-01-cm-dscp-af12-af13' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-af12-af13' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-af12-af13' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 200000 # Unit bps + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-01-cm-dscp-19' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-19' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-19' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 100000 # Unit bps + openconfig-qos:bc: 10000 # Unit bytes + openconfig-qos:queuing-behavior: 'POLICE' + openconfig-qos:conform-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 21 + openconfig-qos:exceed-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 21 + - openconfig-qos:name: 'sched-01-cm-dscp-21' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-21' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-21' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 50 # Percentage + openconfig-qos:bc: 1000 # Unit bytes + openconfig-qos:queuing-behavior: 'POLICE' + openconfig-qos:conform-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 23 + openconfig-qos:exceed-action: + openconfig-qos:config: + openconfig-qos:drop: True + - openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'TWO_RATE_THREE_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-23' + openconfig-qos:two-rate-three-color: + openconfig-qos:config: + openconfig-qos:cir: 100000 # Unit bps + openconfig-qos:bc: 1000 # Unit bytes + openconfig-qos:pir: 200000 # Unit bps + openconfig-qos:be: 1000 # Unit bytes + openconfig-qos:conform-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 25 + openconfig-qos:exceed-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 27 + openconfig-qos:violate-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 29 + - openconfig-qos:name: 'sched-01-cm-dscp-25' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-25' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'TWO_RATE_THREE_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-25' + openconfig-qos:two-rate-three-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 20 # Percentage + openconfig-qos:bc: 100 # Unit bytes + openconfig-qos:pir-pct: 30 # Percentage + openconfig-qos:be: 200 # Unit bytes + openconfig-qos:conform-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 27 + openconfig-qos:exceed-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 29 + openconfig-qos:violate-action: + openconfig-qos:config: + openconfig-qos:drop: True + - openconfig-qos:name: 'sched-01-cm-dscp-31' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-31' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:type: 'TWO_RATE_THREE_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-dscp-31' + openconfig-qos:two-rate-three-color: + openconfig-qos:config: + openconfig-qos:cir: 200000 # Unit bps + openconfig-qos:bc: 20000 # Unit bytes + openconfig-qos:conform-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 46 + openconfig-qos:exceed-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 36 + openconfig-qos:violate-action: + openconfig-qos:config: + openconfig-qos:set-dscp: 38 + - openconfig-qos:name: 'sched-01-class-default' + openconfig-qos:config: + openconfig-qos:name: 'sched-01-class-default' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-class-default-01' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 20 # Percentage + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-02-class-default' + openconfig-qos:config: + openconfig-qos:name: 'sched-02-class-default' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-class-default-02' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir-pct: 30 # Percentage + openconfig-qos:queuing-behavior: 'SHAPE' + - openconfig-qos:name: 'sched-03-class-default' + openconfig-qos:config: + openconfig-qos:name: 'sched-03-class-default' + openconfig-qos:schedulers: + openconfig-qos:scheduler: + - openconfig-qos:sequence: 10 + openconfig-qos:config: + openconfig-qos:sequence: 10 + openconfig-qos:priority: 'STRICT' + openconfig-qos:type: 'ONE_RATE_TWO_COLOR' + openconfig-qos:output: + openconfig-qos:config: + openconfig-qos:output-type: 'FWD_GROUP' + openconfig-qos:output-fwd-group: 'pm-ip-dscp-af11' + openconfig-qos:one-rate-two-color: + openconfig-qos:config: + openconfig-qos:cir: 200000 # Unit bits + openconfig-qos:bc: 1500 # Unit bytes + openconfig-qos:queuing-behavior: 'SHAPE' + openconfig-qos:interfaces: + openconfig-qos:interface: + - openconfig-qos:interface-id: 'GigabitEthernet6' + openconfig-qos:config: + openconfig-qos:interface-id: 'GigabitEthernet6' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-19' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-21' + - openconfig-qos:interface-id: 'GigabitEthernet7' + openconfig-qos:config: + openconfig-qos:interface-id: 'GigabitEthernet7' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-25' + - openconfig-qos:interface-id: 'GigabitEthernet8' + openconfig-qos:config: + openconfig-qos:interface-id: 'GigabitEthernet8' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-af11' + - openconfig-qos:interface-id: 'Loopback100' + openconfig-qos:config: + openconfig-qos:interface-id: 'Loopback100' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-19' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-21' + - openconfig-qos:interface-id: 'Loopback101' + openconfig-qos:config: + openconfig-qos:interface-id: 'Loopback101' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-25' + - openconfig-qos:interface-id: 'Port-channel10' + openconfig-qos:config: + openconfig-qos:interface-id: 'Port-channel10' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-19' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-21' + - openconfig-qos:interface-id: 'Port-channel11' + openconfig-qos:config: + openconfig-qos:interface-id: 'Port-channel11' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-25' + - openconfig-qos:interface-id: 'Port-channel12' + openconfig-qos:config: + openconfig-qos:interface-id: 'Port-channel12' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-11' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-af11' + - openconfig-qos:interface-id: 'Tunnel100' + openconfig-qos:config: + openconfig-qos:interface-id: 'Tunnel100' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-19' + - openconfig-qos:interface-id: 'Tunnel101' + openconfig-qos:config: + openconfig-qos:interface-id: 'Tunnel101' + openconfig-qos:input: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-23' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-dscp-31' + - openconfig-qos:interface-id: 'Tunnel102' + openconfig-qos:config: + openconfig-qos:interface-id: 'Tunnel102' + openconfig-qos:output: + openconfig-qos:scheduler-policy: + openconfig-qos:config: + openconfig-qos:name: 'sched-01-cm-ip-dscp-af11' + + api_method: PUT + rollback: false + assertion_ignore_errors: false + assertions: + - "'+class-map match-all cm-ip-dscp-11:' in changes" + - "'+ match ip dscp 11:' in changes" + - "'+class-map match-all cm-ip-dscp-af11:' in changes" + - "'+ match ip dscp af11:' in changes" + - "'+class-map match-all cm-dscp-13-15:' in changes" + - "'+ match dscp 13 15:' in changes" + - "'+class-map match-all cm-dscp-af12-af13:' in changes" + - "'+ match dscp af12 af13:' in changes" + - "'+class-map match-all cm-dscp-19:' in changes" + - "'+ match dscp 19:' in changes" + - "'+class-map match-all cm-dscp-21:' in changes" + - "'+ match dscp 21:' in changes" + - "'+class-map match-all cm-dscp-23:' in changes" + - "'+ match dscp 23:' in changes" + - "'+class-map match-all cm-dscp-25:' in changes" + - "'+ match dscp 25:' in changes" + - "'+class-map match-all cm-dscp-31:' in changes" + - "'+ match dscp af41:' in changes" + - "'+policy-map pm-class-default-01:' in changes" + - "'+ class class-default:' in changes" + - "'+ priority percent 20:' in changes" + - "'+policy-map pm-class-default-02:' in changes" + - "'+ class class-default:' in changes" + - "'+ priority percent 30:' in changes" + - "'+policy-map pm-ip-dscp-11:' in changes" + - "'+ class cm-ip-dscp-11:' in changes" + - "'+ priority percent 10:' in changes" + - "'+ class cm-ip-dscp-af11:' in changes" + - "'+ priority 100 500:' in changes" + - "'+policy-map pm-ip-dscp-af11:' in changes" + - "'+ class class-default:' in changes" + - "'+ priority 200 1500:' in changes" + - "'+ class cm-ip-dscp-af11:' in changes" + - "'+ priority 200 1000:' in changes" + - "'+policy-map pm-dscp-13-15:' in changes" + - "'+ class cm-dscp-13-15:' in changes" + - "'+ bandwidth percent 20:' in changes" + - "'+policy-map pm-dscp-af12-af13:' in changes" + - "'+ class cm-dscp-af12-af13:' in changes" + - "'+ bandwidth 200000:' in changes" + - "'+ class cm-dscp-13-15:' in changes" + - "'+ bandwidth 300000:' in changes" + - "'+policy-map pm-dscp-19:' in changes" + - "'+ class cm-dscp-19:' in changes" + - "'+ police cir 100000 bc 10000:' in changes" + - "'+ conform-action set-dscp-transmit 21:' in changes" + - "'+ exceed-action set-dscp-transmit 21:' in changes" + - "'+policy-map pm-dscp-21:' in changes" + - "'+ class cm-dscp-21:' in changes" + - "'+ police cir percent 50 bc 1000 ms:' in changes" + - "'+ conform-action set-dscp-transmit 23:' in changes" + - "'+ exceed-action drop:' in changes" + - "'+policy-map pm-dscp-23:' in changes" + - "'+ class cm-dscp-23:' in changes" + - "'+ police cir 100000 bc 1000 pir 200000 be 1000:' in changes" + - "'+ conform-action set-dscp-transmit 25:' in changes" + - "'+ exceed-action set-dscp-transmit 27:' in changes" + - "'+ violate-action set-dscp-transmit 29:' in changes" + - "'+policy-map pm-dscp-25:' in changes" + - "'+ class cm-dscp-25:' in changes" + - "'+ police cir percent 20 bc 100 ms pir percent 30 be 200 ms:' in changes" + - "'+ conform-action set-dscp-transmit 27:' in changes" + - "'+ exceed-action set-dscp-transmit 29:' in changes" + - "'+ violate-action drop:' in changes" + - "'+policy-map pm-dscp-31:' in changes" + - "'+ class cm-dscp-31:' in changes" + - "'+ police cir 200000 bc 20000:' in changes" + - "'+ conform-action set-dscp-transmit ef:' in changes" + - "'+ exceed-action set-dscp-transmit af42:' in changes" + - "'+ violate-action set-dscp-transmit af43:' in changes" + - "' interface GigabitEthernet6:' in changes" + - "'+ service-policy input pm-dscp-19:' in changes" + - "'+ service-policy output pm-dscp-21:' in changes" + - "' interface GigabitEthernet7:' in changes" + - "'+ service-policy input pm-dscp-23:' in changes" + - "'+ service-policy output pm-dscp-25:' in changes" + - "' interface GigabitEthernet8:' in changes" + - "'+ service-policy output pm-ip-dscp-af11:' in changes" + - "'+interface Loopback100:' in changes" + - "'+ service-policy input pm-dscp-19:' in changes" + - "'+ service-policy output pm-dscp-21:' in changes" + - "'+interface Loopback101:' in changes" + - "'+ service-policy input pm-dscp-23:' in changes" + - "'+ service-policy output pm-dscp-25:' in changes" + - "'+interface Port-channel10:' in changes" + - "'+ service-policy input pm-dscp-19:' in changes" + - "'+ service-policy output pm-dscp-21:' in changes" + - "'+interface Port-channel11:' in changes" + - "'+ service-policy input pm-dscp-23:' in changes" + - "'+ service-policy output pm-dscp-25:' in changes" + - "'+interface Port-channel12:' in changes" + - "'+ service-policy input pm-ip-dscp-11:' in changes" + - "'+ service-policy output pm-ip-dscp-af11:' in changes" + - "'+interface Tunnel100:' in changes" + - "'+ service-policy input pm-dscp-19:' in changes" + - "'+interface Tunnel101:' in changes" + - "'+ service-policy input pm-dscp-23:' in changes" + - "'+ service-policy output pm-dscp-31:' in changes" + - "'+interface Tunnel102:' in changes" + - "'+ service-policy output pm-ip-dscp-af11:' in changes" + +- hosts: nso + connection: local + gather_facts: no + roles: + - nso-rollback-load + run_once: true + vars: + rollback_file: "{{ lookup('env', 'PWD') }}/rollback.yaml" diff --git a/test/tests_nso_to_oc/xe/xe_qos.yml b/test/tests_nso_to_oc/xe/xe_qos.yml new file mode 100644 index 00000000..4537ff48 --- /dev/null +++ b/test/tests_nso_to_oc/xe/xe_qos.yml @@ -0,0 +1,869 @@ +--- +- hosts: localhost + gather_facts: no + environment: + NSO_DEVICE: xe1 + vars: + device: "{{ lookup('env', 'TEST_DEVICE_XEROUTER') | default('xe1', True) }}" + tasks: + - name: Run XE QoS tests + include_role: + name: ned-to-oc-test + vars: + script_path: ../../../package_nso_to_oc/xe/xe_qos.py + api_test_data: + - name: Set up OC service config + tags: + - oc_set_up + api_path: mdd:openconfig + api_method: PUT + content: | + mdd:openconfig: + openconfig-interfaces:interfaces: + openconfig-interfaces:interface: + - openconfig-interfaces:name: 'Loopback100' + openconfig-interfaces:config: + openconfig-interfaces:name: 'Loopback100' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'softwareLoopback' + openconfig-interfaces:description: 'Test loopback' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.255.100.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.255.100.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'Loopback101' + openconfig-interfaces:config: + openconfig-interfaces:name: 'Loopback101' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'softwareLoopback' + openconfig-interfaces:description: 'Test loopback' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.255.101.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.255.101.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'GigabitEthernet6' + openconfig-interfaces:config: + openconfig-interfaces:name: 'GigabitEthernet6' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'ethernetCsmacd' + openconfig-interfaces:description: 'Test gigabitethernet' + openconfig-if-ethernet:ethernet: + openconfig-if-ethernet:config: + openconfig-if-ethernet:auto-negotiate: true + openconfig-if-ethernet:enable-flow-control: false + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.6.0.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.6.0.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'GigabitEthernet7' + openconfig-interfaces:config: + openconfig-interfaces:name: 'GigabitEthernet7' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'ethernetCsmacd' + openconfig-interfaces:description: 'Test gigabitethernet' + openconfig-if-ethernet:ethernet: + openconfig-if-ethernet:config: + openconfig-if-ethernet:auto-negotiate: true + openconfig-if-ethernet:enable-flow-control: false + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.7.0.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.7.0.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'GigabitEthernet8' + openconfig-interfaces:config: + openconfig-interfaces:name: 'GigabitEthernet8' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'ethernetCsmacd' + openconfig-interfaces:description: 'Test gigabitethernet' + openconfig-if-ethernet:ethernet: + openconfig-if-ethernet:config: + openconfig-if-ethernet:auto-negotiate: true + openconfig-if-ethernet:enable-flow-control: false + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.8.0.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.8.0.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'Tunnel100' + openconfig-interfaces:config: + openconfig-interfaces:name: 'Tunnel100' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'tunnel' + openconfig-interfaces:mtu: 1476 + openconfig-interfaces:description: 'Test tunnel' + openconfig-if-tunnel:tunnel: + openconfig-if-tunnel:config: + openconfig-if-tunnel:src: '10.255.0.1' + openconfig-if-tunnel:dst: '192.168.172.1' + openconfig-if-tunnel:gre-key: 1 + openconfig-if-tunnel-ext:keepalives: + openconfig-if-tunnel-ext:period: 5 + openconfig-if-tunnel-ext:retries: 3 + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.254.0.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.254.0.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'Tunnel101' + openconfig-interfaces:config: + openconfig-interfaces:name: 'Tunnel101' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'tunnel' + openconfig-interfaces:mtu: 1476 + openconfig-interfaces:description: 'Test tunnel' + openconfig-if-tunnel:tunnel: + openconfig-if-tunnel:config: + openconfig-if-tunnel:src: '10.255.101.1' + openconfig-if-tunnel:dst: '192.168.173.1' + openconfig-if-tunnel:gre-key: 1 + openconfig-if-tunnel-ext:keepalives: + openconfig-if-tunnel-ext:period: 5 + openconfig-if-tunnel-ext:retries: 3 + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.254.101.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.254.101.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'Tunnel102' + openconfig-interfaces:config: + openconfig-interfaces:name: 'Tunnel102' + openconfig-interfaces:enabled: true + openconfig-interfaces:type: 'tunnel' + openconfig-interfaces:mtu: 1476 + openconfig-interfaces:description: 'Test tunnel' + openconfig-if-tunnel:tunnel: + openconfig-if-tunnel:config: + openconfig-if-tunnel:src: '10.255.102.1' + openconfig-if-tunnel:dst: '192.168.174.1' + openconfig-if-tunnel:gre-key: 1 + openconfig-if-tunnel-ext:keepalives: + openconfig-if-tunnel-ext:period: 5 + openconfig-if-tunnel-ext:retries: 3 + openconfig-interfaces:hold-time: + openconfig-interfaces:config: + openconfig-interfaces:down: '10' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 0 + openconfig-interfaces:config: + openconfig-interfaces:index: 0 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.254.102.1' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.254.102.1' + openconfig-if-ip:prefix-length: 24 + openconfig-if-ip:config: + openconfig-if-ip:dhcp-client: false + - openconfig-interfaces:name: 'Port-channel10' + openconfig-if-aggregate:aggregation: + openconfig-if-aggregate:config: + openconfig-if-aggregate:lag-type: 'LACP' + openconfig-interfaces:config: + openconfig-interfaces:description: 'LACP Example PO10' + openconfig-interfaces:enabled: true + openconfig-interfaces:mtu: 1500 + openconfig-interfaces:name: 'Port-channel10' + openconfig-interfaces:type: 'ieee8023adLag' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 105 + openconfig-interfaces:config: + openconfig-interfaces:description: 'Sub interface 105' + openconfig-interfaces:enabled: true + openconfig-interfaces:index: 105 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '10.105.105.105' + openconfig-if-ip:config: + openconfig-if-ip:ip: '10.105.105.105' + openconfig-if-ip:prefix-length: 24 + openconfig-vlan:vlan: + openconfig-vlan:config: + openconfig-vlan:vlan-id: 105 + - openconfig-interfaces:name: 'Port-channel11' + openconfig-if-aggregate:aggregation: + openconfig-if-aggregate:config: + openconfig-if-aggregate:lag-type: 'LACP' + openconfig-interfaces:config: + openconfig-interfaces:description: 'LACP Example PO11' + openconfig-interfaces:enabled: true + openconfig-interfaces:mtu: 1500 + openconfig-interfaces:name: 'Port-channel11' + openconfig-interfaces:type: 'ieee8023adLag' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 105 + openconfig-interfaces:config: + openconfig-interfaces:description: 'Sub interface 105' + openconfig-interfaces:enabled: true + openconfig-interfaces:index: 105 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '11.105.105.105' + openconfig-if-ip:config: + openconfig-if-ip:ip: '11.105.105.105' + openconfig-if-ip:prefix-length: 24 + openconfig-vlan:vlan: + openconfig-vlan:config: + openconfig-vlan:vlan-id: 105 + - openconfig-interfaces:name: 'Port-channel12' + openconfig-if-aggregate:aggregation: + openconfig-if-aggregate:config: + openconfig-if-aggregate:lag-type: 'LACP' + openconfig-interfaces:config: + openconfig-interfaces:description: 'LACP Example PO12' + openconfig-interfaces:enabled: true + openconfig-interfaces:mtu: 1500 + openconfig-interfaces:name: 'Port-channel12' + openconfig-interfaces:type: 'ieee8023adLag' + openconfig-interfaces:subinterfaces: + openconfig-interfaces:subinterface: + - openconfig-interfaces:index: 105 + openconfig-interfaces:config: + openconfig-interfaces:description: 'Sub interface 105' + openconfig-interfaces:enabled: true + openconfig-interfaces:index: 105 + openconfig-if-ip:ipv4: + openconfig-if-ip:addresses: + openconfig-if-ip:address: + - openconfig-if-ip:ip: '12.105.105.105' + openconfig-if-ip:config: + openconfig-if-ip:ip: '12.105.105.105' + openconfig-if-ip:prefix-length: 24 + openconfig-vlan:vlan: + openconfig-vlan:config: + openconfig-vlan:vlan-id: 105 + + - name: NED init Class-map + tags: + - init_class_map + api_path: config/tailf-ned-cisco-ios:class-map + api_method: PATCH + content: | + class-map: + - name: 'cm-ip-dscp-11' + prematch: 'match-all' + description: 'class-map ip dscp 11' + match: + ip: + dscp: + - 11 + - name: 'cm-ip-dscp-af11' + prematch: 'match-all' + description: 'class-map ip dscp af11' + match: + ip: + dscp: + - 'af11' + - name: 'cm-dscp-13-15' + prematch: 'match-all' + description: 'class-map dscp 13 15' + match: + dscp: + - 13 + - 15 + - name: 'cm-dscp-af12-af13' + prematch: 'match-all' + description: 'class-map dscp af12 af13' + match: + dscp: + - 'af12' + - 'af13' + - name: 'cm-dscp-19' + prematch: 'match-all' + description: 'class-map dscp 19' + match: + dscp: + - 19 + - name: 'cm-dscp-21' + prematch: 'match-all' + description: 'class-map dscp 21' + match: + dscp: + - 21 + - name: 'cm-dscp-23' + prematch: 'match-all' + description: 'class-map dscp 23' + match: + dscp: + - 23 + - name: 'cm-dscp-25' + prematch: 'match-all' + description: 'class-map dscp 25' + match: + dscp: + - 25 + - name: 'cm-dscp-31' + prematch: 'match-all' + description: 'class-map dscp 31' + match: + dscp: + - 31 + - name: 'cm-dscp-af41' + prematch: 'match-all' + description: 'class-map dscp af41' + match: + dscp: + - 'af41' + - name: NED init Policy-map + tags: + - init_policy_map + api_path: config/tailf-ned-cisco-ios:policy-map + api_method: PATCH + content: | + policy-map: + - name: 'pm-class-default-01' + class-default: + class: + - name: 'class-default' + priority: # priority.create() + percent: 20 + - name: 'pm-class-default-02' + class-default: + class: + - name: 'class-default' + priority: # priority.create() + percent: 30 + - name: 'pm-ip-dscp-11' + class: + - name: 'cm-ip-dscp-11' + priority: # priority.create() + percent: 10 + - name: 'cm-ip-dscp-af11' + priority: # priority.create() + kilo-bits: 100 + burst: 500 + - name: 'pm-ip-dscp-af11' + class-default: + class: + - name: 'class-default' + priority: # priority.create() + kilo-bits: 200 + burst: 1500 + class: + - name: 'cm-ip-dscp-af11' + priority: # priority.create() + kilo-bits: 200 + burst: 1000 + - name: 'pm-dscp-13-15' + class: + - name: 'cm-dscp-13-15' + bandwidth: + percent: 20 + - name: 'pm-dscp-af12-af13' + class: + - name: 'cm-dscp-af12-af13' + bandwidth: + bits: 200000 + - name: 'cm-dscp-13-15' + bandwidth: + bits: 300000 + - name: 'pm-dscp-19' + class: + - name: 'cm-dscp-19' + police-policy-map: + police: + cir: 100000 + bc: 10000 + actions: + conform-set-dscp-transmit: + conform-action: + set-dscp-transmit: 21 + exceed-set-dscp-transmit: + exceed-action: + set-dscp-transmit: 21 + - name: 'pm-dscp-21' + class: + - name: 'cm-dscp-21' + police-cir-percent: + police: + cir: + percent: + percentage: 50 + bc: 1000 + bc-ms: + ms: {} + actions: + conform-set-dscp-transmit: + conform-action: + set-dscp-transmit: 23 + exceed-drop: + exceed-action: + drop: {} + - name: 'pm-dscp-23' + class: + - name: 'cm-dscp-23' + police-policy-map: + police: + cir: 100000 + bc: 1000 + pir: 200000 + pir-be: + be: 1000 + actions: + conform-set-dscp-transmit: + conform-action: + set-dscp-transmit: 25 + exceed-set-dscp-transmit: + exceed-action: + set-dscp-transmit: 27 + violate-set-dscp-transmit: + violate-action: + set-dscp-transmit: 29 + - name: 'pm-dscp-25' + class: + - name: 'cm-dscp-25' + police-cir-percent: + police: + cir: + percent: + percentage: 20 + bc: 100 + bc-ms: + ms: {} + pir: + percent: 30 + pir-be: + be: 200 + pir-be-ms: + ms: {} + actions: + conform-set-dscp-transmit: + conform-action: + set-dscp-transmit: 27 + exceed-set-dscp-transmit: + exceed-action: + set-dscp-transmit: 29 + violate-drop: + violate-action: + drop: {} + - name: 'pm-dscp-31' + class: + - name: 'cm-dscp-31' + police-policy-map: + police: + cir: 200000 + bc: 20000 + pir: 300000 + pir-be: + be: 2000 + actions: + conform-set-dscp-transmit: + conform-action: + set-dscp-transmit: 'ef' + exceed-set-dscp-transmit: + exceed-action: + set-dscp-transmit: 'af42' + violate-set-dscp-transmit: + violate-action: + set-dscp-transmit: 'af43' + - name: NED init Interface + tags: + - init_interface + api_path: config/tailf-ned-cisco-ios:interface + api_method: PATCH + content: | + interface: + GigabitEthernet: + - name: '6' + service-policy: + output: 'pm-dscp-21' + input: 'pm-dscp-19' + - name: '7' + service-policy: + output: 'pm-dscp-25' + input: 'pm-dscp-23' + - name: '8' + service-policy: + output: 'pm-ip-dscp-af11' + Loopback: + - name: '100' + service-policy: + output: 'pm-dscp-21' + input: 'pm-dscp-19' + - name: '101' + service-policy: + output: 'pm-dscp-25' + input: 'pm-dscp-23' + Port-channel: + - name: '10' + service-policy: + output: 'pm-dscp-21' + input: 'pm-dscp-19' + - name: '11' + service-policy: + output: 'pm-dscp-25' + input: 'pm-dscp-23' + - name: '12' + service-policy: + output: 'pm-ip-dscp-af11' + input: 'pm-ip-dscp-11' + Tunnel: + - name: '100' + service-policy: + input: 'pm-dscp-19' + - name: '101' + service-policy: + output: 'pm-dscp-31' + input: 'pm-dscp-23' + - name: '102' + service-policy: + output: 'pm-ip-dscp-af11' + assertions: + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['name'] == 'class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['config']['name'] == 'class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][0]['id'] == 'term-default-1'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][0]['config']['id'] == 'term-default-1'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-class-default-01'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][1]['id'] == 'term-default-2'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][1]['config']['id'] == 'term-default-2'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][1]['actions']['config']['target-group'] == 'pm-class-default-02'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][2]['id'] == 'term-default-3'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][2]['config']['id'] == 'term-default-3'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][0]['terms']['term'][2]['actions']['config']['target-group'] == 'pm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['name'] == 'cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['config']['name'] == 'cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['terms']['term'][0]['id'] == 'term-1'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['terms']['term'][0]['config']['id'] == 'term-1'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['terms']['term'][0]['conditions']['ipv4']['config']['dscp-set'] == [13, 15]" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][1]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['name'] == 'cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['config']['name'] == 'cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['terms']['term'][0]['id'] == 'term-2'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['terms']['term'][0]['config']['id'] == 'term-2'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 19" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][2]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['name'] == 'cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['config']['name'] == 'cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['terms']['term'][0]['id'] == 'term-3'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['terms']['term'][0]['config']['id'] == 'term-3'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 21" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][3]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['name'] == 'cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['config']['name'] == 'cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['terms']['term'][0]['id'] == 'term-4'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['terms']['term'][0]['config']['id'] == 'term-4'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 23" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][4]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['name'] == 'cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['config']['name'] == 'cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['terms']['term'][0]['id'] == 'term-5'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['terms']['term'][0]['config']['id'] == 'term-5'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 25" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][5]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['name'] == 'cm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['config']['name'] == 'cm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['terms']['term'][0]['id'] == 'term-6'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['terms']['term'][0]['config']['id'] == 'term-6'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 31" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][6]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['name'] == 'cm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['config']['name'] == 'cm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['terms']['term'][0]['id'] == 'term-7'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['terms']['term'][0]['config']['id'] == 'term-7'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['terms']['term'][0]['conditions']['ipv4']['config']['dscp-set'] == [12, 14]" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][7]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][8]['name'] == 'cm-dscp-af41'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][8]['config']['name'] == 'cm-dscp-af41'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][8]['terms']['term'][0]['id'] == 'term-8'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][8]['terms']['term'][0]['config']['id'] == 'term-8'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][8]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 34" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['name'] == 'cm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['config']['name'] == 'cm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['config']['type'] == 'IPV4'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['terms']['term'][0]['id'] == 'term-9'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['terms']['term'][0]['config']['id'] == 'term-9'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 11" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['terms']['term'][0]['conditions']['ipv4']['config']['protocol'] == 4" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][9]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['name'] == 'cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['config']['name'] == 'cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['config']['type'] == 'IPV4'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['terms']['term'][0]['id'] == 'term-10'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['terms']['term'][0]['config']['id'] == 'term-10'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['terms']['term'][0]['conditions']['ipv4']['config']['dscp'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['terms']['term'][0]['conditions']['ipv4']['config']['protocol'] == 4" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['classifiers']['classifier'][10]['terms']['term'][0]['actions']['config']['target-group'] == 'pm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['name'] == 'sched-1-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['config']['name'] == 'sched-1-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-class-default-01'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir-pct'] == 20" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][0]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['name'] == 'sched-1-cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['config']['name'] == 'sched-1-cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir-pct'] == 20" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][1]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['name'] == 'sched-10-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['config']['name'] == 'sched-10-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '100'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['bc'] == 500" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][2]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['name'] == 'sched-11-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['config']['name'] == 'sched-11-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '200'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['bc'] == 1000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][3]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['name'] == 'sched-2-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['config']['name'] == 'sched-2-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-class-default-02'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir-pct'] == 30" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][4]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['config']['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '100000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['bc'] == 10000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'POLICE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['one-rate-two-color']['conform-action']['config']['set-dscp'] == 21" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][5]['schedulers']['scheduler'][0]['one-rate-two-color']['exceed-action']['config']['set-dscp'] == 21" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['name'] == 'sched-3-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['config']['name'] == 'sched-3-class-default'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '200'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['bc'] == 1500" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][6]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['name'] == 'sched-3-cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['config']['name'] == 'sched-3-cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir-pct'] == 50" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['bc'] == 1000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'POLICE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['one-rate-two-color']['conform-action']['config']['set-dscp'] == 23" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][7]['schedulers']['scheduler'][0]['one-rate-two-color']['exceed-action']['config']['drop'] == true" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['config']['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:TWO_RATE_THREE_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['cir'] == '100000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['bc'] == 1000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['pir'] == '200000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['be'] == 1000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['conform-action']['config']['set-dscp'] == 25" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['exceed-action']['config']['set-dscp'] == 27" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][8]['schedulers']['scheduler'][0]['two-rate-three-color']['violate-action']['config']['set-dscp'] == 29" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['name'] == 'sched-5-cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['config']['name'] == 'sched-5-cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:TWO_RATE_THREE_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['cir'] == '20'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['bc'] == 100" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['pir'] == '30'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['be'] == 200" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['conform-action']['config']['set-dscp'] == 27" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['exceed-action']['config']['set-dscp'] == 29" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][9]['schedulers']['scheduler'][0]['two-rate-three-color']['violate-action']['config']['drop'] == true" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['name'] == 'sched-6-cm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['config']['name'] == 'sched-6-cm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:TWO_RATE_THREE_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['cir'] == '200000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['pir'] == '300000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['bc'] == 20000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['config']['be'] == 2000" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['conform-action']['config']['set-dscp'] == 46" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['exceed-action']['config']['set-dscp'] == 36" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][10]['schedulers']['scheduler'][0]['two-rate-three-color']['violate-action']['config']['set-dscp'] == 38" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['name'] == 'sched-7-cm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['config']['name'] == 'sched-7-cm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '200000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][11]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['name'] == 'sched-8-cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['config']['name'] == 'sched-8-cm-dscp-13-15'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-dscp-af12-af13'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir'] == '300000'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][12]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['name'] == 'sched-9-cm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['config']['name'] == 'sched-9-cm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['config']['sequence'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['config']['priority'] == 'STRICT'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['config']['type'] == 'openconfig-qos-types:ONE_RATE_TWO_COLOR'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['output']['config']['output-type'] == 'FWD_GROUP'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['output']['config']['output-fwd-group'] == 'pm-ip-dscp-11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['cir-pct'] == 10" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['scheduler-policies']['scheduler-policy'][13]['schedulers']['scheduler'][0]['one-rate-two-color']['config']['queuing-behavior'] == 'SHAPE'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][5]['interface-id'] == 'GigabitEthernet6'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][5]['config']['interface-id'] == 'GigabitEthernet6'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][5]['input']['scheduler-policy']['config']['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][5]['output']['scheduler-policy']['config']['name'] == 'sched-3-cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][6]['interface-id'] == 'GigabitEthernet7'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][6]['config']['interface-id'] == 'GigabitEthernet7'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][6]['input']['scheduler-policy']['config']['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][6]['output']['scheduler-policy']['config']['name'] == 'sched-5-cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][7]['interface-id'] == 'GigabitEthernet8'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][7]['config']['interface-id'] == 'GigabitEthernet8'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][7]['output']['scheduler-policy']['config']['name'] == 'sched-11-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][8]['interface-id'] == 'Loopback100'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][8]['config']['interface-id'] == 'Loopback100'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][8]['input']['scheduler-policy']['config']['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][8]['output']['scheduler-policy']['config']['name'] == 'sched-3-cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][9]['interface-id'] == 'Loopback101'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][9]['config']['interface-id'] == 'Loopback101'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][9]['input']['scheduler-policy']['config']['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][9]['output']['scheduler-policy']['config']['name'] == 'sched-5-cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][10]['interface-id'] == 'Port-channel10'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][10]['config']['interface-id'] == 'Port-channel10'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][10]['input']['scheduler-policy']['config']['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][10]['output']['scheduler-policy']['config']['name'] == 'sched-3-cm-dscp-21'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][11]['interface-id'] == 'Port-channel11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][11]['config']['interface-id'] == 'Port-channel11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][11]['input']['scheduler-policy']['config']['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][11]['output']['scheduler-policy']['config']['name'] == 'sched-5-cm-dscp-25'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][12]['interface-id'] == 'Port-channel12'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][12]['config']['interface-id'] == 'Port-channel12'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][12]['input']['scheduler-policy']['config']['name'] == 'sched-10-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][12]['output']['scheduler-policy']['config']['name'] == 'sched-11-cm-ip-dscp-af11'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][13]['interface-id'] == 'Tunnel100'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][13]['config']['interface-id'] == 'Tunnel100'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][13]['input']['scheduler-policy']['config']['name'] == 'sched-2-cm-dscp-19'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][14]['interface-id'] == 'Tunnel101'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][14]['config']['interface-id'] == 'Tunnel101'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][14]['input']['scheduler-policy']['config']['name'] == 'sched-4-cm-dscp-23'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][14]['output']['scheduler-policy']['config']['name'] == 'sched-6-cm-dscp-31'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][15]['interface-id'] == 'Tunnel102'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][15]['config']['interface-id'] == 'Tunnel102'" + - "oc_result.json['mdd:openconfig']['openconfig-qos:qos']['interfaces']['interface'][15]['output']['scheduler-policy']['config']['name'] == 'sched-11-cm-ip-dscp-af11'"