Automation

gonzague
Comes here often

Automation

Hello, i have a few questions today (pls remember i am a newbie on Meraki, so pls make your answer easy to understand). I recently setup Postman to do my own extractions because the files proposed by the web site are somewhat limited.

 

So now i want to extrat the list of all equipment we are supervising using the command GET /networks/[networkId]/devices

 

1/ Can i create a batch of such requests to automate the process ? If so, how ?

2/ Can i direct the result of a command to a file ? If so, how ? Can i then select the output format, for example tabular ?

3/ Can i build a more intelligent script, one that will find the list of all network ids first, then enter the get devices command for all networks ?

thanks in advance for your answers ! Gp

16 REPLIES 16
HodyCrouch
Building a reputation

Yes, you can automate Meraki's API calls to get the information you need.  You'll just need a little code to get the job done.  There are many ways and many tools you could use.  This example uses Node.js.  If you're not familiar with using Node, you may need a little help getting started.

 

I assume you already have a valid API Key.  You will need to install the async and request packages using npm.

 

You can get a list of organizations that you can access pretty easily.  If you don't want to do it manually (Postman is fine), you can use a bit of Node.js code:

 

var request = require('request');
var credentials=require('./credentials');  // Includes credentials.API_KEY

const options = {
    url: 'https://dashboard.meraki.com/api/v0/organizations',
    headers: { 
      "X-Cisco-Meraki-API-Key":credentials.API_KEY,
      "Content-Type": 'application/json'
    },
};

request.get(options, function(error, response, body) {
  if (error) console.error(error);
  else {
    var orgList = JSON.parse(body);
    orgList.forEach(function(item) {
      console.log(item.id, item.name);
    });
  }
});

 

Now that you have the organization id, you can get the list of networks.

 

var request = require('request');
var credentials=require('./credentials');  // Includes credentials.API_KEY

const organizationId='ORG_ID_GOES_HERE';

const options = {
    url: 'https://api.meraki.com/api/v0/organizations/' + organizationId + '/networks',
    headers: { 
      "X-Cisco-Meraki-API-Key":credentials.API_KEY,
      "Content-Type": 'application/json'
    },
};

request.get(options, function(error, response, body) {
  if (error) console.error(error);
  else {
    console.log('module.exports = ' + body);
  }
});

When you run this code, send the output to a file.  For example, "node getNetworks.js > networks.js"

 

Since the network list is now in a file, we can use it in the next script to accomplish your #3 request.

 

Getting the device list from each network takes a little more code, but it's not too bad.

 

var request = require('request');
var async = require('async');
var credentials=require('./credentials');  // Includes credentials.API_KEY
var networks=require('./networks.js');

const urlPattern = 'https://dashboard.meraki.com/api/v0/networks/{networkId}/devices'

var options = {
    headers: { 
      "X-Cisco-Meraki-API-Key":credentials.API_KEY,
      "Content-Type": 'application/json'
    },
};

var devices = [];

async.eachSeries(networks, getDeviceList, processDeviceList);

function getDeviceList(network, next) {
  options.url = urlPattern.replace('{networkId}', network.id);

  request.get(options, function(error, response, body) {
    if (error) next(error);
    else {
      devices = devices.concat(JSON.parse(body));
      next();
    }
  });
}

function processDeviceList(err) {
  if (err) console.error(err)
  else {
    console.log('module.exports = ' + JSON.stringify(devices));
  }
}

One thing that I haven't addressed in any of this code is Meraki's API request limit.  Since these requests are all running in serial, I doubt you'll hit the limit.

thanks ! I do not know node.js, so I will check and try !

Hello, thanks for all this. I have to admit I did not manage to get it work. I do not know java... I use to program in C, I do not know the programming linked to internet.. I need java for dummies !!
the require('request') fails, I suppose I have to define a directory , it does not know where to find it ?
In the code I do not see where I indicate my API Key...
Not sure if you have time to help me more ?
HodyCrouch
Building a reputation

I'm using Node.js in this example (not Java).

 

You can install Node.js from https://nodejs.org/en/download/

 

You need to install the request module before running the code:

- create a directory

- create a file for each example, like getOrganizations.js and getNetworks.js (and copy the code I provided)

- create a file called credentials.js and paste the following code (replace with your API key):

module.exports = {API_KEY:'YOUR_KEY_GOES_HERE'};

- from this directory, type 'npm install request'

 

Now, you should be able to run the code.  Feel free to reply if you're still having trouble.  If you have other questions about specific API calls, there's another forum here that you might want to use.

thanks again, this is progressing. So here is the next error message :

orglist.foreach(function(item){

TypeError: orgList.forEach is not a function

 

 

HodyCrouch
Building a reputation

The call is probably failing.  You may not have included your API key, the key is invalid, or something else is going on.

 

Just before the line containing JSON.parse, add a line containing "console.log(body);" and see what you get.

you are right. Seems we have a problem with one of the organizations right now, we just opened a ticket for that.

So anyways, I went to the next step and got the network id just for one organization, your code works !

 

However when I use the 3rd part to get the devices, I get an error again... It does not find async ! What am I missing this time ?

 

When we use an output file, is there a way to change its format to use a tabular form ?

 

found it ... npn install async !!

 

So can we change the output format ? Otherwise I just use a soft to change the format !

HodyCrouch
Building a reputation

Sure.  Give this a try.  Replace processDeviceList with something like this:

 

 

  function processDeviceList(err) {
    if (err) console.error(err)
    else {
      console.log(['lanIp', 'serial', 'mac', 'name', 'networkId'].join('\t'));
      for (var i=0; i<devices.length; i++) {
        let device=devices[i];
        console.log([device.lanIp, device.serial, device.mac, device.name, device.networkId].join('\t'))
      }
    }
  }

 

That's tab-delimited.  You can change the delimiter by replacing the '\t' part with whatever you want.  There are some additional fields available.  Take a look a the Devices documentation in the Meraki Dashboard API help for details.

 

In case it helps anyone else, here's a quick file with the code and steps required to get started.

https://drive.google.com/open?id=19GiAf6cYXAjX3ijZKIYHXVGkTTgj2Qi1

it works, thanks again !

I added the address in the request. Unfortunately there are line breaks in that field and it messes up the entire output. Is there a way to avoid that ?

and by the way I have police issues : St-François I/o St-François. Any idea to correct that ?

HodyCrouch
Building a reputation

I think it's time to close this thread, at least for me.

 

You're talking about issues that can be completely solved in software, but are beyond the scope of basic interactions with Meraki's dashboard API.  There are many ways of dealing with embedded line breaks, but it all depends on how you plan to work with the data.  Your character encoding issue can probably be sorted out by using UTF-8.

alright, thank you very much for your help !

PhilipDAth
Kind of a big deal
Kind of a big deal

When you say "supervising" you don't mean MDM clients (aka iOS and Android devices), do you?

no, I do not !
Andy42
New here

Thank you, 1 more question what does "node_mac" mean in this process?

Get notified when there are additional replies to this discussion.