Browse Source

Update for API v1, which lets us enable VLANs!

Joe Clarke 2 years ago
parent
commit
3a82d301da
2 changed files with 57 additions and 30 deletions
  1. 38 12
      meraki_api/meraki_api.py
  2. 19 18
      setup-meraki-nets.py

+ 38 - 12
meraki_api/meraki_api.py

@@ -31,7 +31,7 @@ import logging
 
 
 class Meraki(object):
-    MERAKI_API = "https://api.meraki.com/api/v0"
+    MERAKI_API = "https://api.meraki.com/api/v1"
 
     _headers = {"X-Cisco-Meraki-API-Key": None, "Content-type": "application/json"}
 
@@ -196,7 +196,7 @@ class Organization(Meraki):
         if not self._check_obj():
             return None
 
-        url = self.ORG_API + "/" + self._id + "/inventory"
+        url = self.ORG_API + "/" + self._id + "/inventoryDevices"
 
         try:
             response = requests.request("GET", url, headers=self._headers)
@@ -248,11 +248,13 @@ class Organization(Meraki):
                     payload["timeZone"] = kwargs[key]
                 elif key == "copy_from_network_id":
                     payload["copyFromNetworkId"] = kwargs[key]
+                elif key == "type":
+                    payload["productTypes"] = kwargs[key]
                 else:
                     payload[key] = kwargs[key]
 
         if "type" not in kwargs:
-            payload["type"] = "wireless switch appliance"
+            payload["productTypes"] = ["wireless", "switch", "appliance"]
 
         url = self.ORG_API + "/" + self._id + "/networks"
         try:
@@ -310,7 +312,7 @@ class Network(Meraki):
             return None
 
         url = self.NET_API + "/" + self._id + "/devices/claim"
-        payload = {"serial": dev._id}
+        payload = {"serials": [dev._id]}
         try:
             response = requests.request("POST", url, json=payload, headers=self._headers)
             response.raise_for_status()
@@ -326,13 +328,34 @@ class Network(Meraki):
         new_dev = Device(key=self._key, id=dev._id, net=self)
         return new_dev
 
+    def enable_vlans(self):
+        if not self._check_obj():
+            return False
+
+        payload = {"vlansEnabled": True}
+
+        url = self.NET_API + "/" + self._id + "/appliance/vlans/settings"
+        try:
+            response = requests.request("PUT", url, json=payload, headers=self._headers)
+            response.raise_for_status()
+        except Exception as e:
+            msg = "Error enabling VLANs for network {}: {} ({})".format(self._name, e, Meraki._get_json_errors(response))
+            if self._logit:
+                logging.error(msg)
+            else:
+                print(msg)
+
+            return False
+
+        return True
+
     def create_vlan(self, name, id, subnet, appliance_ip):
         if not self._check_obj():
             return None
 
         payload = {"id": id, "name": name, "subnet": subnet, "applianceIp": appliance_ip}
 
-        url = self.NET_API + "/" + self._id + "/vlans"
+        url = self.NET_API + "/" + self._id + "/appliance/vlans"
         try:
             response = requests.request("POST", url, json=payload, headers=self._headers)
             response.raise_for_status()
@@ -358,7 +381,7 @@ class Network(Meraki):
 
         url = self.NET_API + "/" + self._id + "/networks/appliance/trafficShaping"
         try:
-            response = requests.request("POST", url, json=payload, headers=self._headers)
+            response = requests.request("PUT", url, json=payload, headers=self._headers)
             response.raise_for_status()
         except Exception as e:
             msg = "Error setting traffic shaping limit in network {}: {} ({})".format(self._name, e, Meraki._get_json_errors(response))
@@ -383,7 +406,7 @@ class SSID(Meraki):
         self._net = kwargs["net"]
 
         self._class_name = "SSID"
-        self._api_url_endpoint = "/networks/" + self._net.get(Network._id_prop) + "/ssids"
+        self._api_url_endpoint = "/networks/" + self._net.get(Network._id_prop) + "/wireless/ssids"
         self.SSID_API = self.MERAKI_API + self._api_url_endpoint
 
     def update_ssid(self, **kwargs):
@@ -440,7 +463,7 @@ class Vlan(Meraki):
         self._net = kwargs["net"]
 
         self._class_name = "Vlan"
-        self._api_url_endpoint = "/networks/" + self._net.get(Network._id_prop) + "/vlans"
+        self._api_url_endpoint = "/networks/" + self._net.get(Network._id_prop) + "/appliance/vlans"
         self.VLAN_API = self.MERAKI_API + self._api_url_endpoint
 
     def update_vlan(self, **kwargs):
