Skip to content

Commit

Permalink
changed the functionality of switchport.py and added utilities functi…
Browse files Browse the repository at this point in the history
…ons and changes in 'show interfaces' command and updated 'mock_tables'
  • Loading branch information
MuhammadUmarAsad committed Oct 20, 2022
1 parent ce91938 commit 8358561
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 286 deletions.
139 changes: 66 additions & 73 deletions config/switchport.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from os import access
from statistics import mode
import click
from .utils import log
import utilities_common.cli as clicommon
from utilities_common.db import Db

# since default vlan id is 1
default_vid = 1

db = Db
#
# 'switchport' mode ('config switchport ...')
#
Expand All @@ -19,17 +16,16 @@ def switchport():


@switchport.command("mode")
@click.argument("type", metavar="<mode_type>", Required=True, type=click.Choice(["access", "trunk", "routed"]))
@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\nmode_type can either be:\n\t access for untagged mode\n\t trunk for tagged mode \n\t routed for non vlan mode"""
"""switchport mode help commands\nmode_type can either be:\n\t -> access \n\t -> trunk \n\t -> routed"""

ctx = click.get_current_context()

log.log_info(
"'switchport mode {} {}' executing...".format(type, port))

vlan = 'Vlan{}'.format(default_vid)
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":
Expand All @@ -39,82 +35,79 @@ def switchport_mode(db, type, port):
if port is None:
ctx.fail("cannot find port name for alias {}".format(alias))

# mode type is either access or trunk
if type != "routed":

# checking if default Vlan has been created or not
if not clicommon.check_if_vlanid_exist(db.cfgdb, vlan):

db.cfgdb.set_entry('VLAN', vlan, {'vlanid': default_vid})

log.log_info(
"'vlan add {}' in switchport mode executing...".format(default_vid))

# tagging_mode will be untagged if access and tagged if trunk
if clicommon.is_port_mirror_dst_port(db.cfgdb, port):
if clicommon.is_port_mirror_dst_port(db.cfgdb, port):
ctx.fail("{} is configured as mirror destination port".format(port))

if clicommon.is_port_vlan_member(db.cfgdb, port, vlan):
ctx.fail("{} is already a member of {}".format(port, vlan))

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))

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("{} is a router interface!".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))

# checking if it exists in default Vlan1
if clicommon.port_vlan_member_exist(db, vlan, port):

existing_port_vlan_status = clicommon.get_existing_port_vlan_status(
db, vlan, port)
existing_status = "access" if existing_port_vlan_status == "untagged" else "trunk"
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))

if (type == existing_status):
ctx.fail("{} is already in {} mode!".format(port, type))
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("{} is a router interface!".format(port))

elif (type != existing_status):
portchannel_member_table = db.cfgdb.get_table('PORTCHANNEL_MEMBER')

if (type == "trunk" and existing_status == "access"):
db.cfgdb.mod_entry('VLAN_MEMBER', (vlan, port), {
'tagging_mode': "tagged"})
if (is_port and clicommon.interface_is_in_portchannel(portchannel_member_table, port)):
ctx.fail("{} is part of portchannel!".format(port))

elif (type == "access" and existing_status == "trunk"):
db.cfgdb.mod_entry('VLAN_MEMBER', (vlan, port), {
'tagging_mode': "untagged"})
port_table_data = db.cfgdb.get_table('PORT')
port_data = port_table_data[port]

# switched the mode of already defined switchport
click.echo("{} switched from {} to {} mode".format(
port, existing_status, type))
# mode type is either access or trunk
if type != "routed":

# if it not exists already set entry
if "mode" in port_data:
existing_mode = port_data["mode"]
else:
db.cfgdb.set_entry('VLAN_MEMBER', (vlan, port), {
'tagging_mode': "untagged" if type == "access" else "tagged"})

click.echo("{} switched to {} mode. Added to default {}".format(
port, type, vlan))
existing_mode = "routed"
mode_exists_status = False

if existing_mode == "routed":
if mode_exists_status:
db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)})
if not mode_exists_status:
db.cfgdb.set_entry("PORT", port, {"mode": "{}".format(type)})

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,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))

db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)})

click.echo("{} switched from {} to {} mode.".format(port, existing_mode, type))

# if mode type is routed
else:

if clicommon.check_if_vlanid_exist(db.cfgdb, vlan) == False:
ctx.fail("{} is already in routed mode".format(port))
if clicommon.interface_is_tagged_member(db,port):
ctx.fail("{} has tagged member|s. \nRemove them to change mode to {}".format(port,type))

if not clicommon.is_port_vlan_member(db.cfgdb, port, vlan):
ctx.fail("{} is already in routed mode".format(port))
if clicommon.interface_is_untagged_member(db,port):
ctx.fail("{} has tagged member|s. \nRemove them to change mode to {}".format(port,type))

db.cfgdb.set_entry('VLAN_MEMBER', (vlan, port), None)
if "mode" in port_data:
existing_mode = port_data["mode"]
else:
existing_mode = "routed"
mode_exists_status = False

if not mode_exists_status:
db.cfgdb.set_entry("PORT", port, {"mode": "{}".format(type)})
click.echo("{} switched to {} mode.".format(port, type))

if mode_exists_status and existing_mode == type:
ctx.fail("{} is already in {} mode".format(port,type))

db.cfgdb.mod_entry("PORT", port, {"mode": "{}".format(type)})
click.echo("{} switched from {} to {} mode".format(port,existing_mode,type))

click.echo("{} is in {} mode. Removed from default {}".format(
port, type, vlan))
23 changes: 20 additions & 3 deletions config/vlan.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from os import access
from statistics import mode
import click
import utilities_common.cli as clicommon

Expand Down Expand Up @@ -195,12 +197,11 @@ def add_vlan_member(db, vid, port, untagged, multiple, except_flag):
config_db = ValidatedConfigDBConnector(db.cfgdb)
# parser will parse the vid input if there are syntax errors it will throw error

vid_list = clicommon.vlan_member_input_parser(
ctx, db, except_flag, multiple, vid)
vid_list = clicommon.vlan_member_input_parser(ctx, db, except_flag, multiple, vid)

# multiple vlan command cannot be used to add multiple untagged vlan members
if untagged and (multiple or except_flag or vid == "all"):
ctx.fail("Port cannot have more than one untagged Vlan.")
ctx.fail("{} cannot have more than one untagged Vlan.".format(port))

if ADHOC_VALIDATION:
for vid in vid_list:
Expand Down Expand Up @@ -259,7 +260,23 @@ def add_vlan_member(db, vid, port, untagged, multiple, except_flag):
# TODO: MISSING CONSTRAINT IN YANG MODEL
if (clicommon.interface_is_untagged_member(db.cfgdb, port) and untagged):
ctx.fail("{} is already untagged member!".format(port))

# checking mode status of port if its access, trunk or routed
port_table_data = db.cfgdb.get_table('PORT')
port_data = port_table_data[port]

if "mode" not in port_data:
ctx.fail("{} is in routed mode!\nUse switchport mode command to changes port mode")
else:
existing_mode = port_data[mode]

mode_type = "access" if untagged else "trunk"
if existing_mode == "access" and mode_type == "trunk": # TODO: MISSING CONSTRAINT IN YANG MODEL
ctx.fail("{} is in access mode! Tagged Members cannot be added".format(existing_mode))

if existing_mode == mode_type or (existing_mode == "trunk" and mode_type == "access"):
pass

# in case of exception in list last added member will be shown to user
try:
config_db.set_entry('VLAN_MEMBER', (vlan, port), {
Expand Down
Loading

0 comments on commit 8358561

Please sign in to comment.