I am still working on my script to copy an SSID between networks and change an SSID. But now I struggle with the implementation of the API.
Problem:
I use getNetworkWirelessSsid to read the SSID and write the SSID with updateNetworkWirelessSsid.
But the API call getNetworkWirelessSsid gives me the following result for my test-SSID:
{'authMode': '8021x-radius',
'availabilityTags': [],
'availableOnAllAps': True,
'bandSelection': 'Dual band operation',
'defaultVlanId': 999,
'dot11r': {'adaptive': False, 'enabled': False},
'dot11w': {'enabled': True, 'required': True},
'enabled': True,
'encryptionMode': 'wpa-eap',
...
'wpaEncryptionMode': 'WPA2 only'}
The Schema Definition for updateNetworkWirelessSsid has some restrictions that make this invalid, and I can't write it back. For example, this SSID uses DOT1X authentication, but I get the element "encryptionMode" returned, which is only valid for PSK SSIDs. There are a couple of more restrictions where elements are dependent on each other.
How do I handle this (and I will never understand why this invalid element is returned)?
I can only think of having if-conditions where I match each restriction and remove the element if this element is not allowed on this SSID:
if source_ssid["authMode"] == '8021x-radius':
source_ssid.pop('encryptionMode')
But this is an extremely dirty workaround, and I need an individual function for each object I want to copy.
Or is there a "switch" or "parameter" to tell the system to ignore everything that is not valid? At least I didn't find anything like this.
Any idea or advice?
You are describing the endpoint that I hate the most.
You do a 'GET' of the SSID settings, you get bunch of nonsense , you try to 'PUT' the same exact data, you get bunch of errors 🙂 fun
Well, although this doesn't help, I am happy to see that I am not alone in my frustration ... 🤣
I must be lucky not to have run into this yet using my approach above. 🙂
If that happened - you test for the invalids and delete from my kwargs that I build. Or maybe if I specify kwargs that are not used, they get ignored by updateNetworkWirelessSsid. I guess they would have to be ignored.
I applaud the effort and steadfastness @KarstenI but you could have done this manually by now 😉
I think big and not only for the 15 branches where I need it now ... 😉
And I also see it as a preparation for the DEVASC certification that I want to do eventually.
Here is the jist of it, using Python, for MR based networks:
First grab the settings from the source network:
# Grab the current WiFi settings
ssidSettings=dashboard.wireless.getNetworkWirelessSsid(fromNetworkId,ssidNumber)
Then copy all of the settings to the new network:
# Build the SSID argument list
kwargs = {}
for setting in ssidSettings:
kwargs[setting]=ssidSettings[setting]
dashboard.wireless.updateNetworkWirelessSsid(toNet['id'],**kwargs)
@sungod probably has a better approach ...
And this is working for you Phil ? I don't have the same luck 😞
Recently I can't copy my WPA2-Enterprise SSID settings. When I do the push It pukes couple errors about RadSecTLS timeouts ( which are not visible on the dashboard ). Opened a case , waiting ...
Yes, I've used it maybe 10 to 20 times to copy WiFi settings.
I tend to follow old-school defensive programming practices...
There are API calls that return elements with a None value when they really shouldn't, or that change behaviour without notice, or that give the same data with different element names for no apparent reason.
Anything I need to rely on, I code to validate each element and then follow the rules to build the parameter list for the write operation. It's more effort, but still a lot easier than paper coding pads and opcode tables.
I know if I trust what an API response provides, there is a higher likelihood something will break, probably at 0200 on a Saturday.
My favorite example 🙂
get /networks/{networkId}/wireless/ssids
{'authMode': '8021x-radius',
'availabilityTags': [],
'availableOnAllAps': True,
'bandSelection': 'Dual band operation',
'dot11r': {'adaptive': False, 'enabled': True},
'dot11w': {'enabled': False, 'required': False},
'enabled': True,
'encryptionMode': 'wpa-eap',
'ipAssignmentMode': 'Bridge mode',
'lanIsolationEnabled': False,
'mandatoryDhcpEnabled': False,
'minBitrate': 11,
'name': 'XXXXXX',
'number': 0,
'perClientBandwidthLimitDown': 0,
'perClientBandwidthLimitUp': 0,
'perSsidBandwidthLimitDown': 0,
'perSsidBandwidthLimitUp': 0,
'radiusAccountingEnabled': True,
'radiusAccountingInterimInterval': 1200,
'radiusAccountingServers': [{'caCertificate': None,
'host': 'XXXXX',
'id': 'XXXXXXX',
'openRoamingCertificateId': None,
'port': 1813},
{'caCertificate': None,
'host': 'XXXXXX',
'id': 'XXXXXX',
'openRoamingCertificateId': None,
'port': 1813}],
'radiusAttributeForGroupPolicies': 'Airespace-ACL-Name',
'radiusAuthenticationNasId': '$NODE_MAC$:$VAP_NUM$',
'radiusCalledStationId': '$NODE_MAC$:$VAP_NAME$',
'radiusCoaEnabled': True,
'radiusFailoverPolicy': None,
'radiusFallbackEnabled': False,
'radiusLoadBalancingPolicy': None,
'radiusOverride': True,
'radiusProxyEnabled': False,
'radiusRadsecTlsIdleTimeout': 900,
'radiusServerAttemptsLimit': 3,
'radiusServerTimeout': 1,
'radiusServers': [{'caCertificate': None,
'host': 'XXXX',
'id': 'XXXXXX',
'openRoamingCertificateId': None,
'port': 1812},
{'caCertificate': None,
'host': 'XXXXXX',
'id': 'XXXXX',
'openRoamingCertificateId': None,
'port': 1812}],
'radiusTestingEnabled': False,
'speedBurst': {'enabled': False},
'splashPage': 'None',
'ssidAdminAccessible': False,
'useVlanTagging': False,
'visible': False,
'wpaEncryptionMode': 'WPA2 only'}
you try to push to a new network :
"RADIUS RADSec TLS idle timeout interval must be greater than RADIUS accounting interim interval"
remove "radiusRadsecTlsIdleTimeout" ( because where did that come from ? not present on the dashboard . I know 1200 > 900)
you get : 'encryptionMode' must be one of: 'wep' or 'wpa'
remove encryptionMod. It works....
How hard is it to push the same payload that you got....