Skip to content

Commit 346cebb

Browse files
author
Shiyue Cheng
committed
updated w/ release 1.1.0b3
1 parent 096676a commit 346cebb

7 files changed

Lines changed: 195 additions & 23 deletions

File tree

meraki/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
SUPPRESS_LOGGING, SIMULATE_API_CALLS, BE_GEO_ID, MERAKI_PYTHON_SDK_CALLER
2121
)
2222

23-
__version__ = '1.1.0b2'
23+
__version__ = '1.1.0b3'
2424

2525
class DashboardAPI(object):
2626
"""

meraki/aio/api/appliance.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,22 @@ def updateNetworkApplianceSecurityMalware(self, networkId: str, mode: str, **kwa
700700

701701
return self._session.put(metadata, resource, payload)
702702

703+
def getNetworkApplianceSettings(self, networkId: str):
704+
"""
705+
**Return the appliance settings for a network**
706+
https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-settings
707+
708+
- networkId (string): (required)
709+
"""
710+
711+
metadata = {
712+
'tags': ['appliance', 'configure', 'settings'],
713+
'operation': 'getNetworkApplianceSettings'
714+
}
715+
resource = f'/networks/{networkId}/appliance/settings'
716+
717+
return self._session.get(metadata, resource)
718+
703719
def getNetworkApplianceSingleLan(self, networkId: str):
704720
"""
705721
**Return single LAN configuration**

meraki/aio/api/networks.py

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,14 +435,67 @@ def removeNetworkDevices(self, networkId: str, serial: str):
435435

436436
return self._session.post(metadata, resource, payload)
437437

438-
def getNetworkEvents(self, networkId: str, total_pages=1, direction='prev', **kwargs):
438+
def getNetworkEnvironmentalEvents(self, networkId: str, total_pages=1, direction='next', **kwargs):
439+
"""
440+
**List the environmental events for the network**
441+
https://developer.cisco.com/meraki/api-v1/#!get-network-environmental-events
442+
443+
- networkId (string): (required)
444+
- total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages
445+
- direction (string): direction to paginate, either "next" (default) or "prev" page
446+
- includedEventTypes (array): A list of event types. The returned events will be filtered to only include events with these types.
447+
- excludedEventTypes (array): A list of event types. The returned events will be filtered to exclude events with these types.
448+
- sensorSerial (string): The serial of the sensor device which the list of events will be filtered with
449+
- gatewaySerial (string): The serial of the environmental gateway device which the list of events will be filtered with
450+
- perPage (integer): The number of entries per page returned. Acceptable range is 3 - 1000. Default is 10.
451+
- startingAfter (string): A token used by the server to indicate the start of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it.
452+
- endingBefore (string): A token used by the server to indicate the end of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it.
453+
"""
454+
455+
kwargs.update(locals())
456+
457+
metadata = {
458+
'tags': ['networks', 'monitor', 'environmental', 'events'],
459+
'operation': 'getNetworkEnvironmentalEvents'
460+
}
461+
resource = f'/networks/{networkId}/environmental/events'
462+
463+
query_params = ['includedEventTypes', 'excludedEventTypes', 'sensorSerial', 'gatewaySerial', 'perPage', 'startingAfter', 'endingBefore', ]
464+
params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params}
465+
466+
array_params = ['includedEventTypes', 'excludedEventTypes', ]
467+
for k, v in kwargs.items():
468+
if k.strip() in array_params:
469+
params[f'{k.strip()}[]'] = kwargs[f'{k}']
470+
params.pop(k.strip())
471+
472+
return self._session.get_pages(metadata, resource, params, total_pages, direction)
473+
474+
def getNetworkEnvironmentalEventsEventTypes(self, networkId: str):
475+
"""
476+
**List the event type to human-readable description**
477+
https://developer.cisco.com/meraki/api-v1/#!get-network-environmental-events-event-types
478+
479+
- networkId (string): (required)
480+
"""
481+
482+
metadata = {
483+
'tags': ['networks', 'configure', 'environmental', 'events', 'eventTypes'],
484+
'operation': 'getNetworkEnvironmentalEventsEventTypes'
485+
}
486+
resource = f'/networks/{networkId}/environmental/events/eventTypes'
487+
488+
return self._session.get(metadata, resource)
489+
490+
def getNetworkEvents(self, networkId: str, total_pages=1, direction='prev', event_log_end_time=None, **kwargs):
439491
"""
440492
**List the events for the network**
441493
https://developer.cisco.com/meraki/api-v1/#!get-network-events
442494
443495
- networkId (string): (required)
444496
- total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages
445497
- direction (string): direction to paginate, either "next" or "prev" (default) page
498+
- event_log_end_time (string): ISO8601 Zulu/UTC time, to use in conjunction with startingAfter, to retrieve events within a time window
446499
- productType (string): The product type to fetch events for. This parameter is required for networks with multiple device types. Valid types are wireless, appliance, switch, systemsManager, camera, and cellularGateway
447500
- includedEventTypes (array): A list of event types. The returned events will be filtered to only include events with these types.
448501
- excludedEventTypes (array): A list of event types. The returned events will be filtered to exclude events with these types.
@@ -476,7 +529,7 @@ def getNetworkEvents(self, networkId: str, total_pages=1, direction='prev', **kw
476529
params[f'{k.strip()}[]'] = kwargs[f'{k}']
477530
params.pop(k.strip())
478531

479-
return self._session.get_pages(metadata, resource, params, total_pages, direction)
532+
return self._session.get_pages(metadata, resource, params, total_pages, direction, event_log_end_time)
480533

481534
def getNetworkEventsEventTypes(self, networkId: str):
482535
"""
@@ -764,7 +817,7 @@ def deleteNetworkGroupPolicy(self, networkId: str, groupPolicyId: str):
764817

