Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 48 additions & 56 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7120,6 +7120,50 @@ def disable():
# 'config interface ipv6 enable use-link-local-only <interface-name>'
#

def _get_ipv6_ll_intf_type(interface_name):
"""Map an interface name (full or shortname) to the CONFIG_DB table used
for ipv6_use_link_local_only.
"""
table_name = get_interface_table_name(interface_name)
if table_name in ("INTERFACE", "PORTCHANNEL_INTERFACE",
"VLAN_INTERFACE", "VLAN_SUB_INTERFACE"):
return table_name
return ""


def _validate_ipv6_ll_interface(ctx, db, interface_name, interface_type):
"""Shared validation for ipv6 link-local enable/disable commands."""
if not interface_type:
ctx.fail("'interface_name' is not valid. Valid names "
"[Ethernet/Eth/PortChannel/Po/Vlan/Sub-interface]")

if interface_type == "VLAN_INTERFACE":
if not clicommon.is_valid_vlan_interface(db, interface_name):
ctx.fail("Interface name %s is invalid."
" Please enter a valid interface name!!"
% (interface_name))
else:
if interface_name_is_valid(db, interface_name) is False:
ctx.fail("Interface name %s is invalid."
" Please enter a valid interface name!!"
% (interface_name))

is_sub_intf = VLAN_SUB_INTERFACE_SEPARATOR in interface_name
if not is_sub_intf:
portchannel_member_table = db.get_table('PORTCHANNEL_MEMBER')
if interface_is_in_portchannel(portchannel_member_table,
interface_name):
ctx.fail("{} is configured as a member of portchannel."
" Cannot configure the IPv6 link local mode!"
.format(interface_name))

vlan_member_table = db.get_table('VLAN_MEMBER')
if interface_is_in_vlan(vlan_member_table, interface_name):
ctx.fail("{} is configured as a member of vlan."
" Cannot configure the IPv6 link local mode!"
.format(interface_name))


