Skip to content

Commit 17dca33

Browse files
committed
Add portchannel mac-addr set command
1 parent fb2e5cd commit 17dca33

File tree

3 files changed

+86
-6
lines changed

3 files changed

+86
-6
lines changed

config/main.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,6 +2435,7 @@ def remove_portchannel(ctx, portchannel_name):
24352435
ctx.fail("Error: Portchannel {} contains members. Remove members before deleting Portchannel!".format(portchannel_name))
24362436

24372437
try:
2438+
db.set_entry('PORTCHANNEL_INTERFACE', portchannel_name, None)
24382439
db.set_entry('PORTCHANNEL', portchannel_name, None)
24392440
except JsonPatchConflict:
24402441
ctx.fail("{} is not present.".format(portchannel_name))
@@ -2673,6 +2674,38 @@ def set_portchannel_retry_count(ctx, portchannel_name, retry_count):
26732674
ctx.fail("Unable to set the retry count: {}".format(e))
26742675

26752676

2677+
@portchannel.group(cls=clicommon.AbbreviationGroup, name='mac-addr')
2678+
@click.pass_context
2679+
def portchannel_mac_addr(ctx):
2680+
pass
2681+
2682+
2683+
@portchannel_mac_addr.command('set')
2684+
@click.argument('portchannel_name', metavar='<portchannel_name>', required=True)
2685+
@click.argument('mac_addr', metavar='<mac_addr>', required=True)
2686+
@click.pass_context
2687+
def set_portchannel_mac_addr(ctx, portchannel_name, mac_addr):
2688+
"""Set the mac address for a port channel"""
2689+
db = ValidatedConfigDBConnector(ctx.obj['db'])
2690+
2691+
# Don't proceed if the port channel name is not valid
2692+
if is_portchannel_name_valid(portchannel_name) is False:
2693+
ctx.fail("{} is invalid!, name should have prefix '{}' and suffix '{}'"
2694+
.format(portchannel_name, CFG_PORTCHANNEL_PREFIX, CFG_PORTCHANNEL_NO))
2695+
2696+
# Don't proceed if the port channel does not exist
2697+
if is_portchannel_present_in_db(db, portchannel_name) is False:
2698+
ctx.fail("{} is not present.".format(portchannel_name))
2699+
2700+
if not re.match("^[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", mac_addr.lower()):
2701+
ctx.fail("Provided mac address is not valid")
2702+
2703+
try:
2704+
db.set_entry("PORTCHANNEL_INTERFACE", portchannel_name, {"mac_addr": mac_addr})
2705+
except ValueError:
2706+
ctx.fail("Portchannel name is invalid or nonexistent")
2707+
2708+
26762709
#
26772710
# 'mirror_session' group ('config mirror_session ...')
26782711
#
@@ -4975,9 +5008,12 @@ def remove(ctx, interface_name, ip_addr):
49755008
clicommon.run_command(command)
49765009
remove_router_interface_ip_address(config_db, interface_name, ip_address)
49775010
interface_addresses = get_interface_ipaddresses(config_db, interface_name)
4978-
if len(interface_addresses) == 0 and is_interface_bind_to_vrf(config_db, interface_name) is False and get_intf_ipv6_link_local_mode(ctx, interface_name, table_name) != "enable":
5011+
if len(interface_addresses) == 0 and is_interface_bind_to_vrf(config_db, interface_name) is False and \
5012+
get_intf_ipv6_link_local_mode(ctx, interface_name, table_name) != "enable":
49795013
if table_name != "VLAN_SUB_INTERFACE":
4980-
config_db.set_entry(table_name, interface_name, None)
5014+
interface_entry = config_db.get_entry(table_name, interface_name)
5015+
if len(interface_entry) == 0:
5016+
config_db.set_entry(table_name, interface_name, None)
49815017

49825018
#
49835019
# 'loopback-action' subcommand

tests/portchannel_test.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,42 @@ def test_set_non_existing_portchannel_retry_count(self):
318318
assert result.exit_code != 0
319319
assert "Error: PortChannel0005 is not present." in result.output
320320

321+
def test_set_invalid_portchannel_mac_addr(self):
322+
runner = CliRunner()
323+
db = Db()
324+
obj = {'db': db.cfgdb}
325+
326+
result = runner.invoke(config.config.commands["portchannel"].commands["mac-addr"].commands["set"],
327+
["Ethernet48", "00:11:22:33:44:55"], obj=obj)
328+
print(result.exit_code)
329+
print(result.output)
330+
assert result.exit_code != 0
331+
assert "Error: Ethernet48 is invalid!" in result.output
332+
333+
def test_set_non_existing_portchannel_mac_addr(self):
334+
runner = CliRunner()
335+
db = Db()
336+
obj = {'db': db.cfgdb}
337+
338+
result = runner.invoke(config.config.commands["portchannel"].commands["mac-addr"].commands["set"],
339+
["PortChannel0005", "00:11:22:33:44:55"], obj=obj)
340+
print(result.exit_code)
341+
print(result.output)
342+
assert result.exit_code != 0
343+
assert "Error: PortChannel0005 is not present." in result.output
344+
345+
def test_set_portchannel_mac_addr(self):
346+
runner = CliRunner()
347+
db = Db()
348+
obj = {'db': db.cfgdb}
349+
350+
result = runner.invoke(config.config.commands["portchannel"].commands["mac-addr"].commands["set"],
351+
["PortChannel1001", "00:11:22:33:44:55"], obj=obj)
352+
print(result.exit_code)
353+
print(result.output)
354+
assert result.exit_code == 0
355+
assert result.output == ""
356+
321357
originalSubprocessPopen = subprocess.Popen
322358

323359
class SubprocessMock:

utilities_common/cli.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,21 +415,29 @@ def is_port_router_interface(config_db, port):
415415
"""Check if port is a router interface"""
416416

417417
interface_table = config_db.get_table('INTERFACE')
418-
for intf in interface_table:
419-
if port == intf:
418+
for intf in interface_table.keys():
419+
if is_ip_prefix_in_key(intf) and port == intf[0]:
420420
return True
421421

422+
entry = config_db.get_entry('INTERFACE', port)
423+
if entry.get('ipv6_use_link_local_only') == 'enable':
424+
return True
425+
422426
return False
423427

424428

425429
def is_pc_router_interface(config_db, pc):
426430
"""Check if portchannel is a router interface"""
427431

428432
pc_interface_table = config_db.get_table('PORTCHANNEL_INTERFACE')
429-
for intf in pc_interface_table:
430-
if pc == intf:
433+
for intf in pc_interface_table.keys():
434+
if is_ip_prefix_in_key(intf) and pc == intf[0]:
431435
return True
432436

437+
entry = config_db.get_entry('PORTCHANNEL_INTERFACE', pc)
438+
if entry.get('ipv6_use_link_local_only') == 'enable':
439+
return True
440+
433441
return False
434442

435443

0 commit comments

Comments
 (0)