765818
def getNetworkMerakiAuthUsers(self, networkId: str):
766819
"""
767-
**List the splash or RADIUS users configured under Meraki Authentication for a network**
820+
**List the users configured under Meraki Authentication for a network (splash guest or RADIUS users for a wireless network, or client VPN users for a wired network)**
768821
https://developer.cisco.com/meraki/api-v1/#!get-network-meraki-auth-users
769822
770823
- networkId (string): (required)
@@ -780,22 +833,22 @@ def getNetworkMerakiAuthUsers(self, networkId: str):
780833

781834
def createNetworkMerakiAuthUser(self, networkId: str, email: str, name: str, password: str, authorizations: list, **kwargs):
782835
"""
783-
**Create a user configured with Meraki Authentication for a network (currently supports 802.1X and Splash Guest users, and currently, organizations have a 50,000 user cap)**
836+
**Create a user configured with Meraki Authentication for a network (currently supports 802.1X, splash guest, and client VPN users, and currently, organizations have a 50,000 user cap)**
784837
https://developer.cisco.com/meraki/api-v1/#!create-network-meraki-auth-user
785838
786839
- networkId (string): (required)
787840
- email (string): Email address of the user
788841
- name (string): Name of the user
789842
- password (string): The password for this user account
790843
- authorizations (array): Authorization zones and expiration dates for the user.
791-
- accountType (string): Authorization type for user. Can be either 'Guest' or '802.1X'. Defaults to '802.1X'.
844+
- accountType (string): Authorization type for user. Can be 'Guest' or '802.1X' for wireless networks, or 'Client VPN' for wired networks. Defaults to '802.1X'.
792845
- emailPasswordToUser (boolean): Whether or not Meraki should email the password to user. Default is false.
793846
"""
794847

795848
kwargs.update(locals())
796849

797850
if 'accountType' in kwargs:
798-
options = ['Guest', '802.1X']
851+
options = ['Guest', '802.1X', 'Client VPN']
799852
assert kwargs['accountType'] in options, f'''"accountType" cannot be "{kwargs['accountType']}", & must be set to one of: {options}'''
800853

801854
metadata = {
@@ -811,7 +864,7 @@ def createNetworkMerakiAuthUser(self, networkId: str, email: str, name: str, pas
811864

812865
def getNetworkMerakiAuthUser(self, networkId: str, merakiAuthUserId: str):
813866
"""
814-
**Return the Meraki Auth splash or RADIUS user**
867+
**Return the Meraki Auth splash guest, RADIUS, or client VPN user**
815868
https://developer.cisco.com/meraki/api-v1/#!get-network-meraki-auth-user
816869
817870
- networkId (string): (required)
@@ -828,7 +881,7 @@ def getNetworkMerakiAuthUser(self, networkId: str, merakiAuthUserId: str):
828881