@enable.command('use-link-local-only')
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
Expand All @@ -7132,34 +7176,8 @@ def enable_use_link_local_only(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

if interface_name.startswith("Ethernet"):
interface_type = "INTERFACE"
elif interface_name.startswith("PortChannel"):
interface_type = "PORTCHANNEL_INTERFACE"
elif interface_name.startswith("Vlan"):
interface_type = "VLAN_INTERFACE"
else:
ctx.fail("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan]")

if (interface_type == "INTERFACE" ) or (interface_type == "PORTCHANNEL_INTERFACE"):
if interface_name_is_valid(db, interface_name) is False:
ctx.fail("Interface name %s is invalid. Please enter a valid interface name!!" %(interface_name))

if (interface_type == "VLAN_INTERFACE"):
if not clicommon.is_valid_vlan_interface(db, interface_name):
ctx.fail("Interface name %s is invalid. Please enter a valid interface name!!" %(interface_name))

portchannel_member_table = db.get_table('PORTCHANNEL_MEMBER')

if interface_is_in_portchannel(portchannel_member_table, interface_name):
ctx.fail("{} is configured as a member of portchannel. Cannot configure the IPv6 link local mode!"
.format(interface_name))

vlan_member_table = db.get_table('VLAN_MEMBER')

if interface_is_in_vlan(vlan_member_table, interface_name):
ctx.fail("{} is configured as a member of vlan. Cannot configure the IPv6 link local mode!"
.format(interface_name))
interface_type = _get_ipv6_ll_intf_type(interface_name)
_validate_ipv6_ll_interface(ctx, db, interface_name, interface_type)

interface_dict = db.get_table(interface_type)
set_ipv6_link_local_only_on_interface(db, interface_dict, interface_type, interface_name, "enable")
Expand All @@ -7180,34 +7198,8 @@ def disable_use_link_local_only(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

interface_type = ""
if interface_name.startswith("Ethernet"):
interface_type = "INTERFACE"
elif interface_name.startswith("PortChannel"):
interface_type = "PORTCHANNEL_INTERFACE"
elif interface_name.startswith("Vlan"):
interface_type = "VLAN_INTERFACE"
else:
ctx.fail("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan]")

if (interface_type == "INTERFACE" ) or (interface_type == "PORTCHANNEL_INTERFACE"):
if interface_name_is_valid(db, interface_name) is False:
ctx.fail("Interface name %s is invalid. Please enter a valid interface name!!" %(interface_name))

if (interface_type == "VLAN_INTERFACE"):
if not clicommon.is_valid_vlan_interface(db, interface_name):
ctx.fail("Interface name %s is invalid. Please enter a valid interface name!!" %(interface_name))

portchannel_member_table = db.get_table('PORTCHANNEL_MEMBER')

if interface_is_in_portchannel(portchannel_member_table, interface_name):
ctx.fail("{} is configured as a member of portchannel. Cannot configure the IPv6 link local mode!"
.format(interface_name))

vlan_member_table = db.get_table('VLAN_MEMBER')
if interface_is_in_vlan(vlan_member_table, interface_name):
ctx.fail("{} is configured as a member of vlan. Cannot configure the IPv6 link local mode!"
.format(interface_name))
interface_type = _get_ipv6_ll_intf_type(interface_name)
_validate_ipv6_ll_interface(ctx, db, interface_name, interface_type)

interface_dict = db.get_table(interface_type)
set_ipv6_link_local_only_on_interface(db, interface_dict, interface_type, interface_name, "disable")
Expand Down
12 changes: 12 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,18 @@ def link_local_mode(namespace, verbose):
else:
body.append([port, 'Disabled'])

sub_intf_dict = config_db.get_table('VLAN_SUB_INTERFACE')
for sub_intf in sub_intf_dict.keys():
if not isinstance(sub_intf, tuple):
value = sub_intf_dict[sub_intf]
if 'ipv6_use_link_local_only' in value:
if value['ipv6_use_link_local_only'] == 'enable':
body.append([sub_intf, 'Enabled'])
else:
body.append([sub_intf, 'Disabled'])
else:
body.append([sub_intf, 'Disabled'])

click.echo(tabulate(body, header, tablefmt="grid"))

#
Expand Down
130 changes: 130 additions & 0 deletions tests/ipv6_link_local_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@
+------------------+----------+
| Vlan4000 | Disabled |
+------------------+----------+
| Vlan1111 | Disabled |
+------------------+----------+
| Ethernet0.10 | Disabled |
+------------------+----------+
| Eth36.10 | Disabled |
+------------------+----------+
| Po0001.10 | Disabled |
+------------------+----------+
"""

class TestIPv6LinkLocal(object):
Expand Down Expand Up @@ -224,6 +232,128 @@ def test_config_enable_disable_ipv6_link_local_on_all_valid_interfaces(self):
assert result.exit_code == 0
assert result.output == ''

def test_config_enable_disable_ipv6_link_local_on_sub_interface(self):
runner = CliRunner()
db = Db()
obj = {'config_db': db.cfgdb}

enable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["enable"]
.commands["use-link-local-only"])
disable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["disable"]
.commands["use-link-local-only"])

result = runner.invoke(enable_cmd, ["Ethernet0.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

result = runner.invoke(disable_cmd, ["Ethernet0.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

def test_config_enable_disable_ipv6_link_local_on_shortname_sub_interface(self):
runner = CliRunner()
db = Db()
obj = {'config_db': db.cfgdb}

enable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["enable"]
.commands["use-link-local-only"])
disable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["disable"]
.commands["use-link-local-only"])

result = runner.invoke(enable_cmd, ["Eth36.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

result = runner.invoke(disable_cmd, ["Eth36.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

result = runner.invoke(enable_cmd, ["Po0001.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

result = runner.invoke(disable_cmd, ["Po0001.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == ''

def test_config_enable_ipv6_link_local_on_nonexistent_sub_interface(self):
runner = CliRunner()
db = Db()
obj = {'config_db': db.cfgdb}

enable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["enable"]
.commands["use-link-local-only"])

result = runner.invoke(enable_cmd, ["Ethernet0.999"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code != 0
assert ('invalid' in result.output.lower()
or 'Invalid' in result.output)

def test_config_enable_ipv6_link_local_on_nonexistent_shortname(self):
runner = CliRunner()
db = Db()
obj = {'config_db': db.cfgdb}

enable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["enable"]
.commands["use-link-local-only"])

result = runner.invoke(enable_cmd, ["Eth99.99"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code != 0
assert 'invalid' in result.output.lower()

def test_config_enable_ipv6_link_local_on_bogus_prefix(self):
runner = CliRunner()
db = Db()
obj = {'config_db': db.cfgdb}

enable_cmd = (config.config.commands["interface"]
.commands["ipv6"].commands["enable"]
.commands["use-link-local-only"])

result = runner.invoke(enable_cmd, ["Et36.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code != 0
assert 'not valid' in result.output

result = runner.invoke(enable_cmd, ["Foo0.10"], obj=obj)
print(result.exit_code)
print(result.output)
assert result.exit_code != 0
assert 'not valid' in result.output

def test_show_ipv6_link_local_mode_includes_sub_interfaces(self):
runner = CliRunner()
db = Db()
obj = {'db': db.cfgdb}

show_cmd = show.cli.commands["ipv6"].commands["link-local-mode"]
result = runner.invoke(show_cmd, [], obj=obj)
print(result.output)
assert 'Ethernet0.10' in result.output

def test_vlan_member_add_on_link_local_interface(self):
runner = CliRunner()
db = Db()
Expand Down
Loading