-
Notifications
You must be signed in to change notification settings - Fork 667
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
Fix for Switch Port Modes and VLAN CLI Enhancement #3108
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
e36950c
Fix for switchport mode PR
sabakram bdddd97
Fix for cli.py
sabakram 643d6a5
Fix for indentation
sabakram 1c523b6
Fix for error
sabakram 53afe45
Fix
sabakram 09c2a6f
Fixing indentation errors
sabakram e7bc924
Fix for error
sabakram 3e869e5
Fix for failures
sabakram 789cfd4
Fix for errors
sabakram 7bc67d7
Fix for port version
sabakram afa1476
Fix for DB migrator versions
sabakram 4529899
Fix for db migrator version function
sabakram b469f1b
Fixing versions
sabakram 2a7bd65
Fix for cli.py
sabakram a87039d
Fix for vlan_test.py
sabakram ad3a193
Fix for failures
sabakram 7593c2d
Fix for unexpected characters
sabakram 9a3340d
Fixing error message
sabakram 5e9a8f0
Fix for routed port
sabakram File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,7 @@ | |
from .config_mgmt import ConfigMgmtDPB, ConfigMgmt | ||
from . import mclag | ||
from . import syslog | ||
from . import switchport | ||
from . import dns | ||
|
||
# mock masic APIs for unit test | ||
|
@@ -105,6 +106,7 @@ | |
PORT_SPEED = "speed" | ||
PORT_TPID = "tpid" | ||
DEFAULT_TPID = "0x8100" | ||
PORT_MODE= "switchport_mode" | ||
|
||
asic_type = None | ||
|
||
|
@@ -1211,6 +1213,9 @@ def config(ctx): | |
# DNS module | ||
config.add_command(dns.dns) | ||
|
||
# Switchport module | ||
config.add_command(switchport.switchport) | ||
|
||
@config.command() | ||
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false, | ||
expose_value=False, prompt='Existing files will be overwritten, continue?') | ||
|
@@ -4532,19 +4537,40 @@ def add(ctx, interface_name, ip_addr, gw): | |
if interface_name is None: | ||
ctx.fail("'interface_name' is None!") | ||
|
||
# Add a validation to check this interface is not a member in vlan before | ||
# changing it to a router port | ||
vlan_member_table = config_db.get_table('VLAN_MEMBER') | ||
if (interface_is_in_vlan(vlan_member_table, interface_name)): | ||
click.echo("Interface {} is a member of vlan\nAborting!".format(interface_name)) | ||
return | ||
|
||
portchannel_member_table = config_db.get_table('PORTCHANNEL_MEMBER') | ||
|
||
if interface_is_in_portchannel(portchannel_member_table, interface_name): | ||
ctx.fail("{} is configured as a member of portchannel." | ||
.format(interface_name)) | ||
|
||
|
||
# Add a validation to check this interface is in routed mode before | ||
# assigning an IP address to it | ||
|
||
sub_intf = False | ||
|
||
if clicommon.is_valid_port(config_db, interface_name): | ||
is_port = True | ||
elif clicommon.is_valid_portchannel(config_db, interface_name): | ||
is_port = False | ||
else: | ||
sub_intf = True | ||
|
||
if not sub_intf: | ||
interface_mode = "routed" | ||
if is_port: | ||
interface_data = config_db.get_entry('PORT',interface_name) | ||
elif not is_port: | ||
interface_data = config_db.get_entry('PORTCHANNEL',interface_name) | ||
|
||
if "mode" in interface_data: | ||
interface_mode = interface_data["mode"] | ||
|
||
if interface_mode != "routed": | ||
ctx.fail("Interface {} is not in routed mode!".format(interface_name)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can display the current mode in the error message. |
||
return | ||
|
||
|
||
try: | ||
ip_address = ipaddress.ip_interface(ip_addr) | ||
except ValueError as err: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import click | ||
from .utils import log | ||
import utilities_common.cli as clicommon | ||
|
||
# | ||
# 'switchport' mode ('config switchport ...') | ||
# | ||
|
||
|
||
@click.group(cls=clicommon.AbbreviationGroup, name='switchport') | ||
def switchport(): | ||
"""Switchport mode configuration tasks""" | ||
pass | ||
|
||
|
||
@switchport.command("mode") | ||
@click.argument("type", metavar="<mode_type>", required=True, type=click.Choice(["access", "trunk", "routed"])) | ||
@click.argument("port", metavar="port", required=True) | ||
@clicommon.pass_db | ||
def switchport_mode(db, type, port): | ||
"""switchport mode help commands.Mode_type can be access or trunk or routed""" | ||
|
||
ctx = click.get_current_context() | ||
|
||
log.log_info("'switchport mode {} {}' executing...".format(type, port)) | ||
mode_exists_status = True | ||
|
||
# checking if port name with alias exists | ||
if clicommon.get_interface_naming_mode() == "alias": | ||
alias = port | ||
iface_alias_converter = clicommon.InterfaceAliasConverter(db) | ||
port = iface_alias_converter.alias_to_name(port) | ||
if port is None: | ||
ctx.fail("cannot find port name for alias {}".format(alias)) | ||
|
||
if clicommon.is_port_mirror_dst_port(db.cfgdb, port): | ||
ctx.fail("{} is configured as mirror destination port".format(port)) | ||
|
||
|
||
if clicommon.is_valid_port(db.cfgdb, port): | ||
is_port = True | ||
elif clicommon.is_valid_portchannel(db.cfgdb, port): | ||
is_port = False | ||
else: | ||
ctx.fail("{} does not exist".format(port)) | ||
|
||
portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER') | ||
|
||
if (is_port and clicommon.interface_is_in_portchannel(portchannel_member_table, port)): | ||
ctx.fail("{} is part of portchannel!".format(port)) | ||
|
||
if is_port: | ||
port_data = db.cfgdb.get_entry('PORT',port) | ||
else: | ||
port_data = db.cfgdb.get_entry('PORTCHANNEL',port) | ||
|
||
# mode type is either access or trunk | ||
if type != "routed": | ||
|
||
if "mode" in port_data: | ||
existing_mode = port_data["mode"] | ||
else: | ||
existing_mode = "routed" | ||
mode_exists_status = False | ||
if (is_port and clicommon.is_port_router_interface(db.cfgdb, port)) or \ | ||
(not is_port and clicommon.is_pc_router_interface(db.cfgdb, port)): | ||
ctx.fail("Remove IP from {} to change mode!".format(port)) | ||
|
||
if existing_mode == "routed": | ||
if mode_exists_status: | ||
# if the port in an interface | ||
if is_port: | ||
db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)}) | ||
# if not port then is a port channel | ||
elif not is_port: | ||
db.cfgdb.mod_entry("PORTCHANNEL", port, {"mode": "{}".format(type)}) | ||
|
||
if not mode_exists_status: | ||
port_data["mode"] = type | ||
if is_port: | ||
db.cfgdb.set_entry("PORT", port, port_data) | ||
# if not port then is a port channel | ||
elif not is_port: | ||
db.cfgdb.set_entry("PORTCHANNEL", port, port_data) | ||
|
||
if existing_mode == type: | ||
ctx.fail("{} is already in the {} mode".format(port,type)) | ||
else: | ||
if existing_mode == "access" and type == "trunk": | ||
pass | ||
if existing_mode == "trunk" and type == "access": | ||
if clicommon.interface_is_tagged_member(db.cfgdb,port): | ||
ctx.fail("{} is in {} mode and have tagged member(s).\nRemove tagged member(s) from {} to switch to {} mode".format(port,existing_mode,port,type)) | ||
if is_port: | ||
db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)}) | ||
# if not port then is a port channel | ||
elif not is_port: | ||
db.cfgdb.mod_entry("PORTCHANNEL", port, {"mode": "{}".format(type)}) | ||
|
||
click.echo("{} switched from {} to {} mode".format(port, existing_mode, type)) | ||
|
||
# if mode type is routed | ||
else: | ||
|
||
if clicommon.interface_is_tagged_member(db.cfgdb,port): | ||
ctx.fail("{} has tagged member(s). \nRemove them to change mode to {}".format(port,type)) | ||
|
||
if clicommon.interface_is_untagged_member(db.cfgdb,port): | ||
ctx.fail("{} has untagged member. \nRemove it to change mode to {}".format(port,type)) | ||
|
||
if "mode" in port_data: | ||
existing_mode = port_data["mode"] | ||
else: | ||
existing_mode = "routed" | ||
mode_exists_status = False | ||
|
||
if not mode_exists_status: | ||
port_data["mode"] = type | ||
if is_port: | ||
db.cfgdb.set_entry("PORT", port, port_data) | ||
|
||
# if not port then is a port channel | ||
elif not is_port: | ||
db.cfgdb.set_entry("PORTCHANNEL", port, port_data) | ||
pass | ||
|
||
elif mode_exists_status and existing_mode == type: | ||
ctx.fail("{} is already in {} mode".format(port,type)) | ||
|
||
else: | ||
if is_port: | ||
db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)}) | ||
# if not port then is a port channel | ||
elif not is_port: | ||
db.cfgdb.mod_entry("PORTCHANNEL", port, {"mode": "{}".format(type)}) | ||
|
||
click.echo("{} switched from {} to {} mode".format(port,existing_mode,type)) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this check removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have added a check for switchport mode routed, a routed port fulfill this behavior that a interface has a vlan membership or not. So this check becomes redundant after addition of new check.