Skip to content

Commit e310ed3

Browse files
Junchao-Mellanoxmssonicbld
authored andcommitted
Support disable/enable syslog rate limit feature (sonic-net#3072)
Depends on PR sonic-net/sonic-buildimage#17458 What I did Add CLIs to enable/disable containercfgd to optimize warm/fast boot path How I did it Add CLIs to enable/disable containercfgd How to verify it unit test manual test
1 parent b0908bd commit e310ed3

File tree

3 files changed

+196
-0
lines changed

3 files changed

+196
-0
lines changed

config/syslog.py

+83
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,86 @@ def rate_limit_container(db, service_name, interval, burst):
471471
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
472472
syslog_common.service_validator(feature_data, service_name)
473473
syslog_common.save_rate_limit_to_db(db, service_name, interval, burst, log)
474+
475+
476+
@syslog.group(
477+
name="rate-limit-feature",
478+
cls=clicommon.AliasedGroup
479+
)
480+
def rate_limit_feature():
481+
""" Configure syslog rate limit feature """
482+
pass
483+
484+
485+
@rate_limit_feature.command("enable")
486+
@clicommon.pass_db
487+
def enable_rate_limit_feature(db):
488+
""" Enable syslog rate limit feature """
489+
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
490+
for feature_name in feature_data.keys():
491+
click.echo(f'Enabling syslog rate limit feature for {feature_name}')
492+
output, _ = clicommon.run_command(['docker', 'ps', '-q', '-f', 'status=running', '-f', f'name={feature_name}'], return_cmd=True)
493+
if not output:
494+
click.echo(f'{feature_name} is not running, ignoring...')
495+
continue
496+
497+
output, _ = clicommon.run_command(['docker', 'exec', '-i', feature_name, 'supervisorctl', 'status', 'containercfgd'],
498+
ignore_error=True, return_cmd=True)
499+
if 'no such process' not in output:
500+
click.echo(f'Syslog rate limit feature is already enabled in {feature_name}, ignoring...')
501+
continue
502+
503+
commands = [
504+
['docker', 'cp', '/usr/share/sonic/templates/containercfgd.conf', f'{feature_name}:/etc/supervisor/conf.d/'],
505+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'reread'],
506+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'update'],
507+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'start', 'containercfgd']
508+
]
509+
510+
failed = False
511+
for command in commands:
512+
output, ret = clicommon.run_command(command, return_cmd=True)
513+
if ret != 0:
514+
failed = True
515+
click.echo(f'Enable syslog rate limit feature for {feature_name} failed - {output}')
516+
break
517+
518+
if not failed:
519+
click.echo(f'Enabled syslog rate limit feature for {feature_name}')
520+
521+
522+
@rate_limit_feature.command("disable")
523+
@clicommon.pass_db
524+
def disable_rate_limit_feature(db):
525+
""" Disable syslog rate limit feature """
526+
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
527+
for feature_name in feature_data.keys():
528+
click.echo(f'Disabling syslog rate limit feature for {feature_name}')
529+
output, _ = clicommon.run_command(['docker', 'ps', '-q', '-f', 'status=running', '-f', f'name={feature_name}'], return_cmd=True)
530+
if not output:
531+
click.echo(f'{feature_name} is not running, ignoring...')
532+
continue
533+
534+
output, _ = clicommon.run_command(['docker', 'exec', '-i', feature_name, 'supervisorctl', 'status', 'containercfgd'],
535+
ignore_error=True, return_cmd=True)
536+
if 'no such process' in output:
537+
click.echo(f'Syslog rate limit feature is already disabled in {feature_name}, ignoring...')
538+
continue
539+
540+
commands = [
541+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'stop', 'containercfgd'],
542+
['docker', 'exec', '-i', feature_name, 'rm', '-f', '/etc/supervisor/conf.d/containercfgd.conf'],
543+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'reread'],
544+
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'update']
545+
]
546+
failed = False
547+
for command in commands:
548+
output, ret = clicommon.run_command(command, return_cmd=True)
549+
if ret != 0:
550+
failed = True
551+
click.echo(f'Disable syslog rate limit feature for {feature_name} failed - {output}')
552+
break
553+
554+
if not failed:
555+
click.echo(f'Disabled syslog rate limit feature for {feature_name}')
556+

doc/Command-Reference.md

