Skip to content

Commit 37e29da

Browse files
Merge branch 'master' into pcie_aer
2 parents ce8cacd + d07ca5f commit 37e29da

File tree

171 files changed

+308046
-1469
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+308046
-1469
lines changed

LICENSE

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2016-2020 Microsoft, Inc.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

README.md

+39-2
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,53 @@ This repository produces two packages, as follows:
1515

1616
A Python wheel package, containing all the Python source code for the command-line utilities
1717

18+
#### Setting up a build/test environment
19+
20+
The sonic-utilities package depends on a number of other packages, many of which are available via PyPI, but some are part of the SONiC codebase. When building/testing the package, setuptools/pip will attempt to install the packages available from PyPI. However, you will need to manually build and install the SONiC dependencies before attempting to build or test the package.
21+
22+
Currently, this list of dependencies is as follows:
23+
24+
25+
- libyang_1.0.73_amd64.deb
26+
- libyang-cpp_1.0.73_amd64.deb
27+
- python3-yang_1.0.73_amd64.deb
28+
- redis_dump_load-1.1-py3-none-any.whl
29+
- swsssdk-2.0.1-py3-none-any.whl
30+
- sonic_py_common-1.0-py3-none-any.whl
31+
- sonic_config_engine-1.0-py3-none-any.whl
32+
- sonic_yang_mgmt-1.0-py3-none-any.whl
33+
- sonic_yang_models-1.0-py3-none-any.whl
34+
35+
36+
A convenient alternative is to let the SONiC build system configure a build enviroment for you. This can be done by cloning the [sonic-buildimage](https://github.com/Azure/sonic-buildimage) repo, building the sonic-utilities package inside the Debian Buster slave container, and staying inside the container once the build finishes. During the build process, the SONiC build system will build and install all the necessary dependencies inside the container. After following the instructions to clone and initialize the sonic-buildimage repo, this can be done as follows:
37+
38+
1. Configure the build environment for an ASIC type (any type will do, here we use `generic`)
39+
```
40+
make configure PLATFORM=generic
41+
```
42+
43+
2. Build the sonic-utilities Python wheel package inside the Buster slave container, and tell the build system to keep the container alive when finished
44+
```
45+
make NOJESSIE=1 NOSTRETCH=1 KEEP_SLAVE_ON=yes target/python-wheels/sonic_utilities-1.2-py3-none-any.whl
46+
```
47+
48+
3. When the build finishes, your prompt will change to indicate you are inside the slave container. Change into the `src/sonic-utilities/` directory
49+
```
50+
user@911799f161a0:/sonic$ cd src/sonic-utilities/
51+
```
52+
53+
4. You can now make changes to the sonic-utilities source and build the package or run unit tests with the commands below. When finished, you can exit the container by calling `exit`.
54+
1855
#### To build
1956
2057
```
21-
python2 setup.py bdist_wheel
58+
python3 setup.py bdist_wheel
2259
```
2360
2461
#### To run unit tests
2562
2663
```
27-
python2 setup.py test
64+
python3 setup.py test
2865
```
2966
3067

ThirdPartyLicenses.txt

-30
This file was deleted.

acl_loader/main.py

+21-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
import click
4-
import ipaddr
4+
import ipaddress
55
import json
66
import syslog
77

@@ -10,7 +10,8 @@
1010
import pyangbind.lib.pybindJSON as pybindJSON
1111
from natsort import natsorted
1212
from sonic_py_common import device_info
13-
from swsssdk import ConfigDBConnector, SonicV2Connector, SonicDBConfig
13+
from swsssdk import ConfigDBConnector, SonicDBConfig
14+
from swsscommon.swsscommon import SonicV2Connector
1415

1516

1617
def info(msg):
@@ -29,7 +30,7 @@ def error(msg):
2930

3031

3132
def deep_update(dst, src):
32-
for key, value in src.iteritems():
33+
for key, value in src.items():
3334
if isinstance(value, dict):
3435
node = dst.setdefault(key, {})
3536
deep_update(node, value)
@@ -181,7 +182,7 @@ def read_policers_info(self):
181182
# For multi-npu platforms we will read from any one of front asic namespace
182183
# config db as the information should be same across all config db
183184
if self.per_npu_configdb:
184-
namespace_configdb = (self.per_npu_configdb.values())[0]
185+
namespace_configdb = list(self.per_npu_configdb.values())[0]
185186
self.policers_db_info = namespace_configdb.get_table(self.POLICER)
186187
else:
187188
self.policers_db_info = self.configdb.get_table(self.POLICER)
@@ -198,19 +199,19 @@ def read_sessions_info(self):
198199
# For multi-npu platforms we will read from any one of front asic namespace
199200
# config db as the information should be same across all config db
200201
if self.per_npu_configdb:
201-
namespace_configdb = (self.per_npu_configdb.values())[0]
202+
namespace_configdb = list(self.per_npu_configdb.values())[0]
202203
self.sessions_db_info = namespace_configdb.get_table(self.CFG_MIRROR_SESSION_TABLE)
203204
else:
204205
self.sessions_db_info = self.configdb.get_table(self.CFG_MIRROR_SESSION_TABLE)
205-
for key in self.sessions_db_info.keys():
206+
for key in self.sessions_db_info:
206207
if self.per_npu_statedb:
207208
# For multi-npu platforms we will read from all front asic name space
208209
# statedb as the monitor port will be differnt for each asic
209210
# and it's status also might be different (ideally should not happen)
210211
# We will store them as dict of 'asic' : value
211212
self.sessions_db_info[key]["status"] = {}
212213
self.sessions_db_info[key]["monitor_port"] = {}
213-
for namespace_key, namespace_statedb in self.per_npu_statedb.iteritems():
214+
for namespace_key, namespace_statedb in self.per_npu_statedb.items():
214215
state_db_info = namespace_statedb.get_all(self.statedb.STATE_DB, "{}|{}".format(self.STATE_MIRROR_SESSION_TABLE, key))
215216
self.sessions_db_info[key]["status"][namespace_key] = state_db_info.get("status", "inactive") if state_db_info else "error"
216217
self.sessions_db_info[key]["monitor_port"][namespace_key] = state_db_info.get("monitor_port", "") if state_db_info else ""
@@ -366,7 +367,7 @@ def validate_actions(self, table_name, action_props):
366367
# For multi-npu we will read using anyone statedb connector for front asic namespace.
367368
# Same information should be there in all state DB's
368369
# as it is static information about switch capability
369-
namespace_statedb = (self.per_npu_statedb.values())[0]
370+
namespace_statedb = list(self.per_npu_statedb.values())[0]
370371
capability = namespace_statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
371372
else:
372373
capability = self.statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
@@ -416,7 +417,7 @@ def convert_ip(self, table_name, rule_idx, rule):
416417
# FIXME: 0 is a valid protocol number, but openconfig seems to use it as a default value,
417418
# so there isn't currently a good way to check if the user defined proto=0 or not.
418419
if rule.ip.config.protocol:
419-
if self.ip_protocol_map.has_key(rule.ip.config.protocol):
420+
if rule.ip.config.protocol in self.ip_protocol_map:
420421
rule_props["IP_PROTOCOL"] = self.ip_protocol_map[rule.ip.config.protocol]
421422
else:
422423
try:
@@ -429,14 +430,14 @@ def convert_ip(self, table_name, rule_idx, rule):
429430

430431
if rule.ip.config.source_ip_address:
431432
source_ip_address = rule.ip.config.source_ip_address.encode("ascii")
432-
if ipaddr.IPNetwork(source_ip_address).version == 4:
433+
if ipaddress.ip_network(source_ip_address).version == 4:
433434
rule_props["SRC_IP"] = source_ip_address
434435
else:
435436
rule_props["SRC_IPV6"] = source_ip_address
436437

437438
if rule.ip.config.destination_ip_address:
438439
destination_ip_address = rule.ip.config.destination_ip_address.encode("ascii")
439-
if ipaddr.IPNetwork(destination_ip_address).version == 4:
440+
if ipaddress.ip_network(destination_ip_address).version == 4:
440441
rule_props["DST_IP"] = destination_ip_address
441442
else:
442443
rule_props["DST_IPV6"] = destination_ip_address
@@ -578,7 +579,7 @@ def full_update(self):
578579
be removed and new rules in that table will be installed.
579580
:return:
580581
"""
581-
for key in self.rules_db_info.keys():
582+
for key in self.rules_db_info:
582583
if self.current_table is None or self.current_table == key[0]:
583584
self.configdb.mod_entry(self.ACL_RULE, key, None)
584585
# Program for per front asic namespace also if present
@@ -604,10 +605,10 @@ def incremental_update(self):
604605
# update on dataplane ACLs, and only perform an incremental update on
605606
# control plane ACLs.
606607

607-
new_rules = set(self.rules_info.iterkeys())
608+
new_rules = set(self.rules_info.keys())
608609
new_dataplane_rules = set()
609610
new_controlplane_rules = set()
610-
current_rules = set(self.rules_db_info.iterkeys())
611+
current_rules = set(self.rules_db_info.keys())
611612
current_dataplane_rules = set()
612613
current_controlplane_rules = set()
613614

@@ -672,7 +673,7 @@ def delete(self, table=None, rule=None):
672673
:param rule:
673674
:return:
674675
"""
675-
for key in self.rules_db_info.iterkeys():
676+
for key in self.rules_db_info:
676677
if not table or table == key[0]:
677678
if not rule or rule == key[1]:
678679
self.configdb.set_entry(self.ACL_RULE, key, None)
@@ -689,7 +690,7 @@ def show_table(self, table_name):
689690
header = ("Name", "Type", "Binding", "Description", "Stage")
690691

691692
data = []
692-
for key, val in self.get_tables_db_info().iteritems():
693+
for key, val in self.get_tables_db_info().items():
693694
if table_name and key != table_name:
694695
continue
695696

@@ -727,7 +728,7 @@ def show_session(self, session_name):
727728

728729
erspan_data = []
729730
span_data = []
730-
for key, val in self.get_sessions_db_info().iteritems():
731+
for key, val in self.get_sessions_db_info().items():
731732
if session_name and key != session_name:
732733
continue
733734

@@ -755,7 +756,7 @@ def show_policer(self, policer_name):
755756
header = ("Name", "Type", "Mode", "CIR", "CBS")
756757

757758
data = []
758-
for key, val in self.get_policers_db_info().iteritems():
759+
for key, val in self.get_policers_db_info().items():
759760
if policer_name and key != policer_name:
760761
continue
761762

@@ -806,7 +807,7 @@ def pop_matches(val):
806807
return matches
807808

808809
raw_data = []
809-
for (tname, rid), val in self.get_rules_db_info().iteritems():
810+
for (tname, rid), val in self.get_rules_db_info().items():
810811

811812
if table_name and table_name != tname:
812813
continue

clear/main.py

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
#! /usr/bin/python -u
2-
3-
import click
1+
import configparser
42
import os
53
import subprocess
64

7-
try:
8-
# noinspection PyPep8Naming
9-
import ConfigParser as configparser
10-
except ImportError:
11-
# noinspection PyUnresolvedReferences
12-
import configparser
5+
import click
136

147

158
# This is from the aliases example:
@@ -84,6 +77,7 @@ def get_routing_stack():
8477
proc = subprocess.Popen(command,
8578
stdout=subprocess.PIPE,
8679
shell=True,
80+
text=True,
8781
stderr=subprocess.STDOUT)
8882
stdout = proc.communicate()[0]
8983
proc.wait()
@@ -101,7 +95,7 @@ def get_routing_stack():
10195

10296
def run_command(command, pager=False, return_output=False):
10397
# Provide option for caller function to Process the output.
104-
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
98+
proc = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE)
10599
if return_output:
106100
return proc.communicate()
107101
elif pager:
@@ -368,10 +362,11 @@ def clear_vlan_fdb(vlanid):
368362
# 'line' command
369363
#
370364
@cli.command('line')
371-
@click.argument('linenum')
372-
def line(linenum):
365+
@click.argument('target')
366+
@click.option('--devicename', '-d', is_flag=True, help="clear by name - if flag is set, interpret target as device name instead")
367+
def line(target, devicename):
373368
"""Clear preexisting connection to line"""
374-
cmd = "consutil clear " + str(linenum)
369+
cmd = "consutil clear {}".format("--devicename " if devicename else "") + str(target)
375370
run_command(cmd)
376371

