RADIUSdesk WiFi Hotspot Manager and GUI for FreeRADIUS
MESHdesk Streamlined Mesh Controller

Importing a list of NAS devices in bulk

Background

  • So you manage to land a big deal with a company who asked you to deploy a Coova Chilli based AP on each of their sites.
  • Their sites are scattered across the USA and Canada.
  • You ordered 500 pieces of your specially priced hardware ($30 a piece!) which you manage to get pre-flashed with your own version of OpenWrt along with your company logo nicely silk screened on the devices.
  • These devices just arrived all the way from China.
  • Now you become a clever geek and automate the import of these devices into RADIUSdesk by using your scripting skills and the RADIUSdesk API.
  • You used Firebug and record the actions when adding and configuring one device.

Information gathering

Item Value Comment
user_id 182 This is the ID of the Access Provider to which these NAS devices will belong.
token 52190fff-a800-48eb-b1f2-478bc0a80167 The token of the root user. Yours will change each time you change the password of the root user.
shortname Carson_City_01 This convention you decided to use is the city _01, _02 etc
secret Carson_City_01_a1v This convention you decided to use is the shortname and three random characters
dynamic_attribute NAS-Identifier You will configure CoovaChilli on each AP to have this value the same as shortname
dynamic_value Carson_City_01 This will be the same as shortname
realms for NAS 32 (true) For the list of realms that the NAS can use; you need to determine the Realm ID and post it as the parameter name (it will be a number) and the value of this simply boolean true.
target URL http://127.0.0.1/cake2/rd_cake/nas/add_dynamic.json We add them as Dynamic items since we don't know their IP Addresses

Additional work

  • We now have all the info to script the POST action for adding the NAS device.
  • The JSON string returned (provided it is successful) after the add action will contain the id of the NAS. (This require SVN xyz or higher)
  • We can use this value for the next actions which is to:
    • Change the Device Type to Coova-Chilli Heartbeat
    • Add the MAC Address of the device. This will be used by the heartbeat script.
    • Activate the heartbeat and set it to mark as dead after 300 seconds.
    • Populate the Optional Info → NAS-Identifier field.
    • Activate the Auto Close Stale Sessions (after 1 hour = 3600 seconds)

Here's what the POST will contain:

Item Value Comment
community 00-AA-BB-CC-DD MAC Address of the Device (eth0)
heartbeat_dead_after 300 5 minutes
id 60 The newly return NAS id value from the previous POST which created it
monitor heartbeat We use the heartbeat system
nasidentifier Carson_City_01 Same as shortname
session_auto_close session_auto_close
session_dead_time 3600
token 52190fff-a800-48eb-b1f2-478bc0a80167
type CoovaChilli-Heartbeat
target URL http://127.0.0.1/cake2/rd_cake/nas/edit.json

Script to bulk import

  • Here is the php script. Be sure to also check the CSV file later in this document as reference.
add_many_nas_devices.php
<?php
 
print("RADIUSdesk API to Add many NAS devices specified in an external CSV file\n");
/*
    * = required
 
    == Adding a new NAS device ==
 
    *user_id 	        182 	[This is the ID of the Access Provider to which these NAS devices will belong.]
    *token 	            52190fff-a800-48eb-b1f2-478bc0a80167 	[The token of the root user. ]
    *shortname 	        Carson_City_01 	[This convention you decided to use is the city _01, _02 etc]
    *secret 	        Carson_City_01_a1v 	[This convention you decided to use is the shortname and three random characters]
    *dynamic_attribute 	NAS-Identifier 	[You will configure CoovaChilli on each AP to have this value the same as shortname]
    *dynamic_value 	    Carson_City_01 	[This will be the same as shortname]
    *32                 true 	[realm id number... one or more]
 
    target URL 	        http://127.0.0.1/cake2/rd_cake/nas/add_dynamic.json [We add them as Dynamic items since we don't know their IP Addresses]
 
 
    == Editing an existing NAS device ==
 
    *community 	            36-4b-77-6a-f8-44 	[MAC Address of the Device (eth0)]
    *heartbeat_dead_after 	300 	[5 minutes]
    *id 	                60 	[The newly return NAS id value from the previous POST which created it]
    *monitor 	            heartbeat 	[We use the heartbeat system]
    *nasidentifier 	        Carson_City_01 	[Same as shortname]
    *session_auto_close 	session_auto_close 	
    *session_dead_time 	    3600 	
    *token 	                52190fff-a800-48eb-b1f2-478bc0a80167 	
    *type 	                CoovaChilli-Heartbeat 
 
    target URL              http://127.0.0.1/cake2/rd_cake/nas/edit_nas.json
 
*/
 
