Skip to content

Commit

Permalink
Merge branch 'master' into dev-logrotate-config
Browse files Browse the repository at this point in the history
  • Loading branch information
fastiuk committed Nov 11, 2024
2 parents d7cbec9 + 093ed4a commit 6dab93b
Show file tree
Hide file tree
Showing 36 changed files with 1,127 additions and 428 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ stages:
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo apt-add-repository https://packages.microsoft.com/debian/11/prod
sudo apt-get update
sudo apt-get install -y dotnet-sdk-5.0
sudo apt-get install -y dotnet-sdk-8.0
displayName: "Install .NET CORE"
- script: |
Expand Down
182 changes: 173 additions & 9 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,19 @@ def multiasic_write_to_db(filename, load_sysinfo):
migrate_db_to_lastest(ns)


def config_file_yang_validation(filename):
config_to_check = read_json_file(filename)
sy = sonic_yang.SonicYang(YANG_DIR)
sy.loadYangModel()
try:
sy.loadData(configdbJson=config_to_check)
sy.validate_data_tree()
except sonic_yang.SonicYangException as e:
click.secho("{} fails YANG validation! Error: {}".format(filename, str(e)),
fg='magenta')
raise click.Abort()


# This is our main entrypoint - the main 'config' command
@click.group(cls=clicommon.AbbreviationGroup, context_settings=CONTEXT_SETTINGS)
@click.pass_context
Expand Down Expand Up @@ -1810,6 +1823,13 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
click.echo("Input {} config file(s) separated by comma for multiple files ".format(num_cfg_file))
return

if filename is not None and filename != "/dev/stdin":
if multi_asic.is_multi_asic():
# Multiasic has not 100% fully validated. Thus pass here.
pass
else:
config_file_yang_validation(filename)

#Stop services before config push
if not no_service_restart:
log.log_notice("'reload' stopping services...")
Expand Down Expand Up @@ -2000,15 +2020,7 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config,
# Multiasic has not 100% fully validated. Thus pass here.
pass
else:
sy = sonic_yang.SonicYang(YANG_DIR)
sy.loadYangModel()
try:
sy.loadData(configdbJson=config_to_check)
sy.validate_data_tree()
except sonic_yang.SonicYangException as e:
click.secho("{} fails YANG validation! Error: {}".format(golden_config_path, str(e)),
fg='magenta')
raise click.Abort()
config_file_yang_validation(golden_config_path)

# Dependency check golden config json
if multi_asic.is_multi_asic():
Expand Down Expand Up @@ -4236,6 +4248,105 @@ def del_user(db, user):
click.echo("Restart service snmp failed with error {}".format(e))
raise click.Abort()


#
# 'bmp' group ('config bmp ...')
#
@config.group()
@clicommon.pass_db
def bmp(db):
"""BMP-related configuration"""
pass


#
# common function to update bmp config table
#
@clicommon.pass_db
def update_bmp_table(db, table_name, value):
log.log_info(f"'bmp {value} {table_name}' executing...")
bmp_table = db.cfgdb.get_table('BMP')
if not bmp_table:
bmp_table = {'table': {table_name: value}}
else:
bmp_table['table'][table_name] = value
db.cfgdb.mod_entry('BMP', 'table', bmp_table['table'])


#
# 'enable' subgroup ('config bmp enable ...')
#
@bmp.group()
@clicommon.pass_db
def enable(db):
"""Enable BMP table dump """
pass


#
# 'bgp-neighbor-table' command ('config bmp enable bgp-neighbor-table')
#
@enable.command('bgp-neighbor-table')
@clicommon.pass_db
def enable_bgp_neighbor_table(db):
update_bmp_table('bgp_neighbor_table', 'true')


#
# 'bgp-rib-out-table' command ('config bmp enable bgp-rib-out-table')
#
@enable.command('bgp-rib-out-table')
@clicommon.pass_db
def enable_bgp_rib_out_table(db):
update_bmp_table('bgp_rib_out_table', 'true')


#
# 'bgp-rib-in-table' command ('config bmp enable bgp-rib-in-table')
#
@enable.command('bgp-rib-in-table')
@clicommon.pass_db
def enable_bgp_rib_in_table(db):
update_bmp_table('bgp_rib_in_table', 'true')


#
# 'disable' subgroup ('config bmp disable ...')
#
@bmp.group()
@clicommon.pass_db
def disable(db):
"""Disable BMP table dump """
pass


#
# 'bgp-neighbor-table' command ('config bmp disable bgp-neighbor-table')
#
@disable.command('bgp-neighbor-table')
@clicommon.pass_db
def disable_bgp_neighbor_table(db):
update_bmp_table('bgp_neighbor_table', 'false')


#
# 'bgp-rib-out-table' command ('config bmp disable bgp-rib-out-table')
#
@disable.command('bgp-rib-out-table')
@clicommon.pass_db
def diable_bgp_rib_out_table(db):
update_bmp_table('bgp_rib_out_table', 'false')


#
# 'bgp-rib-in-table' command ('config bmp disable bgp-rib-in-table')
#
@disable.command('bgp-rib-in-table')
@clicommon.pass_db
def disable_bgp_rib_in_table(db):
update_bmp_table('bgp_rib_in_table', 'false')


