Skip to content

Commit

Permalink
add mirror session use case
Browse files Browse the repository at this point in the history
  • Loading branch information
isabelmsft committed Oct 8, 2022
1 parent a817896 commit ab72eef
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 21 deletions.
68 changes: 47 additions & 21 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ def validate_mirror_session_config(config_db, session_name, dst_port, src_port,
""" Check if SPAN mirror-session config is valid """
ctx = click.get_current_context()
if len(config_db.get_entry('MIRROR_SESSION', session_name)) != 0:
click.echo("Error: {} already exists".format(session_name))
click.echo("Error: {} already exists".format(session_name)) # TODO: MISSING CONSTRAINT IN YANG MODEL
return False

vlan_member_table = config_db.get_table('VLAN_MEMBER')
Expand Down Expand Up @@ -2333,25 +2333,35 @@ def add_erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer
session_info['gre_type'] = gre_type

session_info = gather_session_info(session_info, policer, queue, src_port, direction)
ctx = click.get_current_context()

"""
For multi-npu platforms we need to program all front asic namespaces
"""
namespaces = multi_asic.get_all_namespaces()
if not namespaces['front_ns']:
config_db = ConfigDBConnector()
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
config_db.connect()
if validate_mirror_session_config(config_db, session_name, None, src_port, direction) is False:
return
config_db.set_entry("MIRROR_SESSION", session_name, session_info)
if ADHOC_VALIDATION:
if validate_mirror_session_config(config_db, session_name, None, src_port, direction) is False:
return
try:
config_db.set_entry("MIRROR_SESSION", session_name, session_info)
except ValueError as e:
ctx.fail("Invalid mirror session config. Error: {}".format(e))

else:
per_npu_configdb = {}
for front_asic_namespaces in namespaces['front_ns']:
per_npu_configdb[front_asic_namespaces] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces)
per_npu_configdb[front_asic_namespaces] = ValidatedConfigDBConnector(ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces))
per_npu_configdb[front_asic_namespaces].connect()
if validate_mirror_session_config(per_npu_configdb[front_asic_namespaces], session_name, None, src_port, direction) is False:
return
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info)
if ADHOC_VALIDATION:
if validate_mirror_session_config(per_npu_configdb[front_asic_namespaces], session_name, None, src_port, direction) is False:
return
try:
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info)
except ValueError as e:
ctx.fail("Invalid mirror session config. Error: {}".format(e))

@mirror_session.group(cls=clicommon.AbbreviationGroup, name='span')
@click.pass_context
Expand Down Expand Up @@ -2383,25 +2393,34 @@ def add_span(session_name, dst_port, src_port, direction, queue, policer):
}

session_info = gather_session_info(session_info, policer, queue, src_port, direction)
ctx = click.get_current_context()

"""
For multi-npu platforms we need to program all front asic namespaces
"""
namespaces = multi_asic.get_all_namespaces()
if not namespaces['front_ns']:
config_db = ConfigDBConnector()
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
config_db.connect()
if validate_mirror_session_config(config_db, session_name, dst_port, src_port, direction) is False:
return
config_db.set_entry("MIRROR_SESSION", session_name, session_info)
if ADHOC_VALIDATION:
if validate_mirror_session_config(config_db, session_name, dst_port, src_port, direction) is False:
return
try:
config_db.set_entry("MIRROR_SESSION", session_name, session_info)
except ValueError as e:
ctx.fail("Invalid mirror session config. Error: {}".format(e))
else:
per_npu_configdb = {}
for front_asic_namespaces in namespaces['front_ns']:
per_npu_configdb[front_asic_namespaces] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces)
per_npu_configdb[front_asic_namespaces] = ValidatedConfigDBConnector(ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces))
per_npu_configdb[front_asic_namespaces].connect()
if validate_mirror_session_config(per_npu_configdb[front_asic_namespaces], session_name, dst_port, src_port, direction) is False:
return
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info)
if ADHOC_VALIDATION:
if validate_mirror_session_config(per_npu_configdb[front_asic_namespaces], session_name, dst_port, src_port, direction) is False:
return
try:
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info)
except ValueError as e:
ctx.fail("Invalid mirror session config. Error: {}".format(e))


@mirror_session.command()
Expand All @@ -2413,16 +2432,23 @@ def remove(session_name):
For multi-npu platforms we need to program all front asic namespaces
"""
namespaces = multi_asic.get_all_namespaces()
ctx = click.get_current_context()
if not namespaces['front_ns']:
config_db = ConfigDBConnector()
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
config_db.connect()
config_db.set_entry("MIRROR_SESSION", session_name, None)
try:
config_db.set_entry("MIRROR_SESSION", session_name, None)
except JsonPatchConflict:
ctx.fail("Failed to remove MIRROR_SESSION {}".format(session_name))
else:
per_npu_configdb = {}
for front_asic_namespaces in namespaces['front_ns']:
per_npu_configdb[front_asic_namespaces] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces)
per_npu_configdb[front_asic_namespaces] = ValidatedConfigDBConnector(ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces))
per_npu_configdb[front_asic_namespaces].connect()
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, None)
try:
per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, None)
except JsonPatchConflict:
ctx.fail("Failed to remove MIRROR_SESSION {}".format(session_name))

#
# 'pfcwd' group ('config pfcwd ...')
Expand Down
17 changes: 17 additions & 0 deletions config/validated_config_db_connector.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import jsonpatch
import subprocess
from jsonpointer import JsonPointer

from sonic_py_common import device_info
Expand All @@ -12,6 +13,15 @@ def ValidatedConfigDBConnector(config_db_connector):
config_db_connector.delete_table = validated_delete_table
return config_db_connector

def is_table_present_config_db(table):
cmd = "sonic-cfggen -d --print-data"
result = subprocess.Popen(cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
text, err = result.communicate()
return_code = result.returncode
if return_code: # non-zero means failure
raise Exception(f"Failed to get running config, Return code: {return_code}, Error: {err}")
return table in text

def make_path_value_jsonpatch_compatible(table, key, value):
if type(key) == tuple:
path = JsonPointer.from_parts([table, '|'.join(key)]).path
Expand All @@ -22,6 +32,13 @@ def make_path_value_jsonpatch_compatible(table, key, value):
return path, value

def create_gcu_patch(op, table, key=None, value=None):
gcu_json_input = []
if op == "add" and not is_table_present_config_db(table):
gcu_json = {"op": "{}".format(op),
"path": "/{}".format(table),
"value": {}}
gcu_json_input.append(gcu_json)

if key:
path, value = make_path_value_jsonpatch_compatible(table, key, value)
else:
Expand Down

0 comments on commit ab72eef

Please sign in to comment.