Cisco Meraki Deprecated

Cloud controlled WiFi, routing, and security. Deprecated. Use CiscoMerakiv2 instead.

IT Services · Cisco Meraki

Details

IDCisco Meraki
ProviderCisco Systems
CategoryIT Services
From Version5.0.0
Supported ModulesAgentix XSIAM

README

Cloud controlled WiFi, routing, and security.
This integration was integrated and tested with version 1.0.0 of Cisco Meraki

Configure Cisco Meraki in Cortex

Parameter Required
API Key True
Trust any certificate (not secure) False
Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

meraki-fetch-organizations


List the organizations that the api-key has privileges on.

Base Command

meraki-fetch-organizations

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
Organization List List of organizations. Each includes the ID and name.

Command Example


#### Context Example

```json
{
    "Organization": [
        {
            "ID": "828552",
            "Name": "Demisto"
        }
    ]
}

Human Readable Output

Organizations

id name url
828552 Demisto https://n146.meraki.com/o/N7z3rd/manage/organization/overview

meraki-get-organization-license-state


License state for an organization.

Base Command

meraki-get-organization-license-state

Input

Argument Name Description Required
organizationId Organization ID. Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
status String License status.
expirationDate String License expiration date.

Command Example

!meraki-get-organization-license-state organizationId=828552

Human Readable Output

Organization License State

status expirationDate
OK N/A

meraki-fetch-organization-inventory


List of inventories for an organization.

Base Command

meraki-fetch-organization-inventory

Input

Argument Name Description Required
organizationId Organization ID. Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
Devices List List of devices. Each includes Serial, NetworkId, Model, ClaimedAt, PublicIp, and MAC.

Command Example

!meraki-fetch-organization-inventory organizationId=828552

Human Readable Output

Organization Inventory

No entries.

meraki-fetch-networks


List the networks in an organization.

Base Command

meraki-fetch-networks

Input

Argument Name Description Required
organizationId Organization ID. Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
Network List List of networks. Each includes ID, Name, Type, OrganizationId, Tags, and TimeZone.

Command Example

!meraki-fetch-networks organizationId=828552

Context Example

{
    "Network": [
        {
            "ID": "N_645140646620837008",
            "Name": "Demisto-DEV",
            "OrganizationId": "828552",
            "Tags": null,
            "Timezone": "America/Los_Angeles",
            "Type": "switch"
        }
    ]
}

Human Readable Output

Networks

id organizationId name timeZone productTypes.0 type disableMyMerakiCom disableRemoteStatusPage
N_645140646620837008 828552 Demisto-DEV America/Los_Angeles switch switch - true

meraki-fetch-devices


List the devices in a network.

Base Command

meraki-fetch-devices

Input

Argument Name Description Required
networkId Network ID. Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
Device List List of devices. Each includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address.

Command Example

!meraki-fetch-devices networkId=N_645140646620837008

Human Readable Output

Devices

No entries.

meraki-fetch-device-uplink


List of uplink information for a device.

Base Command

meraki-fetch-device-uplink

Input

Argument Name Description Required
networkId Network ID. Required
serial Device serial number. Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
Uplink List List of device uplink. Each includes Status and Interface

Command Example


#### Human Readable Output

### meraki-fetch-ssids

***
List the SSIDs in a network.

#### Base Command

`meraki-fetch-ssids`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| networkId | Network ID. | Required |
| headers | Table's headers to be shown by order. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| SSID | List | List of SSIDs. Each includes Number, NetworkId, Name, SplashPage, BandSelection, Enabled, AuthMode, and WalledGardenRanges. |

#### Command Example

Human Readable Output

meraki-fetch-clients


List the clients of a device, up to a maximum of a month ago.

Base Command

meraki-fetch-clients

Input

Argument Name Description Required
serial Device serial number. Required
timespan The timespan (in seconds) during which clients will be fetched. Must be at most one month and in seconds (e.g., 1 day is 86400 seconds). Required
headers Table’s headers to be shown by order. Optional

Context Output

Path Type Description
Client List List of clients. Each includes ID, MAC, IP, Description, mDNSName, Hostname, Usage, and VLAN.

Command Example


#### Human Readable Output

### meraki-fetch-firewall-rules

***
List of L3 firewall rules for an SSID.

#### Base Command

`meraki-fetch-firewall-rules`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| networkId | Network ID. | Required |
| number | SSID number. | Required |
| headers | Table's headers to be shown by order. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Firewall | List | List of firewalls. Each includes Number, NetworkId, Policy, Protocol, DestPort, DestCidr, and Comment. |

#### Command Example

Human Readable Output

meraki-remove-device


Remove a single device.

Base Command

meraki-remove-device

Input

Argument Name Description Required
networkId Network ID. Required
serial Serial number of the device to remove. Required

Context Output

There is no context output for this command.

Command Example


#### Human Readable Output

### meraki-get-device

***
Get a single device.

#### Base Command

`meraki-get-device`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| networkId | Network ID. | Required |
| serial | Device serial number. | Required |
| headers | Table's headers to be shown by order. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Device | unknown | Device which includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address |

#### Command Example

Human Readable Output

meraki-update-device


Update the attributes of a device.

Base Command

meraki-update-device

Input

Argument Name Description Required
networkId Network ID. Required
serial Serial number of the device to update. Required
name New name of the device. Optional
tags New tags of the device. Optional
address New address of the device. Optional
lat New latitude of the device. Optional
lng New longitude of the device. Optional

Context Output

Path Type Description
Device unknown Updated device which includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address.

Command Example


#### Human Readable Output

### meraki-claim-device

***
Claim a device into a network.

#### Base Command

`meraki-claim-device`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| networkId | Network ID. | Required |
| serial | Serial number of the device to claim. | Required |

#### Context Output

There is no context output for this command.

#### Command Example

Human Readable Output

meraki-update-firewall-rules


Update rule to L3 firewall rules of an SSID.

Base Command

meraki-update-firewall-rules

Input

Argument Name Description Required
networkId Network ID. Required
number SSID number. Default is . Required
allowLanAccess Whether to allow or deny wireless client access to the local LAN. True allows access and false denies access. Possible values: true, false. Possible values are: true, false. Required
policy Whether to allow or deny a protocol. Possible values: “allow” and “deny”. Possible values are: allow, deny. Required
protocol The type of protocol. Possi ble values: “tcp”, “udp”, “icmp”, and “any”. Possible values are: tcp, udp, icmp, any. Required
destPort The destination port. Can be “any” or an integer within the range of 1-65535. Required
destCidr The destination IP address or subnet in CIDR form. Can also be “any”. Required
comment A note about the rule. Optional
removeOthers Whether to remove all other rules. True removes all other rules. False only adds the rule. Possible values: “true” and “false”. Possible values are: true, false. Required

Context Output

Path Type Description
Firewall List List of firewalls. Each includes Number, NetworkId, Policy, Protocol, DestPort, DestCidr, and Comment

Command Example

``````

Human Readable Output

Configuration parameters

  • apiKey — API Key
  • apikey_creds
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (14)

  • meraki-claim-device Deprecated

    Claim a device into a network.

  • meraki-fetch-clients Deprecated

    List the clients of a device, up to a maximum of a month ago.

  • meraki-fetch-device-uplink Deprecated

    List of uplink information for a device.

  • meraki-fetch-devices Deprecated

    List the devices in a network.

  • meraki-fetch-firewall-rules Deprecated

    List of L3 firewall rules for an SSID.

  • meraki-fetch-networks Deprecated

    List the networks in an organization.

  • meraki-fetch-organization-inventory Deprecated

    List of inventories for an organization.

  • meraki-fetch-organizations Deprecated

    List the organizations that the api-key has privileges on.

  • meraki-fetch-ssids Deprecated

    List the SSIDs in a network.

  • meraki-get-device Deprecated

    Get a single device.

  • meraki-get-organization-license-state Deprecated

    License state for an organization.

  • meraki-remove-device Deprecated

    Remove a single device.

  • meraki-update-device Deprecated

    Update the attributes of a device.

  • meraki-update-firewall-rules Deprecated

    Update rule to L3 firewall rules of an SSID.

commonfields:
  id: Cisco Meraki
  version: -1
name: Cisco Meraki
display: Cisco Meraki (Deprecated)
deprecated: true
category: IT Services
provider: Cisco Systems
image: data:image/png;base64,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
description: Cloud controlled WiFi, routing, and security. Deprecated. Use CiscoMerakiv2 instead.
detaileddescription: Get the API key from the Meraki dashboard.
configuration:
- display: API Key
  name: apiKey
  defaultvalue: ""
  type: 4
  hidden: true
- name: apikey_creds
  type: 9
  displaypassword: API Key
  hiddenusername: true
- display: Trust any certificate (not secure)
  name: insecure
  required: false
  type: 8
- display: Use system proxy settings
  name: proxy
  required: false
  type: 8
script:
  script: >
    /**
       * flatten nested object to top level fields
       * @param {Object | Array<Object>} ob - object to flatten
       * @returns {String} the flatten object
       * { "a": "bla", "b": { "c": "hello", "d": "there" } } => { "a": "bla", "b.c" = "hello", "b.d": "there" }
    */

    var flattenObject = function(ob) {
        var toReturn = {};

        for (var i in ob) {
            if (!ob.hasOwnProperty(i)) continue;

            if ((typeof ob[i]) == 'object') {
                var flatObject = flattenObject(ob[i]);
                for (var x in flatObject) {
                    if (!flatObject.hasOwnProperty(x)) continue;

                    toReturn[i + '.' + x] = flatObject[x];
                }
            } else {
                toReturn[i] = ob[i];
            }
        }
        return toReturn;
    };


    /**
       * Converts a demisto table in JSON form to a Markdown table
       * @param {String} name - the name of the table
       * @param {Object | Array<Object>} table - the JSON table - Array of objects with the same keys
       * @param {Array} headers - optinal, the output markdown table will show only this headers (by order)
       * @returns {String} Markdown representation of the original list
    */

    var tableToMd = function(name, table, headers) {

        if (!(table instanceof Array)){
              table = [table];
          }

        var res = '### ' + name + '\n';
        table = table.map(flattenObject);
        if(table && table.length) {
            // use table's keys if headers are not provieded
            if(!headers) {
                headers = Object.keys(table[0]);
            }

            // headers
            res += headers.join('|') + '\n';
            res += headers.map(function(h) { return '-'; }).join('|') + '\n';

            // body
            for(var i = 0; i< table.length; i++) {
                var obj = table[i];
                var values = [];
                var val;
                headers.forEach(function(key) {
                    val = '-';
                    if (obj[key] || obj[key] === '0' || obj[key] === '0') {
                        val = obj[key];
                    }
                    values.push(val);
                });
                res += values.join('|') + '\n';
            }
        } else {
            res += '**No entries.**\n';
        }
        return res;
    }


    var createTableEntry = function (name, contents, context, headers) {
        return {
            // type
            Type: entryTypes.note,
             // contents
            ContentsFormat: formats.json, Contents: contents,
            // human-readable
            ReadableContentsFormat: formats.markdown, HumanReadable: tableToMd(name, contents, headers),
            // context
            EntryContext: context
        };
    }


    var createTextEntry = function(text) {
        return text;
    }


    var createMapEntry = function(obj) {

        var location = {
            lat: obj.lat,
            lng: obj.lng
        };

        return {
            // type
            Type: 15, // entryTypes.map,
             // contents
            ContentsFormat: formats.json, Contents: location
        };
    }


    var merakiUrlPrefix = 'https://api.meraki.com/api/v0/';

    var apiKey = params.apikey_creds ? params.apikey_creds.password : params.apiKey;

    var insecure = params.insecure;

    var proxy = params.proxy;


    var sendRequest = function(url, method, body) {

        var requestMethod = method || 'GET';
        var requestUrl = merakiUrlPrefix + url;

        var httpParams = {
            Method: requestMethod,
            Headers: {
                'X-Cisco-Meraki-API-Key': [apiKey],
                'Content-Type': ['application/json'],
            },
            Body: body
        };

        var res = http(
            requestUrl,
            httpParams,
            insecure,
            proxy,
            true // no redirect (e.i. request is not automatically redirect - instead it will return 302)
        );

        // catch redirect response
        if (res && (res.StatusCode === 302 || res.StatusCode === 308)) {
            var redirectUrl = res.Headers.Location;

            res = http(
                    redirectUrl,
                    httpParams,
                    insecure,
                    proxy
            );
        }

        if (!res || res.StatusCode < 200 || res.StatusCode >= 300) {
            throw 'Request Failed. '
            + '\nUrl: ' + requestUrl
            + '\nStatus code: ' + res.StatusCode
            + '\nSurl: ' + res.StatusCode
            + '.\nBody: ' + JSON.stringify(res) + '.';
        }

        if(requestMethod === 'POST') {
            // action succeed - than just return true
            return true;
        } else {
             var resBody = JSON.parse(res.Body);
        if (resBody === undefined) {
           throw 'Request Failed, returned response with no body';
        }
        return resBody;
        }
    };


    /**
       * return a function that transform object from some structure to other
       * @param {Array} fields - array of {from: String, to: String} - to transform by
       * @returns {Function} array from the original string-list
    */

    var mapObjFunction = function(mapFields) {
        return function(obj) {
            var res = {};
            mapFields.forEach(function(f) {
               res[f.to] = (obj[f.from] !== undefined) ? obj[f.from] : null;
            });
            return res;
        }
    }


    // maps device api-object to context-object

    var mapDeviceFunction = mapObjFunction([
        { from: 'serial', to: 'Serial' },
        { from: 'name', to: 'Name' },
        { from: 'mac', to: 'MAC' },
        { from: 'lat', to: 'Lat' },
        { from: 'lng', to: 'Lng' },
        { from: 'address', to: 'Address' },
        { from: 'lanIp', to: 'LanIp' },
        { from: 'tags', to: 'Tags' },
        { from: 'networkId', to: 'NetworkId' },
        { from: 'model', to: 'Model' },
        { from: 'claimedAt', to: 'ClaimedAt' },
        { from: 'publicIp', to: 'PublicIp' }
    ]);


    // maps firewall api-object to context-object

    var mapFirewallFunction = mapObjFunction([
        { from: 'comment', to: 'Comment' },
        { from: 'policy', to: 'Policy' },
        { from: 'protocol', to: 'Protocol' },
        { from: 'destPort', to: 'DestPort' },
        { from: 'destCidr', to: 'DestCidr' }
    ]);


    // --------- organizations ------- //

    var fetchOrganizations = function() {
        // get result from http
        var organizations = sendRequest('organizations');

        // create context
        var context = {};
        if(organizations && organizations.length) {
            context.Organization = organizations.map(mapObjFunction([
                { from: 'id', to: 'ID' },
                { from: 'name', to: 'Name' }
            ]));
        }
        return createTableEntry("Organizations", organizations, context);
    };


    var getOrganizationLiceseState = function(organizationId, headers) {
        // get result from http
        var license = sendRequest('organizations/' + organizationId + '/licenseState');

        return createTableEntry("Organization License State", license, {}, headers);
    };


    var fetchOrganizationInventory = function(organizationId, headers) {
        // get result from http
        var devices = sendRequest('organizations/' + organizationId + '/inventory');

         // create context
        var context = {};
        if(devices && devices.length) {
            context.Device = devices.map(mapDeviceFunction);
        }

        return createTableEntry("Organization Inventory", devices, context, headers);
    };


    // --------- networks ------- //


    var fetchNetworks = function(organizationId, headers) {
         // get result from http
        var networks = sendRequest('organizations/' + organizationId + '/networks');

         // create context
        var context = {};
        if(networks && networks.length) {
            context.Network = networks.map(mapObjFunction([
                { from: 'id', to: 'ID' },
                { from: 'organizationId', to: 'OrganizationId' },
                { from: 'type', to: 'Type' },
                { from: 'name', to: 'Name' },
                { from: 'timeZone', to: 'Timezone' },
                { from: 'tags', to: 'Tags' },
            ]));
        }

        return createTableEntry("Networks", networks, context, headers);
    };


    // --------- devices ------- //


    var fetchDevices = function(networkId, headers) {
         // get result from http
        var devices = sendRequest('networks/' + networkId + '/devices');

         // create context
        var context = {};
        if(devices && devices.length) {
            context.Device = devices.map(mapDeviceFunction);
        }

        return createTableEntry("Devices", devices, context, headers);
    };


    var fetchDeviceUplink = function(networkId, serial, headers) {
        // get result from http
        var uplinks = sendRequest('networks/' + networkId + '/devices/' + serial + '/uplink');

         // create context
        var context = {};
        if(uplinks && uplinks.length) {
            context.Uplink = uplinks.map(mapObjFunction([
                { from: 'status', to: 'Status' },
                { from: 'interface', to: 'Interface' }
            ]));
        }
        return createTableEntry("Device Uplink", uplinks, context, headers);
    };


    var fetchDeviceClients = function(serial, timespan, headers) {
        // get result from http
        var clients = sendRequest('devices/' + serial + '/clients?timespan=' + timespan);

         // create context
        var context = {};
        if(clients && clients.length) {
            context.Client = clients.map(mapObjFunction([
                { from: 'description', to: 'Description' },
                { from: 'mdnsName', to: 'mDNSName' },
                { from: 'dhcpHostname', to: 'Hostname' },
                { from: 'usage', to: 'Usage' },
                { from: 'mac', to: 'MAC' },
                { from: 'ip', to: 'IP' },
                { from: 'id', to: 'ID' },
                { from: 'vlan', to: 'VLAN' }
            ]));
        }

        return createTableEntry("Clients", clients, context, headers);
    };


    var getDevice = function(networkId, serial, headers) {
         // get result from http
        var device = sendRequest('networks/' + networkId + '/devices/' + serial);

         // create context
        var context = {};
        if(device) {
            context.Device = mapDeviceFunction(device);
        }

        return [createTableEntry("Device " + serial, device, context, headers), createMapEntry(device)];
    };


    var removeDevice = function(networkId, serial) {
        var res = sendRequest('networks/' + networkId + '/devices/' + serial + '/remove', 'POST');

        var textResult;
        if(res) {
                textResult = 'Successfully removed device ' + serial + ' from network ' + networkId;
        } else {
            textResult = 'Failed to removed device ' + serial + ' from network ' + networkId;
        }
        return createTextEntry(textResult);
    };


    var updateDevice = function(networkId, serial, updateArgs) {
        //send update request
        var url = 'networks/' + networkId + '/devices/' + serial;

        var body = {};
        var keys = Object.keys(updateArgs);
        keys.forEach(function (key) {
           if(updateArgs[key]) {
               body[key] = updateArgs[key];
           }
        });

        var device = sendRequest(url, 'PUT', JSON.stringify(body));

        // create context
        var context = {};
        if(device) {
            context.Device = mapDeviceFunction(device);
        }

        return createTableEntry("Successfully Updated Device " + serial, device, context);
    }


    var claimDevice = function(networkId, serial) {
        var url = 'networks/' + networkId + '/devices/claim';
        var body = { serial: serial };

        var succeed = succeed(url, 'POST', JSON.stringify(body));

        var resStr;
        if(succeed) {
            resStr = 'Successfully joined device ' + serial + ' to network ' + networkId;
        } else {
            resStr = 'Failed to claim device ' + serial + ' to network ' + networkId;
        }
    };


    var fetchSsids = function(networkId, headers) {
        // get result from http
        var ssids = sendRequest('networks/' + networkId + '/ssids');


         // create context
        var context = {};
        if(ssids && ssids.length) {
            context.SSID = ssids
            .map(mapObjFunction([
                { from: 'name', to: 'Name' },
                { from: 'splashPage', to: 'SplashPage' },
                { from: 'bandSelection', to: 'BandSelection' },
                { from: 'enabled', to: 'Enabled' },
                { from: 'authMode', to: 'AuthMode' },
                { from: 'walledGardenRanges', to: 'WalledGardenRanges' },
                { from: 'number', to: 'Number' }
            ]))
            .map(function(ssid) {
                ssid.NetworkId = networkId;
                return ssid;
            });
        }
        return createTableEntry("SSIDs", ssids, context, headers);
    };


    var fetchFirewallRules = function(networkId, number, headers) {
        // get result from http
        var firewalls = sendRequest('networks/' + networkId + '/ssids/' + number + '/l3FirewallRules');
         // create context
        var context = {};
        if(firewalls && firewalls.length) {
            context.Firewall = firewalls
            .map(mapFirewallFunction)
            .map(function(fireWall) {
                fireWall.NetworkId = networkId;
                fireWall.Number = number;
                return fireWall;
            });
        }
        return createTableEntry("Firewall Rules", firewalls, context, headers);
    };


    var updateFirewallRules = function(networkId, number, allowLanAccess, removeOthers, rule) {
        var url = 'networks/' + networkId + '/ssids/' + number + '/l3FirewallRules';

        var rules;
        if(removeOthers) {
            rules = [rule];
        } else {
            rules = sendRequest('networks/' + networkId + '/ssids/' + number + '/l3FirewallRules');
            rules = rules.slice(0, -2); // remove defulat & local LAN access rules
            rules.push(rule);
        }
        var body = {
            allowLanAccess: allowLanAccess,
            rules: rules
        };

        var firewalls = sendRequest(url, 'PUT', JSON.stringify(body));

         // create context
        var context = {};
        if(firewalls && firewalls.length) {
            context.Firewall = firewalls
            .map(mapFirewallFunction)
            .map(function(fireWall) {
                fireWall.NetworkId = networkId;
                fireWall.Number = number;
                return fireWall;
            });
        }
        return createTableEntry("Firewall Rules", firewalls, context);
    };



    // --------------------- main -------------------- //

    switch (command) {
        case 'test-module':
            fetchOrganizations();
            return 'ok';
        // organization
        case 'meraki-fetch-organizations':
            return fetchOrganizations();
        case 'meraki-fetch-organization-inventory':
            return fetchOrganizationInventory(
                args.organizationId,
                args.headers && args.headers.split(',')
            );
        case 'meraki-get-organization-license-state':
            return getOrganizationLiceseState(
                args.organizationId,
                args.headers && args.headers.split(',')
            );
        // network
        case 'meraki-fetch-networks':
            return fetchNetworks(
                args.organizationId,
                args.headers && args.headers.split(',')
            );
        // device
        case 'meraki-fetch-devices':
            return fetchDevices(
                args.networkId,
                args.headers && args.headers.split(',')
            );
        case 'meraki-get-device':
            return getDevice(
                args.networkId,
                args.serial,
                args.headers && args.headers.split(',')
            );
        case 'meraki-update-device':
            return updateDevice(
                args.networkId,
                args.serial,
                { // updateArgs
                    name: args.name,
                    tags: args.tags,
                    address: args.address,
                    lat: args.lat,
                    lng: args.lng
                }
            );
        case 'meraki-claim-device':
            return claimDevice(
                args.serial,
                args.networkId
            );
        case 'meraki-fetch-device-uplink':
             return fetchDeviceUplink(
                args.networkId,
                args.serial,
                args.headers && args.headers.split(',')
            );
        case 'meraki-fetch-clients':
            return fetchDeviceClients(
                args.serial,
                args.timespan,
                args.headers && args.headers.split(',')
            );
        case 'meraki-fetch-firewall-rules':
            return fetchFirewallRules(
                args.networkId,
                args.number,
                args.headers && args.headers.split(',')
            );
        case 'meraki-update-firewall-rules':
            return updateFirewallRules(
                args.networkId,
                args.number,
                (args.allowLanAccess === "true"),
                (args.removeOthers === "true"),
                {
                    policy: args.policy,
                    protocol: args.protocol,
                    destPort: args.destPort,
                    destCidr: args.destCidr,
                    comment: args.comment
                }
            );
        case 'meraki-remove-device':
            var networkId = args.networkId;
            var serial = args.serial;
            return removeDevice(networkId, serial);
        // ssid
        case 'meraki-fetch-ssids':
            return fetchSsids(
                args.networkId,
                args.headers && args.headers.split(',')
            );
        default:
            throw 'Unrecognized command';
    }
  type: javascript
  commands:
  - name: meraki-fetch-organizations
    deprecated: true
    arguments: []
    outputs:
    - contextPath: Organization
      description: List of organizations. Each includes the ID and name.
      type: list
    description: List the organizations that the api-key has privileges on.
  - name: meraki-get-organization-license-state
    deprecated: true
    arguments:
    - name: organizationId
      required: true
      description: Organization ID.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: status
      description: License status.
      type: String
    - contextPath: expirationDate
      description: License expiration date.
      type: String
    description: License state for an organization.
  - name: meraki-fetch-organization-inventory
    deprecated: true
    arguments:
    - name: organizationId
      required: true
      description: Organization ID.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Devices
      description: List of devices. Each includes Serial, NetworkId, Model, ClaimedAt, PublicIp, and MAC.
      type: list
    description: List of inventories for an organization.
  - name: meraki-fetch-networks
    deprecated: true
    arguments:
    - name: organizationId
      required: true
      description: Organization ID.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Network
      description: List of networks. Each includes ID, Name, Type, OrganizationId, Tags, and TimeZone.
      type: list
    description: List the networks in an organization.
  - name: meraki-fetch-devices
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Device
      description: List of devices. Each includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address.
      type: list
    description: List the devices in a network.
  - name: meraki-fetch-device-uplink
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: serial
      required: true
      description: Device serial number.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Uplink
      description: List of device uplink. Each includes Status and Interface.
      type: list
    description: List of uplink information for a device.
  - name: meraki-fetch-ssids
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: SSID
      description: List of SSIDs. Each includes Number, NetworkId, Name, SplashPage, BandSelection, Enabled, AuthMode, and WalledGardenRanges.
      type: list
    description: List the SSIDs in a network.
  - name: meraki-fetch-clients
    deprecated: true
    arguments:
    - name: serial
      required: true
      description: Device serial number.
    - name: timespan
      required: true
      description: 'The timespan (in seconds) during which clients will be fetched. Must be at most one month and in seconds (e.g., 1 day is 86400 seconds).'
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Client
      description: List of clients. Each includes ID, MAC, IP, Description, mDNSName, Hostname, Usage, and VLAN.
      type: list
    description: List the clients of a device, up to a maximum of a month ago.
  - name: meraki-fetch-firewall-rules
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: number
      required: true
      description: SSID number.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Firewall
      description: List of firewalls. Each includes Number, NetworkId, Policy, Protocol, DestPort, DestCidr, and Comment.
      type: list
    description: List of L3 firewall rules for an SSID.
  - name: meraki-remove-device
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: serial
      required: true
      description: Serial number of the device to remove.
    description: Remove a single device.
  - name: meraki-get-device
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: serial
      required: true
      description: Device serial number.
    - name: headers
      description: Table's headers to be shown by order.
    outputs:
    - contextPath: Device
      description: Device which includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address.
    description: Get a single device.
  - name: meraki-update-device
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: serial
      required: true
      description: Serial number of the device to update.
    - name: name
      description: New name of the device.
    - name: tags
      description: New tags of the device.
    - name: address
      description: New address of the device.
    - name: lat
      description: New latitude of the device.
    - name: lng
      description: New longitude of the device.
    outputs:
    - contextPath: Device
      description: Updated device which includes Serial, Name, Lat, Lng, Model, NetworkId, Tags, MAC, and Address.
    description: Update the attributes of a device.
  - name: meraki-claim-device
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: serial
      required: true
      description: Serial number of the device to claim.
    description: Claim a device into a network.
  - name: meraki-update-firewall-rules
    deprecated: true
    arguments:
    - name: networkId
      required: true
      description: Network ID.
    - name: number
      required: true
      description: SSID number.
      defaultValue: ' '
    - name: allowLanAccess
      required: true
      auto: PREDEFINED
      predefined:
      - "true"
      - "false"
      description: 'Whether to allow or deny wireless client access to the local LAN. True allows access and false denies access. Possible values: true, false.'
    - name: policy
      required: true
      auto: PREDEFINED
      predefined:
      - allow
      - deny
      description: 'Whether to allow or deny a protocol. Possible values: "allow" and "deny".'
    - name: protocol
      required: true
      auto: PREDEFINED
      predefined:
      - tcp
      - udp
      - icmp
      - any
      description: 'The type of protocol. Possi ble values: "tcp", "udp", "icmp", and "any".'
    - name: destPort
      required: true
      description: 'The destination port. Can be "any" or an integer within the range of 1-65535.'
    - name: destCidr
      required: true
      description: The destination IP address or subnet in CIDR form. Can also be "any".
    - name: comment
      description: A note about the rule.
    - name: removeOthers
      required: true
      auto: PREDEFINED
      predefined:
      - "true"
      - "false"
      description: 'Whether to remove all other rules. True removes all other rules. False only adds the rule. Possible values: "true" and "false".'
    outputs:
    - contextPath: Firewall
      description: List of firewalls. Each includes Number, NetworkId, Policy, Protocol, DestPort, DestCidr, and Comment.
      type: list
    description: Update rule to L3 firewall rules of an SSID.
tests:
- Cisco-Meraki-Test
fromversion: 5.0.0