829882
def deleteNetworkMerakiAuthUser(self, networkId: str, merakiAuthUserId: str):
830883
"""
831-
**Delete a user configured with Meraki Authentication (currently, 802.1X RADIUS and Splash Guest users can be deleted)**
884+
**Delete a user configured with Meraki Authentication (currently, 802.1X RADIUS, splash guest, and client VPN users can be deleted)**
832885
https://developer.cisco.com/meraki/api-v1/#!delete-network-meraki-auth-user
833886
834887
- networkId (string): (required)
@@ -845,7 +898,7 @@ def deleteNetworkMerakiAuthUser(self, networkId: str, merakiAuthUserId: str):
845898

846899
def updateNetworkMerakiAuthUser(self, networkId: str, merakiAuthUserId: str, **kwargs):
847900
"""
848-
**Update a user configured with Meraki Authentication (currently, 802.1X RADIUS and Splash Guest users can be updated)**
901+
**Update a user configured with Meraki Authentication (currently, 802.1X RADIUS, splash guest, and client VPN users can be deleted)**
849902
https://developer.cisco.com/meraki/api-v1/#!update-network-meraki-auth-user
850903
851904
- networkId (string): (required)

meraki/aio/rest_session.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,32 +275,48 @@ async def get(self, metadata, url, params=None):
275275
return await response.json()
276276

277277
async def get_pages(
278-
self, metadata, url, params=None, total_pages=-1, direction="next"
278+
self, metadata, url, params=None, total_pages=-1, direction="next", event_log_end_time=None
279279
):
280280
if type(total_pages) == str and total_pages.lower() == "all":
281281
total_pages = -1
282+
elif type(total_pages) == str and total_pages.isnumeric():
283+
total_pages = int(total_pages)
282284
metadata["page"] = 1
283285

284286
response = await self.request(metadata, "GET", url, params=params)
285287
results = await response.json()
286288

289+
# For event log endpoint when using 'next' direction, so results/events are sorted chronologically
290+
if type(results) == dict and metadata["operation"] == "getNetworkEvents" and direction == "next":
291+
results["events"] = results["events"][::-1]
292+
287293
# Get additional pages if more than one requested
288294
while total_pages != 1:
289295
links = response.links
290296

291297
# GET the subsequent page
292298
if direction == "next" and "next" in links:
293-
# Prevent getNetworkEvents from infinite loop when requesting events after specified endingBefore time
299+
# Prevent getNetworkEvents from infinite loop as time goes forward
294300
if metadata["operation"] == "getNetworkEvents":
295301
starting_after = urllib.parse.unquote(links["next"]["url"].split("startingAfter=")[1])
296302
delta = datetime.utcnow() - datetime.fromisoformat(starting_after[:-1])
297303
# Break out of loop if startingAfter returned from next link is within 5 minutes of current time
298304
if delta.total_seconds() < 300:
299305
break
306+
# Or if next page is past the specified window's end time
307+
elif event_log_end_time and starting_after > event_log_end_time:
308+
break
300309

301310
metadata["page"] += 1
302311
response = await self.request(metadata, "GET", links["next"]["url"])
303312
elif direction == "prev" and "prev" in links:
313+
# Prevent getNetworkEvents from infinite loop as time goes backward (to epoch 0)
314+
if metadata["operation"] == "getNetworkEvents":
315+
ending_before = urllib.parse.unquote(links["prev"]["url"].split("endingBefore=")[1])
316+
# Break out of loop if endingBefore returned from prev link is before 2014
317+
if ending_before < "2014-01-01":
318+
break
319+
304320
metadata["page"] += 1
305321
response = await self.request(metadata, "GET", links["prev"]["url"])
306322
else:
@@ -315,6 +331,8 @@ async def get_pages(
315331
start = json_response["pageStartAt"]
316332
end = json_response["pageEndAt"]
317333
events = json_response["events"]
334+
if direction == "next":
335+
events = events[::-1]
318336
if start < results["pageStartAt"]:
319337
results["pageStartAt"] = start
320338
if end > results["pageEndAt"]:

meraki/api/appliance.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,22 @@ def updateNetworkApplianceSecurityMalware(self, networkId: str, mode: str, **kwa
700700

701701
return self._session.put(metadata, resource, payload)
702702

703+
def getNetworkApplianceSettings(self, networkId: str):
704+
"""
705+
**Return the appliance settings for a network**
706+
https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-settings
707+
708+
- networkId (string): (required)
709+
"""
710+
711+
metadata = {
712+
'tags': ['appliance', 'configure', 'settings'],
713+
'operation': 'getNetworkApplianceSettings'
714+
}
715+
resource = f'/networks/{networkId}/appliance/settings'
716+
717+
return self._session.get(metadata, resource)
718+
703719
def getNetworkApplianceSingleLan(self, networkId: str):
704720
"""
705721
**Return single LAN configuration**

0 commit comments

Comments
 (0)