Skip updating port setting if no value is entered

Solved
eroche
Getting noticed

Skip updating port setting if no value is entered

So updating a script I did where I am updating a switchport settings as a whole instead of individually updating on each setting.

 

Say I want to update the following (names not correct syntax) :

  • name
  • enabled
  • poe enabled
  • vlan
  • port type
  • allowed vlans

 

If I select Access as port type it will skip the allowed vlans question but when I go the list out what I entered to verify as well as the updateDeviceSwitchPort command I get an error that allowed_vlans is blank and has no value assigned.

 

So is it possible to somehow skip the setting that are blank and not try to list or update?

 

Here is my code. API is an environment variable and switch SN is hardcoded but removed.

Thanks in Advance!

 

 

import meraki
import os
import time
import pprint
from colorama import init as colorama_init
from colorama import Fore, Back
from colorama import Style
import inquirer
from inquirer.themes import GreenPassion
import progressbar

def get_meraki_api_key():
    api_key = os.getenv('MERAKI_API_KEY')
    if not api_key:
        raise ValueError("No API key found. Please set the MERAKI_API_KEY enviroment variable.")
    return api_key



# Select Device    
sw_sn = '<sw sn>'
port = input ('\n' + 'What port would you like to update? (1,2...48): ')
print (Fore.BLUE,Style.BRIGHT +'\n' + 'Below is the current information for that port:  ' + '\n')
API_KEY = get_meraki_api_key()
dashboard = meraki.DashboardAPI(API_KEY, suppress_logging=True)
serial = (sw_sn) 
port_id = (port)

response = dashboard.switch.getDeviceSwitchPort(serial, port_id)
    
fields = ['portId', 'name', 'enabled', 'poeEnabled', 'type', 'vlan', 'voiceVlan', 'allowedVlans', 'accessPolicyType','isolationEnabled', 'rstpEnabled', 'stpGuard', 'linkNegotiation']
    
for field in fields:
    print (f"{field}: {response[field]}")
        
# Update settings   
def update_values():
    print ('----------------------------------------------------------------' + Style.RESET_ALL)
    print (Fore.YELLOW,Style.BRIGHT +'\n' + 'Please enter the updated values, which are Case-Sensitive:  ' + '\n')
    port_name = input ('\n' + 'Port Name:  ')
    enable = input ('Enable Port [True or False]:  ')
    port_type = input ('Port Type [Trunk or Access]:  ')
    d_vlan = input ('Data VLAN:  ')
    if port_type == ('Access'):
        v_vlan = input ('Voice VLAN:  ')
    if port_type == ('Trunk'):
        v_allowed = input ('Allowed VLANs [1,3 or 1-3 or All]: ')
    rstp_enabled = input ('RSTP Enable [True or False]:  ')
    stp_guard = input ('STP Guard [Disabled, Root Guard, BPDU guard, Loop Guard]:  ')
    access_policy = input ('Access Policy [Open, MAC Allowed, Stickey MAC MAC Allowed, Internal DOT1x]:  ')
    if access_policy == ('MAC Allowed'):
        mac_allowed = input ('MAC Address [xx:xx:xx:xx:xx:xx, xx:xx:xx:xx:xx:xx): ')
    if access_policy == ('Sticky MAC Allowed list'):
        sticky_mac_allowed = input ('MAC Address [xx:xx:xx:xx:xx:xx, xx:xx:xx:xx:xx:xx): ')
        mac_allowed_limit = input ('How many MAC Address Allowed: ')
    poe_enabled = input ('PoE Enabled [True or False]:  ')


    print ('\n' + 'Here are the values you entered')
    #print ('\n' + 'Port Name: ' + port_name + '\n' + 'Port Enabled: ' + enable + '\n' + 'Port Type: ' + port_type + '\n' + 'Data VLAN: ' + d_vlan + '\n' + 'Voice VLAN: ' + v_vlan + '\n' + 'VLANs Allowed: ' + v_allowed + 'RSTP: ' + rstp_enabled + '\n' + 'STP Guard: ' + stp_guard + '\n' + 'Access Policy: ' + access_policy + '\n' + 'MACs Aloowed: ' + mac_allowed + '\n' + 'Sticky MACs Allowed: ' + sticky_mac_allowed + '\n' + 'MAC Allows Limit: ' + mac_allowed_limit + '\n' + 'PoE Enabled: ' + poe_enabled)

    validate = input ('\n' + 'Are all values correct [Y or N]:  ')
 
        
    if validate in {'Y', 'y'}:
        response = dashboard.switch.updateDeviceSwitchPort(
            serial, port_id,
            name = port_name,
            enabled = enable,
			type = port_type,
			vlan = d_vlan,
			voiceVlan = v_vlan,
			allowedVlans = v_allowed,
			rstpEnables = rstp_enabled,
			stpGuard = stp_guard,
			accessPolicyType = access_policy,
			macAllowedList = mac_allowed,
			stickyMacAllowedList = sticky_mac_allowed,
			stickyMacAllowListLimit = mac_allowed_limit,
			poeEnabled = poe_enabled,
				
            )
                
        response = dashboard.switch.getDeviceSwitchPort(serial, port_id)
    
        fields = ['portId', 'name', 'enabled', 'poeEnabled', 'type', 'vlan', 'voiceVlan', 'allowedVlans', 'isolationEnabled', 'rstpEnabled', 'stpGuard', 'accessPolicyType'
		  , 'macAllowedList', 'stickyMacAllowListLimit', 'linkNegotiation']
    
        for field in fields:
            print ('\n' + 'Here are the New Settings: ' + '\n')
            print (f"{field}: {response[field]}")
        input  ('\n' + 'Press Enter to return to Main Menu: ')
