Giter Site home page Giter Site logo

packetsar / meraki-cli Goto Github PK

View Code? Open in Web Editor NEW
81.0 81.0 16.0 3.02 MB

A simple CLI tool to automate and control your Cisco Meraki Dashboard

License: MIT License

Shell 0.89% Python 99.11%
cisco cisco-meraki cisco-meraki-ap cisco-meraki-api cli-helper meraki meraki-api meraki-cli meraki-dashboard meraki-sdk meraki-systems

meraki-cli's People

Contributors

mikevoelker avatar oborys avatar packetsar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meraki-cli's Issues

Cannot filter on inconsistent keys

Some Meraki API endpoints return inconsistent keys in their data. An example of this is the switch getDeviceSwitchPortsStatuses command/function which will return lldp keys and values for a port only when data exists to populate the value. Example below:

~/$ meraki -j -f lldp:test switch getDeviceSwitchPortsStatuses --serial XXXX-XXXX-XXXX
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/bin/meraki", line 8, in <module>
    sys.exit(main())
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/meraki_cli/__main__.py", line 1188, in main
    result = _object_filter(result, args.filters,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/meraki_cli/__main__.py", line 709, in _object_filter
    if re.search(fdict['regex'], str(item[fdict['key']])):
KeyError: 'lldp'
~/$ 

This makes filtering based on those inconsistent keys impossible because the _object_filter() function will throw a KeyError when it attempts to filter a dict which doesn't contain the key. This is, up to this point, intended behavior. In fact there is even a test case for it (testObjectFilterKeyMissingError()).

This behavior needs to be changed to allow inconsistent, or even nonexistent keys to be provided for filtering. It is, however, not preferred to silently fail as that would prevent the user from being alerted of a mistake.

Below is a proposed NEW way to handle this within the _object_filter() function:


If working under the default "OR" logic:

  • Loop through each filter key
    • Perform a check of all dicts in the listofdicts for the filter key
      • If the key exists in even a single dict, then escape the check and allow the next key to be checked
      • If the key does NOT exist in any of the dicts, then throw a warning and allow the next key to be checked (do not return from the filter, since we are using OR logic, and the next filter might allow objects to pass)
  • Perform the filtering of the objects
    • If the object is missing a filter key, then fail only that filter. If the key exists filter as normal

If working under the "AND" logic:

  • Loop through each filter key
    • Perform a check of all dicts in the listofdicts for the filter key
      • If the key exists in even a single dict, then escape the check and allow the next key to be checked
      • If the key does NOT exist in any of the dicts, then throw a warning and return an empty result (since none of the objects will be able to pass through the filter)
        • REASONING: It is better to return an empty result (to be safe) than return everything. If somebody fat fingers a filter key and pipes it into another command, and we default to returning everything, the results could be disastrous
  • Perform the filtering of the objects
    • If the object is missing a filter key, then filter out that object. If the key exists filter as normal

getDeviceLldpCdp Output

When using the command meraki devices getDeviceLldpCdp --serial <serial num>, the resulting table contains only the "sourceMac" and none of the actual LLDP or CDP data.

Trying it with the -ddd argument, we recieve the following Discarding data in table squash: ports: {'4': {'cdp'..... The code is obviously retrieving the CDP/LLDP results but discarding the wrong parts in order to create the table.

Thank you so much for creating this tool, it is excellent for quick lookups and adjustments!

List arguments should use proper nargs in argparse

Currently, the command meraki -ddd organizations createOrganizationNetwork --organizationId xxxxxxxxx --name "Meraki-CLI Network" --productTypes appliance switch will only pass the first --productTypes argument value (appliance) instead of accepting multiple.

When building the argument, we should use something like nargs='+' to automatically create the list expected by the function.

Positional arguments don't decode JSON

If a positional (required) argument with a list or dict annotation type is passed into Meraki-CLI, and that value is of proper JSON format, it is not decoded into a native dict/list, but it should be.

If the argument comes from a keyword arg in the source method, this decode happens fine.

Complex data tabulation using the -s option

Allow the input of JSONPath-like syntax to extract complex data for tabulation.

Example:

The meraki networks getNetworkClients command provides output like

    {
        "id": "xxxxxxxx",
        "mac": "xx:xx:xx:xx:xx:xx",
        "description": "SomeEndpoint",
        "usage": {
            "sent": 711311,
            "recv": 345962,
            "total": 1057274
        },
        "status": "Online",
        "notes": null,
        "groupPolicy8021x": null,
        "adaptivePolicyGroup": null,
        "smInstalled": false
    }

Normally, the usage data is squashed out of tabulation.

Allow the use of an option like -s "id,mac,usage.sent,usage.recv" with dot-separators to extract and tabulate the nested data.

Wrong table data when keys inconsistent

When running meraki networks getNetworkDevices --networkId N_XXX, if some devices have a name set (and therefore have a name key in their returned object) and some devices do not, the names and models get mixed together in the same column with the name overwriting the model when it does exist.

Shortcuts, or "Extra" commands

Hi John, Couple of requests for you sir!

Could we create a shortcut command path when assigning as static IP address to a Meraki Device, currently its quite long see example below.

meraki -j devices updateDeviceManagementInterface --serial "QXXX-XXXX-XXX" --wan1
'{
"usingStaticIp": true,
"staticIp": "0.0.0.0",
"staticSubnetMask": "255.255.255.0",
"staticGatewayIp": "0.0.0.0",
"staticDns": [
"1.1.1.1"
],
"vlan": 666
}'

Would it also be possible to globally enable static IP addresses for all devices with in a given network?

Not able to get switches while listing Inventory Devices

The cli is already awesome. I would appreaciate if I can get switch names on some of the commands like:

  • meraki -f networkId:L_ organizations getOrganizationInventoryDevices --organizationId <...>
  • meraki -f model:^MS organizations getOrganizationInventoryDevices --organizationId <...>

meraki switch getDeviceSwitchPorts --serial

Hello friends,
I want to use output of this command to display on remote monitor/LCD screen (for example to a remote Riser Room which has Meraki switch for engineer easier to watch), what is best way to approach this thing?
Many thanks.

1.0.0+ Enhancement Requests and Known Bugs

Logging enhancement requests and known bugs here. If you have reported a bug or feature request and it is accepted as such, then it will show up here and your original issue will be closed.

CLI help pages not formatting optional arguments

The CLI help page for updateDevice looks like the below. The arguments under 'All Arguments' should have the double-hyphen like they do in the Command Guide. This needs to be fixed for all commands

~$ 
~$ meraki devices updateDevice
usage: meraki devices updateDevice [-h] --serial STRING [--kwargs JSON_STRING]

        **UPDATE THE ATTRIBUTES OF A DEVICE**
        https://developer.cisco.com/meraki/api-v1/#!update-device

All Arguments:

        - serial (string): (required)
        - name (string): The name of a device
        - tags (array): The list of tags of a device
        - lat (number): The latitude of a device
        - lng (number): The longitude of a device
        - address (string): The address of a device
        - notes (string): The notes for the device. String. Limited to 255 characters.
        - moveMapMarker (boolean): Whether or not to set the latitude and longitude of a device based on the new address. Only applies when lat and lng are not specified.
        - switchProfileId (string): The ID of a switch profile to bind to the device (for available switch profiles, see the 'Switch Profiles' endpoint). Use null to unbind the switch device from the current profile. For a device to be bindable to a switch profile, it must (1) be a switch, and (2) belong to a network that is bound to a configuration template.
        - floorPlanId (string): The floor plan to associate to this device. null disassociates the device from the floorplan.
        
Function Signature:
	>>> def updateDevice(serial: str, **kwargs):

Required Arguments:
  --serial STRING       (required)

Misc Arguments:
  -h, --help            Show help for this command
  --kwargs JSON_STRING  (Advanced Users) Optional arguments in JSON format 

ERROR: the following arguments are required: --serial
~$ 
~$ 

Inconsistent object keys result in missing table headers

It is possible that an array of objects (list of dicts) returned from an endpoint call can have inconsistent keys. The preparation of data for tabulation samples the keys in the first dictionary in the list. If dicts later in the list have keys nonexistent in the first dict, then columns from them will have missing header text.

Below is an example from getNetworkWirelessSsids

┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ name              ┃ enabled ┃ authMode ┃ ipAssignmentMode ┃                ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ TEST1 Open WiFi   │ True    │ open     │ NAT mode         │                │
│ TEST1 Secure WiFi │ True    │ psk      │ NAT mode         │ supersecret123 │
└───────────────────┴─────────┴──────────┴──────────────────┴────────────────┘

Change `-s` to filter actual data

Make -s filter actual data instead of just control the tabulation. It should be able to be used to filter what data is sent over a pipeline to another command. Just like how -f will filter "rows", -s should filter "columns"

Unable to Get Switch Ports Statuses Packets Info

I'm trying to get the CRC errors information on the switch ports packet information but the output is only "port id". I issue this command: meraki switch getDeviceSwitchPortsStatusesPackets --serial 'XXXX-XXXX-XXX' with the correct switch serial number but nothing come out but only port id table. If I tried using postman, I can get the XML data in full. The other command I tried so far is working for switch like portStatuses. Only this one is not working. Is there some option that I am missing? Thanks

miorzaharin

Piplined errors not handling properly

The below command can misbehave in one of two ways depending on the scenario. This will only happen when the queried network does not have wireless settings.

Scenario 1
If the very first network processed against getNetworkWirelessSsids does not have wireless settings, then the entire execution will error out and fail.

Scenario 2
If the second or higher network does not have wireless settings, then a code 400 error log is thrown with message {'errors': ['This endpoint only supports wireless networks']}, but the table output is still printed from the last network.

meraki organizations getOrganizationNetworks --organizationId <some_id> | meraki -t "networkId=id" wireless getNetworkWirelessSsids

Note: Errors experienced when pipelined should be logged and shown, but should not kill all execution.

Output formatting through Jinja2

Allow the JSON output of Meraki-CLI to be formatted through a custom-written Jinja2 template file. This will allow parsing and extraction of data into a customized format

Is there a way to update an AP's DHCP VLAN entry?

Let's say we have Access Points in different buildings and use different VLANs to pull DHCP. Is there a CLI method to update the VLAN entry so it still uses DHCP, but the VLAN ID changes from 200 to 100 or something like that? I saw issue 17 which was a request for extra features. (#17). Is there anything like that for DHCP VLAN ID's for devices?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.