Skip to content

Commit

Permalink
Merge branch 'master' into pcie_aer
Browse files Browse the repository at this point in the history
  • Loading branch information
ArunSaravananBalachandran authored Nov 18, 2020
2 parents ce8cacd + d07ca5f commit 37e29da
Show file tree
Hide file tree
Showing 171 changed files with 308,046 additions and 1,469 deletions.
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2016-2020 Microsoft, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,53 @@ This repository produces two packages, as follows:

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

#### Setting up a build/test environment

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.

Currently, this list of dependencies is as follows:


- libyang_1.0.73_amd64.deb
- libyang-cpp_1.0.73_amd64.deb
- python3-yang_1.0.73_amd64.deb
- redis_dump_load-1.1-py3-none-any.whl
- swsssdk-2.0.1-py3-none-any.whl
- sonic_py_common-1.0-py3-none-any.whl
- sonic_config_engine-1.0-py3-none-any.whl
- sonic_yang_mgmt-1.0-py3-none-any.whl
- sonic_yang_models-1.0-py3-none-any.whl


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:

1. Configure the build environment for an ASIC type (any type will do, here we use `generic`)
```
make configure PLATFORM=generic
```
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
```
make NOJESSIE=1 NOSTRETCH=1 KEEP_SLAVE_ON=yes target/python-wheels/sonic_utilities-1.2-py3-none-any.whl
```
3. When the build finishes, your prompt will change to indicate you are inside the slave container. Change into the `src/sonic-utilities/` directory
```
user@911799f161a0:/sonic$ cd src/sonic-utilities/
```
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`.
#### To build
```
python2 setup.py bdist_wheel
python3 setup.py bdist_wheel
```
#### To run unit tests
```
python2 setup.py test
python3 setup.py test
```
Expand Down
30 changes: 0 additions & 30 deletions ThirdPartyLicenses.txt

This file was deleted.

41 changes: 21 additions & 20 deletions acl_loader/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python3

import click
import ipaddr
import ipaddress
import json
import syslog

Expand All @@ -10,7 +10,8 @@
import pyangbind.lib.pybindJSON as pybindJSON
from natsort import natsorted
from sonic_py_common import device_info
from swsssdk import ConfigDBConnector, SonicV2Connector, SonicDBConfig
from swsssdk import ConfigDBConnector, SonicDBConfig
from swsscommon.swsscommon import SonicV2Connector


def info(msg):
Expand All @@ -29,7 +30,7 @@ def error(msg):


def deep_update(dst, src):
for key, value in src.iteritems():
for key, value in src.items():
if isinstance(value, dict):
node = dst.setdefault(key, {})
deep_update(node, value)
Expand Down Expand Up @@ -181,7 +182,7 @@ def read_policers_info(self):
# For multi-npu platforms we will read from any one of front asic namespace
# config db as the information should be same across all config db
if self.per_npu_configdb:
namespace_configdb = (self.per_npu_configdb.values())[0]
namespace_configdb = list(self.per_npu_configdb.values())[0]
self.policers_db_info = namespace_configdb.get_table(self.POLICER)
else:
self.policers_db_info = self.configdb.get_table(self.POLICER)
Expand All @@ -198,19 +199,19 @@ def read_sessions_info(self):
# For multi-npu platforms we will read from any one of front asic namespace
# config db as the information should be same across all config db
if self.per_npu_configdb:
namespace_configdb = (self.per_npu_configdb.values())[0]
namespace_configdb = list(self.per_npu_configdb.values())[0]
self.sessions_db_info = namespace_configdb.get_table(self.CFG_MIRROR_SESSION_TABLE)
else:
self.sessions_db_info = self.configdb.get_table(self.CFG_MIRROR_SESSION_TABLE)
for key in self.sessions_db_info.keys():
for key in self.sessions_db_info:
if self.per_npu_statedb:
# For multi-npu platforms we will read from all front asic name space
# statedb as the monitor port will be differnt for each asic
# and it's status also might be different (ideally should not happen)
# We will store them as dict of 'asic' : value
self.sessions_db_info[key]["status"] = {}
self.sessions_db_info[key]["monitor_port"] = {}
for namespace_key, namespace_statedb in self.per_npu_statedb.iteritems():
for namespace_key, namespace_statedb in self.per_npu_statedb.items():
state_db_info = namespace_statedb.get_all(self.statedb.STATE_DB, "{}|{}".format(self.STATE_MIRROR_SESSION_TABLE, key))
self.sessions_db_info[key]["status"][namespace_key] = state_db_info.get("status", "inactive") if state_db_info else "error"
self.sessions_db_info[key]["monitor_port"][namespace_key] = state_db_info.get("monitor_port", "") if state_db_info else ""
Expand Down Expand Up @@ -366,7 +367,7 @@ def validate_actions(self, table_name, action_props):
# For multi-npu we will read using anyone statedb connector for front asic namespace.
# Same information should be there in all state DB's
# as it is static information about switch capability
namespace_statedb = (self.per_npu_statedb.values())[0]
namespace_statedb = list(self.per_npu_statedb.values())[0]
capability = namespace_statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
else:
capability = self.statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
Expand Down Expand Up @@ -416,7 +417,7 @@ def convert_ip(self, table_name, rule_idx, rule):
# FIXME: 0 is a valid protocol number, but openconfig seems to use it as a default value,
# so there isn't currently a good way to check if the user defined proto=0 or not.
if rule.ip.config.protocol:
if self.ip_protocol_map.has_key(rule.ip.config.protocol):
if rule.ip.config.protocol in self.ip_protocol_map:
rule_props["IP_PROTOCOL"] = self.ip_protocol_map[rule.ip.config.protocol]
else:
try:
Expand All @@ -429,14 +430,14 @@ def convert_ip(self, table_name, rule_idx, rule):

if rule.ip.config.source_ip_address:
source_ip_address = rule.ip.config.source_ip_address.encode("ascii")
if ipaddr.IPNetwork(source_ip_address).version == 4:
if ipaddress.ip_network(source_ip_address).version == 4:
rule_props["SRC_IP"] = source_ip_address
else:
rule_props["SRC_IPV6"] = source_ip_address

if rule.ip.config.destination_ip_address:
destination_ip_address = rule.ip.config.destination_ip_address.encode("ascii")
if ipaddr.IPNetwork(destination_ip_address).version == 4:
if ipaddress.ip_network(destination_ip_address).version == 4:
rule_props["DST_IP"] = destination_ip_address
else:
rule_props["DST_IPV6"] = destination_ip_address
Expand Down Expand Up @@ -578,7 +579,7 @@ def full_update(self):
be removed and new rules in that table will be installed.
:return:
"""
for key in self.rules_db_info.keys():
for key in self.rules_db_info:
if self.current_table is None or self.current_table == key[0]:
self.configdb.mod_entry(self.ACL_RULE, key, None)
# Program for per front asic namespace also if present
Expand All @@ -604,10 +605,10 @@ def incremental_update(self):
# update on dataplane ACLs, and only perform an incremental update on
# control plane ACLs.

new_rules = set(self.rules_info.iterkeys())
new_rules = set(self.rules_info.keys())
new_dataplane_rules = set()
new_controlplane_rules = set()
current_rules = set(self.rules_db_info.iterkeys())
current_rules = set(self.rules_db_info.keys())
current_dataplane_rules = set()
current_controlplane_rules = set()

Expand Down Expand Up @@ -672,7 +673,7 @@ def delete(self, table=None, rule=None):
:param rule:
:return:
"""
for key in self.rules_db_info.iterkeys():
for key in self.rules_db_info:
if not table or table == key[0]:
if not rule or rule == key[1]:
self.configdb.set_entry(self.ACL_RULE, key, None)
Expand All @@ -689,7 +690,7 @@ def show_table(self, table_name):
header = ("Name", "Type", "Binding", "Description", "Stage")

data = []
for key, val in self.get_tables_db_info().iteritems():
for key, val in self.get_tables_db_info().items():
if table_name and key != table_name:
continue

Expand Down Expand Up @@ -727,7 +728,7 @@ def show_session(self, session_name):

erspan_data = []
span_data = []
for key, val in self.get_sessions_db_info().iteritems():
for key, val in self.get_sessions_db_info().items():
if session_name and key != session_name:
continue

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

data = []
for key, val in self.get_policers_db_info().iteritems():
for key, val in self.get_policers_db_info().items():
if policer_name and key != policer_name:
continue

Expand Down Expand Up @@ -806,7 +807,7 @@ def pop_matches(val):
return matches

raw_data = []
for (tname, rid), val in self.get_rules_db_info().iteritems():
for (tname, rid), val in self.get_rules_db_info().items():

if table_name and table_name != tname:
continue
Expand Down
21 changes: 8 additions & 13 deletions clear/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
#! /usr/bin/python -u

import click
import configparser
import os
import subprocess

try:
# noinspection PyPep8Naming
import ConfigParser as configparser
except ImportError:
# noinspection PyUnresolvedReferences
import configparser
import click


# This is from the aliases example:
Expand Down Expand Up @@ -84,6 +77,7 @@ def get_routing_stack():
proc = subprocess.Popen(command,
stdout=subprocess.PIPE,
shell=True,
text=True,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
Expand All @@ -101,7 +95,7 @@ def get_routing_stack():

def run_command(command, pager=False, return_output=False):
# Provide option for caller function to Process the output.
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
proc = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE)
if return_output:
return proc.communicate()
elif pager:
Expand Down Expand Up @@ -368,10 +362,11 @@ def clear_vlan_fdb(vlanid):
# 'line' command
#
@cli.command('line')
@click.argument('linenum')
def line(linenum):
@click.argument('target')
@click.option('--devicename', '-d', is_flag=True, help="clear by name - if flag is set, interpret target as device name instead")
def line(target, devicename):
"""Clear preexisting connection to line"""
cmd = "consutil clear " + str(linenum)
cmd = "consutil clear {}".format("--devicename " if devicename else "") + str(target)
run_command(cmd)

#
Expand Down
9 changes: 0 additions & 9 deletions config/aaa.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#!/usr/bin/env python -u
# -*- coding: utf-8 -*-

import click

from swsssdk import ConfigDBConnector
import utilities_common.cli as clicommon

Expand Down Expand Up @@ -193,8 +189,3 @@ def delete(address):
config_db.connect()
config_db.set_entry('TACPLUS_SERVER', address, None)
tacacs.add_command(delete)


if __name__ == "__main__":
aaa()

44 changes: 44 additions & 0 deletions config/chassis_modules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/sbin/env python

import click

import utilities_common.cli as clicommon

#
# 'chassis_modules' group ('config chassis_modules ...')
#
@click.group(cls=clicommon.AliasedGroup)
def chassis_modules():
"""Configure chassis-modules options"""
pass

#
# 'shutdown' subcommand ('config chassis_modules shutdown ...')
#
@chassis_modules.command('shutdown')
@clicommon.pass_db
@click.argument('chassis_module_name', metavar='<module_name>', required=True)
def shutdown_chassis_module(db, chassis_module_name):
"""Chassis-module shutdown of module"""
config_db = db.cfgdb
ctx = click.get_current_context()

if not chassis_module_name.startswith("SUPERVISOR") and \
not chassis_module_name.startswith("LINE-CARD") and \
not chassis_module_name.startswith("FABRIC-CARD"):
ctx.fail("'module_name' has to begin with 'SUPERVISOR', 'LINE-CARD' or 'FABRIC-CARD'")

fvs = {'admin_status': 'down'}
config_db.set_entry('CHASSIS_MODULE', chassis_module_name, fvs)

#
# 'startup' subcommand ('config chassis_modules startup ...')
#
@chassis_modules.command('startup')
@clicommon.pass_db
@click.argument('chassis_module_name', metavar='<module_name>', required=True)
def startup_chassis_module(db, chassis_module_name):
"""Chassis-module startup of module"""
config_db = db.cfgdb

config_db.set_entry('CHASSIS_MODULE', chassis_module_name, None)
Loading

0 comments on commit 37e29da

Please sign in to comment.