#
# 'bgp' group ('config bgp ...')
#
Expand Down Expand Up @@ -8053,6 +8164,59 @@ def max_sessions(max_sessions):
{'max_sessions': max_sessions})


#
# 'banner' group ('config banner ...')
#
@config.group()
def banner():
"""Configuring system banner messages"""
pass


@banner.command()
@click.argument('state', metavar='<enabled|disabled>', required=True, type=click.Choice(['enabled', 'disabled']))
def state(state):
"""Set banner feature state"""

config_db = ConfigDBConnector()
config_db.connect()
config_db.mod_entry(swsscommon.CFG_BANNER_MESSAGE_TABLE_NAME, 'global',
{'state': state})


@banner.command()
@click.argument('message', metavar='<message>', required=True)
def login(message):
"""Set login message"""

config_db = ConfigDBConnector()
config_db.connect()
config_db.mod_entry(swsscommon.CFG_BANNER_MESSAGE_TABLE_NAME, 'global',
{'login': message})


@banner.command()
@click.argument('message', metavar='<message>', required=True)
def logout(message):
"""Set logout message"""

config_db = ConfigDBConnector()
config_db.connect()
config_db.mod_entry(swsscommon.CFG_BANNER_MESSAGE_TABLE_NAME, 'global',
{'logout': message})


@banner.command()
@click.argument('message', metavar='<message>', required=True)
def motd(message):
"""Set message of the day"""

config_db = ConfigDBConnector()
config_db.connect()
config_db.mod_entry(swsscommon.CFG_BANNER_MESSAGE_TABLE_NAME, 'global',
{'motd': message})


#
# 'logrotate' group ('config logrotate ...')
#
Expand Down
34 changes: 0 additions & 34 deletions config/plugins/mlnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,40 +164,6 @@ def mlnx():
""" Mellanox platform configuration tasks """
pass


# 'sniffer' group
@mlnx.group()
def sniffer():
""" Utility for managing Mellanox SDK/PRM sniffer """
pass


# 'sdk' subgroup
@sniffer.group()
def sdk():
"""SDK Sniffer - Command Line to enable/disable SDK sniffer"""
pass


@sdk.command()
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false, expose_value=False,
prompt='Swss service will be restarted, continue?')
def enable():
"""Enable SDK Sniffer"""
click.echo("Enabling SDK sniffer")
sdk_sniffer_enable()
click.echo("Note: the sniffer file may exhaust the space on /var/log, please disable it when you are done with this sniffering.")


@sdk.command()
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false, expose_value=False,
prompt='Swss service will be restarted, continue?')
def disable():
"""Disable SDK Sniffer"""
click.echo("Disabling SDK sniffer")
sdk_sniffer_disable()


def sdk_sniffer_enable():
"""Enable SDK Sniffer"""
sdk_sniffer_filename = sniffer_filename_generate(SDK_SNIFFER_TARGET_PATH,
Expand Down
54 changes: 54 additions & 0 deletions config/syslog.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,3 +642,57 @@ def disable_rate_limit_feature(db, service_name, namespace):

if not failed:
click.echo(f'Disabled syslog rate limit feature for {feature_name}')


@syslog.command('level')
@click.option("-i", "--identifier",
required=True,
help="Log identifier in DB for which loglevel is applied (provided with -l)")
@click.option("-l", "--level",
required=True,
help="Loglevel value",
type=click.Choice(['DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERROR']))
@click.option("--container",
help="Container name to which the SIGHUP is sent (provided with --pid or --program)")
@click.option("--program",
help="Program name to which the SIGHUP is sent (provided with --container)")
@click.option("--pid",
help="Process ID to which the SIGHUP is sent (provided with --container if PID is from container)")
@click.option('--namespace', '-n', 'namespace', default=None,
type=click.Choice(multi_asic_util.multi_asic_ns_choices()),
show_default=True, help='Namespace name')
@clicommon.pass_db
def level(db, identifier, level, container, program, pid, namespace):
""" Configure log level """
if program and not container:
raise click.UsageError('--program must be specified with --container')

if container and not program and not pid:
raise click.UsageError('--container must be specified with --pid or --program')

if not namespace:
cfg_db = db.cfgdb
else:
asic_id = multi_asic.get_asic_id_from_name(namespace)
container = f'{container}{asic_id}'
cfg_db = db.cfgdb_clients[namespace]

cfg_db.mod_entry('LOGGER', identifier, {'LOGLEVEL': level})
if not container and not program and not pid:
return

log_config = cfg_db.get_entry('LOGGER', identifier)
require_manual_refresh = log_config.get('require_manual_refresh')
if not require_manual_refresh:
return

if container:
if program:
command = ['docker', 'exec', '-i', container, 'supervisorctl', 'signal', 'HUP', program]
else:
command = ['docker', 'exec', '-i', container, 'kill', '-s', 'SIGHUP', pid]
else:
command = ['kill', '-s', 'SIGHUP', pid]
output, ret = clicommon.run_command(command, return_cmd=True)
if ret != 0:
raise click.ClickException(f'Failed: {output}')
Loading

0 comments on commit 6dab93b

Please sign in to comment.