$user_id	            = '182';
$token	                = '52190fff-a800-48eb-b1f2-478bc0a80167';
$dynamic_attribute      = 'NAS-Identifier'; 
$realm_1	            = 34;
$url                    = 'http://127.0.0.1/cake2/rd_cake/nas/add_dynamic.json';
$url_edit               = 'http://127.0.0.1/cake2/rd_cake/nas/edit_nas.json';
 
//Read the file with the list of names and MAC Addr.
$nas_devices_csv        = "./sample_nas.csv";
$nas_devices = file($nas_devices_csv,FILE_IGNORE_NEW_LINES);
foreach($nas_devices as $nas_device){
 
    $items      = explode(",",$nas_device);
    $shortname  = $items[0];
    $mac        = $items[1];
    $secret     = $shortname."_".substr(sha1(rand()), 0, 3);
    print("Adding $shortname with MAC: $mac and secret of $secret\n");
 
    // The data to send to the API
    $postData = array(
        'user_id'               => $user_id,
        'token'                 => $token,
        'shortname'             => $shortname,
        'secret'                => $secret,
        'dynamic_attribute'     => 'NAS-Identifier',
        'dynamic_value'         => $shortname,
        "$realm_1"              => true,
    );
 
    // Setup cURL
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
 
        CURLOPT_POST            => TRUE,
        CURLOPT_RETURNTRANSFER  => TRUE,
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json'
        ),
        CURLOPT_POSTFIELDS => json_encode($postData)
    ));
 
    // Send the request
    $response = curl_exec($ch);
 
    // Check for errors
    if($response === FALSE){
        die(curl_error($ch));
    }
 
    // Decode the response
    $responseData = json_decode($response, TRUE);
    //print_r($responseData);
 
    //======================================================
    if($responseData['success'] == true){
        $id = $responseData['data']['id'];
        print("Newly added id is $id\n");
 
        //--- We now need to modify this entry by specifying a few things:
        // The data to send to the API
        $editData = array(
            'community'             => $mac,
            'heartbeat_dead_after'  => 300,
            'id'                    => $id,
            'monitor'               => 'heartbeat',
            'nasidentifier'         => $shortname,
            'session_auto_close'    => 'session_auto_close',
            'session_dead_time'     => 3600,
            'type'                  => 'CoovaChilli-Heartbeat',
            'token'                 => $token
        );
 
        // Setup cURL
        $ch_e = curl_init($url_edit);
        curl_setopt_array($ch_e, array(
 
            CURLOPT_POST            => TRUE,
            CURLOPT_RETURNTRANSFER  => TRUE,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
            CURLOPT_POSTFIELDS => json_encode($editData)
        ));
 
        // Send the request
        $response_e = curl_exec($ch_e);
 
        // Check for errors
        if($response_e === FALSE){
            die(curl_error($ch_e));
        }
 
        // Decode the response
        $responseData_e = json_decode($response_e, TRUE);
        print_r($responseData_e);
    }
    //=========================================================
}
?>
  • Here is the CSV file
Carson_City_01,36-4b-77-6a-f8-44
Boston_01,36-4b-77-6a-f8-48
Salt_Lake_City_01,36-4b-77-6a-f8-40

Cappy Hoding ;-)