0

I've been trying to use Ansible to print the CRC count using the ip -s -s link show command in a Red Hat machine. My stdout_lines is a list with below output:

 "stdout_lines": [
        "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000",
        "    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00",
        "    RX: bytes  packets  errors  dropped overrun mcast   ",
        "    0          0        0       0       0       0       ",
        "    RX errors: length   crc     frame   fifo    missed",
        "               0        0       0       0       0       ",
        "    TX: bytes  packets  errors  dropped carrier collsns ",
        "    0          0        0       0       0       0       ",
        "    TX errors: aborted  fifo   window heartbeat transns",
        "               0        0       0       0       0       ",
        "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000",
        "    link/ether 00:15:5d:e3:bb:dd brd ff:ff:ff:ff:ff:ff",
        "    RX: bytes  packets  errors  dropped overrun mcast   ",
        "    102522514  69859    0       0       0       1205    ",
        "    RX errors: length   crc     frame   fifo    missed",
        "               0        0       0       0       0       ",
        "    TX: bytes  packets  errors  dropped carrier collsns ",
        "    1179376    15194    0       0       0       0       ",
        "    TX errors: aborted  fifo   window heartbeat transns",
        "               0        0       0       0       5       "
    ]

So far I have tried these steps to create an Ansible playbook

  1. Read the line numbered 1:, 2: and map the interfaces lo, eth0
  2. Now read the lines and search the line with "RX errors: crc" for each interface (lo, eth0)
  3. Also read the lines below "RX errors: crc" line and print the value for CRC column

But I did not succeed. Any suggestion is welcome.

U880D
  • 8,601
  • 6
  • 24
  • 40
amitk
  • 143
  • 1
  • 1
  • 9

2 Answers2

1

Rather than playing around unsatisfyingly with a format made for humans, use a format made for parsing from scratch when it is available (aka json which is the -j switch for the ip command).

The below example gets information from cards available on my home machine. Change the var to whatever suits your needs.

---
- name: Display CRC errors for given network cards
  hosts: localhost
  gather_facts: false

  vars:
    report_cards:
      - lo
      - enp5s0

  tasks:

    - name: Get detailed information from links
      ansible.builtin.command: ip -s -s -j link show
      register: ip_link_cmd
      changed_when: false

    - name: Display information for given devices
      vars:
        link: "{{ item.ifname }}"
        crc_errors: "{{ item.stats64.rx.crc_errors }}"
      ansible.builtin.debug:
        msg: "CRC Errors for link {{ link }}: {{ crc_errors }}"
      loop: "{{ ip_link_cmd.stdout | from_json
        | selectattr('ifname', 'in', report_cards) }}"
      loop_control:
        label: "{{ link }}"

Running the above playbook on my machine gives:

PLAY [Display CRC errors for given network cards] *******************************************************

TASK [Get detailed information from links] **************************************************************
ok: [localhost]

TASK [Display information for given devices] ************************************************************
ok: [localhost] => (item=lo) => {
    "msg": "CRC Errors for link lo: 0"
}
ok: [localhost] => (item=enp5s0) => {
    "msg": "CRC Errors for link enp5s0: 0"
}

PLAY RECAP **********************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Just a note ... Whereby in general the `ip` command has an option `-j, --json` in example in RHEL 7.x it hasn't. There it might be necessary to following something like in [How to retrieve the routing tables in JSON format (Linux)?](https://serverfault.com/questions/1031569/). However, good example, therefore +1. – U880D May 30 '23 at 08:01
0

Whereby in general the ip command has an option -j, --json in example in RHEL 7.x it hasn't. There it might be necessary to use an other approach.

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Get detailed information from links
    ansible.builtin.command: ip -s -s link show
    register: result
    changed_when: false

  - name: Convert command's result to JSON
    ansible.builtin.debug:
      msg: "{{ result.stdout | community.general.jc('ip') }}"

Please take note that jc filter – Convert output of many shell commands and file-types to JSON has it's own requirements which needs to resolved before. Furthermore, it will be necessary to specifiy the Parser. Because of the lack of testing environment, I haven't tested for the ip command yet.

Further Documentation Similar Q&A

U880D
  • 8,601
  • 6
  • 24
  • 40
  • Hello, First off thank you for stepping in, as you correctly pointed out in RHEL 7.x , the '-j' json option is not present, So had to work through the ansible playbook to get a json format. **Sample output of my playbook** [ { "crc": " 0 0 0 0 0 ", "interface": "lo" }, { "crc": " 0 0 0 0 0 ", "interface": "eth0" } – amitk Jun 06 '23 at 18:56
  • Hi, I have tried your playbook , its giving the below error. fatal: [localhost]: FAILED! => {"msg": "Error in jc filter plugin: No module named 'jc.parsers.crc'"} Then I tried the jc filter with (k,v), the output gives me interface and crc report but not in a desired format, with the use of regular expression and loop over interface for which line can gives us the desired CRC output against the interface in json format. Thanks Amit K – amitk Jun 06 '23 at 19:18