#        main_menu()
    
    elif validate in {'N', 'n'}:
        input ('\n' + 'Darn, Ok lets try this again, press Enter: ')
        clearconsole()
        print ('\n' + 'Current Values:' + '\n')
            
        response = dashboard.switch.getDeviceSwitchPort(serial, port_id)
    
        fields = ['portId', 'name', 'enabled', 'poeEnabled', 'type', 'vlan', 'voiceVlan', 'allowedVlans', 'isolationEnabled', 'rstpEnabled', 'stpGuard', 'linkNegotiation']
    
        for field in fields:
            print (f"{field}: {response[field]}")
                
        update_values()
            
    else:
        print ('you need to select Y,y,N or n')
            
            
update_values()

 

 

 

1 Accepted Solution
eroche
Getting noticed

Great thank you, I will give that I try.

 

The response line is the fields that will be updated so that is where I need to add or leave out which fields to update. So, if I leave a field blank and just hit enter or for instance if I select Trunk as port_type then I have it bypassing the voiceVlan option. Either one of these should leave their respective args out of the response line.

 

Hope that helps to clarify.

View solution in original post

8 Replies 8
eroche
Getting noticed

@sungod or @PhilipDAth  Any thoughts on this? Trying to find a way to add or skip a setting in the response = dashboard.switch.updateDeviceSwitchPort depending if has a value or left blank. I tried to an append but that doesn't do the trick. Any thought would be much appricated!

 

Thanks in Advance!

sungod
Kind of a big deal

IWhat you are doing here...

       response = dashboard.switch.updateDeviceSwitchPort(
            serial, port_id,
            name = port_name,
            enabled = enable,
			type = port_type,
			vlan = d_vlan,
			voiceVlan = v_vlan,
			allowedVlans = v_allowed,
			rstpEnables = rstp_enabled,
			stpGuard = stp_guard,
			accessPolicyType = access_policy,
			macAllowedList = mac_allowed,
			stickyMacAllowedList = sticky_mac_allowed,
			stickyMacAllowListLimit = mac_allowed_limit,
			poeEnabled = poe_enabled,
				
            )

...is pass the function arguments irrespective of whether they have a value, which causes the problem.

 

Instead, you need to build the argument list on the fly, only including things that have  a value.

 

You have the two mandatory positional arguments, serial and portId, the rest are optional keyword arguments in the form kwarg=value,

 

I'd think if you build the keyword arguments in a dictionary, you could then pass it to the call.

 

Something like...

#create an empty disctionary
the_args = {}

