Skip to content

Commit acaf3d8

Browse files
committed
fix c9400 show environment all
1 parent 18fe49c commit acaf3d8

File tree

8 files changed

+114380
-0
lines changed

8 files changed

+114380
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--------------------------------------------------------------------------------
2+
Fix
3+
--------------------------------------------------------------------------------
4+
* C9400
5+
* Modified/Revised ShowEnvironmentAll:
6+
* Changed schema to include "switch" for every switch in the stack.
7+
* Updated regex pattern to accomodate for "Switch:1" and "Switch: 1" outputs and use those as keys to the power supply and fantray parsing.

sdk_generator/outputs/github_parser.json

Lines changed: 112680 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from genie import abstract
2+
abstract.declare_token(revision='1')
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Python
2+
import re
3+
4+
# Metaparser
5+
from genie.metaparser import MetaParser
6+
from genie.metaparser.util.schemaengine import Any, Optional, Or
7+
8+
class ShowEnvironmentAllSchema(MetaParser):
9+
"""Schema for show environment all
10+
show environment all | include {include} """
11+
12+
schema = {
13+
Optional('critical_alarms'): int,
14+
Optional('major_alarms'): int,
15+
Optional('minor_alarms'): int,
16+
'sensor_list': {
17+
Any(): {
18+
'slot': {
19+
Any(): {
20+
'sensor': {
21+
Any(): {
22+
'state': str,
23+
'reading': str,
24+
Optional('threshold'): {
25+
'minor': int,
26+
'major': int,
27+
'critical': int,
28+
'shutdown': int,
29+
'unit': str,
30+
}
31+
}
32+
}
33+
}
34+
}
35+
}
36+
},
37+
'switch': {
38+
Any(): {
39+
'power_supply': {
40+
'slot': {
41+
Any(): {
42+
'model_no': str,
43+
'type': str,
44+
'capacity': str,
45+
'status': str,
46+
'fan_1_state': str,
47+
'fan_2_state': str,
48+
}
49+
},
50+
'current_configuration_mode': str,
51+
'current_operating_state': str,
52+
'currently_active': int,
53+
'currently_available': int,
54+
},
55+
'fantray': {
56+
'status': str,
57+
'power_consumed_by_fantray_watts': int,
58+
'fantray_airflow_direction': str,
59+
'fantray_beacon_led': str,
60+
'fantray_status_led': str,
61+
'system': str,
62+
},
63+
},
64+
},
65+
}
66+
67+
68+
class ShowEnvironmentAll(ShowEnvironmentAllSchema):
69+
"""Parser for show environment all
70+
show environment all | include {include}"""
71+
72+
cli_command = [
73+
'show environment all', 'show environment all | include {include}'
74+
]
75+
76+
def cli(self, include='', output=None):
77+
if not output:
78+
if include:
79+
cmd = self.cli_command[1].format(include=include)
80+
else:
81+
cmd = self.cli_command[0]
82+
output = self.device.execute(cmd)
83+
84+
# initial return dictionary
85+
ret_dict = {}
86+
87+
# Number of Critical alarms: 0
88+
p1 = re.compile(
89+
r'^Number +of +Critical +alarms: +(?P<critic_alarms>\d+)$')
90+
91+
# Number of Major alarms: 0
92+
p2 = re.compile(r'^Number +of +Major +alarms: +(?P<maj_alarms>\d+)$')
93+
94+
# Number of Minor alarms: 0
95+
p3 = re.compile(r'^Number +of +Minor +alarms: +(?P<min_alarms>\d+)$')
96+
97+
# Sensor List: Environmental Monitoring
98+
p4 = re.compile(r'Sensor\s+List:\s+(?P<sensor_list>.+)')
99+
100+
# Sensor Location State Reading Threshold(Minor,Major,Critical,Shutdown)
101+
# Temp: Coretemp Chassis1-R0 Normal 46 Celsius (107,117,123,125)(Celsius)
102+
# Temp: UADP Chassis1-R0 Normal 54 Celsius (107,117,123,125)(Celsius)
103+
# V1: VX1 Chassis1-R0 Normal 871 mV na
104+
# V1: VX2 Chassis1-R0 Normal 1498 mV na
105+
# V1: VX3 Chassis1-R0 Normal 1055 mV na
106+
# V1: VX4 Chassis1-R0 Normal 852 mV na
107+
# V1: VX5 Chassis1-R0 Normal 1507 mV na
108+
# V1: VX6 Chassis1-R0 Normal 1301 mV na
109+
# V1: VX7 Chassis1-R0 Normal 1005 mV na
110+
p5 = re.compile(
111+
r'(?P<sensor_name>\S+(:\s+\S+)?)\s+(?P<slot>\S+[0-9])\s+(?P<state>\S+)\s+(?P<reading>\d+\s+\S+(\s+(AC|DC))?)\s+(\((?P<minor>\d+\s*),(?P<major>\d+\s*),(?P<critical>\d+\s*),(?P<shutdown>\d+\s*)\)\((?P<unit>\S+)\))?'
112+
)
113+
114+
# Switch:1
115+
p6 = re.compile(r'^Switch:(?P<switch>\d+)')
116+
117+
# Power Fan States
118+
# Supply Model No Type Capacity Status 1 2
119+
# ------ -------------------- ---- -------- ------------ -----------
120+
# PS1 C9400-PWR-3200AC ac 3200 W active good good
121+
# PS2 C9400-PWR-3200AC ac n.a. faulty good good
122+
p7 = re.compile(
123+
r'(?P<ps_slot>PS\S+)\s+(?P<model_no>\S+)\s+(?P<type>\S+)\s+(?P<capacity>\S+(\s+\S+)?)\s+(?P<status>\S+)\s+(?P<fan_1_state>\S+)\s+(?P<fan_2_state>\S+)$'
124+
)
125+
126+
# PS Current Configuration Mode : Combined
127+
# PS Current Operating State : Combined
128+
# Power supplies currently active : 1
129+
# Power supplies currently available : 1
130+
p8 = re.compile(
131+
r'(PS|Power supplies)\s+(?P<ps_key>.+)\s+:\s+(?P<ps_value>\S+)')
132+
133+
# Switch 1:
134+
p9 = re.compile(r'^Switch +(?P<switch>\d+)')
135+
136+
# Fantray : good
137+
# Power consumed by Fantray : 540 Watts
138+
# Fantray airflow direction : side-to-side
139+
# Fantray beacon LED: off
140+
# Fantray status LED: green
141+
# SYSTEM : GREEN
142+
p10 = re.compile(
143+
r'(?P<fantray_key>((.+)?Fantray(.+)?)|SYSTEM)(\s+)?:\s+(?P<fantray_value>(\S+)|(\d+\s+Watts))'
144+
)
145+
146+
for line in output.splitlines():
147+
line = line.strip()
148+
149+
# Number of Critical alarms: 0
150+
m = p1.match(line)
151+
if m:
152+
group = m.groupdict()
153+
ret_dict['critical_alarms'] = int(group['critic_alarms'])
154+
continue
155+
156+
# Number of Major alarms: 0
157+
m = p2.match(line)
158+
if m:
159+
group = m.groupdict()
160+
ret_dict['major_alarms'] = int(group['maj_alarms'])
161+
continue
162+
163+
# Number of Minor alarms: 0
164+
m = p3.match(line)
165+
if m:
166+
group = m.groupdict()
167+
ret_dict['minor_alarms'] = int(group['min_alarms'])
168+
continue
169+
170+
# Sensor List: Environmental Monitoring
171+
m = p4.match(line)
172+
if m:
173+
group = m.groupdict()
174+
sensor_dict = ret_dict.setdefault('sensor_list',
175+
{}).setdefault(
176+
group['sensor_list'], {})
177+
continue
178+
179+
# Sensor Location State Reading Threshold(Minor,Major,Critical,Shutdown)
180+
# Temp: Coretemp R0 Normal 48 Celsius (107,117,123,125)(Celsius)
181+
# Temp: UADP R0 Normal 56 Celsius (107,117,123,125)(Celsius)
182+
# V1: VX1 R0 Normal 869 mV na
183+
# Temp: inlet R0 Normal 32 Celsius (56 ,66 ,96 ,98 )(Celsius)
184+
m = p5.match(line)
185+
if m:
186+
group = m.groupdict()
187+
sensor_name = group.pop('sensor_name')
188+
slot = group.pop('slot')
189+
fin_dict = sensor_dict.setdefault('slot', {}).setdefault(slot, {}).\
190+
setdefault('sensor', {}).setdefault(sensor_name, {})
191+
192+
fin_dict['state'] = group['state']
193+
fin_dict['reading'] = group['reading']
194+
if group['minor']:
195+
fin_dict.setdefault('threshold', {})
196+
for key in [
197+
'minor', 'major', 'critical', 'shutdown', 'unit'
198+
]:
199+
fin_dict['threshold'][key] = int(
200+
group[key]) if key != 'unit' else group[key]
201+
continue
202+
203+
# Switch:1
204+
m = p6.match(line)
205+
if m:
206+
group = m.groupdict()
207+
switch = group['switch']
208+
sw_dict = ret_dict.setdefault('switch', {}).setdefault(switch, {})
209+
210+
# Power Fan States
211+
# Supply Model No Type Capacity Status 1 2
212+
# ------ -------------------- ---- -------- ------------ -----------
213+
# PS1 C9400-PWR-3200AC ac 3200 W active good good
214+
# PS2 C9400-PWR-3200AC ac n.a. faulty good good
215+
m = p7.match(line)
216+
if m:
217+
group = m.groupdict()
218+
ps_slot = group.pop('ps_slot')
219+
ps_dict = sw_dict.setdefault('power_supply', {})
220+
ps_slot_dict = ps_dict.setdefault('slot',
221+
{}).setdefault(ps_slot, {})
222+
ps_slot_dict.update({k: v for k, v in group.items()})
223+
224+
# PS Current Configuration Mode : Combined
225+
# PS Current Operating State : Combined
226+
# Power supplies currently active : 1
227+
# Power supplies currently available : 1
228+
m = p8.match(line)
229+
if m:
230+
group = m.groupdict()
231+
ps_key = group['ps_key'].strip().lower().replace(' ', '_')
232+
if 'active' in ps_key or 'available' in ps_key:
233+
ps_value = int(group['ps_value'])
234+
else:
235+
ps_value = group['ps_value']
236+
ps_dict.setdefault(ps_key, ps_value)
237+
238+
# Switch 1:
239+
m = p9.match(line)
240+
if m:
241+
group = m.groupdict()
242+
switch = group['switch']
243+
sw_dict = ret_dict.setdefault('switch', {}).setdefault(switch, {})
244+
245+
# Fantray : good
246+
# Power consumed by Fantray : 540 Watts
247+
# Fantray airflow direction : side-to-side
248+
# Fantray beacon LED: off
249+
# Fantray status LED: green
250+
# SYSTEM : GREEN
251+
m = p10.match(line)
252+
if m:
253+
group = m.groupdict()
254+
fantray_key = group['fantray_key'].strip().lower().replace(
255+
' ', '_')
256+
if 'power_consumed' in fantray_key:
257+
fantray_value = int(group['fantray_value'])
258+
fantray_key += '_watts'
259+
else:
260+
fantray_value = group['fantray_value']
261+
if 'fantray' == fantray_key:
262+
sw_dict.setdefault('fantray',
263+
{}).setdefault('status', fantray_value)
264+
else:
265+
sw_dict.setdefault('fantray',
266+
{}).setdefault(fantray_key,
267+
fantray_value)
268+
269+
return ret_dict

src/genie/libs/parser/iosxe/cat9k/c9400/rv1/tests/ShowEnvironmentAll/cli/empty/empty_output_output.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)