377372
#

config/aaa.py

-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
#!/usr/bin/env python -u
2-
# -*- coding: utf-8 -*-
3-
41
import click
5-
62
from swsssdk import ConfigDBConnector
73
import utilities_common.cli as clicommon
84

@@ -193,8 +189,3 @@ def delete(address):
193189
config_db.connect()
194190
config_db.set_entry('TACPLUS_SERVER', address, None)
195191
tacacs.add_command(delete)
196-
197-
198-
if __name__ == "__main__":
199-
aaa()
200-

config/chassis_modules.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/sbin/env python
2+
3+
import click
4+
5+
import utilities_common.cli as clicommon
6+
7+
#
8+
# 'chassis_modules' group ('config chassis_modules ...')
9+
#
10+
@click.group(cls=clicommon.AliasedGroup)
11+
def chassis_modules():
12+
"""Configure chassis-modules options"""
13+
pass
14+
15+
#
16+
# 'shutdown' subcommand ('config chassis_modules shutdown ...')
17+
#
18+
@chassis_modules.command('shutdown')
19+
@clicommon.pass_db
20+
@click.argument('chassis_module_name', metavar='<module_name>', required=True)
21+
def shutdown_chassis_module(db, chassis_module_name):
22+
"""Chassis-module shutdown of module"""
23+
config_db = db.cfgdb
24+
ctx = click.get_current_context()
25+
26+
if not chassis_module_name.startswith("SUPERVISOR") and \
27+
not chassis_module_name.startswith("LINE-CARD") and \
28+
not chassis_module_name.startswith("FABRIC-CARD"):
29+
ctx.fail("'module_name' has to begin with 'SUPERVISOR', 'LINE-CARD' or 'FABRIC-CARD'")
30+
31+
fvs = {'admin_status': 'down'}
32+
config_db.set_entry('CHASSIS_MODULE', chassis_module_name, fvs)
33+
34+
#
35+
# 'startup' subcommand ('config chassis_modules startup ...')
36+
#
37+
@chassis_modules.command('startup')
38+
@clicommon.pass_db
39+
@click.argument('chassis_module_name', metavar='<module_name>', required=True)
40+
def startup_chassis_module(db, chassis_module_name):
41+
"""Chassis-module startup of module"""
42+
config_db = db.cfgdb
43+
44+
config_db.set_entry('CHASSIS_MODULE', chassis_module_name, None)

0 commit comments

Comments
 (0)