[Day #46 Pyats Series] Validate QoS policy configurations using pyATS for Cisco [Python for Network Engineer]

[Day #46 Pyats Series] Validate QoS policy configurations using pyATS for Cisco [Python for Network Engineer]

Introduction on the Key Points

Welcome to Day 46 of the 101 Days of pyATS (Vendor-Agnostic) series! In today’s lab-driven session, we’re focusing on validating QoS (Quality of Service) policy configurations using Cisco’s pyATS and Genie framework.

Whether you’re managing enterprise WANs, campus LANs, or service provider cores, QoS is crucial for ensuring priority for voice, video, or business-critical traffic. But validating QoS policies manually—such as checking policy-maps, class-maps, bandwidth guarantees, and queuing behaviors—is time-consuming and prone to error.

This is where pyATS + Genie come to the rescue!

In this post, you’ll:

  • Understand how to validate QoS service policies using structured outputs
  • Run pyATS scripts to inspect class-map counters, bandwidth guarantees, and marking actions
  • Visualize CLI vs structured comparison for accuracy
  • Scale your checks across routers and interfaces
  • Use this practical case if you’re learning Python for Network Engineer roles focused on automation and config compliance

Let’s automate your QoS validation lifecycle!


Topology Overview

We’ll use a 2-router Cisco IOS-XE topology configured with QoS:

             +--------+         +--------+
| R1 |---------| R2 |
+--------+ +--------+

[Outbound QoS] [Policy applied at R1]
  • R1 is the source router applying a service-policy OUT on its WAN-facing interface
  • R2 acts as the receiving router, validating the impact of QoS during traffic simulation
  • We’ll validate configured QoS policies and operational state, including packet counters, drops, and markings

Topology & Communications

On R1, we’ll have the following:

  • Class-map: Match traffic based on DSCP/ACL
  • Policy-map: Define bandwidth or priority
  • Service-policy: Applied outbound on interface (e.g., Gig0/1)

Example CLI configuration on R1:

class-map match-any VOICE
match dscp ef

policy-map OUTBOUND_QOS
class VOICE
priority 1000
class class-default
fair-queue

interface GigabitEthernet0/1
service-policy output OUTBOUND_QOS

We’ll validate this config is:

  • Properly applied
  • Counters increment during traffic
  • Matches real-time behavior using Genie parsed output

Workflow Script

Here’s a pyATS script to validate the QoS configuration and counters:

# File: qos_policy_validation.py

from genie.testbed import load

# Load testbed
testbed = load('testbed.yml')
device = testbed.devices['R1']

device.connect(log_stdout=False)

print("\n--- Validating QoS Policies on R1 ---\n")

try:
    output = device.parse('show policy-map interface')

    for interface, data in output.items():
        if 'service_policy' not in data:
            continue

        print(f"Interface: {interface}")
        for direction, policy_info in data['service_policy'].items():
            print(f"  Direction: {direction}")
            for policy, details in policy_info.items():
                print(f"    Policy Name: {policy}")
                for class_name, class_data in details['class_map'].items():
                    print(f"      Class: {class_name}")
                    print(f"        Packets: {class_data.get('packets', 0)}")
                    print(f"        Bytes: {class_data.get('bytes', 0)}")
                    print(f"        Drop: {class_data.get('drop', {}).get('bytes', 0)}")
                    print(f"        Match Criteria: {class_data.get('match', {})}")
except Exception as e:
    print(f"Failed to parse: {e}")

Explanation by Line

  • testbed = load('testbed.yml') – Loads device login and details
  • device.connect() – Establishes connection using SSH/console
  • show policy-map interface – Pulls service-policy operational data
  • Looping logic – Parses interface, direction (input/output), policy name
  • QoS class details – Packet counts, bytes, drop stats, match conditions

You can easily add logic to alert if packet counts are 0 (meaning policy isn’t matching traffic) or mismatched DSCP values.


testbed.yml Example

testbed:
  name: qos_testbed
  credentials:
    default:
      username: cisco
      password: cisco

devices:
  R1:
    os: iosxe
    type: router
    connections:
      cli:
        protocol: ssh
        ip: 192.168.100.1

You can add more devices (e.g., R2, switches) to scale multi-node validations.


Post-validation CLI Screenshots (Expected Output)

On R1:

R1# show policy-map interface GigabitEthernet0/1
 GigabitEthernet0/1

  Service-policy output: OUTBOUND_QOS

    Class-map: VOICE (match-any)
      100 packets, 80000 bytes
      0 drop

    Class-map: class-default
      300 packets, 240000 bytes
      fair-queue

This output confirms:

  • Policy correctly applied
  • Traffic matches VOICE class
  • No drops
  • Genie parser will extract this into structured JSON for easier logic

FAQs

1. Why is it essential to validate QoS policy configurations in enterprise networks?

QoS (Quality of Service) ensures that critical traffic (like voice, video, or real-time apps) gets prioritized over best-effort traffic. Misconfigured QoS policies can:

  • Lead to jitter, packet loss, or delay for business-critical applications.
  • Cause misclassified traffic, rendering QoS ineffective.
  • Break SLA guarantees in multi-tenant or ISP environments.

Using pyATS, you can automate the verification of class maps, policy maps, and service policies, ensuring consistent configuration and correct application across platforms.


2. What specific QoS elements should be validated using pyATS scripts?

A robust pyATS QoS validation should check for:

  • Class-map correctness (match statements like DSCP, ACLs, COS)
  • Policy-map configuration (actions like police, priority, bandwidth)
  • Service-policy attachment on correct interfaces/directions
  • Queue statistics to verify if the policy is actively being used
  • DSCP-to-class mapping on ingress

These validations help identify whether QoS policies are:

  • Configured correctly
  • Applied to the intended interfaces
  • Actively enforcing traffic shaping/queuing

3. How does pyATS retrieve and parse QoS configurations on Cisco platforms?

Using Genie parsers for commands like:

show policy-map interface
show class-map
show policy-map

you can access structured data like:

parsed_output['GigabitEthernet1']['service_policy']['input']['policy_name']
parsed_output['class_map']['match_criteria']
parsed_output['class_map']['match']

This lets you:

  • Validate class match criteria (e.g., DSCP EF for VoIP)
  • Ensure correct policing/shaping actions
  • Verify policy attachment on correct interfaces

4. Can pyATS be used to validate QoS across multiple vendors (e.g., Cisco, Juniper, Arista)?

Yes. While Genie supports Cisco out of the box, for multi-vendor validation, you can:

  • Use Unicon CLI-based capture for commands like show class-of-service, show qos, etc.
  • Parse the output using custom regex or textfsm templates
  • Normalize the data into a common dictionary structure

This makes your pyATS tests vendor-agnostic, ensuring QoS consistency across platforms like:

  • Cisco (policy-map/class-map)
  • Arista (QoS maps)
  • Juniper (class-of-service)
  • Fortigate (traffic shaping profiles)

5. How can I confirm that a service-policy is applied in the correct direction (input/output)?

In your pyATS logic, extract the policy direction from:

parsed_output['interfaces']['GigabitEthernet0/1']['service_policy']['input']

or

parsed_output['interfaces']['GigabitEthernet0/1']['service_policy']['output']

Then compare it with your intended design baseline. If missing or attached in the wrong direction:

self.failed("Policy not applied in the intended direction")

This ensures that QoS classification and marking occur at the right stage of packet processing.


6. How do I validate if QoS queues are actively matching traffic?

Use show policy-map interface output to check for:

  • Matched packets/bytes per class
  • Drop statistics
  • Policing/shaping counters

In pyATS:

if int(matched_packets) == 0:
    self.failed(f"No traffic matched class {class_name}")

This helps detect:

  • Inactive policies
  • Misclassified traffic
  • Misplaced access-lists

It’s also useful in pre/post-change validation or during WAN optimization audits.


7. What are common QoS misconfigurations that pyATS can catch?

Some practical issues pyATS can catch:

  • Class maps matching wrong DSCP/ACL
  • Policy maps missing priority for voice/video
  • Service-policy applied to wrong interface
  • Policing instead of shaping in high-latency links
  • Policy direction mismatch (input vs output)
  • Unused class-maps defined but never hit

Automating this validation ensures SLA adherence, especially in voice, video, or multi-tenant deployments.


YouTube Link

Watch the Complete Python for Network Engineer: Validate QoS policy configurations using pyATS for Cisco [Python for Network Engineer] Lab Demo & Explanation on our channel:

Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Why Robot Framework for Network Automation?

Join Our Training

Love how we automated QoS policy validation today?

This is just a glimpse into the power of Python and pyATS for automating network configuration compliance, troubleshooting, and observability.

Trainer Sagar Dhawan is conducting a 3-month instructor-led training program focused on:

  • Python for Network Engineer workflows
  • pyATS + Genie for production-grade test automation
  • Ansible Playbooks, RESTCONF/NETCONF
  • Real-world use cases: QoS, BGP, ACLs, VRFs, APIs
  • CI/CD Integration + DevNet Associate prep

View Course Outline Here

Limited Seats | Real Projects | Certification Ready
If you’re a network engineer looking to upskill in automation, now is your moment!

Join our upcoming batch and master Python for Network Engineer roles using hands-on projects.

Enroll Now & Future‑Proof Your Career
Emailinfo@networkjourney.com
WhatsApp / Call: +91 97395 21088