Skip to content

Commit 6447308

Browse files
bktsim-aristardjeric-aristakenneth-arista
authored
[chassis][multi-asic] Make PFC commands use a class (#3057)
What I did This change puts contents originally in pfc/main.py into a class, to support the usage of the multi-asic helper in a future change. This change is required, as multi-asic helper being used expects members self.config_db and self.db to exist when a function with the decorator run_on_multi_asic is called. The multi-asic class helper will be used to add multi-asic support to pfc commands in a following pull request. This is a part of the set of changes being pushed for sonic-net/sonic-buildimage#15148 How I did it Moved contents of PFC commands into a class. There are no functional changes. Co-authored-by: rdjeric <[email protected]> Co-authored-by: Kenneth Cheung <[email protected]>
1 parent b53e0c3 commit 6447308

File tree

3 files changed

+282
-106
lines changed

3 files changed

+282
-106
lines changed

pfc/main.py

+119-106
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python3
2-
32
import click
43
from swsscommon.swsscommon import ConfigDBConnector
54
from tabulate import tabulate
@@ -8,153 +7,167 @@
87
ALL_PRIORITIES = [str(x) for x in range(8)]
98
PRIORITY_STATUS = ['on', 'off']
109

11-
def configPfcAsym(interface, pfc_asym):
12-
"""
13-
PFC handler to configure asymmentric PFC.
14-
"""
15-
configdb = ConfigDBConnector()
16-
configdb.connect()
1710

18-
configdb.mod_entry("PORT", interface, {'pfc_asym': pfc_asym})
11+
class Pfc(object):
12+
def __init__(self, cfgdb=None):
13+
self.cfgdb = cfgdb
1914

15+
def configPfcAsym(self, interface, pfc_asym):
16+
"""
17+
PFC handler to configure asymmetric PFC.
18+
"""
19+
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
20+
configdb.connect()
2021

21-
def showPfcAsym(interface):
22-
"""
23-
PFC handler to display asymmetric PFC information.
24-
"""
25-
header = ('Interface', 'Asymmetric')
22+
configdb.mod_entry("PORT", interface, {'pfc_asym': pfc_asym})
2623

27-
configdb = ConfigDBConnector()
28-
configdb.connect()
24+
def showPfcAsym(self, interface):
25+
"""
26+
PFC handler to display asymmetric PFC information.
27+
"""
28+
header = ('Interface', 'Asymmetric')
2929

30-
if interface:
31-
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|{0}'.format(interface))
32-
else:
33-
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|*')
30+
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
31+
configdb.connect()
3432

35-
table = []
36-
37-
for i in db_keys or [None]:
38-
key = None
39-
if i:
40-
key = i.split('|')[-1]
33+
if interface:
34+
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|{0}'.format(interface))
35+
else:
36+
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|*')
4137

42-
if key and key.startswith('Ethernet'):
43-
entry = configdb.get_entry('PORT', key)
44-
table.append([key, entry.get('pfc_asym', 'N/A')])
38+
table = []
4539

46-
sorted_table = natsorted(table)
40+
for i in db_keys or [None]:
41+
key = None
42+
if i:
43+
key = i.split('|')[-1]
4744

48-
click.echo()
49-
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
50-
click.echo()
45+
if key and key.startswith('Ethernet'):
46+
entry = configdb.get_entry('PORT', key)
47+
table.append([key, entry.get('pfc_asym', 'N/A')])
5148

52-
def configPfcPrio(status, interface, priority):
53-
configdb = ConfigDBConnector()
54-
configdb.connect()
49+
sorted_table = natsorted(table)
5550

56-
if interface not in configdb.get_keys('PORT_QOS_MAP'):
57-
click.echo('Cannot find interface {0}'.format(interface))
58-
return
51+
click.echo()
52+
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
53+
click.echo()
5954

60-
"""Current lossless priorities on the interface"""
61-
entry = configdb.get_entry('PORT_QOS_MAP', interface)
62-
enable_prio = entry.get('pfc_enable').split(',')
63-
64-
"""Avoid '' in enable_prio"""
65-
enable_prio = [x.strip() for x in enable_prio if x.strip()]
66-
67-
if status == 'on' and priority in enable_prio:
68-
click.echo('Priority {0} has already been enabled on {1}'.format(priority, interface))
69-
return
70-
71-
if status == 'off' and priority not in enable_prio:
72-
click.echo('Priority {0} is not enabled on {1}'.format(priority, interface))
73-
return
74-
75-
if status == 'on':
76-
enable_prio.append(priority)
77-
78-
else:
79-
enable_prio.remove(priority)
80-
81-
enable_prio.sort()
82-
configdb.mod_entry("PORT_QOS_MAP", interface, {'pfc_enable': ','.join(enable_prio)})
83-
84-
"""Show the latest PFC configuration"""
85-
showPfcPrio(interface)
86-
87-
def showPfcPrio(interface):
88-
"""
89-
PFC handler to display PFC enabled priority information.
90-
"""
91-
header = ('Interface', 'Lossless priorities')
92-
table = []
55+
def configPfcPrio(self, status, interface, priority):
56+
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
57+
configdb.connect()
58+
59+
if interface not in configdb.get_keys('PORT_QOS_MAP'):
60+
click.echo('Cannot find interface {0}'.format(interface))
61+
return
62+
63+
"""Current lossless priorities on the interface"""
64+
entry = configdb.get_entry('PORT_QOS_MAP', interface)
65+
enable_prio = entry.get('pfc_enable').split(',')
66+
67+
"""Avoid '' in enable_prio"""
68+
enable_prio = [x.strip() for x in enable_prio if x.strip()]
69+
70+
if status == 'on' and priority in enable_prio:
71+
click.echo('Priority {0} has already been enabled on {1}'.format(priority, interface))
72+
return
73+
74+
if status == 'off' and priority not in enable_prio:
75+
click.echo('Priority {0} is not enabled on {1}'.format(priority, interface))
76+
return
77+
78+
if status == 'on':
79+
enable_prio.append(priority)
80+
81+
else:
82+
enable_prio.remove(priority)
83+
84+
enable_prio.sort()
85+
configdb.mod_entry("PORT_QOS_MAP", interface, {'pfc_enable': ','.join(enable_prio)})
86+
87+
"""Show the latest PFC configuration"""
88+
self.showPfcPrio(interface)
9389

94-
configdb = ConfigDBConnector()
95-
configdb.connect()
96-
97-
"""Get all the interfaces with QoS map information"""
98-
intfs = configdb.get_keys('PORT_QOS_MAP')
99-
100-
"""The user specifies an interface but we cannot find it"""
101-
if interface and interface not in intfs:
102-
click.echo('Cannot find interface {0}'.format(interface))
103-
return
104-
105-
if interface:
106-
intfs = [interface]
107-
108-
for intf in intfs:
109-
entry = configdb.get_entry('PORT_QOS_MAP', intf)
110-
table.append([intf, entry.get('pfc_enable', 'N/A')])
111-
112-
sorted_table = natsorted(table)
113-
click.echo()
114-
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
115-
click.echo()
90+
def showPfcPrio(self, interface):
91+
"""
92+
PFC handler to display PFC enabled priority information.
93+
"""
94+
header = ('Interface', 'Lossless priorities')
95+
table = []
96+
97+
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
98+
configdb.connect()
99+
100+
"""Get all the interfaces with QoS map information"""
101+
intfs = configdb.get_keys('PORT_QOS_MAP')
102+
103+
"""The user specifies an interface but we cannot find it"""
104+
if interface and interface not in intfs:
105+
click.echo('Cannot find interface {0}'.format(interface))
106+
return
107+
108+
if interface:
109+
intfs = [interface]
110+
111+
for intf in intfs:
112+
entry = configdb.get_entry('PORT_QOS_MAP', intf)
113+
table.append([intf, entry.get('pfc_enable', 'N/A')])
114+
115+
sorted_table = natsorted(table)
116+
click.echo()
117+
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
118+
click.echo()
116119

117120
@click.group()
118-
def cli():
121+
@click.pass_context
122+
def cli(ctx):
119123
"""PFC Command Line"""
120-
pass
124+
# Use the cfgdb object if given as input.
125+
cfgdb = None if ctx.obj is None else ctx.obj.cfgdb
126+
127+
ctx.obj = {'pfc': Pfc(cfgdb)}
121128

122129
@cli.group()
123-
def config():
130+
@click.pass_context
131+
def config(ctx):
124132
"""Config PFC"""
125133
pass
126134

127135
@cli.group()
128-
def show():
136+
@click.pass_context
137+
def show(ctx):
129138
"""Show PFC information"""
130139
pass
131140

132141
@click.command()
133142
@click.argument('status', type=click.Choice(PRIORITY_STATUS))
134143
@click.argument('interface', type=click.STRING)
135-
def configAsym(status, interface):
144+
@click.pass_context
145+
def configAsym(ctx, status, interface):
136146
"""Configure asymmetric PFC on a given port."""
137-
configPfcAsym(interface, status)
147+
ctx.obj['pfc'].configPfcAsym(interface, status)
138148

139149
@click.command()
140150
@click.argument('status', type=click.Choice(PRIORITY_STATUS))
141151
@click.argument('interface', type=click.STRING)
142152
@click.argument('priority', type=click.Choice(ALL_PRIORITIES))
143-
def configPrio(status, interface, priority):
153+
@click.pass_context
154+
def configPrio(ctx, status, interface, priority):
144155
"""Configure PFC on a given priority."""
145-
configPfcPrio(status, interface, priority)
146-
156+
ctx.obj['pfc'].configPfcPrio(status, interface, priority)
157+
147158
@click.command()
148159
@click.argument('interface', type=click.STRING, required=False)
149-
def showAsym(interface):
160+
@click.pass_context
161+
def showAsym(ctx, interface):
150162
"""Show asymmetric PFC information"""
151-
showPfcAsym(interface)
163+
ctx.obj['pfc'].showPfcAsym(interface)
152164

153165
@click.command()
154166
@click.argument('interface', type=click.STRING, required=False)
155-
def showPrio(interface):
167+
@click.pass_context
168+
def showPrio(ctx, interface):
156169
"""Show PFC priority information"""
157-
showPfcPrio(interface)
170+
ctx.obj['pfc'].showPfcPrio(interface)
158171

159172
config.add_command(configAsym, "asymmetric")
160173
config.add_command(configPrio, "priority")

tests/pfc_input/assert_show_output.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
pfc_asym_cannot_find_intf = """\
2+
3+
Interface Asymmetric
4+
----------- ------------
5+
6+
"""
7+
8+
pfc_cannot_find_intf = """\
9+
Cannot find interface Ethernet1234
10+
"""
11+
12+
pfc_show_asymmetric_all = """\
13+
14+
Interface Asymmetric
15+
----------- ------------
16+
Ethernet0 off
17+
Ethernet4 off
18+
Ethernet8 off
19+
Ethernet12 off
20+
Ethernet16 off
21+
Ethernet20 off
22+
Ethernet24 off
23+
Ethernet28 off
24+
Ethernet32 off
25+
Ethernet36 off
26+
Ethernet40 off
27+
Ethernet44 off
28+
Ethernet48 off
29+
Ethernet52 off
30+
Ethernet56 off
31+
Ethernet60 off
32+
Ethernet64 off
33+
Ethernet68 off
34+
Ethernet72 off
35+
Ethernet76 off
36+
Ethernet80 off
37+
Ethernet84 off
38+
Ethernet88 off
39+
Ethernet92 off
40+
Ethernet96 off
41+
Ethernet100 off
42+
Ethernet104 off
43+
Ethernet108 off
44+
Ethernet112 off
45+
Ethernet116 off
46+
Ethernet120 off
47+
Ethernet124 off
48+
49+
"""
50+
51+
pfc_show_asymmetric_intf = """\
52+
53+
Interface Asymmetric
54+
----------- ------------
55+
Ethernet0 off
56+
57+
"""
58+
59+
pfc_show_priority_all = """\
60+
61+
Interface Lossless priorities
62+
----------- ---------------------
63+
Ethernet0 3,4
64+
Ethernet4 3,4
65+
66+
"""
67+
68+
pfc_show_priority_intf = """\
69+
70+
Interface Lossless priorities
71+
----------- ---------------------
72+
Ethernet0 3,4
73+
74+
"""
75+
76+
pfc_config_priority_on = """\
77+
78+
Interface Lossless priorities
79+
----------- ---------------------
80+
Ethernet0 3,4,5
81+
82+
"""

0 commit comments

Comments
 (0)