#for each keyword arg, if it isn't empty/None add the keyword and value
#    note for numeric values this test would call 0 false, so you need to
#    make sure the way you test is appropriate for each keyword value type!
if v_allowed:
    #add the keyword and value to the dictionary
    the_args["allowedVlans"] = v_allowed

#repeat for every keyword, then make the call
       
response = dashboard.switch.updateDeviceSwitchPort(
    serial, port_id,
    the_args		
)

 

eroche
Getting noticed

Great thank you, I will give that I try.

 

The response line is the fields that will be updated so that is where I need to add or leave out which fields to update. So, if I leave a field blank and just hit enter or for instance if I select Trunk as port_type then I have it bypassing the voiceVlan option. Either one of these should leave their respective args out of the response line.

 

Hope that helps to clarify.

eroche
Getting noticed

Ok...so tested it. I am getting the following error which makes sense but how to get around? 

 

UnboundLocalError: cannot access local variable 'v_allowed' where it is not associated with a value

 

The error is due to skipping the instance because the port_type is Access.

 

Also, the proper syntax for the numeric values would be == "0" or is False?

 

Here is what I have currently

 

    port_name = input ('\n' + 'Port Name:  ')

    enable = input ('Enable Port [True or False]:  ')

    port_type = input ('Port Type [Trunk or Access]:  ')

    d_vlan = input ('Data VLAN:  ')

    if port_type == ('Access'):

        v_vlan = input ('Voice VLAN:  ')

    if port_type == ('Trunk'):

        v_allowed = input ('Allowed VLANs [1,3 or 1-3 or All]: ')

    rstp_enabled = input ('RSTP Enable [True or False]:  ')

    stp_guard = input ('STP Guard [Disabled, Root Guard, BPDU guard, Loop Guard]:  ')

    access_policy = input ('Access Policy [Open, MAC Allowed, Stickey MAC MAC Allowed, Internal DOT1x]:  ')

    if access_policy == ('MAC Allowed'):

        mac_allowed = input ('MAC Address [xx:xx:xx:xx:xx:xx, xx:xx:xx:xx:xx:xx): ')

    if access_policy == ('Sticky MAC Allowed list'):

        sticky_mac_allowed = input ('MAC Address [xx:xx:xx:xx:xx:xx, xx:xx:xx:xx:xx:xx): ')

        mac_allowed_limit = input ('How many MAC Address Allowed: ')

    poe_enabled = input ('PoE Enabled [True or False]:  ')





    response_update = {}

    

    if port_name:

        response_update["name"] = port_name

    if enable:

        response_update["enabled"] = enable

    if port_type:

        response_update["type"] = port_type

    if d_vlan == '0':

        response_update["vlan"] = d_vlan

    if v_vlan == '0':

        response_update["voiceVlan"] = v_vlan

    if v_allowed == '0':

        response_update["allowedVlans"] = v_allowed

    if rstp_enabled:

        response_update["rstpEnabled"] = rstp_enabled

    if stp_guard:

       response_update["stpGuard"] = stp_guard

    if access_policy:

       response_update["accessPolicyType"] = access_policy

    if mac_allowed:

       response_update["macAllowedList"] = mac_allowed

    if sticky_mac_allowed:

        response_update["stickyMacAllowedList"]

    if mac_allowed_limit == '0':

        response_update["stickyMacAllowListLimit"]

    if poe_enabled:

        response_update["poeEnabled"] = poe_enabled

    

 

eroche
Getting noticed

Ok got around that error by adding key = "" before the ending the values.

 

Now at an error for to many args for the response portion

 

TypeError: Switch.updateDeviceSwitchPort() takes 3 positional arguments but 4 were given

 

response = dashboard.switch.updateDeviceSwitchPort(

            serial, port_id,

            response_update,			

            )

 

I have run into this before but not sure how to correct this one.

sungod
Kind of a big deal

Try adding ** like this...

response = dashboard.switch.updateDeviceSwitchPort(

            serial, port_id,

            **response_update,			

            )
eroche
Getting noticed

Ok that fixed it...what does ** do?

sungod
Kind of a big deal

In this context, ** 'unpacks' the dictionary into keyword arguments to the function.

Get notified when there are additional replies to this discussion.