General
The ecCloud API is a public version of the one we use behind the scenes when you make configuration changes and perform other common actions, such as device registration, report generation, etc, via the Cloud Controller UI.
Configuration is a bit complex, so please check out the examples below, as well as inspect the API calls that the browser makes when saving the configuration for a site or device. This should give you an idea of what data will need to be sent and how it should be formatted when making the API calls.
API Key Permissions
The permissions of your Cloud's user account will be associated with the available actions of the API key you generate for that account - this means that you must have ownership level permissions in order to perform all available API actions. If you'd prefer a more restricted API user, you can of course create a limited user (guest) and generate an API key from that user account.
You must also generate different API keys for each cloud in which you have access. For example, let's say you own Cloud A and Cloud B. If you generate an API key for Cloud A, you will not be able to access the data in Cloud B - you will need to generate a separate API key for Cloud B.
Generating API Keys
In order to generate an API key for your production cloud account, navigate to the Manage Clouds page by clicking the cloud icon on the top nav bar and selecting the "Manage Clouds" option at the bottom of the list.
From there, locate the Cloud in the list for which you want to generate the API key, and click the "API Keys" button next to it:
Now click on the "Create New API Key" button and accept the terms and conditions:
Your API key will be displayed in the grey box. The first part of the API key (the 8 characters before the first period) is the API key ID and can be used to identify the API key.
Important Note: once your API key is generated, copy it some place secure immediately as we do not store it in our database!
You can revoke an API key, or generate additional API keys, at any time from the API key management form:
Basic API Instructions
You can find the list of available production API definitions here:
Once you generate an API key, accessing the API is pretty straightforward. You'll start by adding two headers to each request:
- Set a header called x-api-key to your API key
- Set a header called content-type to application/json
Here's an example showing how to use curl to GET all devices in a given site:
Request:
Response:
{
[
{"id" : "281474976711073",
"name" : "Mock Device-9",
"site_id" : "281474976710783",
"sn" : "0000022",
"mac" : "00:00:00:00:00:16",
"status_id" : "STATUS_ONLINE",
"state_id" : "STATE_REGISTERED",
"health_id" : "HEALTH_NORMAL",
"blocked" : false,
"last_contact" : "2018-05-21T19:30:44.285Z",
"created_at" : "2017-03-22T15:14:35.000Z",
"updated_at" : "2018-05-16T13:00:44.000Z",
"product_brand_id" : "1",
"type" : "NET_ENTERPRISE",
"hostname" : "mock-device-9",
"suspend_config" : false,
"decomm" : false,
"license_type" : "LICENSE_TYPE_FREE"
},
{"id" : "281474976711070",
"name" : "Mock Device-6",
"site_id" : "281474976710783",
"sn" : "0000019",
"mac" : "00:00:00:00:00:13",
"status_id" : "STATUS_ONLINE",
"state_id" : "STATE_REGISTERED",
"health_id" : "HEALTH_NORMAL",
"blocked" : false,
"last_contact" : "2018-05-21T19:30:44.286Z",
"created_at" : "2017-03-22T15:14:35.000Z",
"updated_at" : "2018-05-16T13:00:29.000Z",
"product_brand_id" : "1",
....
}
And the same request using a RESTFUL web client:
Note : error responses are always returned as a plain text message, not JSON-formatted.
Here's an example of a response when using an invalid API key:
Request :
x-api-key header is not valid
Changing Configuration via the API
In the IgniteNet Cloud front end, we use the idea of "site-inheritance policies" to determine which keys take priority when merging a site’s configuration settings with the device’s configuration settings.
Site inheritance policies are nothing more than a predefined set of rules that we call config value ORIGIN. When the config is initialized, the policy rule set is applied initially. However, nothing prevents to change the ORIGIN to a completely custom rules to suit your needs, different from existing these configuration policies.
Both the site's configuration settings and the device's configuration settings are stored as JSON objects on our database, and after they’re merged together, the final result is translated to the local configuration format used on the device (UCI), and pushed down in a configuration task.
The configuration update process is split across different events:
- Config changes are POSTed via API
- Config task is created within several minutes
- Config task is sent to device
- Config task is executed by device
Configuration Structure
The configuration object is a very simple JSON object with a key/value pair for each configuration key/value in the device or site level configuration:
{
"locale/deviceLang" :
{
"value" : "auto",
"origin": "site-device"
},
"radio/r5/enable" :
{
"value ": "1",
"origin" : "device"
},
"network/lan/enable" :
{
"value " : "1",
"origin" : "site"
}
}
Additionally, each device value has origin option that indicates whether it takes precedence over site setting.
The key is made up of one or more root nodes, zero or more additional nodes, and zero or one properties:
- radio/: is the root node
- r5/ : is a node
- enable : is the property name
You’ll also notice that some node have numeric ids, where others don’t:
{
"wireless/1000000584/broadcastSSID" : {}
}
vs
{
"radio/global/bandSteering" : {}
}
The first key, the one with the id after the root node, is a numeric nodes, and what we refer to as entities.
Entities include such keys as SSIDs/VAPs, local logins, LANs, and other type of config settings where the user is allowed to created an indeterminate number of items. All entities are assigned a numeric id.
It's important to note:
- IDs < 1000000000 are reserved for device level entities, and
- IDs > 1000000000 are used for site level entities .
These translate into UCI property "__uid" in the configuration that ends up on the device.
Some UIDs are generated with crc32 algorithm. See users/ for example. This boils down to preventing duplicate user names and overriding them by name.
You should not override the subnodes of an entity - only override the whole thing. For example, once you change the network name of an inherited SSID/VAP from the device-level configuration, you’ll want to create an override for that whole SSID. You could change the WPA passkey at the site level for the same SSID object, and it would not apply to the the device level SSID due to the override.
Configuration Merging
We provide two levels of configuration: site and device. When config changes occur, site and device configurations are combined and translated into a format that device can understand. To determine which setting will take precedence, please refer to this table:
Site Key |
Device Key |
ORIGIN |
RESULT |
undefined |
defined |
device |
device_value |
defined |
defined |
site-device |
device_value |
defined |
defined |
site |
site_value |
defined |
undefined |
site |
site_value |
Origin is defined as:
- device: setting is defined in device config only
- site-device: device overrides values from site config
- site: setting is originating from site configuration
The important thing to note here is that when changing a device’s configuration from the API, you will be responsible in setting the proper merge behavior for a key. This not not true for sites, however. Site configuration keys will always have ORIGIN set to "site".
The merger module knows nothing about the device’s configuration policy - it only cares about the merge behavior you’ve specified for each key.
That being said, the configuration policy must still be properly set for a device for the case where you login to the IgniteNet Cloud front end to view/edit a device’s configuration.
Additional Examples
"OK, but what does this even mean, I just want to change config!"
The IgniteNet config format follows complex rules that are abstracted away by the Cloud UI. Consider this a low level access to the raw configuration.
Because there are 100’s of possible configuration keys (each with their own set of dependencies), the easiest way to figure out the resulting config you want will be to make the change you want in the Cloud UI, then fetch the device’s config object from the API via the /devices/{deviceId}/config call and figure out what changed.
On a similar note, when setting a device or site’s configuration from the API, it’s best to fetch the current config object and apply whatever changes to you want to it, then pass the object back, instead of trying to rebuild the full config from scratch each time.
Please note that we continuously add and remove options from the config structure. Because of this we must put this in bold: do not update configuration with a predefined set of keys - always use existing values, or provided defaults to form new entities in config.
You have a couple of different options to proceed from here:
If you have any doubt about the allowed values of a config key, you can view a device’s configuration from the IgniteNet Cloud UI via the console in the developer tools:
That being said, here's a very simple example showing how to change a device's configuration, specifically creating a device-level override for a device's hotspot landing URL setting.
First, you'll make a GET request to fetch the current device config and timestamp:
GET https://cloud.ignitenet.com/pub/v1/device/INSERT_DEVICE_ID/config-changes
You'll see a response like this:
{
"unfinishedTaskCount": 0,
"configSuspended": false,
"configResync": false,
"timestamp": "5d478d10-4313-11e8-ba24-2de5f1a646e0", <-- You'll see this for your next POST action
"serverSideChanged": false,
"site": {...}, <-- For reference: this is the device's site-level config
"device": {...}, <-- For reference: this is the device's device-level config
"defaults": {...}
}
Next, POST the config changes to the same config-changes route:
POST https://cloud.ignitenet.com/pub/v1/device/INSERT_DEVICE_ID/config-changes
Make sure to include the timestamp from the GET response when forming the body:
{
"timestamp ": "5d478d10-4313-11e8-ba24-2de5f1a646e0",
"changes":
{
"hotspot/landingURL":
{
"value" : "https://www/.ignitenet.com",
"origin" : "site-device"
}
}
}
Reminder: an "origin" of site-device means the setting was inherited from the site level but is now being overriden at the device level config. Future changes to the site-level value will not have an affect on the device's config due to the override.
Once the POST completes, you can login to the Cloud UI and see a new override exists for this device's hotspot landing URL setting.
Timeouts and Errors
Error Handling
Handling unexpected situations is an important part of using the IgniteNet Cloud API. We run weekly maintenance on our production systems on Wednesdays of each week, which means there is a small chance of intermittent interruptions in service. Please expect some requests to fail and design your integration to be robust and able to recover from temporary failures.
Here are some of the possible error codes:
-
429 Too Many Requests :
We've received too many API requests from your network. There is a limit of 200 HTTP requests per 10s (or 20 rps).
-
502 Bad Gateway :
-
503 Service Unavailable :
The API service is undergoing maintenance.
When you encounter one of these errors, you can either inspect request manually or program your client in such a way that the request is retried later. We recommend a minimum retry interval of 60s with a maximum of 10 retries.
500 Internal Server Error
You do not always need to report 500 Errors to the support team as we are notified of these failures and issue hot patch fixes as soon as we can. Depending on the nature of the failure, you may be able to recover after a certain period of time. We recommend one retry after 60s.
Timeouts
It's possible for a request to time out due to network conditions. We use 30s timeouts internally, therefore if your request hangs longer than that without receiving any data, you can consider it failed. It's generally safe to retry GET and PUT methods.
Comments
0 comments
Article is closed for comments.