Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CLI Support for IPv6 Helpers and DHCPv6 Relay Counters #8593

Merged
merged 14 commits into from
Sep 24, 2021
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import show.main as show
from click.testing import CliRunner


expected_counts = """\
Message Type
-------------- --
Solicit
Advertise
Request
Confirm
Renew
Rebind
Reply
Release
Decline
Relay-Forward
Relay-Reply

"""
class TestDhcp6RelayCounters(object):

def test_show_counts(self):
runner = CliRunner()
#runner.invoke(clear.cli.commands["dhcp6relay-counters"], [])
kellyyeh marked this conversation as resolved.
Show resolved Hide resolved
result = runner.invoke(show.cli.commands["dhcp6relay-counters"].commands["counts"], [])
print(result.output)
assert result.output == expected_counts

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import subprocess
import show.main as show
from click.testing import CliRunner

expected_table = """\
-------- ------------
Vlan1000 fc02:2000::1
-------- ------------

"""
class TestDhcpRelayHelper(object):

def test_show_dhcpv6_helper(self):
runner = CliRunner()
subprocess.run('sonic-db-cli CONFIG_DB hmset "DHCP_RELAY|Vlan1000" "fc02:2000::1"', shell=True)
result = runner.invoke(show.cli.commands["dhcp_relay_helper"].commands["ipv6"], [])
print(result.output)
assert result.output == expected_table

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import sys
import click
sys.path.insert(0, '../../show/plugins/')
from show_dhcp6relay_counters import DHCPv6_Counter


# sonic-clear dhcp6relay_counters
@click.command('dhcp6relay_counters')
@click.option('-i', '--interface', required=False)
def dhcp6relay_clear_counters(interface):
""" Clear dhcp6relay message counts """

counter = DHCPv6_Counter()
counter_intf = counter.get_interface()

if interface:
counter.clear_table(interface)
else:
for intf in counter_intf:
counter.clear_table(intf)

def register(cli):
cli.add_command(dhcp6relay_clear_counters)

if __name__ == '__main__':
dhcp6relay_clear_counters()
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import click
import utilities_common.cli as clicommon

from tabulate import tabulate

from swsscommon.swsscommon import SonicV2Connector


# STATE_DB Table
DHCPv6_COUNTER_TABLE = 'DHCPv6_COUNTER_TABLE'

# DHCPv6 Counter Messages
messages = ["Solicit", "Advertise", "Request", "Confirm", "Renew", "Rebind", "Reply", "Release", "Decline", "Relay-Forward", "Relay-Reply"]

class DHCPv6_Counter(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please add code comment

def __init__(self):
self.db = SonicV2Connector(use_unix_socket_path=False)
self.db.connect(self.db.STATE_DB)
self.table_name = DHCPv6_COUNTER_TABLE + self.db.get_db_separator(self.db.STATE_DB)


def get_interface(self):
""" Get all names of all interfaces in DHCPv6_COUNTER_TABLE """
vlans = []
for key in self.db.keys(self.db.STATE_DB):
if DHCPv6_COUNTER_TABLE in key:
vlans.append(key[21:])
return vlans


def get_dhcp6relay_msg_count(self, interface, msg):
""" Get count of a dhcp6relay message """
count = self.db.get(self.db.STATE_DB, self.table_name + str(interface), str(msg))
data = [str(msg), count]
return data


def clear_table(self, interface):
""" Reset all message counts to 0 """
for msg in messages:
self.db.set(self.db.STATE_DB, self.table_name + str(interface), str(msg), '0')

def print_count(counter, intf):
data = []
for i in messages:
data.append(counter.get_dhcp6relay_msg_count(intf, i))
print(tabulate(data, headers = ["Message Type", intf], tablefmt='simple', stralign='right') + "\n")


#
# 'dhcp6relay_counters' group ###
#


@click.group(cls=clicommon.AliasedGroup)
def dhcp6relay_counters():
"""Show DHCPv6 counter"""
pass


# 'counts' subcommand ("show dhcp6relay_counters counts")
@dhcp6relay_counters.command('counts')
@click.option('-i', '--interface', required=False)
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def counts(interface, verbose):
"""Show dhcp6relay message counts"""

counter = DHCPv6_Counter()
counter_intf = counter.get_interface()

if interface:
print_count(counter, interface)
else:
for intf in counter_intf:
print_count(counter, intf)


def register(cli):
cli.add_command(dhcp6relay_counters)

if __name__ == '__main__':
dhcp6relay_counters()
35 changes: 35 additions & 0 deletions dockers/docker-dhcp-relay/cli/show/plugins/show_dhcpv6_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import click
from tabulate import tabulate
from swsscommon.swsscommon import ConfigDBConnector

import utilities_common.cli as clicommon

DHCP_RELAY = 'DHCP_RELAY'

@click.group(cls=clicommon.AliasedGroup, name="dhcp_relay_helper")
def dhcp_relay_helper():
"""Show DHCP_Relay helper information"""
pass

@dhcp_relay_helper.command('ipv6')
def get_dhcpv6_helper_address():
config_db = ConfigDBConnector()
if config_db is not None:
config_db.connect()
table_data = config_db.get_table(DHCP_RELAY)
if table_data is not None:
for vlan in config_db.get_keys(DHCP_RELAY):
vlan_data = table_data.get(vlan)
helpers_data = vlan_data.get('dhcpv6_server')
if helpers_data is not None:
addr = {vlan:[]}
for ip in helpers_data.split(','):
addr[vlan].append(ip)
print(tabulate({'Interface':[vlan], vlan:addr.get(vlan)}, tablefmt='simple', stralign='right') + '\n')

def register(cli):
cli.add_command(dhcp_relay_helper)

if __name__ == '__main__':
dhcp_relay_helper()

3 changes: 2 additions & 1 deletion files/build_templates/manifest.json.j2
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"cli": {
"config": "{{ config_cli_plugin|default('') }}",
"show": "{{ show_cli_plugin|default('') }}"
"show": "{{ show_cli_plugin|default('') }}",
"clear": "{{ clear_cli_plugin|default('') }}"
}
}
3 changes: 3 additions & 0 deletions rules/docker-dhcp-relay.mk
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@ $(DOCKER_DHCP_RELAY)_CONTAINER_TMPFS += /var/tmp/

$(DOCKER_DHCP_RELAY)_CLI_CONFIG_PLUGIN = /cli/config/plugins/dhcp_relay.py
$(DOCKER_DHCP_RELAY)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_dhcp_relay.py
$(DOCKER_DHCP_RELAY)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_dhcp6relay_counters.py
$(DOCKER_DHCP_RELAY)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_dhcpv6_helper.py
$(DOCKER_DHCP_RELAY)_CLI_CLEAR_PLUGIN = /cli/clear/plugins/clear_dhcp6relay_counter.py

$(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
1 change: 1 addition & 0 deletions rules/functions
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ define generate_manifest
$(eval export tmpfs=$($(1).gz_CONTAINER_TMPFS))
$(eval export config_cli_plugin=$($(1).gz_CLI_CONFIG_PLUGIN))
$(eval export show_cli_plugin=$($(1).gz_CLI_SHOW_PLUGIN))
$(eval export clear_cli_plugin=$($(1).gz_CLI_CLEAR_PLUGIN))
j2 $($*.gz_PATH)/Dockerfile$(2).j2 > $($(1).gz_PATH)/Dockerfile$(2)
j2 --customize scripts/j2cli/json_filter.py files/build_templates/manifest.json.j2 > $($(1).gz_PATH)/manifest.common.json
if [ -f $($*.gz_PATH)/manifest.part.json.j2 ]; then
Expand Down