diff --git a/meraki/__init__.py b/meraki/__init__.py index 9d47d81..ca3f1ce 100644 --- a/meraki/__init__.py +++ b/meraki/__init__.py @@ -46,8 +46,8 @@ ) from meraki.rest_session import * -__version__ = '2.1.2' -__api_version__ = '1.65.0' +__version__ = '2.2.0' +__api_version__ = '1.68.0' class DashboardAPI(object): diff --git a/meraki/aio/api/appliance.py b/meraki/aio/api/appliance.py index 9a6c3b6..635dad8 100644 --- a/meraki/aio/api/appliance.py +++ b/meraki/aio/api/appliance.py @@ -870,7 +870,7 @@ def updateNetworkApplianceFirewallSettings(self, networkId: str, **kwargs): def getNetworkAppliancePorts(self, networkId: str): """ - **List per-port VLAN settings for all ports of a MX.** + **List per-port VLAN settings for all ports of a secure router or security appliance.** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-ports - networkId (string): Network ID @@ -889,7 +889,7 @@ def getNetworkAppliancePorts(self, networkId: str): def getNetworkAppliancePort(self, networkId: str, portId: str): """ - **Return per-port VLAN settings for a single MX port.** + **Return per-port VLAN settings for a single secure router or security appliance port.** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-port - networkId (string): Network ID @@ -910,7 +910,7 @@ def getNetworkAppliancePort(self, networkId: str, portId: str): def updateNetworkAppliancePort(self, networkId: str, portId: str, **kwargs): """ - **Update the per-port VLAN settings for a single MX port.** + **Update the per-port VLAN settings for a single secure router or security appliance port.** https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-port - networkId (string): Network ID @@ -1984,6 +1984,50 @@ def updateNetworkApplianceTrafficShapingVpnExclusions(self, networkId: str, **kw + def connectNetworkApplianceUmbrellaAccount(self, networkId: str, api: dict): + """ + **Connect a Cisco Umbrella account to this network** + https://developer.cisco.com/meraki/api-v1/#!connect-network-appliance-umbrella-account + + - networkId (string): Network ID + - api (object): Umbrella API credentials + """ + + kwargs = locals() + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'connectNetworkApplianceUmbrellaAccount' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/appliance/umbrella/account/connect' + + body_params = ['api', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def disconnectNetworkApplianceUmbrellaAccount(self, networkId: str): + """ + **Disconnect Umbrella account from this network** + https://developer.cisco.com/meraki/api-v1/#!disconnect-network-appliance-umbrella-account + + - networkId (string): Network ID + """ + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'disconnectNetworkApplianceUmbrellaAccount' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/appliance/umbrella/account/disconnect' + + return self._session.post(metadata, resource) + + + def getNetworkApplianceUplinksUsageHistory(self, networkId: str, **kwargs): """ **Get the sent and received bytes for each uplink of a network.** @@ -2014,7 +2058,7 @@ def getNetworkApplianceUplinksUsageHistory(self, networkId: str, **kwargs): def getNetworkApplianceVlans(self, networkId: str): """ - **List the VLANs for a Cisco Secure Router network** + **List the VLANs for a Security Appliance network** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-vlans - networkId (string): Network ID @@ -2047,6 +2091,7 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg - mask (integer): Mask used for the subnet of all bound to the template networks. Applicable only for template network. - ipv6 (object): IPv6 configuration on the VLAN - dhcpHandling (string): The appliance's handling of DHCP requests on this VLAN. One of: 'Run a DHCP server', 'Relay DHCP to another server' or 'Do not respond to DHCP requests' + - dhcpRelayServerIps (array): The IPs (IPv4) of the DHCP servers that DHCP requests should be relayed to. CIDR/subnet notation and hostnames are not supported. - dhcpLeaseTime (string): The term of DHCP leases if the appliance is running a DHCP server on this VLAN. One of: '30 minutes', '1 hour', '4 hours', '12 hours', '1 day' or '1 week' - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this VLAN must use the IP address assigned by the DHCP server. Clients who use a static IP address won't be able to associate. Only available on firmware versions 17.0 and above - dhcpBootOptionsEnabled (boolean): Use DHCP boot options specified in other properties @@ -2074,7 +2119,7 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg networkId = urllib.parse.quote(str(networkId), safe='') resource = f'/networks/{networkId}/appliance/vlans' - body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpBootNextServer', 'dhcpBootFilename', 'dhcpOptions', ] + body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpRelayServerIps', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpBootNextServer', 'dhcpBootFilename', 'dhcpOptions', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) diff --git a/meraki/aio/api/networks.py b/meraki/aio/api/networks.py index 41ff895..876d0a7 100644 --- a/meraki/aio/api/networks.py +++ b/meraki/aio/api/networks.py @@ -363,7 +363,7 @@ def getNetworkClientsOverview(self, networkId: str, **kwargs): - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 31 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 31 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 31 days. The default is 1 day. - - resolution (integer): The time resolution in seconds for returned data. The valid resolutions are: 7200, 86400, 604800, 2592000. The default is 604800. + - resolution (integer): The time resolution in seconds for returned data. The valid resolutions are: 7200, 86400, 604800, 2629746. The default is 604800. """ kwargs.update(locals()) diff --git a/meraki/aio/api/organizations.py b/meraki/aio/api/organizations.py index 0f1c55f..9ad24d3 100644 --- a/meraki/aio/api/organizations.py +++ b/meraki/aio/api/organizations.py @@ -1858,7 +1858,7 @@ def getOrganizationConfigurationChanges(self, organizationId: str, total_pages=1 - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 365 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 365 days. The default is 365 days. - - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 5000. Default is 5000. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100000. Default is 5000. - 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. - networkId (string): Filters on the given network @@ -2220,6 +2220,7 @@ def createOrganizationDevicesPacketCaptureCapture(self, organizationId: str, ser - duration (integer): Duration in seconds of packet capture - filterExpression (string): Filter expression for packet capture - interface (string): Interface of the device + - advanced (object): Advanced filters for IOSXE devices (supported for Campus Gateway devices only) """ kwargs.update(locals()) @@ -2231,7 +2232,7 @@ def createOrganizationDevicesPacketCaptureCapture(self, organizationId: str, ser organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/devices/packetCapture/captures' - body_params = ['serials', 'name', 'outputType', 'destination', 'ports', 'notes', 'duration', 'filterExpression', 'interface', ] + body_params = ['serials', 'name', 'outputType', 'destination', 'ports', 'notes', 'duration', 'filterExpression', 'interface', 'advanced', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) @@ -2249,6 +2250,7 @@ def bulkOrganizationDevicesPacketCaptureCapturesCreate(self, organizationId: str - notes (string): Reason for capture - duration (integer): Duration of the capture in seconds - filterExpression (string): Filter expression for the capture + - advanced (object): Advanced capture options (optional) """ kwargs.update(locals()) @@ -2260,7 +2262,7 @@ def bulkOrganizationDevicesPacketCaptureCapturesCreate(self, organizationId: str organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/devices/packetCapture/captures/bulkCreate' - body_params = ['devices', 'notes', 'duration', 'filterExpression', 'name', ] + body_params = ['devices', 'notes', 'duration', 'filterExpression', 'name', 'advanced', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) @@ -3080,6 +3082,44 @@ def getOrganizationFloorPlansAutoLocateStatuses(self, organizationId: str, total + def getOrganizationIntegrationsDeployable(self, organizationId: str): + """ + **Provides a list of integrations that can be enabled for an Organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-integrations-deployable + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'integrations', 'deployable'], + 'operation': 'getOrganizationIntegrationsDeployable' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/integrations/deployable' + + return self._session.get(metadata, resource) + + + + def getOrganizationIntegrationsDeployed(self, organizationId: str): + """ + **Provides a list of integrations enabled for an Organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-integrations-deployed + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'integrations', 'deployed'], + 'operation': 'getOrganizationIntegrationsDeployed' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/integrations/deployed' + + return self._session.get(metadata, resource) + + + def getOrganizationIntegrationsXdrNetworks(self, organizationId: str, total_pages=1, direction='next', **kwargs): """ **Returns the networks in the organization that have XDR enabled** @@ -3214,6 +3254,7 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di - tags (array): Filter devices by tags. The filtering is case-sensitive. If tags are included, 'tagsFilterType' should also be included (see below). - tagsFilterType (string): To use with 'tags' parameter, to filter devices which contain ANY or ALL given tags. Accepted values are 'withAnyTags' or 'withAllTags', default is 'withAnyTags'. - productTypes (array): Filter devices by product type. Accepted values are appliance, camera, campusGateway, cellularGateway, secureConnect, sensor, switch, systemsManager, wireless, and wirelessController. + - eoxStatuses (array): Filter devices by EoX status. Accepted values are 'endOfSale', 'endOfSupport', 'nearEndOfSupport', or 'null'. Use 'null' to filter for devices with no EOX data. Supports multiple values for multi-select filtering. """ kwargs.update(locals()) @@ -3232,10 +3273,10 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/inventory/devices' - query_params = ['perPage', 'startingAfter', 'endingBefore', 'usedState', 'search', 'macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'tagsFilterType', 'productTypes', ] + query_params = ['perPage', 'startingAfter', 'endingBefore', 'usedState', 'search', 'macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'tagsFilterType', 'productTypes', 'eoxStatuses', ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} - array_params = ['macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'productTypes', ] + array_params = ['macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'productTypes', 'eoxStatuses', ] for k, v in kwargs.items(): if k.strip() in array_params: params[f'{k.strip()}[]'] = kwargs[f'{k}'] @@ -3245,6 +3286,25 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di + def getOrganizationInventoryDevicesEoxOverview(self, organizationId: str): + """ + **Fetch the EOX summary for an organization, including counts of devices that are end-of-sale, end-of-support, and end-of-support-soon.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-devices-eox-overview + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'devices', 'eox'], + 'operation': 'getOrganizationInventoryDevicesEoxOverview' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/devices/eox/overview' + + return self._session.get(metadata, resource) + + + def createOrganizationInventoryDevicesSwapsBulk(self, organizationId: str, swaps: list): """ **Swap the devices identified by devices.old with a devices.new, then perform the :afterAction on the devices.old.** @@ -3457,6 +3517,57 @@ def createOrganizationInventoryOnboardingCloudMonitoringPrepare(self, organizati + def claimOrganizationInventoryOrders(self, organizationId: str, claimId: str, **kwargs): + """ + **Claim an order by the secure unique order claim number, the order claim id** + https://developer.cisco.com/meraki/api-v1/#!claim-organization-inventory-orders + + - organizationId (string): Organization ID + - claimId (string): The unique order claim id + - subscriptions (array): The individual subscriptions to claim + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'orders'], + 'operation': 'claimOrganizationInventoryOrders' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/orders/claim' + + body_params = ['claimId', 'subscriptions', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def previewOrganizationInventoryOrders(self, organizationId: str, claimId: str): + """ + **Preview the results and status of an order claim by the secure order id** + https://developer.cisco.com/meraki/api-v1/#!preview-organization-inventory-orders + + - organizationId (string): Organization ID + - claimId (string): The unique order claim id + """ + + kwargs = locals() + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'orders'], + 'operation': 'previewOrganizationInventoryOrders' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/orders/preview' + + body_params = ['claimId', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + def releaseFromOrganizationInventory(self, organizationId: str, **kwargs): """ **Release a list of claimed devices from an organization.** @@ -3849,6 +3960,69 @@ def combineOrganizationNetworks(self, organizationId: str, name: str, networkIds + def createNetworkMove(self, organizationId: str, network: dict, organizations: dict, **kwargs): + """ + **Move networks from one organization to another** + https://developer.cisco.com/meraki/api-v1/#!create-network-move + + - organizationId (string): Organization ID + - network (object): Network to be moved + - organizations (object): Organizations involved in the network move + - simulate (boolean): If true, simulates the network move and validates the operation without committing changes. The network will remain in the source organization. + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'networks'], + 'operation': 'createNetworkMove' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/networks/moves' + + body_params = ['network', 'organizations', 'simulate', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def getNetworkMoves(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **Return a list of network move operations in the organization** + https://developer.cisco.com/meraki/api-v1/#!get-network-moves + + - 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 10 - 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. + - moveIds (array): Array of network move operation IDs to include. If not specified, all network moves will be returned. + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'networks', 'moves'], + 'operation': 'getNetworkMoves' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/networks/moves' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'moveIds', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = ['moveIds', ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f'{k.strip()}[]'] = kwargs[f'{k}'] + params.pop(k.strip()) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationOpenapiSpec(self, organizationId: str, **kwargs): """ **Return the OpenAPI Specification of the organization's API documentation in JSON** @@ -4467,6 +4641,36 @@ def deleteOrganizationSamlRole(self, organizationId: str, samlRoleId: str): + def getOrganizationSaseNetworksEligible(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List of MX networks or templates that can be enrolled into Secure Access** + https://developer.cisco.com/meraki/api-v1/#!get-organization-sase-networks-eligible + + - 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 5. + - 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): If provided, filters results by network name + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'sase', 'networks', 'eligible'], + 'operation': 'getOrganizationSaseNetworksEligible' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/sase/networks/eligible' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'search', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationSnmp(self, organizationId: str): """ **Return the SNMP settings for an organization** diff --git a/meraki/aio/api/sensor.py b/meraki/aio/api/sensor.py index 817b8fc..b1e2e00 100644 --- a/meraki/aio/api/sensor.py +++ b/meraki/aio/api/sensor.py @@ -174,7 +174,7 @@ def getNetworkSensorAlertsOverviewByMetric(self, networkId: str, **kwargs): - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 731 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 366 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 366 days. The default is 7 days. If interval is provided, the timespan will be autocalculated. - - interval (integer): The time interval in seconds for returned data. The valid intervals are: 900, 3600, 86400, 604800, 2592000. The default is 604800. Interval is calculated if time params are provided. + - interval (integer): The time interval in seconds for returned data. The valid intervals are: 900, 3600, 86400, 604800, 2629746. The default is 604800. Interval is calculated if time params are provided. """ kwargs.update(locals()) @@ -451,7 +451,7 @@ def getOrganizationSensorReadingsHistory(self, organizationId: str, total_pages= - 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. - - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days and 6 hours from today. + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days, 5 hours, 49 minutes, and 12 seconds from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 7 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 7 days. The default is 2 hours. - networkIds (array): Optional parameter to filter readings by network. diff --git a/meraki/aio/api/switch.py b/meraki/aio/api/switch.py index 7672607..cc31564 100644 --- a/meraki/aio/api/switch.py +++ b/meraki/aio/api/switch.py @@ -84,8 +84,8 @@ def getDeviceSwitchPortsStatusesPackets(self, serial: str, **kwargs): https://developer.cisco.com/meraki/api-v1/#!get-device-switch-ports-statuses-packets - serial (string): Serial - - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 1 day from today. - - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameter t0. The value must be in seconds and be less than or equal to 1 day. The default is 1 day. + - t0 (string): The beginning of the timespan for the data. The value is used only to determine the elapsed duration between t0 and the time of the request; the API snaps that duration to the nearest preset window (5 minutes, 15 minutes, 1 hour, or 1 day). + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify t0. The value must be in seconds and be less than or equal to 86400 seconds (1 day). The default is 1 day. """ kwargs.update(locals()) @@ -1602,7 +1602,7 @@ def createNetworkSwitchRoutingMulticastRendezvousPoint(self, networkId: str, int - vrf (object): The VRF with PIM enabled L3 interface """ - kwargs = locals() + kwargs.update(locals()) metadata = { 'tags': ['switch', 'configure', 'routing', 'multicast', 'rendezvousPoints'], diff --git a/meraki/aio/api/wireless.py b/meraki/aio/api/wireless.py index f936aef..df49ebe 100644 --- a/meraki/aio/api/wireless.py +++ b/meraki/aio/api/wireless.py @@ -102,6 +102,9 @@ def getDeviceWirelessConnectionStats(self, serial: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'connectionStats'], @@ -183,6 +186,9 @@ def getDeviceWirelessLatencyStats(self, serial: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'latencyStats'], @@ -681,6 +687,9 @@ def getNetworkWirelessClientsConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'connectionStats'], @@ -717,6 +726,9 @@ def getNetworkWirelessClientsLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'latencyStats'], @@ -753,6 +765,9 @@ def getNetworkWirelessClientConnectionStats(self, networkId: str, clientId: str, if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'connectionStats'], @@ -877,6 +892,9 @@ def getNetworkWirelessClientLatencyStats(self, networkId: str, clientId: str, ** if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'latencyStats'], @@ -913,6 +931,9 @@ def getNetworkWirelessConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'connectionStats'], @@ -986,6 +1007,9 @@ def getNetworkWirelessDevicesConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'devices', 'connectionStats'], @@ -1022,6 +1046,9 @@ def getNetworkWirelessDevicesLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'devices', 'latencyStats'], @@ -1296,6 +1323,9 @@ def getNetworkWirelessFailedConnections(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'failedConnections'], @@ -1374,6 +1404,9 @@ def getNetworkWirelessLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'latencyStats'], @@ -1444,6 +1477,34 @@ def getNetworkWirelessMeshStatuses(self, networkId: str, total_pages=1, directio + def updateNetworkWirelessRadioRrm(self, networkId: str, **kwargs): + """ + **Update the AutoRF settings for a wireless network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-radio-rrm + + - networkId (string): Network ID + - busyHour (object): Busy Hour settings + - channel (object): Channel settings + - fra (object): FRA settings + - ai (object): AI settings + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'radio', 'rrm'], + 'operation': 'updateNetworkWirelessRadioRrm' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/wireless/radio/rrm' + + body_params = ['busyHour', 'channel', 'fra', 'ai', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.put(metadata, resource, payload) + + + def getNetworkWirelessRfProfiles(self, networkId: str, **kwargs): """ **List RF profiles for this network** @@ -1629,6 +1690,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): - locationAnalyticsEnabled (boolean): Toggle for enabling or disabling location analytics for your network - upgradeStrategy (string): The default strategy that network devices will use to perform an upgrade. Requires firmware version MR 26.8 or higher. - ledLightsOn (boolean): Toggle for enabling or disabling LED lights on all APs in the network (making them run dark) + - multicastToUnicastConversion (object): Multicast-to-unicast conversion settings across the network - namedVlans (object): Named VLAN settings for wireless networks. """ @@ -1645,7 +1707,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): networkId = urllib.parse.quote(str(networkId), safe='') resource = f'/networks/{networkId}/wireless/settings' - body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'namedVlans', ] + body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'multicastToUnicastConversion', 'namedVlans', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.put(metadata, resource, payload) @@ -3073,6 +3135,122 @@ def getOrganizationWirelessDevicesPowerModeHistory(self, organizationId: str, to + def getOrganizationWirelessDevicesProvisioningDeployments(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List the zero touch deployments for wireless access points in an organization** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-provisioning-deployments + + - 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 20. + - 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): Filter by MAC address, serial number, new device name, old device name, or model. + - sortBy (string): Field used to sort results. Default is 'status'. + - sortOrder (string): Sort order. Default is 'asc'. + - deploymentType (string): Filter deployments by type. + """ + + kwargs.update(locals()) + + if 'sortBy' in kwargs: + options = ['afterAction', 'createdAt', 'deploymentId', 'name', 'status'] + assert kwargs['sortBy'] in options, f'''"sortBy" cannot be "{kwargs['sortBy']}", & 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}''' + if 'deploymentType' in kwargs: + options = ['deploy', 'replace'] + assert kwargs['deploymentType'] in options, f'''"deploymentType" cannot be "{kwargs['deploymentType']}", & must be set to one of: {options}''' + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'getOrganizationWirelessDevicesProvisioningDeployments' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'search', 'sortBy', 'sortOrder', 'deploymentType', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + + def createOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, items: list, **kwargs): + """ + **Create a zero touch deployment for a wireless access point** + https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'createOrganizationWirelessDevicesProvisioningDeployment' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def updateOrganizationWirelessDevicesProvisioningDeployments(self, organizationId: str, items: list, **kwargs): + """ + **Update a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-provisioning-deployments + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'updateOrganizationWirelessDevicesProvisioningDeployments' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.put(metadata, resource, payload) + + + + def deleteOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, deploymentId: str): + """ + **Delete a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - deploymentId (string): Deployment ID + """ + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'deleteOrganizationWirelessDevicesProvisioningDeployment' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + deploymentId = urllib.parse.quote(str(deploymentId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments/{deploymentId}' + + return self._session.delete(metadata, resource) + + + def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ **Query for details on the organization's RADSEC device Certificate Authority certificates (CAs)** @@ -3529,6 +3707,47 @@ def recalculateOrganizationWirelessRadioAutoRfChannels(self, organizationId: str + def getOrganizationWirelessRadioRrmByNetwork(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List the AutoRF settings of an organization by network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-radio-rrm-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 + - networkIds (array): Optional parameter to filter results by network. + - startingAfter (string): Retrieving items after this network ID + - endingBefore (string): Retrieving items before this network ID + - perPage (integer): Number of items per page + - sortOrder (string): The sort order of items + """ + + 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': ['wireless', 'configure', 'radio', 'rrm', 'byNetwork'], + 'operation': 'getOrganizationWirelessRadioRrmByNetwork' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/radio/rrm/byNetwork' + + query_params = ['networkIds', 'startingAfter', 'endingBefore', 'perPage', 'sortOrder', ] + 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()) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationWirelessRfProfilesAssignmentsByDevice(self, organizationId: str, total_pages=1, direction='next', **kwargs): """ **List the RF profiles of an organization by device** diff --git a/meraki/aio/rest_session.py b/meraki/aio/rest_session.py index 105419a..450f65c 100644 --- a/meraki/aio/rest_session.py +++ b/meraki/aio/rest_session.py @@ -240,7 +240,10 @@ async def _request(self, metadata, method, url, **kwargs): message_is_dict = True else: message_is_dict = False - except aiohttp.client_exceptions.ContentTypeError: + except ( + json.decoder.JSONDecodeError, + aiohttp.client_exceptions.ContentTypeError, + ): message_is_dict = False try: message = (await response.text())[:100] diff --git a/meraki/api/appliance.py b/meraki/api/appliance.py index 224710b..09c9e68 100644 --- a/meraki/api/appliance.py +++ b/meraki/api/appliance.py @@ -870,7 +870,7 @@ def updateNetworkApplianceFirewallSettings(self, networkId: str, **kwargs): def getNetworkAppliancePorts(self, networkId: str): """ - **List per-port VLAN settings for all ports of a MX.** + **List per-port VLAN settings for all ports of a secure router or security appliance.** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-ports - networkId (string): Network ID @@ -889,7 +889,7 @@ def getNetworkAppliancePorts(self, networkId: str): def getNetworkAppliancePort(self, networkId: str, portId: str): """ - **Return per-port VLAN settings for a single MX port.** + **Return per-port VLAN settings for a single secure router or security appliance port.** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-port - networkId (string): Network ID @@ -910,7 +910,7 @@ def getNetworkAppliancePort(self, networkId: str, portId: str): def updateNetworkAppliancePort(self, networkId: str, portId: str, **kwargs): """ - **Update the per-port VLAN settings for a single MX port.** + **Update the per-port VLAN settings for a single secure router or security appliance port.** https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-port - networkId (string): Network ID @@ -1984,6 +1984,50 @@ def updateNetworkApplianceTrafficShapingVpnExclusions(self, networkId: str, **kw + def connectNetworkApplianceUmbrellaAccount(self, networkId: str, api: dict): + """ + **Connect a Cisco Umbrella account to this network** + https://developer.cisco.com/meraki/api-v1/#!connect-network-appliance-umbrella-account + + - networkId (string): Network ID + - api (object): Umbrella API credentials + """ + + kwargs = locals() + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'connectNetworkApplianceUmbrellaAccount' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/appliance/umbrella/account/connect' + + body_params = ['api', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def disconnectNetworkApplianceUmbrellaAccount(self, networkId: str): + """ + **Disconnect Umbrella account from this network** + https://developer.cisco.com/meraki/api-v1/#!disconnect-network-appliance-umbrella-account + + - networkId (string): Network ID + """ + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'disconnectNetworkApplianceUmbrellaAccount' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/appliance/umbrella/account/disconnect' + + return self._session.post(metadata, resource) + + + def getNetworkApplianceUplinksUsageHistory(self, networkId: str, **kwargs): """ **Get the sent and received bytes for each uplink of a network.** @@ -2014,7 +2058,7 @@ def getNetworkApplianceUplinksUsageHistory(self, networkId: str, **kwargs): def getNetworkApplianceVlans(self, networkId: str): """ - **List the VLANs for a Cisco Secure Router network** + **List the VLANs for a Security Appliance network** https://developer.cisco.com/meraki/api-v1/#!get-network-appliance-vlans - networkId (string): Network ID @@ -2047,6 +2091,7 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg - mask (integer): Mask used for the subnet of all bound to the template networks. Applicable only for template network. - ipv6 (object): IPv6 configuration on the VLAN - dhcpHandling (string): The appliance's handling of DHCP requests on this VLAN. One of: 'Run a DHCP server', 'Relay DHCP to another server' or 'Do not respond to DHCP requests' + - dhcpRelayServerIps (array): The IPs (IPv4) of the DHCP servers that DHCP requests should be relayed to. CIDR/subnet notation and hostnames are not supported. - dhcpLeaseTime (string): The term of DHCP leases if the appliance is running a DHCP server on this VLAN. One of: '30 minutes', '1 hour', '4 hours', '12 hours', '1 day' or '1 week' - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this VLAN must use the IP address assigned by the DHCP server. Clients who use a static IP address won't be able to associate. Only available on firmware versions 17.0 and above - dhcpBootOptionsEnabled (boolean): Use DHCP boot options specified in other properties @@ -2074,7 +2119,7 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg networkId = urllib.parse.quote(str(networkId), safe='') resource = f'/networks/{networkId}/appliance/vlans' - body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpBootNextServer', 'dhcpBootFilename', 'dhcpOptions', ] + body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpRelayServerIps', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpBootNextServer', 'dhcpBootFilename', 'dhcpOptions', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) diff --git a/meraki/api/batch/appliance.py b/meraki/api/batch/appliance.py index 278bc31..70c8296 100644 --- a/meraki/api/batch/appliance.py +++ b/meraki/api/batch/appliance.py @@ -191,7 +191,7 @@ def updateNetworkApplianceFirewallMulticastForwarding(self, networkId: str, rule def updateNetworkAppliancePort(self, networkId: str, portId: str, **kwargs): """ - **Update the per-port VLAN settings for a single MX port.** + **Update the per-port VLAN settings for a single secure router or security appliance port.** https://developer.cisco.com/meraki/api-v1/#!update-network-appliance-port - networkId (string): Network ID @@ -804,6 +804,62 @@ def updateNetworkApplianceTrafficShapingVpnExclusions(self, networkId: str, **kw + def connectNetworkApplianceUmbrellaAccount(self, networkId: str, api: dict): + """ + **Connect a Cisco Umbrella account to this network** + https://developer.cisco.com/meraki/api-v1/#!connect-network-appliance-umbrella-account + + - networkId (string): Network ID + - api (object): Umbrella API credentials + """ + + kwargs = locals() + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'connectNetworkApplianceUmbrellaAccount' + } + resource = f'/networks/{networkId}/appliance/umbrella/account/connect' + + body_params = ['api', ] + 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 disconnectNetworkApplianceUmbrellaAccount(self, networkId: str): + """ + **Disconnect Umbrella account from this network** + https://developer.cisco.com/meraki/api-v1/#!disconnect-network-appliance-umbrella-account + + - networkId (string): Network ID + """ + + metadata = { + 'tags': ['appliance', 'configure', 'umbrella', 'account'], + 'operation': 'disconnectNetworkApplianceUmbrellaAccount' + } + resource = f'/networks/{networkId}/appliance/umbrella/account/disconnect' + + action = { + "resource": resource, + "operation": "create", + } + return action + + + + + + def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwargs): """ **Add a VLAN** @@ -820,9 +876,12 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg - mask (integer): Mask used for the subnet of all bound to the template networks. Applicable only for template network. - ipv6 (object): IPv6 configuration on the VLAN - dhcpHandling (string): The appliance's handling of DHCP requests on this VLAN. One of: 'Run a DHCP server', 'Relay DHCP to another server' or 'Do not respond to DHCP requests' + - dhcpRelayServerIps (array): The IPs (IPv4) of the DHCP servers that DHCP requests should be relayed to. CIDR/subnet notation and hostnames are not supported. - dhcpLeaseTime (string): The term of DHCP leases if the appliance is running a DHCP server on this VLAN. One of: '30 minutes', '1 hour', '4 hours', '12 hours', '1 day' or '1 week' - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this VLAN must use the IP address assigned by the DHCP server. Clients who use a static IP address won't be able to associate. Only available on firmware versions 17.0 and above - dhcpBootOptionsEnabled (boolean): Use DHCP boot options specified in other properties + - dhcpBootNextServer (string): DHCP boot option to direct boot clients to the server to load the boot file from + - dhcpBootFilename (string): DHCP boot option for boot filename - dhcpOptions (array): The list of DHCP options that will be included in DHCP responses. Each object in the list should have "code", "type", and "value" properties. """ @@ -844,7 +903,7 @@ def createNetworkApplianceVlan(self, networkId: str, id: str, name: str, **kwarg } resource = f'/networks/{networkId}/appliance/vlans' - body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpOptions', ] + body_params = ['id', 'name', 'subnet', 'applianceIp', 'groupPolicyId', 'templateVlanType', 'cidr', 'mask', 'ipv6', 'dhcpHandling', 'dhcpRelayServerIps', 'dhcpLeaseTime', 'mandatoryDhcp', 'dhcpBootOptionsEnabled', 'dhcpBootNextServer', 'dhcpBootFilename', 'dhcpOptions', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { "resource": resource, diff --git a/meraki/api/batch/organizations.py b/meraki/api/batch/organizations.py index 5e3d9a8..7a28e58 100644 --- a/meraki/api/batch/organizations.py +++ b/meraki/api/batch/organizations.py @@ -999,6 +999,38 @@ def enableOrganizationIntegrationsXdrNetworks(self, organizationId: str, network + def claimOrganizationInventoryOrders(self, organizationId: str, claimId: str, **kwargs): + """ + **Claim an order by the secure unique order claim number, the order claim id** + https://developer.cisco.com/meraki/api-v1/#!claim-organization-inventory-orders + + - organizationId (string): Organization ID + - claimId (string): The unique order claim id + - subscriptions (array): The individual subscriptions to claim + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'orders'], + 'operation': 'claimOrganizationInventoryOrders' + } + resource = f'/organizations/{organizationId}/inventory/orders/claim' + + body_params = ['claimId', 'subscriptions', ] + 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 assignOrganizationLicensesSeats(self, organizationId: str, licenseId: str, networkId: str, seatCount: int): """ **Assign SM seats to a network** diff --git a/meraki/api/batch/wireless.py b/meraki/api/batch/wireless.py index 5986e28..f22d2cc 100644 --- a/meraki/api/batch/wireless.py +++ b/meraki/api/batch/wireless.py @@ -564,6 +564,40 @@ def updateNetworkWirelessLocationScanning(self, networkId: str, **kwargs): + def updateNetworkWirelessRadioRrm(self, networkId: str, **kwargs): + """ + **Update the AutoRF settings for a wireless network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-radio-rrm + + - networkId (string): Network ID + - busyHour (object): Busy Hour settings + - channel (object): Channel settings + - fra (object): FRA settings + - ai (object): AI settings + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'radio', 'rrm'], + 'operation': 'updateNetworkWirelessRadioRrm' + } + resource = f'/networks/{networkId}/wireless/radio/rrm' + + body_params = ['busyHour', 'channel', 'fra', 'ai', ] + 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 createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectionType: str, **kwargs): """ **Creates new RF profile for this network** @@ -700,6 +734,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): - locationAnalyticsEnabled (boolean): Toggle for enabling or disabling location analytics for your network - upgradeStrategy (string): The default strategy that network devices will use to perform an upgrade. Requires firmware version MR 26.8 or higher. - ledLightsOn (boolean): Toggle for enabling or disabling LED lights on all APs in the network (making them run dark) + - multicastToUnicastConversion (object): Multicast-to-unicast conversion settings across the network - namedVlans (object): Named VLAN settings for wireless networks. """ @@ -715,7 +750,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): } resource = f'/networks/{networkId}/wireless/settings' - body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'namedVlans', ] + body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'multicastToUnicastConversion', 'namedVlans', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { "resource": resource, @@ -1383,6 +1418,96 @@ def updateNetworkWirelessZigbee(self, networkId: str, **kwargs): + def createOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, items: list, **kwargs): + """ + **Create a zero touch deployment for a wireless access point** + https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'createOrganizationWirelessDevicesProvisioningDeployment' + } + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + 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 updateOrganizationWirelessDevicesProvisioningDeployments(self, organizationId: str, items: list, **kwargs): + """ + **Update a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-provisioning-deployments + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'updateOrganizationWirelessDevicesProvisioningDeployments' + } + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + 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 deleteOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, deploymentId: str): + """ + **Delete a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - deploymentId (string): Deployment ID + """ + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'deleteOrganizationWirelessDevicesProvisioningDeployment' + } + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments/{deploymentId}' + + action = { + "resource": resource, + "operation": "destroy", + } + return action + + + + + + def createOrganizationWirelessLocationScanningReceiver(self, organizationId: str, network: dict, url: str, version: str, radio: dict, sharedSecret: str): """ **Add new receiver for scanning API** diff --git a/meraki/api/networks.py b/meraki/api/networks.py index a28b514..d483dd5 100644 --- a/meraki/api/networks.py +++ b/meraki/api/networks.py @@ -363,7 +363,7 @@ def getNetworkClientsOverview(self, networkId: str, **kwargs): - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 31 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 31 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 31 days. The default is 1 day. - - resolution (integer): The time resolution in seconds for returned data. The valid resolutions are: 7200, 86400, 604800, 2592000. The default is 604800. + - resolution (integer): The time resolution in seconds for returned data. The valid resolutions are: 7200, 86400, 604800, 2629746. The default is 604800. """ kwargs.update(locals()) diff --git a/meraki/api/organizations.py b/meraki/api/organizations.py index d0be4ef..29f3d90 100644 --- a/meraki/api/organizations.py +++ b/meraki/api/organizations.py @@ -1858,7 +1858,7 @@ def getOrganizationConfigurationChanges(self, organizationId: str, total_pages=1 - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 365 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 365 days. The default is 365 days. - - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 5000. Default is 5000. + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100000. Default is 5000. - 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. - networkId (string): Filters on the given network @@ -2220,6 +2220,7 @@ def createOrganizationDevicesPacketCaptureCapture(self, organizationId: str, ser - duration (integer): Duration in seconds of packet capture - filterExpression (string): Filter expression for packet capture - interface (string): Interface of the device + - advanced (object): Advanced filters for IOSXE devices (supported for Campus Gateway devices only) """ kwargs.update(locals()) @@ -2231,7 +2232,7 @@ def createOrganizationDevicesPacketCaptureCapture(self, organizationId: str, ser organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/devices/packetCapture/captures' - body_params = ['serials', 'name', 'outputType', 'destination', 'ports', 'notes', 'duration', 'filterExpression', 'interface', ] + body_params = ['serials', 'name', 'outputType', 'destination', 'ports', 'notes', 'duration', 'filterExpression', 'interface', 'advanced', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) @@ -2249,6 +2250,7 @@ def bulkOrganizationDevicesPacketCaptureCapturesCreate(self, organizationId: str - notes (string): Reason for capture - duration (integer): Duration of the capture in seconds - filterExpression (string): Filter expression for the capture + - advanced (object): Advanced capture options (optional) """ kwargs.update(locals()) @@ -2260,7 +2262,7 @@ def bulkOrganizationDevicesPacketCaptureCapturesCreate(self, organizationId: str organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/devices/packetCapture/captures/bulkCreate' - body_params = ['devices', 'notes', 'duration', 'filterExpression', 'name', ] + body_params = ['devices', 'notes', 'duration', 'filterExpression', 'name', 'advanced', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.post(metadata, resource, payload) @@ -3080,6 +3082,44 @@ def getOrganizationFloorPlansAutoLocateStatuses(self, organizationId: str, total + def getOrganizationIntegrationsDeployable(self, organizationId: str): + """ + **Provides a list of integrations that can be enabled for an Organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-integrations-deployable + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'integrations', 'deployable'], + 'operation': 'getOrganizationIntegrationsDeployable' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/integrations/deployable' + + return self._session.get(metadata, resource) + + + + def getOrganizationIntegrationsDeployed(self, organizationId: str): + """ + **Provides a list of integrations enabled for an Organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-integrations-deployed + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'integrations', 'deployed'], + 'operation': 'getOrganizationIntegrationsDeployed' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/integrations/deployed' + + return self._session.get(metadata, resource) + + + def getOrganizationIntegrationsXdrNetworks(self, organizationId: str, total_pages=1, direction='next', **kwargs): """ **Returns the networks in the organization that have XDR enabled** @@ -3214,6 +3254,7 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di - tags (array): Filter devices by tags. The filtering is case-sensitive. If tags are included, 'tagsFilterType' should also be included (see below). - tagsFilterType (string): To use with 'tags' parameter, to filter devices which contain ANY or ALL given tags. Accepted values are 'withAnyTags' or 'withAllTags', default is 'withAnyTags'. - productTypes (array): Filter devices by product type. Accepted values are appliance, camera, campusGateway, cellularGateway, secureConnect, sensor, switch, systemsManager, wireless, and wirelessController. + - eoxStatuses (array): Filter devices by EoX status. Accepted values are 'endOfSale', 'endOfSupport', 'nearEndOfSupport', or 'null'. Use 'null' to filter for devices with no EOX data. Supports multiple values for multi-select filtering. """ kwargs.update(locals()) @@ -3232,10 +3273,10 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di organizationId = urllib.parse.quote(str(organizationId), safe='') resource = f'/organizations/{organizationId}/inventory/devices' - query_params = ['perPage', 'startingAfter', 'endingBefore', 'usedState', 'search', 'macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'tagsFilterType', 'productTypes', ] + query_params = ['perPage', 'startingAfter', 'endingBefore', 'usedState', 'search', 'macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'tagsFilterType', 'productTypes', 'eoxStatuses', ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} - array_params = ['macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'productTypes', ] + array_params = ['macs', 'networkIds', 'serials', 'models', 'orderNumbers', 'tags', 'productTypes', 'eoxStatuses', ] for k, v in kwargs.items(): if k.strip() in array_params: params[f'{k.strip()}[]'] = kwargs[f'{k}'] @@ -3245,6 +3286,25 @@ def getOrganizationInventoryDevices(self, organizationId: str, total_pages=1, di + def getOrganizationInventoryDevicesEoxOverview(self, organizationId: str): + """ + **Fetch the EOX summary for an organization, including counts of devices that are end-of-sale, end-of-support, and end-of-support-soon.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-devices-eox-overview + + - organizationId (string): Organization ID + """ + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'devices', 'eox'], + 'operation': 'getOrganizationInventoryDevicesEoxOverview' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/devices/eox/overview' + + return self._session.get(metadata, resource) + + + def createOrganizationInventoryDevicesSwapsBulk(self, organizationId: str, swaps: list): """ **Swap the devices identified by devices.old with a devices.new, then perform the :afterAction on the devices.old.** @@ -3457,6 +3517,57 @@ def createOrganizationInventoryOnboardingCloudMonitoringPrepare(self, organizati + def claimOrganizationInventoryOrders(self, organizationId: str, claimId: str, **kwargs): + """ + **Claim an order by the secure unique order claim number, the order claim id** + https://developer.cisco.com/meraki/api-v1/#!claim-organization-inventory-orders + + - organizationId (string): Organization ID + - claimId (string): The unique order claim id + - subscriptions (array): The individual subscriptions to claim + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'orders'], + 'operation': 'claimOrganizationInventoryOrders' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/orders/claim' + + body_params = ['claimId', 'subscriptions', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def previewOrganizationInventoryOrders(self, organizationId: str, claimId: str): + """ + **Preview the results and status of an order claim by the secure order id** + https://developer.cisco.com/meraki/api-v1/#!preview-organization-inventory-orders + + - organizationId (string): Organization ID + - claimId (string): The unique order claim id + """ + + kwargs = locals() + + metadata = { + 'tags': ['organizations', 'configure', 'inventory', 'orders'], + 'operation': 'previewOrganizationInventoryOrders' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/inventory/orders/preview' + + body_params = ['claimId', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + def releaseFromOrganizationInventory(self, organizationId: str, **kwargs): """ **Release a list of claimed devices from an organization.** @@ -3849,6 +3960,69 @@ def combineOrganizationNetworks(self, organizationId: str, name: str, networkIds + def createNetworkMove(self, organizationId: str, network: dict, organizations: dict, **kwargs): + """ + **Move networks from one organization to another** + https://developer.cisco.com/meraki/api-v1/#!create-network-move + + - organizationId (string): Organization ID + - network (object): Network to be moved + - organizations (object): Organizations involved in the network move + - simulate (boolean): If true, simulates the network move and validates the operation without committing changes. The network will remain in the source organization. + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'networks'], + 'operation': 'createNetworkMove' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/networks/moves' + + body_params = ['network', 'organizations', 'simulate', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def getNetworkMoves(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **Return a list of network move operations in the organization** + https://developer.cisco.com/meraki/api-v1/#!get-network-moves + + - 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 10 - 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. + - moveIds (array): Array of network move operation IDs to include. If not specified, all network moves will be returned. + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'networks', 'moves'], + 'operation': 'getNetworkMoves' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/networks/moves' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'moveIds', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = ['moveIds', ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f'{k.strip()}[]'] = kwargs[f'{k}'] + params.pop(k.strip()) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationOpenapiSpec(self, organizationId: str, **kwargs): """ **Return the OpenAPI Specification of the organization's API documentation in JSON** @@ -4467,6 +4641,36 @@ def deleteOrganizationSamlRole(self, organizationId: str, samlRoleId: str): + def getOrganizationSaseNetworksEligible(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List of MX networks or templates that can be enrolled into Secure Access** + https://developer.cisco.com/meraki/api-v1/#!get-organization-sase-networks-eligible + + - 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 5. + - 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): If provided, filters results by network name + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['organizations', 'configure', 'sase', 'networks', 'eligible'], + 'operation': 'getOrganizationSaseNetworksEligible' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/sase/networks/eligible' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'search', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationSnmp(self, organizationId: str): """ **Return the SNMP settings for an organization** diff --git a/meraki/api/sensor.py b/meraki/api/sensor.py index 540e5fd..9bcb5ee 100644 --- a/meraki/api/sensor.py +++ b/meraki/api/sensor.py @@ -174,7 +174,7 @@ def getNetworkSensorAlertsOverviewByMetric(self, networkId: str, **kwargs): - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 731 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 366 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 366 days. The default is 7 days. If interval is provided, the timespan will be autocalculated. - - interval (integer): The time interval in seconds for returned data. The valid intervals are: 900, 3600, 86400, 604800, 2592000. The default is 604800. Interval is calculated if time params are provided. + - interval (integer): The time interval in seconds for returned data. The valid intervals are: 900, 3600, 86400, 604800, 2629746. The default is 604800. Interval is calculated if time params are provided. """ kwargs.update(locals()) @@ -451,7 +451,7 @@ def getOrganizationSensorReadingsHistory(self, organizationId: str, total_pages= - 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. - - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days and 6 hours from today. + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 365 days, 5 hours, 49 minutes, and 12 seconds from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 7 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 7 days. The default is 2 hours. - networkIds (array): Optional parameter to filter readings by network. diff --git a/meraki/api/switch.py b/meraki/api/switch.py index 32520af..152d1da 100644 --- a/meraki/api/switch.py +++ b/meraki/api/switch.py @@ -84,8 +84,8 @@ def getDeviceSwitchPortsStatusesPackets(self, serial: str, **kwargs): https://developer.cisco.com/meraki/api-v1/#!get-device-switch-ports-statuses-packets - serial (string): Serial - - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 1 day from today. - - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameter t0. The value must be in seconds and be less than or equal to 1 day. The default is 1 day. + - t0 (string): The beginning of the timespan for the data. The value is used only to determine the elapsed duration between t0 and the time of the request; the API snaps that duration to the nearest preset window (5 minutes, 15 minutes, 1 hour, or 1 day). + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify t0. The value must be in seconds and be less than or equal to 86400 seconds (1 day). The default is 1 day. """ kwargs.update(locals()) diff --git a/meraki/api/wireless.py b/meraki/api/wireless.py index ac7adfe..ef7e03f 100644 --- a/meraki/api/wireless.py +++ b/meraki/api/wireless.py @@ -102,6 +102,9 @@ def getDeviceWirelessConnectionStats(self, serial: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'connectionStats'], @@ -183,6 +186,9 @@ def getDeviceWirelessLatencyStats(self, serial: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'latencyStats'], @@ -681,6 +687,9 @@ def getNetworkWirelessClientsConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'connectionStats'], @@ -717,6 +726,9 @@ def getNetworkWirelessClientsLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'latencyStats'], @@ -753,6 +765,9 @@ def getNetworkWirelessClientConnectionStats(self, networkId: str, clientId: str, if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'connectionStats'], @@ -877,6 +892,9 @@ def getNetworkWirelessClientLatencyStats(self, networkId: str, clientId: str, ** if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'clients', 'latencyStats'], @@ -913,6 +931,9 @@ def getNetworkWirelessConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'connectionStats'], @@ -986,6 +1007,9 @@ def getNetworkWirelessDevicesConnectionStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'devices', 'connectionStats'], @@ -1022,6 +1046,9 @@ def getNetworkWirelessDevicesLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'devices', 'latencyStats'], @@ -1296,6 +1323,9 @@ def getNetworkWirelessFailedConnections(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'failedConnections'], @@ -1374,6 +1404,9 @@ def getNetworkWirelessLatencyStats(self, networkId: str, **kwargs): if 'band' in kwargs: options = ['2.4', '5', '6'] assert kwargs['band'] in options, f'''"band" cannot be "{kwargs['band']}", & must be set to one of: {options}''' + if 'ssid' in kwargs: + options = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + assert kwargs['ssid'] in options, f'''"ssid" cannot be "{kwargs['ssid']}", & must be set to one of: {options}''' metadata = { 'tags': ['wireless', 'monitor', 'latencyStats'], @@ -1444,6 +1477,34 @@ def getNetworkWirelessMeshStatuses(self, networkId: str, total_pages=1, directio + def updateNetworkWirelessRadioRrm(self, networkId: str, **kwargs): + """ + **Update the AutoRF settings for a wireless network** + https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-radio-rrm + + - networkId (string): Network ID + - busyHour (object): Busy Hour settings + - channel (object): Channel settings + - fra (object): FRA settings + - ai (object): AI settings + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'radio', 'rrm'], + 'operation': 'updateNetworkWirelessRadioRrm' + } + networkId = urllib.parse.quote(str(networkId), safe='') + resource = f'/networks/{networkId}/wireless/radio/rrm' + + body_params = ['busyHour', 'channel', 'fra', 'ai', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.put(metadata, resource, payload) + + + def getNetworkWirelessRfProfiles(self, networkId: str, **kwargs): """ **List RF profiles for this network** @@ -1629,6 +1690,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): - locationAnalyticsEnabled (boolean): Toggle for enabling or disabling location analytics for your network - upgradeStrategy (string): The default strategy that network devices will use to perform an upgrade. Requires firmware version MR 26.8 or higher. - ledLightsOn (boolean): Toggle for enabling or disabling LED lights on all APs in the network (making them run dark) + - multicastToUnicastConversion (object): Multicast-to-unicast conversion settings across the network - namedVlans (object): Named VLAN settings for wireless networks. """ @@ -1645,7 +1707,7 @@ def updateNetworkWirelessSettings(self, networkId: str, **kwargs): networkId = urllib.parse.quote(str(networkId), safe='') resource = f'/networks/{networkId}/wireless/settings' - body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'namedVlans', ] + body_params = ['meshingEnabled', 'ipv6BridgeEnabled', 'locationAnalyticsEnabled', 'upgradeStrategy', 'ledLightsOn', 'multicastToUnicastConversion', 'namedVlans', ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} return self._session.put(metadata, resource, payload) @@ -3073,6 +3135,122 @@ def getOrganizationWirelessDevicesPowerModeHistory(self, organizationId: str, to + def getOrganizationWirelessDevicesProvisioningDeployments(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List the zero touch deployments for wireless access points in an organization** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-provisioning-deployments + + - 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 20. + - 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): Filter by MAC address, serial number, new device name, old device name, or model. + - sortBy (string): Field used to sort results. Default is 'status'. + - sortOrder (string): Sort order. Default is 'asc'. + - deploymentType (string): Filter deployments by type. + """ + + kwargs.update(locals()) + + if 'sortBy' in kwargs: + options = ['afterAction', 'createdAt', 'deploymentId', 'name', 'status'] + assert kwargs['sortBy'] in options, f'''"sortBy" cannot be "{kwargs['sortBy']}", & 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}''' + if 'deploymentType' in kwargs: + options = ['deploy', 'replace'] + assert kwargs['deploymentType'] in options, f'''"deploymentType" cannot be "{kwargs['deploymentType']}", & must be set to one of: {options}''' + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'getOrganizationWirelessDevicesProvisioningDeployments' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + query_params = ['perPage', 'startingAfter', 'endingBefore', 'search', 'sortBy', 'sortOrder', 'deploymentType', ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + + def createOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, items: list, **kwargs): + """ + **Create a zero touch deployment for a wireless access point** + https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'createOrganizationWirelessDevicesProvisioningDeployment' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.post(metadata, resource, payload) + + + + def updateOrganizationWirelessDevicesProvisioningDeployments(self, organizationId: str, items: list, **kwargs): + """ + **Update a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-provisioning-deployments + + - organizationId (string): Organization ID + - items (array): List of zero touch deployments to create + - meta (object): Metadata relevant to the paginated dataset + """ + + kwargs.update(locals()) + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'updateOrganizationWirelessDevicesProvisioningDeployments' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments' + + body_params = ['items', 'meta', ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + return self._session.put(metadata, resource, payload) + + + + def deleteOrganizationWirelessDevicesProvisioningDeployment(self, organizationId: str, deploymentId: str): + """ + **Delete a zero touch deployment** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-wireless-devices-provisioning-deployment + + - organizationId (string): Organization ID + - deploymentId (string): Deployment ID + """ + + metadata = { + 'tags': ['wireless', 'configure', 'devices', 'provisioning', 'deployments'], + 'operation': 'deleteOrganizationWirelessDevicesProvisioningDeployment' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + deploymentId = urllib.parse.quote(str(deploymentId), safe='') + resource = f'/organizations/{organizationId}/wireless/devices/provisioning/deployments/{deploymentId}' + + return self._session.delete(metadata, resource) + + + def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ **Query for details on the organization's RADSEC device Certificate Authority certificates (CAs)** @@ -3529,6 +3707,47 @@ def recalculateOrganizationWirelessRadioAutoRfChannels(self, organizationId: str + def getOrganizationWirelessRadioRrmByNetwork(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List the AutoRF settings of an organization by network** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-radio-rrm-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 + - networkIds (array): Optional parameter to filter results by network. + - startingAfter (string): Retrieving items after this network ID + - endingBefore (string): Retrieving items before this network ID + - perPage (integer): Number of items per page + - sortOrder (string): The sort order of items + """ + + 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': ['wireless', 'configure', 'radio', 'rrm', 'byNetwork'], + 'operation': 'getOrganizationWirelessRadioRrmByNetwork' + } + organizationId = urllib.parse.quote(str(organizationId), safe='') + resource = f'/organizations/{organizationId}/wireless/radio/rrm/byNetwork' + + query_params = ['networkIds', 'startingAfter', 'endingBefore', 'perPage', 'sortOrder', ] + 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()) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def getOrganizationWirelessRfProfilesAssignmentsByDevice(self, organizationId: str, total_pages=1, direction='next', **kwargs): """ **List the RF profiles of an organization by device** diff --git a/pyproject.toml b/pyproject.toml index bf88541..8d2f610 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "meraki" -version = "2.1.2" +version = "2.2.0" description = "Meraki library for Python" authors = [ {name = "Cisco Meraki",email = "api-feedback@meraki.net"}