+27
Original file line numberDiff line numberDiff line change
@@ -9893,6 +9893,33 @@ This command is used to configure syslog rate limit for containers.
98939893
admin@sonic:~$ sudo config syslog rate-limit-container bgp --interval 300 --burst 20000
98949894
```
98959895
9896+
**config syslog rate-limit-feature enable**
9897+
9898+
This command is used to enable syslog rate limit feature.
9899+
9900+
- Usage:
9901+
```
9902+
config syslog rate-limit-feature enable
9903+
```
9904+
9905+
- Example:
9906+
```
9907+
admin@sonic:~$ sudo config syslog rate-limit-feature enable
9908+
```
9909+
9910+
**config syslog rate-limit-feature disable**
9911+
9912+
This command is used to disable syslog rate limit feature.
9913+
9914+
- Usage:
9915+
```
9916+
config syslog rate-limit-feature disable
9917+
```
9918+
9919+
- Example:
9920+
```
9921+
admin@sonic:~$ sudo config syslog rate-limit-feature disable
9922+
```
98969923
98979924
Go Back To [Beginning of the document](#) or [Beginning of this section](#syslog)
98989925

tests/syslog_test.py

+86
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,89 @@ def test_show_syslog_rate_limit_container_negative(self, subcommand):
399399
logger.debug("\n" + result.output)
400400
logger.debug(result.exit_code)
401401
assert result.exit_code != SUCCESS
402+
403+
@mock.patch('config.syslog.clicommon.run_command')
404+
def test_enable_syslog_rate_limit_feature(self, mock_run):
405+
db = Db()
406+
db.cfgdb.set_entry(FEATURE_TABLE, 'bgp', {SUPPORT_RATE_LIMIT: 'true',
407+
'state': 'enabled'})
408+
409+
runner = CliRunner()
410+
411+
mock_run.return_value = ('no such process', 0)
412+
result = runner.invoke(
413+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["enable"], obj=db
414+
)
415+
assert result.exit_code == SUCCESS
416+
417+
# container not run
418+
mock_run.return_value = ('', 0)
419+
result = runner.invoke(
420+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["enable"], obj=db
421+
)
422+
assert result.exit_code == SUCCESS
423+
424+
# process already running
425+
mock_run.return_value = ('something', 0)
426+
result = runner.invoke(
427+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["enable"], obj=db
428+
)
429+
assert result.exit_code == SUCCESS
430+
431+
# one command fail
432+
def side_effect(*args, **kwargs):
433+
side_effect.call_count += 1
434+
if side_effect.call_count <= 2:
435+
return 'no such process', 0
436+
else:
437+
return '', -1
438+
side_effect.call_count = 0
439+
mock_run.side_effect = side_effect
440+
result = runner.invoke(
441+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["enable"], obj=db
442+
)
443+
assert result.exit_code == SUCCESS
444+
445+
446+
@mock.patch('config.syslog.clicommon.run_command')
447+
def test_disable_syslog_rate_limit_feature(self, mock_run):
448+
db = Db()
449+
db.cfgdb.set_entry(FEATURE_TABLE, 'bgp', {SUPPORT_RATE_LIMIT: 'true',
450+
'state': 'enabled'})
451+
452+
runner = CliRunner()
453+
454+
mock_run.return_value = ('something', 0)
455+
result = runner.invoke(
456+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["disable"], obj=db
457+
)
458+
assert result.exit_code == SUCCESS
459+
460+
# container not run
461+
mock_run.return_value = ('', 0)
462+
result = runner.invoke(
463+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["disable"], obj=db
464+
)
465+
assert result.exit_code == SUCCESS
466+
467+
# process already stopped
468+
mock_run.return_value = ('no such process', 0)
469+
result = runner.invoke(
470+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["disable"], obj=db
471+
)
472+
assert result.exit_code == SUCCESS
473+
474+
# one command fail
475+
def side_effect(*args, **kwargs):
476+
side_effect.call_count += 1
477+
if side_effect.call_count <= 2:
478+
return 'something', 0
479+
else:
480+
return '', -1
481+
side_effect.call_count = 0
482+
mock_run.side_effect = side_effect
483+
result = runner.invoke(
484+
config.config.commands["syslog"].commands["rate-limit-feature"].commands["disable"], obj=db
485+
)
486+
assert result.exit_code == SUCCESS
487+

0 commit comments

Comments
 (0)