Updating Ruckus AP DNS Settings

I ran into an issue recently while trying to do some cleanup on a Ruckus SmartZone wireless controller. We migrated to new AD servers, which also doubled as DNS servers and included assigning new IP addresses to our controllers. All devices on our network with static IP settings needed to be updated. Servers and switching hardware weren’t difficult because we could script the change. Our Ruckus APs were more challenging. With 400+ APs to touch, making the change by hand wasn’t practical. There had to be a way to script the change. No problem. The Ruckus SmartZone controller had an SSH interface. It was pretty easy to get into settings of an AP config, so I could just change the DNS settings, right?

Or Not. It turns out you can’t just change the IP settings of an AP on the SmartZone controller. You can swap from static to DHCP and back, but that results in two reboots of the AP as it reads the config changes. There had to be another way.

I opened a ticket with Ruckus support to see if they had any suggestions. One option proposed was to use the “remote ap-cli” command to set the DNS settings directly on the APs themselves rather than in the config on the controller. Was that a solution? Yes, but if that APs were ever to reset, they would get the old settings from the controller. There had to be another way.

I then talked to our Ruckus Systems Engineer about the problem. He suggested I look at the SmartZone API. The API did have a command to change the IP settings, so I set out figuring out how to use it.

NOTE: Today, you can read through the SmartZone API documentation without a Ruckus support account, but I’ve been told that may change in the future. http://docs.ruckuswireless.com/smartzone/5.1.1/vszh-public-api-reference-guide-511.html

Now, I am not a developer or programmer. My official code learning stopped at VB.Net in 2005, but I’ve been using PowerShell for years to perform Windows and Active Directory management. From a talk I watched by Jeffery Snover (father of PowerShell), I know there are two useful functions I can use to talk with web-based APIs: Invoke-WebRequest & Invoke-RestMethod. Invoke-WebRequest can be used to get a session cookie needed to execute other API commands. Invoke-RestMethod is very similar to Invoke-WebRequest but can automatically parse JSON or XML data and turn them into PSObjects. With that knowledge in hand, I got started.

First, I had to get a web session.

$uri = "https://:8443/wsg/api/public"
$logonuri = $uri+"/v8_1/session"

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json;charset=UTF-8")

#logon
$body = @{"username"="admin";
    "password"="";
    "timeZoneUtcOffset"="-05:00"
    }

$json = $body | ConvertTo-Json


###Requesting a web sessions and adding the cookie to the header file doesn't work in Windows PowerShell 5.1
###Instead HTTPWebRequest from .NET has to be used and pass that session to all the subsequent PowerShell commands.
$webrequest = Invoke-WebRequest -Uri $logonuri -Headers $headers -Body $json -Method Post -SessionVariable websession

Next, I retrieved a list of all the APs managed by the controller. By default, the command paged the result to 100 items at a time, but I could easily loop to capture all the APs.

###Get all the APs on the controller###
$index = 0
$aps = @()
$apsuri = $uri+"/v8_1/aps?index=$index"

do {
    $response = Invoke-RestMethod -Method Get -Uri $apsuri -WebSession
    $websession -Headers $headers
    $aps += $response.list
    $index += 100
    $apsuri = $uri+"/v8_1/aps?index=$index"
} while ($response.hasMore)

Now all I had to do was retrieve the IP settings of each AP, create a JSON object with the new IP settings, and PATCH is back to the controller

#Example DNS addresses
$DNS1 = "1.1.1.1"
$DNS2 = "1.0.0.1"

foreach ($ap in $aps){
    $apuri = $uri+"/v8_1/aps/"+$ap.mac
    $ap = Invoke-RestMethod -Method Get -Uri $apuri -WebSession $websession -Headers $headers
    $oldnetwork = $ap.network

    if ($oldnetwork.ipType -eq "Static") {
        $newnetwork = @{
            "ipType"="Static"; "ip"=$oldnetwork.ip;
            "netmask"=$oldnetwork.netmask;
            "gateway"=$oldnetwork.gateway;
            "primaryDns"=$DNS1;
            "secondaryDns"=$DNS2;
        }
        $networkjson = $newnetwork | ConvertTo-Json

        $networkuri = $apuri+"/network"
        Write-Host "Updating $($ap.name)"
        Invoke-RestMethod -Method Patch -Uri $networkuri -WebSession $websession -Headers $headers -Body $networkjson 

        Remove-Variable networkjson
    } else {
        Write-Host "$($ap.name) is not using static IP settings"
        $notstatic += $ap
    }
}

That’s it. In a matter of fewer than 60 seconds, I was able to update the DNS settings on all the APs managed by our Ruckus Smartzone controller. This was just the start of what is possible through the Smartzone API. If I only wanted to modify APs in a specific zone, I could narrow the AP retrieval down by performing something like this.

###Get all the APs of a zone###
...
$apsuri = $uri+"/v8_1/aps?index=$index&zoneId=<INSERT ZONE ID HERE>"
...

I hope you found this interesting. If you want a complete PowerShell file to play around with, check out my GitHub repository found at https://github.com/agizmo/SmartZone-AP-DNS-Update

Have Fun.
-Tony

Running 40Gb QSFP+ on Dell’s S5048-ON Switches

Subtitle: Remember kids, read the documentation

Recently at work, we upgraded the top-of-rack switches in our datacenter from Dell S4810 to Dell S5048F-ON. The process was supposed to be simple. Both switches ran Dell Networking OS 9 (a rebrand of Force10), and we mirrored to port, port-channel, and VLAN configurations exactly.

Things went well for 2 hours of the process. All the 1/10Gb DACs and fiber transceivers moved to the S5048 switches and worked with no problem. The problem we ran into centered around the 40Gb transceivers. We used QSFP+ SR units from Dell and assumed they be plug and play in the S5048’s 100Gb QSFP28 ports. Surprise, they didn’t. Well, they did, but we had to make a config change. After an hour of troubleshooting, we discovered the command we needed, AND it was well documented. If only we had read the manual…

https://www.dell.com/support/manuals/us/en/04/networking-s5048f-on/s5048f-on-9.14.2.6-config-pub/splitting-100g-ports?guid=guid-60943ca1-cbf8-4958-aa54-4e8d00e331b2&lang=en-us

If you are going to use 40Gb QSFP transceivers or DACs on Dell’s S5048 switches be sure to run the following command

stack-unit <stack unit number> port <port number> portmode single speed 40g

Have fun.
-Tony