Tóm tắt: Quy trình post-check gồm 3 bước: (1) thu thập trạng thái trước thay đổi (iosxr_facts hoặc iosxr_command), (2) đẩy config, (3) thu thập lại rồi kiểm tra bằng ansible.builtin.assert (điều kiện cụ thể), ansible.utils.validate (cấu trúc dữ liệu theo JSON Schema) và ansible.utils.fact_diff (xem cái gì đã đổi). Assert fail thì play dừng với host đó, nên đặt post-check ngay sau task đẩy config. Đẩy config xem Đẩy cấu hình IOS XR bằng Ansible.
Luồng hoạt động
flowchart LR A["Pre-check: iosxr_facts"] --> B["Đẩy config"] B --> C["Post-check: thu thập lại"] C --> D["assert + validate"] C --> E["fact_diff trước/sau"] D -->|"fail"| F["Dừng host, rollback tay"] D -->|"pass"| G["Ghi báo cáo"]
Lệnh
Thu thập trạng thái
iosxr_facts chỉ hỗ trợ một số resource (interfaces, l3_interfaces, lag_interfaces, static_routes, acls, ospfv2, lldp_*, lacp*; xem ansible-doc cisco.iosxr.iosxr_facts). Không có BGP session state, nên với trạng thái runtime dùng iosxr_command rồi parse (xem Parse output show).
- name: Post-check sau thay đổi
hosts: iosxr
gather_facts: false
tasks:
- name: Thu thập interface (cấu hình khai báo)
cisco.iosxr.iosxr_facts:
gather_subset: min
gather_network_resources:
- interfaces
- l3_interfaces
- name: Lấy trạng thái BGP (runtime)
cisco.iosxr.iosxr_command:
commands:
- show bgp ipv4 unicast summary
register: bgp_summaryFacts resource nằm ở ansible_network_resources.<tên> (danh sách dict), còn facts cơ bản như ansible_net_version, ansible_net_hostname.
assert: điều kiện cụ thể
- name: Interface uplink phải enabled và đúng MTU
ansible.builtin.assert:
that:
- uplink.enabled | default(true)
- uplink.mtu == 9192
fail_msg: "{{ inventory_hostname }}: {{ uplink.name }} sai trạng thái: {{ uplink }}"
success_msg: "{{ uplink.name }} OK"
vars:
uplink: >-
{{ ansible_network_resources.interfaces
| selectattr('name', 'equalto', 'GigabitEthernet0/0/0/1')
| first }}| Tham số | Ý nghĩa |
|---|---|
that |
Danh sách biểu thức Jinja2, tất cả phải đúng |
fail_msg / msg |
Thông báo khi fail, nên in giá trị thực tế |
success_msg |
Thông báo khi pass |
quiet: true |
Bớt output dài khi pass |
Chờ hội tụ: retries + until
Sau thay đổi, BGP/IGP cần vài giây mới lên. Dùng until thay vì pause cố định:
- name: Chờ neighbor 192.0.2.2 Established
cisco.iosxr.iosxr_command:
commands:
- show bgp ipv4 unicast summary
register: bgp
until: bgp.stdout[0] | regex_search('(?m)^192\.0\.2\.2\s.*\s\d+\s*$') is not none
retries: 12
delay: 10Cột cuối của show bgp ... summary là số prefix khi session Established, hoặc tên state (Idle, Active) khi chưa lên. Regex trên chỉ khớp khi cột cuối là số. Kiểm tra lại trên phiên bản IOS XR của bạn trước khi dùng cho production.
validate: kiểm tra cấu trúc bằng JSON Schema
ansible.utils.validate (engine mặc định ansible.utils.jsonschema) hữu ích khi dữ liệu đã được parse thành structured và bạn muốn kiểm tra toàn bộ danh sách theo một hợp đồng. Cần pip install jsonschema trên control node.
- name: Mọi neighbor phải Established
ansible.utils.validate:
data: "{{ bgp_neighbors }}"
engine: ansible.utils.jsonschema
criteria:
type: array
items:
type: object
required: [ip, state, prefixes]
properties:
state:
const: Established
prefixes:
type: integer
minimum: 1Ở đây bgp_neighbors là list dict {ip, state, prefixes} do bạn tự parse từ output. Khi dữ liệu không khớp, task fail và liệt kê từng lỗi (đường dẫn trong data và lý do).
fact_diff: so sánh trước/sau
- ansible.builtin.set_fact:
before: "{{ ansible_network_resources }}"
# ... đẩy config, thu thập lại ...
- name: Xem thay đổi
ansible.utils.fact_diff:
before: "{{ before | ansible.utils.to_paths }}"
after: "{{ ansible_network_resources | ansible.utils.to_paths }}"to_paths làm phẳng cây dữ liệu để diff dễ đọc. Có thể truyền chuỗi to_nice_yaml thay thế.
Chạy
ansible-playbook -i inventory/hosts.yml post_check.yml -l pe1-hni
# Mức chi tiết cao hơn để xem giá trị assert đánh giá
ansible-playbook -i inventory/hosts.yml post_check.yml -l pe1-hni -vLỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
Lỗi liên quan jsonschema khi chạy validate |
Thiếu thư viện trên control node | pip install jsonschema trong cùng venv chạy ansible |
ansible.utils không tìm thấy |
Chưa cài collection | ansible-galaxy collection install ansible.utils cisco.iosxr |
ansible_network_resources.interfaces rỗng |
Chưa gather resource đó, hoặc gather_network_resources viết sai tên |
Liệt kê tên hợp lệ bằng available_network_resources: true |
assert báo 'dict object' has no attribute |
selectattr(...) | first không tìm thấy interface |
Dùng default({}) hoặc assert length > 0 trước |
until chạy hết retries dù session đã lên |
Regex không khớp format output của phiên bản XR | In bgp.stdout[0], chỉnh regex |
| Assert pass nhưng thay đổi chưa vào commit | Post-check đọc running-config trước khi commit xong | Đặt post-check sau task config, kiểm tra show configuration commit list |