From 9deb5a1943c0a5e07fd4522170e6f8c13287c406 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 22 Jul 2026 14:46:47 +0000 Subject: [PATCH] Auto-generated library v4.3.0b3 for API v1.72.0-beta.3. --- docs/generation-report.md | 6 + meraki/__init__.py | 2 +- meraki/_version.py | 2 +- meraki/aio/api/appliance.py | 204 ++++++++++++++++++++ meraki/aio/api/assistant.py | 305 ++++++++++++++++++++++++++++-- meraki/aio/api/nac.py | 2 +- meraki/aio/api/organizations.py | 179 ++++++++++++++++++ meraki/aio/api/sm.py | 14 +- meraki/aio/api/switch.py | 8 +- meraki/aio/api/wireless.py | 84 +++++++- meraki/api/appliance.py | 204 ++++++++++++++++++++ meraki/api/assistant.py | 305 ++++++++++++++++++++++++++++-- meraki/api/batch/appliance.py | 83 ++++++++ meraki/api/batch/organizations.py | 91 +++++++++ meraki/api/batch/switch.py | 8 +- meraki/api/batch/wireless.py | 25 +++ meraki/api/nac.py | 2 +- meraki/api/organizations.py | 179 ++++++++++++++++++ meraki/api/sm.py | 14 +- meraki/api/switch.py | 8 +- meraki/api/wireless.py | 84 +++++++- pyproject.toml | 2 +- uv.lock | 2 +- 23 files changed, 1754 insertions(+), 59 deletions(-) diff --git a/docs/generation-report.md b/docs/generation-report.md index 3d74f3be..dd1b334a 100644 --- a/docs/generation-report.md +++ b/docs/generation-report.md @@ -1,5 +1,11 @@ # Generation Report +## 2026-07-22 | Library v4.3.0b3 | API 1.72.0-beta.3 + + +No Python keyword parameter conflicts detected. + + ## 2026-07-16 | Library v4.3.1b0 | API 1.72.0 diff --git a/meraki/__init__.py b/meraki/__init__.py index 83fc9508..eda76d0b 100644 --- a/meraki/__init__.py +++ b/meraki/__init__.py @@ -52,7 +52,7 @@ from meraki._version import __version__ # noqa: F401 from datetime import datetime -__api_version__ = "1.72.0" +__api_version__ = "1.72.0-beta.3" __all__ = [ "APIError", diff --git a/meraki/_version.py b/meraki/_version.py index 2f8beec5..31595a63 100644 --- a/meraki/_version.py +++ b/meraki/_version.py @@ -1 +1 @@ -__version__ = "4.3.1b0" +__version__ = "4.3.0b3" diff --git a/meraki/aio/api/appliance.py b/meraki/aio/api/appliance.py index d3dcfdb7..d3557fc0 100644 --- a/meraki/aio/api/appliance.py +++ b/meraki/aio/api/appliance.py @@ -36,6 +36,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -64,6 +65,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -90,6 +92,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -118,6 +121,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1252,6 +1256,101 @@ def getNetworkAppliancePorts(self, networkId: str): return self._session.get(metadata, resource) + def createNetworkAppliancePortsRadiusServer(self, networkId: str, **kwargs): + """ + **Create a shared MX port RADIUS server for a network** + https://developer.cisco.com/meraki/api-v1/#!create-network-appliance-ports-radius-server + + - networkId (string): Network ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "createNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createNetworkAppliancePortsRadiusServer: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def updateNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str, **kwargs): + """ + **Update a shared MX port RADIUS server for a network** + https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "updateNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + serverId = urllib.parse.quote(str(serverId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateNetworkAppliancePortsRadiusServer: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str): + """ + **Delete a network-owned shared MX port RADIUS server** + https://developer.cisco.com/meraki/api-v1/#!delete-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + """ + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "deleteNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + serverId = urllib.parse.quote(str(serverId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + return self._session.delete(metadata, resource) + def getNetworkAppliancePort(self, networkId: str, portId: str): """ **Return per-port VLAN settings for a single secure router or security appliance port.** @@ -3479,6 +3578,57 @@ def getOrganizationApplianceDevicesInterfacesPortsByDevice(self, organizationId: return self._session.get(metadata, resource, params) + def getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **Returns MX port profile assignments** + https://developer.cisco.com/meraki/api-v1/#!get-organization-appliance-devices-interfaces-ports-profiles-assignments + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - serials (array): Optional device serials to filter by. Results include assignments whose device serial is an exact match for any provided serial. If some requested serials are inaccessible, only accessible matches are returned. Maximum: 50 serials per request. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 50. + - 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. + - 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. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "devices", "interfaces", "ports", "profiles", "assignments"], + "operation": "getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/appliance/devices/interfaces/ports/profiles/assignments" + + query_params = [ + "serials", + "perPage", + "startingAfter", + "endingBefore", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "serials", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationApplianceDevicesPortsTransceiversReadingsHistoryByDevice( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -4382,6 +4532,60 @@ def getOrganizationApplianceInterfacesPacketsOverviewsByDevice( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationAppliancePortsRadiusServersByNetwork( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List shared MX port RADIUS servers by network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-appliance-ports-radius-servers-by-network + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 10. + - 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. + - 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. + - networkIds (array): Optional parameter to filter the results by network IDs. Matches are exact. Maximum array size is 100 + - serverIds (array): Optional parameter to filter the results by RADIUS server IDs. Matches are exact. Maximum array size is 100 + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers", "byNetwork"], + "operation": "getOrganizationAppliancePortsRadiusServersByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/appliance/ports/radius/servers/byNetwork" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + "serverIds", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + "serverIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAppliancePortsRadiusServersByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationApplianceRoutingVrfsSettings(self, organizationId: str): """ **Return the VRF setting for an organization.** diff --git a/meraki/aio/api/assistant.py b/meraki/aio/api/assistant.py index 2f6c0de3..ab6c50d0 100644 --- a/meraki/aio/api/assistant.py +++ b/meraki/aio/api/assistant.py @@ -6,6 +6,294 @@ def __init__(self, session): super().__init__() self._session = session + def createAdministeredAssistantChatCompletion(self, **kwargs): + """ + **Create a synchronous AI assistant chat completion for user-wide threads** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-completion + + - query (string): Simple text question or instruction to send to the AI assistant. Provide either 'query' for text-only requests or 'content' for multi-modal input. + - content (array): List of multi-modal content blocks. Use instead of 'query' to send text or images. Supports text and image types only; for audio and file support, use the messages endpoint. Maximum 8 parts. + - threadId (string): Existing persisted thread ID to continue synchronously. If omitted, the request is handled as a one-off invocation and the response will not include a reusable thread ID. + - platform (string): Platform identifier. Defaults to MERAKI when omitted. Case-insensitive. + - language (string): Optional language override. Defaults to the user's preferred language. + - country (string): Optional country override. Defaults to the user's country. + """ + + kwargs.update(locals()) + + if "platform" in kwargs: + options = ["DIGITAL_TWIN", "DNAC", "MERAKI", "digital_twin", "dnac", "meraki"] + assert kwargs["platform"] in options, ( + f'''"platform" cannot be "{kwargs["platform"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "completions"], + "operation": "createAdministeredAssistantChatCompletion", + } + resource = "/administered/assistant/chat/completions" + + body_params = [ + "query", + "content", + "threadId", + "platform", + "language", + "country", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatCompletion: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThreads(self, total_pages=1, direction="next", **kwargs): + """ + **List all active user-wide conversation threads for the authenticated user.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-threads + + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sort (string): Field to sort results by. Defaults to dateModified. + - sortOrder (string): Sort direction for results. Defaults to desc. + - from (string): Filter threads modified after this timestamp. + - to (string): Filter threads modified before this timestamp. + """ + + kwargs.update(locals()) + + if "sort" in kwargs: + options = ["dateModified", "id", "name"] + assert kwargs["sort"] in options, f'''"sort" cannot be "{kwargs["sort"]}", & must be set to one of: {options}''' + if "sortOrder" in kwargs: + options = ["asc", "desc"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getAdministeredAssistantChatThreads", + } + resource = "/administered/assistant/chat/threads" + + query_params = [ + "perPage", + "sort", + "sortOrder", + "from", + "to", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"getAdministeredAssistantChatThreads: ignoring unrecognized kwargs: {invalid}") + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + def createAdministeredAssistantChatThread(self, **kwargs): + """ + **Create a user-wide conversation thread for multi-turn AI assistant interactions.** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-thread + + - threadName (string): Display name for the new thread. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "createAdministeredAssistantChatThread", + } + resource = "/administered/assistant/chat/threads" + + body_params = [ + "threadName", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThread(self, threadId: str): + """ + **Return a single user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread + + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + return self._session.get(metadata, resource) + + def updateAdministeredAssistantChatThread(self, threadId: str, threadName: str, **kwargs): + """ + **Update the name of a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!update-administered-assistant-chat-thread + + - threadId (string): Thread ID + - threadName (string): New display name for the thread. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "updateAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + body_params = [ + "threadName", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateAdministeredAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteAdministeredAssistantChatThread(self, threadId: str): + """ + **Delete a user-wide conversation thread and all its messages.** + https://developer.cisco.com/meraki/api-v1/#!delete-administered-assistant-chat-thread + + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "deleteAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + return self._session.delete(metadata, resource) + + def getAdministeredAssistantChatThreadMessages(self, threadId: str, total_pages=1, direction="next", **kwargs): + """ + **List messages in a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread-messages + + - threadId (string): Thread ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sortOrder (string): Sort direction for results by timestamp. Defaults to asc. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ["asc", "desc"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getAdministeredAssistantChatThreadMessages", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages" + + query_params = [ + "perPage", + "sortOrder", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getAdministeredAssistantChatThreadMessages: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + def createAdministeredAssistantChatThreadMessage(self, threadId: str, content: list, **kwargs): + """ + **Create a new chat message in an existing user-wide thread.** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-thread-message + + - threadId (string): Thread ID + - content (array): List of message content parts. Supports text, image, audio, and file types. Maximum 8 parts. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "createAdministeredAssistantChatThreadMessage", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages" + + body_params = [ + "content", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatThreadMessage: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThreadMessage(self, threadId: str, messageId: str): + """ + **Return a single message in a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread-message + + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getAdministeredAssistantChatThreadMessage", + } + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages/{messageId}" + + return self._session.get(metadata, resource) + def getOrganizationAssistantCapabilities(self, organizationId: str): """ **List the AI assistant's available capabilities and agents for this organization.** @@ -472,20 +760,3 @@ def createOrganizationAssistantChatThreadMessageFeedback( ) return self._session.post(metadata, resource, payload) - - def getOrganizationAssistantQueryLimits(self, organizationId: str): - """ - **Get query limits for the AI assistant for this organization.** - https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-query-limits - - - organizationId (string): Organization ID - """ - - metadata = { - "tags": ["assistant", "configure", "queryLimits"], - "operation": "getOrganizationAssistantQueryLimits", - } - organizationId = urllib.parse.quote(str(organizationId), safe="") - resource = f"/organizations/{organizationId}/assistant/queryLimits" - - return self._session.get(metadata, resource) diff --git a/meraki/aio/api/nac.py b/meraki/aio/api/nac.py index 0dcad5ca..fdaef7ce 100644 --- a/meraki/aio/api/nac.py +++ b/meraki/aio/api/nac.py @@ -725,7 +725,7 @@ def getOrganizationNacClientsGroups(self, organizationId: str, total_pages=1, di - direction (string): direction to paginate, either "next" (default) or "prev" page - sortOrder (string): Query parameter for specifying the direction of sorting to use for the given sortKey. - sortKey (string): Query parameter to sort the client groups by the value of the specified key. - - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 1000. Default is 1000. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 3000. Default is 1000. - 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. - 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. - search (string): Optional parameter to fuzzy search on client groups. diff --git a/meraki/aio/api/organizations.py b/meraki/aio/api/organizations.py index 149f00ef..839704d5 100644 --- a/meraki/aio/api/organizations.py +++ b/meraki/aio/api/organizations.py @@ -2295,6 +2295,130 @@ def getOrganizationAssuranceAlertsOverviewHistorical( return self._session.get(metadata, resource, params) + def getOrganizationAssuranceAlertsProfiles(self, organizationId: str): + """ + **List the alert profiles for this organization** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-profiles + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "getOrganizationAssuranceAlertsProfiles", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles" + + return self._session.get(metadata, resource) + + def createOrganizationAssuranceAlertsProfile( + self, organizationId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Create an alert profile** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "createOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssuranceAlertsProfile: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def updateOrganizationAssuranceAlertsProfile( + self, organizationId: str, profileId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Update an alert profile** + https://developer.cisco.com/meraki/api-v1/#!update-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "updateOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + profileId = urllib.parse.quote(str(profileId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateOrganizationAssuranceAlertsProfile: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteOrganizationAssuranceAlertsProfile(self, organizationId: str, profileId: str): + """ + **Delete an alert profile for this organization** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + """ + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "deleteOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + profileId = urllib.parse.quote(str(profileId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + return self._session.delete(metadata, resource) + def restoreOrganizationAssuranceAlerts(self, organizationId: str, alertIds: list, **kwargs): """ **Restore health alerts from dismissed** @@ -8449,6 +8573,61 @@ def getOrganizationAccessGroups(self, organizationId: str, total_pages=1, direct return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationIamAdminsAdministratorsLoginsHistory( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List administrator login attempts for the organization (Dashboard Login Attempts)** + https://developer.cisco.com/meraki/api-v1/#!get-organization-iam-admins-administrators-logins-history + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 90 days from today. + - t1 (string): The end of the timespan for the data. t1 can be a maximum of 90 days after t0. + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be less than or equal to 90 days. The default is 7 days. + - perPage (integer): The number of entries per page returned. Acceptable range is 10 - 1000. Default is 100. + - 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. + - 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. + - sortOrder (string): Sorted order of entries. Order options are 'ascending' and 'descending'. Default is 'descending'. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ["ascending", "descending"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["organizations", "monitor", "iam", "admins", "administrators", "logins", "history"], + "operation": "getOrganizationIamAdminsAdministratorsLoginsHistory", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/iam/admins/administrators/logins/history" + + query_params = [ + "t0", + "t1", + "timespan", + "perPage", + "startingAfter", + "endingBefore", + "sortOrder", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationIamAdminsAdministratorsLoginsHistory: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def resolveOrganizationIamAdminsAdministratorsMePermissions( self, organizationId: str, total_pages=1, direction="next", **kwargs ): diff --git a/meraki/aio/api/sm.py b/meraki/aio/api/sm.py index 263da776..0fc01f3f 100644 --- a/meraki/aio/api/sm.py +++ b/meraki/aio/api/sm.py @@ -855,12 +855,17 @@ def getNetworkSmDeviceWlanLists(self, networkId: str, deviceId: str): return self._session.get(metadata, resource) - def getNetworkSmProfiles(self, networkId: str, **kwargs): + def getNetworkSmProfiles(self, networkId: str, total_pages=1, direction="next", **kwargs): """ - **List all profiles in a network** + **List profiles in a network** https://developer.cisco.com/meraki/api-v1/#!get-network-sm-profiles - networkId (string): Network ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 50. Default is 50. + - 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. + - 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. - payloadTypes (array): Filter by payload types """ @@ -874,6 +879,9 @@ def getNetworkSmProfiles(self, networkId: str, **kwargs): resource = f"/networks/{networkId}/sm/profiles" query_params = [ + "perPage", + "startingAfter", + "endingBefore", "payloadTypes", ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} @@ -892,7 +900,7 @@ def getNetworkSmProfiles(self, networkId: str, **kwargs): if invalid and self._session._logger: self._session._logger.warning(f"getNetworkSmProfiles: ignoring unrecognized kwargs: {invalid}") - return self._session.get(metadata, resource, params) + return self._session.get_pages(metadata, resource, params, total_pages, direction) def getNetworkSmScripts(self, networkId: str): """ diff --git a/meraki/aio/api/switch.py b/meraki/aio/api/switch.py index e4436722..0c0166e2 100644 --- a/meraki/aio/api/switch.py +++ b/meraki/aio/api/switch.py @@ -3861,17 +3861,19 @@ def getOrganizationSwitchClientsConnectionsSwitchPortStatusByClient(self, organi return self._session.get(metadata, resource, params) - def cloneOrganizationSwitchProfilesToTemplateNetwork(self, organizationId: str, **kwargs): + def cloneOrganizationSwitchProfilesToTemplateNetwork( + self, organizationId: str, profileIds: list, templateNodeGroupId: str, **kwargs + ): """ **Clone existing switch templates into a destination template network.** https://developer.cisco.com/meraki/api-v1/#!clone-organization-switch-profiles-to-template-network - organizationId (string): Organization ID - profileIds (array): Switch profile IDs to clone - - templateNodeGroupId (string): Destination template network ID + - templateNodeGroupId (string): Canonical destination configuration template ID, as returned by getOrganizationConfigTemplates. Legacy numeric switch node group IDs are also accepted """ - kwargs.update(locals()) + kwargs = locals() metadata = { "tags": ["switch", "configure"], diff --git a/meraki/aio/api/wireless.py b/meraki/aio/api/wireless.py index aea304c7..f28394ea 100644 --- a/meraki/aio/api/wireless.py +++ b/meraki/aio/api/wireless.py @@ -2639,6 +2639,37 @@ def getNetworkWirelessSsids(self, networkId: str): return self._session.get(metadata, resource) + def updateNetworkWirelessSsidsOwe(self, networkId: str, transitions: list, **kwargs): + """ + **Update the OWE transition pairs for a network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssids-owe + + - networkId (string): Network ID + - transitions (array): Array of OWE transition pairs + """ + + kwargs = locals() + + metadata = { + "tags": ["wireless", "configure", "ssids", "owe"], + "operation": "updateNetworkWirelessSsidsOwe", + } + networkId = urllib.parse.quote(str(networkId), safe="") + resource = f"/networks/{networkId}/wireless/ssids/owe" + + body_params = [ + "transitions", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateNetworkWirelessSsidsOwe: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getNetworkWirelessSsid(self, networkId: str, number: str): """ **Return a single MR SSID** @@ -10790,6 +10821,55 @@ def getOrganizationWirelessSsidsOpenRoamingByNetwork(self, organizationId: str, return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessSsidsOweByNetwork(self, organizationId: str, total_pages=1, direction="next", **kwargs): + """ + **Returns an array of objects, each containing OWE transition pairs for the corresponding network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-ssids-owe-by-network + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 1000. Default is 1000. + - 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. + - 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. + - networkIds (array): Optional parameter to filter OWE transition configuration by Network Id. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "ssids", "owe", "byNetwork"], + "operation": "getOrganizationWirelessSsidsOweByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/wireless/ssids/owe/byNetwork" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationWirelessSsidsOweByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessSsidsPoliciesClientExclusionBySsid( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -10805,7 +10885,7 @@ def getOrganizationWirelessSsidsPoliciesClientExclusionBySsid( - 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. - networkIds (array): Optional parameter to filter by Network ID. - includeDisabledSsids (boolean): Optional parameter to include disabled SSID's. - - ssidNumbers (array): Optional parameter to filter by SSID numbers. + - ssidNumbers (array): Optional parameter to filter by SSID numbers. Valid values are 0-14. Maximum 15 SSID numbers. """ kwargs.update(locals()) @@ -10861,7 +10941,7 @@ def getOrganizationWirelessSsidsPoliciesClientExclusionStaticExclusionsBySsid( - 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. - networkIds (array): Optional parameter to filter Network ID. - includeDisabledSsids (boolean): Optional parameter to include disabled SSID's. - - ssidNumbers (array): Optional parameter to filter by SSID numbers. + - ssidNumbers (array): Optional parameter to filter by SSID numbers. Valid values are 0-14. Maximum 15 SSID numbers. """ kwargs.update(locals()) diff --git a/meraki/api/appliance.py b/meraki/api/appliance.py index 7b122133..87c69779 100644 --- a/meraki/api/appliance.py +++ b/meraki/api/appliance.py @@ -36,6 +36,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -64,6 +65,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -90,6 +92,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -118,6 +121,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1252,6 +1256,101 @@ def getNetworkAppliancePorts(self, networkId: str): return self._session.get(metadata, resource) + def createNetworkAppliancePortsRadiusServer(self, networkId: str, **kwargs): + """ + **Create a shared MX port RADIUS server for a network** + https://developer.cisco.com/meraki/api-v1/#!create-network-appliance-ports-radius-server + + - networkId (string): Network ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "createNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createNetworkAppliancePortsRadiusServer: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def updateNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str, **kwargs): + """ + **Update a shared MX port RADIUS server for a network** + https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "updateNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + serverId = urllib.parse.quote(str(serverId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateNetworkAppliancePortsRadiusServer: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str): + """ + **Delete a network-owned shared MX port RADIUS server** + https://developer.cisco.com/meraki/api-v1/#!delete-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + """ + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers"], + "operation": "deleteNetworkAppliancePortsRadiusServer", + } + networkId = urllib.parse.quote(str(networkId), safe="") + serverId = urllib.parse.quote(str(serverId), safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + return self._session.delete(metadata, resource) + def getNetworkAppliancePort(self, networkId: str, portId: str): """ **Return per-port VLAN settings for a single secure router or security appliance port.** @@ -3479,6 +3578,57 @@ def getOrganizationApplianceDevicesInterfacesPortsByDevice(self, organizationId: return self._session.get(metadata, resource, params) + def getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **Returns MX port profile assignments** + https://developer.cisco.com/meraki/api-v1/#!get-organization-appliance-devices-interfaces-ports-profiles-assignments + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - serials (array): Optional device serials to filter by. Results include assignments whose device serial is an exact match for any provided serial. If some requested serials are inaccessible, only accessible matches are returned. Maximum: 50 serials per request. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 50. + - 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. + - 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. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "devices", "interfaces", "ports", "profiles", "assignments"], + "operation": "getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/appliance/devices/interfaces/ports/profiles/assignments" + + query_params = [ + "serials", + "perPage", + "startingAfter", + "endingBefore", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "serials", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationApplianceDevicesInterfacesPortsProfilesAssignments: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationApplianceDevicesPortsTransceiversReadingsHistoryByDevice( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -4382,6 +4532,60 @@ def getOrganizationApplianceInterfacesPacketsOverviewsByDevice( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationAppliancePortsRadiusServersByNetwork( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List shared MX port RADIUS servers by network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-appliance-ports-radius-servers-by-network + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 10. + - 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. + - 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. + - networkIds (array): Optional parameter to filter the results by network IDs. Matches are exact. Maximum array size is 100 + - serverIds (array): Optional parameter to filter the results by RADIUS server IDs. Matches are exact. Maximum array size is 100 + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["appliance", "configure", "ports", "radius", "servers", "byNetwork"], + "operation": "getOrganizationAppliancePortsRadiusServersByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/appliance/ports/radius/servers/byNetwork" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + "serverIds", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + "serverIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAppliancePortsRadiusServersByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationApplianceRoutingVrfsSettings(self, organizationId: str): """ **Return the VRF setting for an organization.** diff --git a/meraki/api/assistant.py b/meraki/api/assistant.py index 45c79123..eed478e8 100644 --- a/meraki/api/assistant.py +++ b/meraki/api/assistant.py @@ -6,6 +6,294 @@ def __init__(self, session): super(Assistant, self).__init__() self._session = session + def createAdministeredAssistantChatCompletion(self, **kwargs): + """ + **Create a synchronous AI assistant chat completion for user-wide threads** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-completion + + - query (string): Simple text question or instruction to send to the AI assistant. Provide either 'query' for text-only requests or 'content' for multi-modal input. + - content (array): List of multi-modal content blocks. Use instead of 'query' to send text or images. Supports text and image types only; for audio and file support, use the messages endpoint. Maximum 8 parts. + - threadId (string): Existing persisted thread ID to continue synchronously. If omitted, the request is handled as a one-off invocation and the response will not include a reusable thread ID. + - platform (string): Platform identifier. Defaults to MERAKI when omitted. Case-insensitive. + - language (string): Optional language override. Defaults to the user's preferred language. + - country (string): Optional country override. Defaults to the user's country. + """ + + kwargs.update(locals()) + + if "platform" in kwargs: + options = ["DIGITAL_TWIN", "DNAC", "MERAKI", "digital_twin", "dnac", "meraki"] + assert kwargs["platform"] in options, ( + f'''"platform" cannot be "{kwargs["platform"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "completions"], + "operation": "createAdministeredAssistantChatCompletion", + } + resource = "/administered/assistant/chat/completions" + + body_params = [ + "query", + "content", + "threadId", + "platform", + "language", + "country", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatCompletion: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThreads(self, total_pages=1, direction="next", **kwargs): + """ + **List all active user-wide conversation threads for the authenticated user.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-threads + + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sort (string): Field to sort results by. Defaults to dateModified. + - sortOrder (string): Sort direction for results. Defaults to desc. + - from (string): Filter threads modified after this timestamp. + - to (string): Filter threads modified before this timestamp. + """ + + kwargs.update(locals()) + + if "sort" in kwargs: + options = ["dateModified", "id", "name"] + assert kwargs["sort"] in options, f'''"sort" cannot be "{kwargs["sort"]}", & must be set to one of: {options}''' + if "sortOrder" in kwargs: + options = ["asc", "desc"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getAdministeredAssistantChatThreads", + } + resource = "/administered/assistant/chat/threads" + + query_params = [ + "perPage", + "sort", + "sortOrder", + "from", + "to", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"getAdministeredAssistantChatThreads: ignoring unrecognized kwargs: {invalid}") + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + def createAdministeredAssistantChatThread(self, **kwargs): + """ + **Create a user-wide conversation thread for multi-turn AI assistant interactions.** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-thread + + - threadName (string): Display name for the new thread. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "createAdministeredAssistantChatThread", + } + resource = "/administered/assistant/chat/threads" + + body_params = [ + "threadName", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThread(self, threadId: str): + """ + **Return a single user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread + + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + return self._session.get(metadata, resource) + + def updateAdministeredAssistantChatThread(self, threadId: str, threadName: str, **kwargs): + """ + **Update the name of a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!update-administered-assistant-chat-thread + + - threadId (string): Thread ID + - threadName (string): New display name for the thread. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "updateAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + body_params = [ + "threadName", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateAdministeredAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteAdministeredAssistantChatThread(self, threadId: str): + """ + **Delete a user-wide conversation thread and all its messages.** + https://developer.cisco.com/meraki/api-v1/#!delete-administered-assistant-chat-thread + + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "deleteAdministeredAssistantChatThread", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}" + + return self._session.delete(metadata, resource) + + def getAdministeredAssistantChatThreadMessages(self, threadId: str, total_pages=1, direction="next", **kwargs): + """ + **List messages in a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread-messages + + - threadId (string): Thread ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sortOrder (string): Sort direction for results by timestamp. Defaults to asc. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ["asc", "desc"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getAdministeredAssistantChatThreadMessages", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages" + + query_params = [ + "perPage", + "sortOrder", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getAdministeredAssistantChatThreadMessages: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + def createAdministeredAssistantChatThreadMessage(self, threadId: str, content: list, **kwargs): + """ + **Create a new chat message in an existing user-wide thread.** + https://developer.cisco.com/meraki/api-v1/#!create-administered-assistant-chat-thread-message + + - threadId (string): Thread ID + - content (array): List of message content parts. Supports text, image, audio, and file types. Maximum 8 parts. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "createAdministeredAssistantChatThreadMessage", + } + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages" + + body_params = [ + "content", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createAdministeredAssistantChatThreadMessage: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getAdministeredAssistantChatThreadMessage(self, threadId: str, messageId: str): + """ + **Return a single message in a user-wide conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-administered-assistant-chat-thread-message + + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getAdministeredAssistantChatThreadMessage", + } + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/administered/assistant/chat/threads/{threadId}/messages/{messageId}" + + return self._session.get(metadata, resource) + def getOrganizationAssistantCapabilities(self, organizationId: str): """ **List the AI assistant's available capabilities and agents for this organization.** @@ -472,20 +760,3 @@ def createOrganizationAssistantChatThreadMessageFeedback( ) return self._session.post(metadata, resource, payload) - - def getOrganizationAssistantQueryLimits(self, organizationId: str): - """ - **Get query limits for the AI assistant for this organization.** - https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-query-limits - - - organizationId (string): Organization ID - """ - - metadata = { - "tags": ["assistant", "configure", "queryLimits"], - "operation": "getOrganizationAssistantQueryLimits", - } - organizationId = urllib.parse.quote(str(organizationId), safe="") - resource = f"/organizations/{organizationId}/assistant/queryLimits" - - return self._session.get(metadata, resource) diff --git a/meraki/api/batch/appliance.py b/meraki/api/batch/appliance.py index be960b51..ff7f9697 100644 --- a/meraki/api/batch/appliance.py +++ b/meraki/api/batch/appliance.py @@ -18,6 +18,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -42,6 +43,7 @@ def createDeviceApplianceInterfacesPortsUpdate(self, serial: str, **kwargs): "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { @@ -64,6 +66,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs - downlink (object): The port's VLAN settings when in LAN mode - speed (string): Link speed for the port, in Mbps - duplex (string): Duplex configuration for the port + - profile (object): The optional LAN port's profile which it inherits from """ kwargs.update(locals()) @@ -88,6 +91,7 @@ def updateDeviceApplianceInterfacesPort(self, serial: str, number: str, **kwargs "downlink", "speed", "duplex", + "profile", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { @@ -374,6 +378,85 @@ def deleteNetworkApplianceInterfacesL3(self, networkId: str, interfaceId: str): } return action + def createNetworkAppliancePortsRadiusServer(self, networkId: str, **kwargs): + """ + **Create a shared MX port RADIUS server for a network. These network-owned servers are shared by all MX ports in the network using '802.1X', 'MAC RADIUS' (MAC-based RADIUS authentication), or 'hybrid' (802.1X authentication with MAC-based RADIUS fallback) access policies. A network can have at most 3 shared servers. This beta operation is available only to organizations with beta API access and may change before GA.** + https://developer.cisco.com/meraki/api-v1/#!create-network-appliance-ports-radius-server + + - networkId (string): Network ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + networkId = urllib.parse.quote(networkId, safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "create", + "body": payload, + } + return action + + def updateNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str, **kwargs): + """ + **Update a shared MX port RADIUS server for a network. These network-owned servers are shared by all MX ports in the network using '802.1X', 'MAC RADIUS' (MAC-based RADIUS authentication), or 'hybrid' (802.1X authentication with MAC-based RADIUS fallback) access policies. Omitted attributes are left unchanged. This beta operation is available only to organizations with beta API access and may change before GA.** + https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + - host (string): IPv4 address or FQDN of the RADIUS server + - port (integer): UDP port the RADIUS server listens on for Access-Requests. Must be between 1 and 65535 + - secret (object): Write-only RADIUS shared secret + """ + + kwargs.update(locals()) + + networkId = urllib.parse.quote(networkId, safe="") + serverId = urllib.parse.quote(serverId, safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + body_params = [ + "host", + "port", + "secret", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "update", + "body": payload, + } + return action + + def deleteNetworkAppliancePortsRadiusServer(self, networkId: str, serverId: str): + """ + **Delete a network-owned shared MX port RADIUS server. This beta operation is available only to organizations with beta API access and may change before GA.** + https://developer.cisco.com/meraki/api-v1/#!delete-network-appliance-ports-radius-server + + - networkId (string): Network ID + - serverId (string): Server ID + """ + + networkId = urllib.parse.quote(networkId, safe="") + serverId = urllib.parse.quote(serverId, safe="") + resource = f"/networks/{networkId}/appliance/ports/radius/servers/{serverId}" + + action = { + "resource": resource, + "operation": "destroy", + } + return action + def updateNetworkAppliancePort(self, networkId: str, portId: str, **kwargs): """ **Update the per-port VLAN settings for a single secure router or security appliance port.** diff --git a/meraki/api/batch/organizations.py b/meraki/api/batch/organizations.py index 83e98edf..5f259fa0 100644 --- a/meraki/api/batch/organizations.py +++ b/meraki/api/batch/organizations.py @@ -617,6 +617,97 @@ def updateOrganizationApiPushReceiversProfile(self, organizationId: str, iname: } return action + def createOrganizationAssuranceAlertsProfile( + self, organizationId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Create an alert profile** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + organizationId = urllib.parse.quote(organizationId, safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "create", + "body": payload, + } + return action + + def updateOrganizationAssuranceAlertsProfile( + self, organizationId: str, profileId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Update an alert profile** + https://developer.cisco.com/meraki/api-v1/#!update-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + organizationId = urllib.parse.quote(organizationId, safe="") + profileId = urllib.parse.quote(profileId, safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "update", + "body": payload, + } + return action + + def deleteOrganizationAssuranceAlertsProfile(self, organizationId: str, profileId: str): + """ + **Delete an alert profile for this organization** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + """ + + organizationId = urllib.parse.quote(organizationId, safe="") + profileId = urllib.parse.quote(profileId, safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + action = { + "resource": resource, + "operation": "destroy", + } + return action + def createOrganizationAuthRadiusServer(self, organizationId: str, address: str, secret: str, **kwargs): """ **Add an organization-wide RADIUS server** diff --git a/meraki/api/batch/switch.py b/meraki/api/batch/switch.py index f69cd322..9c2b27f8 100644 --- a/meraki/api/batch/switch.py +++ b/meraki/api/batch/switch.py @@ -2037,17 +2037,19 @@ def updateOrganizationConfigTemplateSwitchProfilePort( } return action - def cloneOrganizationSwitchProfilesToTemplateNetwork(self, organizationId: str, **kwargs): + def cloneOrganizationSwitchProfilesToTemplateNetwork( + self, organizationId: str, profileIds: list, templateNodeGroupId: str, **kwargs + ): """ **Clone existing switch templates into a destination template network.** https://developer.cisco.com/meraki/api-v1/#!clone-organization-switch-profiles-to-template-network - organizationId (string): Organization ID - profileIds (array): Switch profile IDs to clone - - templateNodeGroupId (string): Destination template network ID + - templateNodeGroupId (string): Canonical destination configuration template ID, as returned by getOrganizationConfigTemplates. Legacy numeric switch node group IDs are also accepted """ - kwargs.update(locals()) + kwargs = locals() organizationId = urllib.parse.quote(organizationId, safe="") resource = f"/organizations/{organizationId}/switch/cloneProfilesToTemplateNetwork" diff --git a/meraki/api/batch/wireless.py b/meraki/api/batch/wireless.py index df63b44e..6a4e9ce8 100644 --- a/meraki/api/batch/wireless.py +++ b/meraki/api/batch/wireless.py @@ -841,6 +841,31 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): } return action + def updateNetworkWirelessSsidsOwe(self, networkId: str, transitions: list, **kwargs): + """ + **Update the OWE transition pairs for a network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssids-owe + + - networkId (string): Network ID + - transitions (array): Array of OWE transition pairs + """ + + kwargs = locals() + + networkId = urllib.parse.quote(networkId, safe="") + resource = f"/networks/{networkId}/wireless/ssids/owe" + + body_params = [ + "transitions", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "update", + "body": payload, + } + return action + def updateNetworkWirelessSsid(self, networkId: str, number: str, **kwargs): """ **Update the attributes of an MR SSID** diff --git a/meraki/api/nac.py b/meraki/api/nac.py index 067cc48e..09bd2070 100644 --- a/meraki/api/nac.py +++ b/meraki/api/nac.py @@ -725,7 +725,7 @@ def getOrganizationNacClientsGroups(self, organizationId: str, total_pages=1, di - direction (string): direction to paginate, either "next" (default) or "prev" page - sortOrder (string): Query parameter for specifying the direction of sorting to use for the given sortKey. - sortKey (string): Query parameter to sort the client groups by the value of the specified key. - - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 1000. Default is 1000. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 3000. Default is 1000. - 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. - 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. - search (string): Optional parameter to fuzzy search on client groups. diff --git a/meraki/api/organizations.py b/meraki/api/organizations.py index 34eb2ca0..1b009e3c 100644 --- a/meraki/api/organizations.py +++ b/meraki/api/organizations.py @@ -2295,6 +2295,130 @@ def getOrganizationAssuranceAlertsOverviewHistorical( return self._session.get(metadata, resource, params) + def getOrganizationAssuranceAlertsProfiles(self, organizationId: str): + """ + **List the alert profiles for this organization** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-profiles + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "getOrganizationAssuranceAlertsProfiles", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles" + + return self._session.get(metadata, resource) + + def createOrganizationAssuranceAlertsProfile( + self, organizationId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Create an alert profile** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "createOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssuranceAlertsProfile: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def updateOrganizationAssuranceAlertsProfile( + self, organizationId: str, profileId: str, name: str, networkIds: list, alertTypes: list, configuration: dict, **kwargs + ): + """ + **Update an alert profile** + https://developer.cisco.com/meraki/api-v1/#!update-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + - name (string): Name of the alert profile + - networkIds (array): Networks associated with this alert profile + - alertTypes (array): Alert types associated with this alert profile + - configuration (object): Alert configuration for this profile + - alertScheduleId (string): ID of the alert schedule associated with this profile + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "updateOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + profileId = urllib.parse.quote(str(profileId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + body_params = [ + "name", + "networkIds", + "alertTypes", + "alertScheduleId", + "configuration", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateOrganizationAssuranceAlertsProfile: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + def deleteOrganizationAssuranceAlertsProfile(self, organizationId: str, profileId: str): + """ + **Delete an alert profile for this organization** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-assurance-alerts-profile + + - organizationId (string): Organization ID + - profileId (string): Profile ID + """ + + metadata = { + "tags": ["organizations", "configure", "alerts", "profiles"], + "operation": "deleteOrganizationAssuranceAlertsProfile", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + profileId = urllib.parse.quote(str(profileId), safe="") + resource = f"/organizations/{organizationId}/assurance/alerts/profiles/{profileId}" + + return self._session.delete(metadata, resource) + def restoreOrganizationAssuranceAlerts(self, organizationId: str, alertIds: list, **kwargs): """ **Restore health alerts from dismissed** @@ -8449,6 +8573,61 @@ def getOrganizationAccessGroups(self, organizationId: str, total_pages=1, direct return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationIamAdminsAdministratorsLoginsHistory( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List administrator login attempts for the organization (Dashboard Login Attempts)** + https://developer.cisco.com/meraki/api-v1/#!get-organization-iam-admins-administrators-logins-history + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 90 days from today. + - t1 (string): The end of the timespan for the data. t1 can be a maximum of 90 days after t0. + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be less than or equal to 90 days. The default is 7 days. + - perPage (integer): The number of entries per page returned. Acceptable range is 10 - 1000. Default is 100. + - 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. + - 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. + - sortOrder (string): Sorted order of entries. Order options are 'ascending' and 'descending'. Default is 'descending'. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ["ascending", "descending"] + assert kwargs["sortOrder"] in options, ( + f'''"sortOrder" cannot be "{kwargs["sortOrder"]}", & must be set to one of: {options}''' + ) + + metadata = { + "tags": ["organizations", "monitor", "iam", "admins", "administrators", "logins", "history"], + "operation": "getOrganizationIamAdminsAdministratorsLoginsHistory", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/iam/admins/administrators/logins/history" + + query_params = [ + "t0", + "t1", + "timespan", + "perPage", + "startingAfter", + "endingBefore", + "sortOrder", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationIamAdminsAdministratorsLoginsHistory: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def resolveOrganizationIamAdminsAdministratorsMePermissions( self, organizationId: str, total_pages=1, direction="next", **kwargs ): diff --git a/meraki/api/sm.py b/meraki/api/sm.py index e4f811c1..26a01905 100644 --- a/meraki/api/sm.py +++ b/meraki/api/sm.py @@ -855,12 +855,17 @@ def getNetworkSmDeviceWlanLists(self, networkId: str, deviceId: str): return self._session.get(metadata, resource) - def getNetworkSmProfiles(self, networkId: str, **kwargs): + def getNetworkSmProfiles(self, networkId: str, total_pages=1, direction="next", **kwargs): """ - **List all profiles in a network** + **List profiles in a network** https://developer.cisco.com/meraki/api-v1/#!get-network-sm-profiles - networkId (string): Network ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 50. Default is 50. + - 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. + - 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. - payloadTypes (array): Filter by payload types """ @@ -874,6 +879,9 @@ def getNetworkSmProfiles(self, networkId: str, **kwargs): resource = f"/networks/{networkId}/sm/profiles" query_params = [ + "perPage", + "startingAfter", + "endingBefore", "payloadTypes", ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} @@ -892,7 +900,7 @@ def getNetworkSmProfiles(self, networkId: str, **kwargs): if invalid and self._session._logger: self._session._logger.warning(f"getNetworkSmProfiles: ignoring unrecognized kwargs: {invalid}") - return self._session.get(metadata, resource, params) + return self._session.get_pages(metadata, resource, params, total_pages, direction) def getNetworkSmScripts(self, networkId: str): """ diff --git a/meraki/api/switch.py b/meraki/api/switch.py index 327f942b..487d2810 100644 --- a/meraki/api/switch.py +++ b/meraki/api/switch.py @@ -3861,17 +3861,19 @@ def getOrganizationSwitchClientsConnectionsSwitchPortStatusByClient(self, organi return self._session.get(metadata, resource, params) - def cloneOrganizationSwitchProfilesToTemplateNetwork(self, organizationId: str, **kwargs): + def cloneOrganizationSwitchProfilesToTemplateNetwork( + self, organizationId: str, profileIds: list, templateNodeGroupId: str, **kwargs + ): """ **Clone existing switch templates into a destination template network.** https://developer.cisco.com/meraki/api-v1/#!clone-organization-switch-profiles-to-template-network - organizationId (string): Organization ID - profileIds (array): Switch profile IDs to clone - - templateNodeGroupId (string): Destination template network ID + - templateNodeGroupId (string): Canonical destination configuration template ID, as returned by getOrganizationConfigTemplates. Legacy numeric switch node group IDs are also accepted """ - kwargs.update(locals()) + kwargs = locals() metadata = { "tags": ["switch", "configure"], diff --git a/meraki/api/wireless.py b/meraki/api/wireless.py index dbad8dfa..fe83ddef 100644 --- a/meraki/api/wireless.py +++ b/meraki/api/wireless.py @@ -2639,6 +2639,37 @@ def getNetworkWirelessSsids(self, networkId: str): return self._session.get(metadata, resource) + def updateNetworkWirelessSsidsOwe(self, networkId: str, transitions: list, **kwargs): + """ + **Update the OWE transition pairs for a network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssids-owe + + - networkId (string): Network ID + - transitions (array): Array of OWE transition pairs + """ + + kwargs = locals() + + metadata = { + "tags": ["wireless", "configure", "ssids", "owe"], + "operation": "updateNetworkWirelessSsidsOwe", + } + networkId = urllib.parse.quote(str(networkId), safe="") + resource = f"/networks/{networkId}/wireless/ssids/owe" + + body_params = [ + "transitions", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateNetworkWirelessSsidsOwe: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getNetworkWirelessSsid(self, networkId: str, number: str): """ **Return a single MR SSID** @@ -10790,6 +10821,55 @@ def getOrganizationWirelessSsidsOpenRoamingByNetwork(self, organizationId: str, return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessSsidsOweByNetwork(self, organizationId: str, total_pages=1, direction="next", **kwargs): + """ + **Returns an array of objects, each containing OWE transition pairs for the corresponding network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-ssids-owe-by-network + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 1000. Default is 1000. + - 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. + - 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. + - networkIds (array): Optional parameter to filter OWE transition configuration by Network Id. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "ssids", "owe", "byNetwork"], + "operation": "getOrganizationWirelessSsidsOweByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/wireless/ssids/owe/byNetwork" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationWirelessSsidsOweByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessSsidsPoliciesClientExclusionBySsid( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -10805,7 +10885,7 @@ def getOrganizationWirelessSsidsPoliciesClientExclusionBySsid( - 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. - networkIds (array): Optional parameter to filter by Network ID. - includeDisabledSsids (boolean): Optional parameter to include disabled SSID's. - - ssidNumbers (array): Optional parameter to filter by SSID numbers. + - ssidNumbers (array): Optional parameter to filter by SSID numbers. Valid values are 0-14. Maximum 15 SSID numbers. """ kwargs.update(locals()) @@ -10861,7 +10941,7 @@ def getOrganizationWirelessSsidsPoliciesClientExclusionStaticExclusionsBySsid( - 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. - networkIds (array): Optional parameter to filter Network ID. - includeDisabledSsids (boolean): Optional parameter to include disabled SSID's. - - ssidNumbers (array): Optional parameter to filter by SSID numbers. + - ssidNumbers (array): Optional parameter to filter by SSID numbers. Valid values are 0-14. Maximum 15 SSID numbers. """ kwargs.update(locals()) diff --git a/pyproject.toml b/pyproject.toml index dce1a499..22c03dac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "meraki" -version = "4.3.1b0" +version = "4.3.0b3" description = "Cisco Meraki Dashboard API library" authors = [ {name = "Cisco Meraki", email = "api-feedback@meraki.net"} diff --git a/uv.lock b/uv.lock index 2bf7ca85..ecef2086 100644 --- a/uv.lock +++ b/uv.lock @@ -549,7 +549,7 @@ wheels = [ [[package]] name = "meraki" -version = "4.3.1b0" +version = "4.3.0b3" source = { editable = "." } dependencies = [ { name = "aiohttp" },