@@ -496,14 +519,15 @@ class Device(Meraki):
         self._net = kwargs["net"]
 
         self._class_name = "Device"
-        self._api_url_endpoint = "/networks/" + self._net.get(Network._id_prop) + "/devices"
+        self._api_url_endpoint = "/devices"
         self.DEV_API = self.MERAKI_API + self._api_url_endpoint
+        self.OLD_DEV_API = self.MERAKI_API + "/networks/" + self._net.get(Network._id_prop) + "/devices"
 
     def remove_device(self):
         if not self._check_obj():
             return False
 
-        url = self.DEV_API + "/" + self._id + "/remove"
+        url = self.OLD_DEV_API + "/" + self._id + "/remove"
         try:
             response = requests.request("POST", url, headers=self._headers)
             response.raise_for_status()
@@ -568,7 +592,7 @@ class SwitchPort(Meraki):
         self._dev = kwargs["dev"]
 
         self._class_name = "SwitchPort"
-        self._api_url_endpoint = "/devices/" + self._net.get(Network._id_prop) + "/switchPorts"
+        self._api_url_endpoint = "/devices/" + self._dev.get(Device._id_prop) + "/switch/ports"
         self.SWP_API = self.MERAKI_API + self._api_url_endpoint
 
     def update_switchport(self, **kwargs):
@@ -576,7 +600,7 @@ class SwitchPort(Meraki):
             return False
 
         payload = {}
-        for key in ["name", "tags", "enabled", "type", "vlan", "voice_vlan", "allowed_vlans", "poe_enabled"]:
+        for key in ["name", "tags", "enabled", "type", "vlan", "voice_vlan", "allowed_vlans", "rstp_enabled", "poe_enabled"]:
             if key in kwargs:
                 if key == "voice_vlan":
                     payload["voiceVlan"] = kwargs[key]
@@ -584,6 +608,8 @@ class SwitchPort(Meraki):
                     payload["allowedVlans"] = kwargs[key]
                 elif key == "poe_enabled":
                     payload["poeEnabled"] = kwargs[key]
+                elif key == "rstp_enabled":
+                    payload["rstpEnabled"] = kwargs[key]
                 else:
                     payload[key] = kwargs[key]
 

+ 19 - 18
setup-meraki-nets.py

@@ -25,7 +25,6 @@
 
 
 from __future__ import print_function
-from builtins import input
 from meraki_api import Meraki, Network, Vlan, SwitchPort, SSID, Device
 import yaml
 import argparse
@@ -219,22 +218,14 @@ def main():
                     nerrors += 1
 
         if "vlans" in network:
-            # Ugh.  There is no API to enable VLANs yet.  So it's best to
-            # make this a manual step.  We could interact over the web, but
-            # then we'd need to ask for a real user's credentials.
-            #
-            # If we copied from an existing network, then we assume that
-            # network has VLANs enabled.  If not, this will fail.
-            #
-            if "copy_from_network" not in network:
-                print("\n")
-                input(
-                    '!!! Enable VLANs for network "{}" manually in the dashboard (under Security appliance > Addressing & VLANs), then hit \
-                    enter to proceed !!!'.format(
-                        nname
-                    )
-                )
-                print("")
+            vres = net_obj.enable_vlans()
+            if not vres:
+                print("{}Error enabling VLANs for network {}!{}".format(Fore.RED, nname, Style.RESET_ALL))
+                nerrors += 1
+                continue
+            else:
+                print("{}update: enabled VLANs for network {}{}".format(Fore.YELLOW, nname, Style.RESET_ALL))
+
             for vname, vlan in network["vlans"].items():
                 done_msg = ""
                 if int(vlan["id"]) != 1:
@@ -338,7 +329,17 @@ def main():
 
                     for port in ports:
                         pargs = {}
-                        for key in ["name", "tags", "enabled", "type", "vlan", "voice_vlan", "allowed_vlans", "poe_enabled"]:
+                        for key in [
+                            "name",
+                            "tags",
+                            "enabled",
+                            "type",
+                            "vlan",
+                            "voice_vlan",
+                            "allowed_vlans",
+                            "rstp_enabled",
+                            "poe_enabled",
+                        ]:
                             if key in switchport:
                                 pargs[key] = switchport[key]
                         res = port.update_switchport(**pargs)