diff --git a/jc/parsers/arp.py b/jc/parsers/arp.py index 130fa7a1..ec1c3ca1 100644 --- a/jc/parsers/arp.py +++ b/jc/parsers/arp.py @@ -222,14 +222,26 @@ def parse( else: for line in cleandata: splitline = line.split() - if '' not in splitline: + + # Ignore AIX bucket information + if 'bucket:' in splitline[0]: + continue + elif 'There' in splitline[0] and 'are' in splitline[1]: + continue + + # AIX uses (incomplete) + elif '' not in splitline and '(incomplete)' not in splitline: output_line = { 'name': splitline[0], 'address': splitline[1].lstrip('(').rstrip(')'), 'hwtype': splitline[4].lstrip('[').rstrip(']'), 'hwaddress': splitline[3], - 'iface': splitline[6], } + # Handle permanence and ignore interface in AIX + if 'permanent' in splitline: + output_line['permanent'] = True + elif 'in' not in splitline[6]: # AIX doesn't show interface + output_line['iface'] = splitline[6] else: output_line = { @@ -237,8 +249,10 @@ def parse( 'address': splitline[1].lstrip('(').rstrip(')'), 'hwtype': None, 'hwaddress': None, - 'iface': splitline[5], } + # AIX doesn't show interface + if len(splitline) >= 5: + output_line['iface'] = splitline[5] raw_output.append(output_line) diff --git a/tests/fixtures/aix-7.1/arp-a.json b/tests/fixtures/aix-7.1/arp-a.json new file mode 100644 index 00000000..919b6b20 --- /dev/null +++ b/tests/fixtures/aix-7.1/arp-a.json @@ -0,0 +1 @@ +[{"name":null,"address":"1.2.3.4","hwtype":"ethernet","hwaddress":"5:6:7:8:9:a","permanent":true},{"name":"v630gw9-3-63-1","address":"9.3.63.1","hwtype":"ethernet","hwaddress":"0:0:5e:0:1:5c"},{"name":"v630vrrp9-3-63-2","address":"9.3.63.2","hwtype":"ethernet","hwaddress":"4c:96:14:59:d7:f0"},{"name":"v630vrrp9-3-63-3","address":"9.3.63.3","hwtype":"ethernet","hwaddress":"3c:8a:b0:0:8f:f0"},{"name":"caju6","address":"9.3.63.4","hwtype":null,"hwaddress":null},{"name":"rock-lp8","address":"9.3.63.173","hwtype":"ethernet","hwaddress":"b6:1b:da:7e:1f:2"}] diff --git a/tests/fixtures/aix-7.1/arp-a.out b/tests/fixtures/aix-7.1/arp-a.out new file mode 100644 index 00000000..dd275873 --- /dev/null +++ b/tests/fixtures/aix-7.1/arp-a.out @@ -0,0 +1,163 @@ + ? (1.2.3.4) at 5:6:7:8:9:a [ethernet] permanent published stored in bucket 93 + + v630gw9-3-63-1 (9.3.63.1) at 0:0:5e:0:1:5c [ethernet] stored in bucket 97 + + v630vrrp9-3-63-2 (9.3.63.2) at 4c:96:14:59:d7:f0 [ethernet] stored in bucket 98 + + v630vrrp9-3-63-3 (9.3.63.3) at 3c:8a:b0:0:8f:f0 [ethernet] stored in bucket 99 + + caju6 (9.3.63.4) at (incomplete) + rock-lp8 (9.3.63.173) at b6:1b:da:7e:1f:2 [ethernet] stored in bucket 120 + +bucket: 0 contains: 0 entries +bucket: 1 contains: 0 entries +bucket: 2 contains: 0 entries +bucket: 3 contains: 0 entries +bucket: 4 contains: 0 entries +bucket: 5 contains: 0 entries +bucket: 6 contains: 0 entries +bucket: 7 contains: 0 entries +bucket: 8 contains: 0 entries +bucket: 9 contains: 0 entries +bucket: 10 contains: 0 entries +bucket: 11 contains: 0 entries +bucket: 12 contains: 0 entries +bucket: 13 contains: 0 entries +bucket: 14 contains: 0 entries +bucket: 15 contains: 0 entries +bucket: 16 contains: 0 entries +bucket: 17 contains: 0 entries +bucket: 18 contains: 0 entries +bucket: 19 contains: 0 entries +bucket: 20 contains: 0 entries +bucket: 21 contains: 0 entries +bucket: 22 contains: 0 entries +bucket: 23 contains: 0 entries +bucket: 24 contains: 0 entries +bucket: 25 contains: 0 entries +bucket: 26 contains: 0 entries +bucket: 27 contains: 0 entries +bucket: 28 contains: 0 entries +bucket: 29 contains: 0 entries +bucket: 30 contains: 0 entries +bucket: 31 contains: 0 entries +bucket: 32 contains: 0 entries +bucket: 33 contains: 0 entries +bucket: 34 contains: 0 entries +bucket: 35 contains: 0 entries +bucket: 36 contains: 0 entries +bucket: 37 contains: 0 entries +bucket: 38 contains: 0 entries +bucket: 39 contains: 0 entries +bucket: 40 contains: 0 entries +bucket: 41 contains: 0 entries +bucket: 42 contains: 0 entries +bucket: 43 contains: 0 entries +bucket: 44 contains: 0 entries +bucket: 45 contains: 0 entries +bucket: 46 contains: 0 entries +bucket: 47 contains: 0 entries +bucket: 48 contains: 0 entries +bucket: 49 contains: 0 entries +bucket: 50 contains: 0 entries +bucket: 51 contains: 0 entries +bucket: 52 contains: 0 entries +bucket: 53 contains: 0 entries +bucket: 54 contains: 0 entries +bucket: 55 contains: 0 entries +bucket: 56 contains: 0 entries +bucket: 57 contains: 0 entries +bucket: 58 contains: 0 entries +bucket: 59 contains: 0 entries +bucket: 60 contains: 0 entries +bucket: 61 contains: 0 entries +bucket: 62 contains: 0 entries +bucket: 63 contains: 0 entries +bucket: 64 contains: 0 entries +bucket: 65 contains: 0 entries +bucket: 66 contains: 0 entries +bucket: 67 contains: 0 entries +bucket: 68 contains: 0 entries +bucket: 69 contains: 0 entries +bucket: 70 contains: 0 entries +bucket: 71 contains: 0 entries +bucket: 72 contains: 0 entries +bucket: 73 contains: 0 entries +bucket: 74 contains: 0 entries +bucket: 75 contains: 0 entries +bucket: 76 contains: 0 entries +bucket: 77 contains: 0 entries +bucket: 78 contains: 0 entries +bucket: 79 contains: 0 entries +bucket: 80 contains: 0 entries +bucket: 81 contains: 0 entries +bucket: 82 contains: 0 entries +bucket: 83 contains: 0 entries +bucket: 84 contains: 0 entries +bucket: 85 contains: 0 entries +bucket: 86 contains: 0 entries +bucket: 87 contains: 0 entries +bucket: 88 contains: 0 entries +bucket: 89 contains: 0 entries +bucket: 90 contains: 0 entries +bucket: 91 contains: 0 entries +bucket: 92 contains: 0 entries +bucket: 93 contains: 1 entries +bucket: 94 contains: 0 entries +bucket: 95 contains: 0 entries +bucket: 96 contains: 0 entries +bucket: 97 contains: 1 entries +bucket: 98 contains: 1 entries +bucket: 99 contains: 1 entries +bucket: 100 contains: 0 entries +bucket: 101 contains: 0 entries +bucket: 102 contains: 0 entries +bucket: 103 contains: 0 entries +bucket: 104 contains: 0 entries +bucket: 105 contains: 0 entries +bucket: 106 contains: 0 entries +bucket: 107 contains: 0 entries +bucket: 108 contains: 0 entries +bucket: 109 contains: 0 entries +bucket: 110 contains: 0 entries +bucket: 111 contains: 0 entries +bucket: 112 contains: 0 entries +bucket: 113 contains: 0 entries +bucket: 114 contains: 0 entries +bucket: 115 contains: 0 entries +bucket: 116 contains: 0 entries +bucket: 117 contains: 0 entries +bucket: 118 contains: 0 entries +bucket: 119 contains: 0 entries +bucket: 120 contains: 1 entries +bucket: 121 contains: 0 entries +bucket: 122 contains: 0 entries +bucket: 123 contains: 0 entries +bucket: 124 contains: 0 entries +bucket: 125 contains: 0 entries +bucket: 126 contains: 0 entries +bucket: 127 contains: 0 entries +bucket: 128 contains: 0 entries +bucket: 129 contains: 0 entries +bucket: 130 contains: 0 entries +bucket: 131 contains: 0 entries +bucket: 132 contains: 0 entries +bucket: 133 contains: 0 entries +bucket: 134 contains: 0 entries +bucket: 135 contains: 0 entries +bucket: 136 contains: 0 entries +bucket: 137 contains: 0 entries +bucket: 138 contains: 0 entries +bucket: 139 contains: 0 entries +bucket: 140 contains: 0 entries +bucket: 141 contains: 0 entries +bucket: 142 contains: 0 entries +bucket: 143 contains: 0 entries +bucket: 144 contains: 0 entries +bucket: 145 contains: 0 entries +bucket: 146 contains: 0 entries +bucket: 147 contains: 0 entries +bucket: 148 contains: 0 entries + +There are 5 entries in the arp table. + diff --git a/tests/test_arp.py b/tests/test_arp.py index 0dccf7f2..052a9153 100644 --- a/tests/test_arp.py +++ b/tests/test_arp.py @@ -42,6 +42,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/arp-a.out'), 'r', encoding='utf-8') as f: centos8_arp_a = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/aix-7.1/arp-a.out'), 'r', encoding='utf-8') as f: + aix_7_1_arp_a = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/arp.json'), 'r', encoding='utf-8') as f: centos_7_7_arp_json = json.loads(f.read()) @@ -76,6 +79,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/arp-a.json'), 'r', encoding='utf-8') as f: centos8_arp_a_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/aix-7.1/arp-a.json'), 'r', encoding='utf-8') as f: + aix_7_1_arp_a_json = json.loads(f.read()) + def test_arp_nodata(self): """ Test 'arp' with no data @@ -148,6 +154,13 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.arp.parse(self.centos8_arp_a, quiet=True), self.centos8_arp_a_json) + def test_arp_a_aix_7_1(self): + """ + Test 'arp -a' on AIX 7.1 with incomplete hw addresses and permanent ARP + entries + """ + self.assertEqual(jc.parsers.arp.parse(self.aix_7_1_arp_a, quiet=True), self.aix_7_1_arp_a_json) + if __name__ == '__main__': unittest.main()