diff --git a/docs/generation-report.md b/docs/generation-report.md index 01ada31..7dca83e 100644 --- a/docs/generation-report.md +++ b/docs/generation-report.md @@ -1,5 +1,11 @@ # Generation Report +## 2026-09-02 | Library v4.5.0 | API 1.74.0 + + +No Python keyword parameter conflicts detected. + + ## 2026-08-05 | Library v4.4.0 | API 1.73.0 diff --git a/meraki/__init__.py b/meraki/__init__.py index 2fa9b49..b3ef9b4 100644 --- a/meraki/__init__.py +++ b/meraki/__init__.py @@ -60,7 +60,7 @@ from meraki._version import __version__ # noqa: F401 from datetime import datetime -__api_version__ = "1.73.0" +__api_version__ = "1.74.0" __all__ = [ "APIError", diff --git a/meraki/_version.py b/meraki/_version.py index ecdb1ce..9faa2c2 100644 --- a/meraki/_version.py +++ b/meraki/_version.py @@ -1 +1 @@ -__version__ = "4.4.0" +__version__ = "4.5.0" diff --git a/meraki/aio/api/appliance.py b/meraki/aio/api/appliance.py index e4984ca..f9954ac 100644 --- a/meraki/aio/api/appliance.py +++ b/meraki/aio/api/appliance.py @@ -1119,7 +1119,7 @@ def updateNetworkApplianceInterfacesL3(self, networkId: str, interfaceId: str, * - networkId (string): Network ID - interfaceId (string): Interface ID - - port (object): Port configuration + - port (object): Port configuration. Set to null to remove the port association. - ipv4 (object): IPv4 configuration """ @@ -1804,6 +1804,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): - applianceIp (string): The appliance IP address of the single LAN - ipv6 (object): IPv6 configuration on the VLAN - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this LAN 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 + - vrf (object): VRF configuration on the Single LAN. Omit this field to preserve the current VRF. """ kwargs.update(locals()) @@ -1820,6 +1821,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): "applianceIp", "ipv6", "mandatoryDhcp", + "vrf", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1877,11 +1879,11 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): - name (string): The name of the SSID. - enabled (boolean): Whether or not the SSID is enabled. - defaultVlanId (integer): The VLAN ID of the VLAN associated to this SSID. This parameter is only valid if the network is in routed mode. - - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki' or '8021x-radius'). + - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki', '8021x-radius' or '8021x-nac'). - psk (string): The passkey for the SSID. This param is only valid if the authMode is 'psk'. - radiusServers (array): The RADIUS 802.1x servers to be used for authentication. This param is only valid if the authMode is '8021x-radius'. - encryptionMode (string): The psk encryption mode for the SSID ('wep' or 'wpa'). This param is only valid if the authMode is 'psk'. - - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' + - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' OR (4) the authMode is '8021x-nac' - visible (boolean): Boolean indicating whether the MX should advertise or hide this SSID. - dhcpEnforcedDeauthentication (object): DHCP Enforced Deauthentication enables the disassociation of wireless clients in addition to Mandatory DHCP. This param is only valid on firmware versions >= MX 17.0 where the associated LAN has Mandatory DHCP Enabled - dot11w (object): The current setting for Protected Management Frames (802.11w). @@ -1890,7 +1892,7 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): kwargs.update(locals()) if "authMode" in kwargs: - options = ["8021x-meraki", "8021x-radius", "open", "psk"] + options = ["8021x-meraki", "8021x-nac", "8021x-radius", "open", "psk"] assert kwargs["authMode"] in options, ( f'''"authMode" cannot be "{kwargs["authMode"]}", & must be set to one of: {options}''' ) diff --git a/meraki/aio/api/campusGateway.py b/meraki/aio/api/campusGateway.py index e33ec92..e7ccac9 100644 --- a/meraki/aio/api/campusGateway.py +++ b/meraki/aio/api/campusGateway.py @@ -115,6 +115,41 @@ def deleteNetworkCampusGatewayCluster(self, networkId: str, clusterId: str): return self._session.delete(metadata, resource) + def updateNetworkCampusGatewaySsidMdns(self, networkId: str, number: str, **kwargs): + """ + **Update the mDNS gateway settings and rules for a SSID and cluster** + https://developer.cisco.com/meraki/api-v1/#!update-network-campus-gateway-ssid-mdns + + - networkId (string): Network ID + - number (string): Number + - enabled (boolean): If true, mDNS gateway is enabled for this SSID and cluster. + - rules (array): List of mDNS forwarding rules. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["campusGateway", "configure", "ssids", "mdns"], + "operation": "updateNetworkCampusGatewaySsidMdns", + } + networkId = urllib.parse.quote(str(networkId), safe="") + number = urllib.parse.quote(str(number), safe="") + resource = f"/networks/{networkId}/campusGateway/ssids/{number}/mdns" + + body_params = [ + "enabled", + "rules", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateNetworkCampusGatewaySsidMdns: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getOrganizationCampusGatewayClientsUsageByNetworkByCluster( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -603,6 +638,95 @@ def getOrganizationCampusGatewayClustersTunnelable( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def batchOrganizationCampusGatewayClustersTunnelingUpdate(self, organizationId: str, items: list, **kwargs): + """ + **Update MCG cluster-network tunnel settings for multiple networks** + https://developer.cisco.com/meraki/api-v1/#!batch-organization-campus-gateway-clusters-tunneling-update + + - organizationId (string): Organization ID + - items (array): MCG cluster-network tunnel settings + """ + + kwargs = locals() + + metadata = { + "tags": ["campusGateway", "configure", "clusters", "tunneling"], + "operation": "batchOrganizationCampusGatewayClustersTunnelingUpdate", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/campusGateway/clusters/tunneling/batchUpdate" + + body_params = [ + "items", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"batchOrganizationCampusGatewayClustersTunnelingUpdate: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List all the MCG cluster-network tunnel settings** + https://developer.cisco.com/meraki/api-v1/#!get-organization-campus-gateway-clusters-tunneling-by-cluster-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 + - clusterIds (array): Optional parameter to filter MCG clusters. This filter uses multiple exact matches + - dataEncryptionEnabled (boolean): Optional parameter to filter cluster-network tunnel settings by data encryption configuration + - networkIds (array): Optional parameter to filter networks. This filter uses multiple exact matches + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 50. + - startingAfter (string): A token used by the server to indicate the start of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - endingBefore (string): A token used by the server to indicate the end of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["campusGateway", "configure", "clusters", "tunneling", "byCluster", "byNetwork"], + "operation": "getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/campusGateway/clusters/tunneling/byCluster/byNetwork" + + query_params = [ + "clusterIds", + "dataEncryptionEnabled", + "networkIds", + "perPage", + "startingAfter", + "endingBefore", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "clusterIds", + "networkIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationCampusGatewayConnections(self, organizationId: str, total_pages=1, direction="next", **kwargs): """ **List the details of APs tunneling through the Campus Gateway clusters** diff --git a/meraki/aio/api/devices.py b/meraki/aio/api/devices.py index 1c02af9..baaaf51 100644 --- a/meraki/aio/api/devices.py +++ b/meraki/aio/api/devices.py @@ -791,6 +791,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): - destination (object): The destination IP or subnet to lookup - nextHop (object): The next hop to lookup - vpn (object): VPN related search criteria + - vrf (object): Virtual routing and forwarding (VRF) search criteria - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret """ @@ -828,6 +829,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): "destination", "nextHop", "vpn", + "vrf", "callback", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/aio/api/licensing.py b/meraki/aio/api/licensing.py index 553f47e..29e8837 100644 --- a/meraki/aio/api/licensing.py +++ b/meraki/aio/api/licensing.py @@ -12,10 +12,17 @@ def getAdministeredLicensingSubscriptionEntitlements(self, **kwargs): https://developer.cisco.com/meraki/api-v1/#!get-administered-licensing-subscription-entitlements - skus (array): Filter to entitlements with the specified SKUs + - subscriptionType (string): Filter entitlements by subscription type """ kwargs.update(locals()) + if "subscriptionType" in kwargs: + options = ["termed", "unified"] + assert kwargs["subscriptionType"] in options, ( + f'''"subscriptionType" cannot be "{kwargs["subscriptionType"]}", & must be set to one of: {options}''' + ) + metadata = { "tags": ["licensing", "configure", "subscription", "entitlements"], "operation": "getAdministeredLicensingSubscriptionEntitlements", @@ -24,6 +31,7 @@ def getAdministeredLicensingSubscriptionEntitlements(self, **kwargs): query_params = [ "skus", + "subscriptionType", ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} diff --git a/meraki/aio/api/networks.py b/meraki/aio/api/networks.py index 83474d0..0ab1278 100644 --- a/meraki/aio/api/networks.py +++ b/meraki/aio/api/networks.py @@ -1200,9 +1200,10 @@ def updateNetworkFirmwareUpgradesStagedEvents(self, networkId: str, stages: list - networkId (string): Network ID - stages (array): All firmware upgrade stages in the network with their start time. + - products (object): Contains firmware upgrade settings """ - kwargs = locals() + kwargs.update(locals()) metadata = { "tags": ["networks", "configure", "firmwareUpgrades", "staged", "events"], @@ -1212,6 +1213,7 @@ def updateNetworkFirmwareUpgradesStagedEvents(self, networkId: str, stages: list resource = f"/networks/{networkId}/firmwareUpgrades/staged/events" body_params = [ + "products", "stages", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/aio/api/switch.py b/meraki/aio/api/switch.py index 14e4e8b..918913b 100644 --- a/meraki/aio/api/switch.py +++ b/meraki/aio/api/switch.py @@ -150,6 +150,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): - tags (array): The list of tags of the switch port. - enabled (boolean): The status of the switch port. - poeEnabled (boolean): The PoE status of the switch port. + - perpetualPoe (object): Perpetual PoE settings for the switch port. + - fastPoe (object): Fast PoE settings for the switch port. - type (string): The type of the switch port ('access', 'trunk', 'stack', 'routed', 'svl' or 'dad'). - vlan (integer): The VLAN of the switch port. For a trunk port, this is the native VLAN. A null value will clear the value set for trunk ports. - voiceVlan (integer): The voice VLAN of the switch port. Only applicable to access ports. @@ -210,6 +212,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): "tags", "enabled", "poeEnabled", + "perpetualPoe", + "fastPoe", "type", "vlan", "voiceVlan", @@ -295,9 +299,9 @@ def createDeviceSwitchRoutingInterface(self, serial: str, name: str, **kwargs): - serial (string): Serial - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -380,7 +384,7 @@ def updateDeviceSwitchRoutingInterface(self, serial: str, interfaceId: str, **kw - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -2423,9 +2427,9 @@ def createNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - networkId (string): Network ID - switchStackId (string): Switch stack ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -2514,7 +2518,7 @@ def updateNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. diff --git a/meraki/aio/api/wireless.py b/meraki/aio/api/wireless.py index c2f93b2..af0b69f 100644 --- a/meraki/aio/api/wireless.py +++ b/meraki/aio/api/wireless.py @@ -248,6 +248,56 @@ def getDeviceWirelessLatencyStats(self, serial: str, **kwargs): return self._session.get(metadata, resource, params) + def getDeviceWirelessRadioOverrides(self, serial: str): + """ + **Return the radio overrides of a device** + https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-radio-overrides + + - serial (string): Serial + """ + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides"], + "operation": "getDeviceWirelessRadioOverrides", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/wireless/radio/overrides" + + return self._session.get(metadata, resource) + + def updateDeviceWirelessRadioOverrides(self, serial: str, **kwargs): + """ + **Update 2.4 GHz, 5 GHz, and 6 GHz radio settings (channel, channel width, power, and enable/disable) that override RF profiles** + https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-radio-overrides + + - serial (string): Serial + - rfProfile (object): This device's RF profile. If omitted, the existing RF profile assignment remains unchanged. + - radios (array): Radio overrides. If omitted, existing per-radio override settings remain unchanged. If provided, only the radios included in the array are updated; the array does not replace the device's full existing set of radio overrides. Read-only response fields for each radio, such as 'band', may be included in the request body and are ignored. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides"], + "operation": "updateDeviceWirelessRadioOverrides", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/wireless/radio/overrides" + + body_params = [ + "rfProfile", + "radios", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateDeviceWirelessRadioOverrides: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getDeviceWirelessRadioSettings(self, serial: str): """ **Return the manually configured radio settings overrides of a device, which take precedence over RF profiles.** @@ -1933,6 +1983,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -1967,6 +2018,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1998,6 +2050,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -2035,6 +2088,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -5183,6 +5237,58 @@ def recalculateOrganizationWirelessRadioAutoRfChannels(self, organizationId: str return self._session.post(metadata, resource, payload) + def getOrganizationWirelessRadioOverridesByDevice(self, organizationId: str, total_pages=1, direction="next", **kwargs): + """ + **Return a list of radio overrides** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-radio-overrides-by-device + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 100. + - startingAfter (string): A token used by the server to indicate the start of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - endingBefore (string): A token used by the server to indicate the end of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - networkIds (array): A list of network IDs. The returned radio overrides will be filtered to only include these networks. + - serials (array): A list of serial numbers. The returned radio overrides will be filtered to only include these serials. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides", "byDevice"], + "operation": "getOrganizationWirelessRadioOverridesByDevice", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/wireless/radio/overrides/byDevice" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + "serials", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + "serials", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationWirelessRadioOverridesByDevice: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessRadioRrmByNetwork(self, organizationId: str, total_pages=1, direction="next", **kwargs): """ **List the AutoRF settings of an organization by network** diff --git a/meraki/api/appliance.py b/meraki/api/appliance.py index b076745..248e6d3 100644 --- a/meraki/api/appliance.py +++ b/meraki/api/appliance.py @@ -1119,7 +1119,7 @@ def updateNetworkApplianceInterfacesL3(self, networkId: str, interfaceId: str, * - networkId (string): Network ID - interfaceId (string): Interface ID - - port (object): Port configuration + - port (object): Port configuration. Set to null to remove the port association. - ipv4 (object): IPv4 configuration """ @@ -1804,6 +1804,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): - applianceIp (string): The appliance IP address of the single LAN - ipv6 (object): IPv6 configuration on the VLAN - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this LAN 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 + - vrf (object): VRF configuration on the Single LAN. Omit this field to preserve the current VRF. """ kwargs.update(locals()) @@ -1820,6 +1821,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): "applianceIp", "ipv6", "mandatoryDhcp", + "vrf", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1877,11 +1879,11 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): - name (string): The name of the SSID. - enabled (boolean): Whether or not the SSID is enabled. - defaultVlanId (integer): The VLAN ID of the VLAN associated to this SSID. This parameter is only valid if the network is in routed mode. - - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki' or '8021x-radius'). + - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki', '8021x-radius' or '8021x-nac'). - psk (string): The passkey for the SSID. This param is only valid if the authMode is 'psk'. - radiusServers (array): The RADIUS 802.1x servers to be used for authentication. This param is only valid if the authMode is '8021x-radius'. - encryptionMode (string): The psk encryption mode for the SSID ('wep' or 'wpa'). This param is only valid if the authMode is 'psk'. - - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' + - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' OR (4) the authMode is '8021x-nac' - visible (boolean): Boolean indicating whether the MX should advertise or hide this SSID. - dhcpEnforcedDeauthentication (object): DHCP Enforced Deauthentication enables the disassociation of wireless clients in addition to Mandatory DHCP. This param is only valid on firmware versions >= MX 17.0 where the associated LAN has Mandatory DHCP Enabled - dot11w (object): The current setting for Protected Management Frames (802.11w). @@ -1890,7 +1892,7 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): kwargs.update(locals()) if "authMode" in kwargs: - options = ["8021x-meraki", "8021x-radius", "open", "psk"] + options = ["8021x-meraki", "8021x-nac", "8021x-radius", "open", "psk"] assert kwargs["authMode"] in options, ( f'''"authMode" cannot be "{kwargs["authMode"]}", & must be set to one of: {options}''' ) diff --git a/meraki/api/batch/appliance.py b/meraki/api/batch/appliance.py index fbf0e78..04a9548 100644 --- a/meraki/api/batch/appliance.py +++ b/meraki/api/batch/appliance.py @@ -270,7 +270,7 @@ def updateNetworkApplianceInterfacesL3(self, networkId: str, interfaceId: str, * - networkId (string): Network ID - interfaceId (string): Interface ID - - port (object): Port configuration + - port (object): Port configuration. Set to null to remove the port association. - ipv4 (object): IPv4 configuration """ @@ -587,6 +587,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): - applianceIp (string): The appliance IP address of the single LAN - ipv6 (object): IPv6 configuration on the VLAN - mandatoryDhcp (object): Mandatory DHCP will enforce that clients connecting to this LAN 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 + - vrf (object): VRF configuration on the Single LAN. Omit this field to preserve the current VRF. """ kwargs.update(locals()) @@ -599,6 +600,7 @@ def updateNetworkApplianceSingleLan(self, networkId: str, **kwargs): "applianceIp", "ipv6", "mandatoryDhcp", + "vrf", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { @@ -618,11 +620,11 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): - name (string): The name of the SSID. - enabled (boolean): Whether or not the SSID is enabled. - defaultVlanId (integer): The VLAN ID of the VLAN associated to this SSID. This parameter is only valid if the network is in routed mode. - - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki' or '8021x-radius'). + - authMode (string): The association control method for the SSID ('open', 'psk', '8021x-meraki', '8021x-radius' or '8021x-nac'). - psk (string): The passkey for the SSID. This param is only valid if the authMode is 'psk'. - radiusServers (array): The RADIUS 802.1x servers to be used for authentication. This param is only valid if the authMode is '8021x-radius'. - encryptionMode (string): The psk encryption mode for the SSID ('wep' or 'wpa'). This param is only valid if the authMode is 'psk'. - - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' + - wpaEncryptionMode (string): The types of WPA encryption. ('WPA1 and WPA2', 'WPA2 only', 'WPA3 Transition Mode' or 'WPA3 only'). This param is only valid if (1) the authMode is 'psk' & the encryptionMode is 'wpa' OR (2) the authMode is '8021x-meraki' OR (3) the authMode is '8021x-radius' OR (4) the authMode is '8021x-nac' - visible (boolean): Boolean indicating whether the MX should advertise or hide this SSID. - dhcpEnforcedDeauthentication (object): DHCP Enforced Deauthentication enables the disassociation of wireless clients in addition to Mandatory DHCP. This param is only valid on firmware versions >= MX 17.0 where the associated LAN has Mandatory DHCP Enabled - dot11w (object): The current setting for Protected Management Frames (802.11w). @@ -631,7 +633,7 @@ def updateNetworkApplianceSsid(self, networkId: str, number: str, **kwargs): kwargs.update(locals()) if "authMode" in kwargs: - options = ["8021x-meraki", "8021x-radius", "open", "psk"] + options = ["8021x-meraki", "8021x-nac", "8021x-radius", "open", "psk"] assert kwargs["authMode"] in options, ( f'''"authMode" cannot be "{kwargs["authMode"]}", & must be set to one of: {options}''' ) diff --git a/meraki/api/batch/campusGateway.py b/meraki/api/batch/campusGateway.py index a4b1a2e..8795047 100644 --- a/meraki/api/batch/campusGateway.py +++ b/meraki/api/batch/campusGateway.py @@ -102,6 +102,35 @@ def deleteNetworkCampusGatewayCluster(self, networkId: str, clusterId: str): } return action + def updateNetworkCampusGatewaySsidMdns(self, networkId: str, number: str, **kwargs): + """ + **Update the mDNS gateway settings and rules for a SSID and cluster** + https://developer.cisco.com/meraki/api-v1/#!update-network-campus-gateway-ssid-mdns + + - networkId (string): Network ID + - number (string): Number + - enabled (boolean): If true, mDNS gateway is enabled for this SSID and cluster. + - rules (array): List of mDNS forwarding rules. + """ + + kwargs.update(locals()) + + networkId = urllib.parse.quote(str(networkId), safe="") + number = urllib.parse.quote(str(number), safe="") + resource = f"/networks/{networkId}/campusGateway/ssids/{number}/mdns" + + body_params = [ + "enabled", + "rules", + ] + 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 provisionOrganizationCampusGatewayClusters( self, organizationId: str, @@ -155,3 +184,28 @@ def provisionOrganizationCampusGatewayClusters( "body": payload, } return action + + def batchOrganizationCampusGatewayClustersTunnelingUpdate(self, organizationId: str, items: list, **kwargs): + """ + **Update MCG cluster-network tunnel settings for multiple networks** + https://developer.cisco.com/meraki/api-v1/#!batch-organization-campus-gateway-clusters-tunneling-update + + - organizationId (string): Organization ID + - items (array): MCG cluster-network tunnel settings + """ + + kwargs = locals() + + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/campusGateway/clusters/tunneling/batchUpdate" + + body_params = [ + "items", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "batch_update", + "body": payload, + } + return action diff --git a/meraki/api/batch/devices.py b/meraki/api/batch/devices.py index 027be86..b20158e 100644 --- a/meraki/api/batch/devices.py +++ b/meraki/api/batch/devices.py @@ -194,6 +194,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): - destination (object): The destination IP or subnet to lookup - nextHop (object): The next hop to lookup - vpn (object): VPN related search criteria + - vrf (object): Virtual routing and forwarding (VRF) search criteria - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret """ @@ -227,6 +228,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): "destination", "nextHop", "vpn", + "vrf", "callback", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/api/batch/networks.py b/meraki/api/batch/networks.py index adfb062..eef3867 100644 --- a/meraki/api/batch/networks.py +++ b/meraki/api/batch/networks.py @@ -1032,7 +1032,7 @@ def createNetworkWebhooksPayloadTemplate(self, networkId: str, name: str, **kwar def deleteNetworkWebhooksPayloadTemplate(self, networkId: str, payloadTemplateId: str): """ - **Destroy a webhook payload template for a network. Does not work for included templates ('wpt_00001', 'wpt_00002', 'wpt_00003', 'wpt_00004', 'wpt_00005', 'wpt_00006', 'wpt_00007' or 'wpt_00008')** + **Destroy a webhook payload template for a network. Does not work for included templates ('wpt_00001', 'wpt_00002', 'wpt_00003', 'wpt_00004', 'wpt_00005', 'wpt_00006', 'wpt_00007', 'wpt_00008' or 'wpt_00009')** https://developer.cisco.com/meraki/api-v1/#!delete-network-webhooks-payload-template - networkId (string): Network ID diff --git a/meraki/api/batch/organizations.py b/meraki/api/batch/organizations.py index f6c1d1d..ead1da9 100644 --- a/meraki/api/batch/organizations.py +++ b/meraki/api/batch/organizations.py @@ -2217,31 +2217,6 @@ def deleteOrganizationSamlIdp(self, organizationId: str, idpId: str): } return action - def batchOrganizationSaseConnectorsDelete(self, organizationId: str, **kwargs): - """ - **Delete SSE Connectors by ID** - https://developer.cisco.com/meraki/api-v1/#!batch-organization-sase-connectors-delete - - - organizationId (string): Organization ID - - items (array): List of connectors to delete (maximum 20 items) - """ - - kwargs.update(locals()) - - organizationId = urllib.parse.quote(str(organizationId), safe="") - resource = f"/organizations/{organizationId}/sase/connectors/batchDelete" - - body_params = [ - "items", - ] - payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} - action = { - "resource": resource, - "operation": "teardown", - "body": payload, - } - return action - def createOrganizationSaseIntegration(self, organizationId: str, api: dict, **kwargs): """ **Create a new Secure Access integration** @@ -2286,56 +2261,6 @@ def deleteOrganizationSaseIntegration(self, organizationId: str, integrationId: } return action - def attachOrganizationSaseSites(self, organizationId: str, items: list, **kwargs): - """ - **Attach sites in this organization to Secure Access. For an organization, a maximum of 2500 sites can be attached if they are in spoke mode or a maximum of 10 sites can be attached in hub mode.** - https://developer.cisco.com/meraki/api-v1/#!attach-organization-sase-sites - - - organizationId (string): Organization ID - - items (array): List of Meraki SD-WAN sites with the associated regions to be attached. - """ - - kwargs = locals() - - organizationId = urllib.parse.quote(str(organizationId), safe="") - resource = f"/organizations/{organizationId}/sase/sites/attach" - - body_params = [ - "items", - ] - 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 detachOrganizationSaseSites(self, organizationId: str, **kwargs): - """ - **Detach sites in this organization from Secure Access. This will remove the sites from Secure Access.** - https://developer.cisco.com/meraki/api-v1/#!detach-organization-sase-sites - - - organizationId (string): Organization ID - - items (array): List of Secure Access sites to be detached. - """ - - kwargs.update(locals()) - - organizationId = urllib.parse.quote(str(organizationId), safe="") - resource = f"/organizations/{organizationId}/sase/sites/detach" - - body_params = [ - "items", - ] - payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} - action = { - "resource": resource, - "operation": "detach", - "body": payload, - } - return action - def updateOrganizationSaseSite(self, organizationId: str, siteId: str, **kwargs): """ **Update the configuration for a site. Currently, only supports updating default route enablement.** diff --git a/meraki/api/batch/switch.py b/meraki/api/batch/switch.py index b0691bb..8e276c9 100644 --- a/meraki/api/batch/switch.py +++ b/meraki/api/batch/switch.py @@ -43,6 +43,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): - tags (array): The list of tags of the switch port. - enabled (boolean): The status of the switch port. - poeEnabled (boolean): The PoE status of the switch port. + - perpetualPoe (object): Perpetual PoE settings for the switch port. + - fastPoe (object): Fast PoE settings for the switch port. - type (string): The type of the switch port ('access', 'trunk', 'stack', 'routed', 'svl' or 'dad'). - vlan (integer): The VLAN of the switch port. For a trunk port, this is the native VLAN. A null value will clear the value set for trunk ports. - voiceVlan (integer): The voice VLAN of the switch port. Only applicable to access ports. @@ -99,6 +101,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): "tags", "enabled", "poeEnabled", + "perpetualPoe", + "fastPoe", "type", "vlan", "voiceVlan", @@ -140,9 +144,9 @@ def createDeviceSwitchRoutingInterface(self, serial: str, name: str, **kwargs): - serial (string): Serial - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -200,7 +204,7 @@ def updateDeviceSwitchRoutingInterface(self, serial: str, interfaceId: str, **kw - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -898,6 +902,36 @@ def updateNetworkSwitchMtu(self, networkId: str, **kwargs): } return action + def createNetworkSwitchPortSchedule(self, networkId: str, name: str, **kwargs): + """ + **Add a switch port schedule** + https://developer.cisco.com/meraki/api-v1/#!create-network-switch-port-schedule + + - networkId (string): Network ID + - name (string): The name for your port schedule. Required + - portSchedule (object): The schedule for switch port scheduling. Schedules are applied to days of the week. + When it's empty, default schedule with all days of a week are configured. + Any unspecified day in the schedule is added as a default schedule configuration of the day. + + """ + + kwargs.update(locals()) + + networkId = urllib.parse.quote(str(networkId), safe="") + resource = f"/networks/{networkId}/switch/portSchedules" + + body_params = [ + "name", + "portSchedule", + ] + 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 updateNetworkSwitchPortSchedule(self, networkId: str, portScheduleId: str, **kwargs): """ **Update a switch port schedule** @@ -1250,7 +1284,7 @@ def updateNetworkSwitchSettings(self, networkId: str, **kwargs): payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { "resource": resource, - "operation": "settings/actions/update", + "operation": "update", "body": payload, } return action @@ -1292,9 +1326,9 @@ def createNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - networkId (string): Network ID - switchStackId (string): Switch stack ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -1354,7 +1388,7 @@ def updateNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. diff --git a/meraki/api/batch/wireless.py b/meraki/api/batch/wireless.py index e517441..2aae844 100644 --- a/meraki/api/batch/wireless.py +++ b/meraki/api/batch/wireless.py @@ -89,6 +89,33 @@ def updateDeviceWirelessElectronicShelfLabel(self, serial: str, **kwargs): } return action + def updateDeviceWirelessRadioOverrides(self, serial: str, **kwargs): + """ + **Update 2.4 GHz, 5 GHz, and 6 GHz radio settings (channel, channel width, power, and enable/disable) that override RF profiles. Read-only fields returned by this endpoint, such as 'serial', 'network', and 'radios[].band', may be included when sending a previously returned object back to this PUT endpoint and will be ignored.** + https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-radio-overrides + + - serial (string): Serial + - rfProfile (object): This device's RF profile. If omitted, the existing RF profile assignment remains unchanged. + - radios (array): Radio overrides. If omitted, existing per-radio override settings remain unchanged. If provided, only the radios included in the array are updated; the array does not replace the device's full existing set of radio overrides. Read-only response fields for each radio, such as 'band', may be included in the request body and are ignored. + """ + + kwargs.update(locals()) + + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/wireless/radio/overrides" + + body_params = [ + "rfProfile", + "radios", + ] + 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 updateDeviceWirelessRadioSettings(self, serial: str, **kwargs): """ **Update 2.4 GHz and 5 GHz radio settings (channel, channel width, power) that override RF profiles. For 6 GHz support or radio enable/disable, use updateDeviceWirelessRadioOverrides instead.** @@ -529,6 +556,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -559,6 +587,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { @@ -588,6 +617,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -621,6 +651,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} action = { diff --git a/meraki/api/campusGateway.py b/meraki/api/campusGateway.py index aaf8028..c0f6f54 100644 --- a/meraki/api/campusGateway.py +++ b/meraki/api/campusGateway.py @@ -115,6 +115,41 @@ def deleteNetworkCampusGatewayCluster(self, networkId: str, clusterId: str): return self._session.delete(metadata, resource) + def updateNetworkCampusGatewaySsidMdns(self, networkId: str, number: str, **kwargs): + """ + **Update the mDNS gateway settings and rules for a SSID and cluster** + https://developer.cisco.com/meraki/api-v1/#!update-network-campus-gateway-ssid-mdns + + - networkId (string): Network ID + - number (string): Number + - enabled (boolean): If true, mDNS gateway is enabled for this SSID and cluster. + - rules (array): List of mDNS forwarding rules. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["campusGateway", "configure", "ssids", "mdns"], + "operation": "updateNetworkCampusGatewaySsidMdns", + } + networkId = urllib.parse.quote(str(networkId), safe="") + number = urllib.parse.quote(str(number), safe="") + resource = f"/networks/{networkId}/campusGateway/ssids/{number}/mdns" + + body_params = [ + "enabled", + "rules", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateNetworkCampusGatewaySsidMdns: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getOrganizationCampusGatewayClientsUsageByNetworkByCluster( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -603,6 +638,95 @@ def getOrganizationCampusGatewayClustersTunnelable( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def batchOrganizationCampusGatewayClustersTunnelingUpdate(self, organizationId: str, items: list, **kwargs): + """ + **Update MCG cluster-network tunnel settings for multiple networks** + https://developer.cisco.com/meraki/api-v1/#!batch-organization-campus-gateway-clusters-tunneling-update + + - organizationId (string): Organization ID + - items (array): MCG cluster-network tunnel settings + """ + + kwargs = locals() + + metadata = { + "tags": ["campusGateway", "configure", "clusters", "tunneling"], + "operation": "batchOrganizationCampusGatewayClustersTunnelingUpdate", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/campusGateway/clusters/tunneling/batchUpdate" + + body_params = [ + "items", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"batchOrganizationCampusGatewayClustersTunnelingUpdate: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + def getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork( + self, organizationId: str, total_pages=1, direction="next", **kwargs + ): + """ + **List all the MCG cluster-network tunnel settings** + https://developer.cisco.com/meraki/api-v1/#!get-organization-campus-gateway-clusters-tunneling-by-cluster-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 + - clusterIds (array): Optional parameter to filter MCG clusters. This filter uses multiple exact matches + - dataEncryptionEnabled (boolean): Optional parameter to filter cluster-network tunnel settings by data encryption configuration + - networkIds (array): Optional parameter to filter networks. This filter uses multiple exact matches + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 50. + - startingAfter (string): A token used by the server to indicate the start of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - endingBefore (string): A token used by the server to indicate the end of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["campusGateway", "configure", "clusters", "tunneling", "byCluster", "byNetwork"], + "operation": "getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/campusGateway/clusters/tunneling/byCluster/byNetwork" + + query_params = [ + "clusterIds", + "dataEncryptionEnabled", + "networkIds", + "perPage", + "startingAfter", + "endingBefore", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "clusterIds", + "networkIds", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationCampusGatewayClustersTunnelingByClusterByNetwork: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationCampusGatewayConnections(self, organizationId: str, total_pages=1, direction="next", **kwargs): """ **List the details of APs tunneling through the Campus Gateway clusters** diff --git a/meraki/api/devices.py b/meraki/api/devices.py index a89bc23..1a0d6e2 100644 --- a/meraki/api/devices.py +++ b/meraki/api/devices.py @@ -791,6 +791,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): - destination (object): The destination IP or subnet to lookup - nextHop (object): The next hop to lookup - vpn (object): VPN related search criteria + - vrf (object): Virtual routing and forwarding (VRF) search criteria - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret """ @@ -828,6 +829,7 @@ def createDeviceLiveToolsRoutingTableLookup(self, serial: str, **kwargs): "destination", "nextHop", "vpn", + "vrf", "callback", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/api/licensing.py b/meraki/api/licensing.py index 15d31df..205d771 100644 --- a/meraki/api/licensing.py +++ b/meraki/api/licensing.py @@ -12,10 +12,17 @@ def getAdministeredLicensingSubscriptionEntitlements(self, **kwargs): https://developer.cisco.com/meraki/api-v1/#!get-administered-licensing-subscription-entitlements - skus (array): Filter to entitlements with the specified SKUs + - subscriptionType (string): Filter entitlements by subscription type """ kwargs.update(locals()) + if "subscriptionType" in kwargs: + options = ["termed", "unified"] + assert kwargs["subscriptionType"] in options, ( + f'''"subscriptionType" cannot be "{kwargs["subscriptionType"]}", & must be set to one of: {options}''' + ) + metadata = { "tags": ["licensing", "configure", "subscription", "entitlements"], "operation": "getAdministeredLicensingSubscriptionEntitlements", @@ -24,6 +31,7 @@ def getAdministeredLicensingSubscriptionEntitlements(self, **kwargs): query_params = [ "skus", + "subscriptionType", ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} diff --git a/meraki/api/networks.py b/meraki/api/networks.py index 00fb032..e290dbf 100644 --- a/meraki/api/networks.py +++ b/meraki/api/networks.py @@ -1200,9 +1200,10 @@ def updateNetworkFirmwareUpgradesStagedEvents(self, networkId: str, stages: list - networkId (string): Network ID - stages (array): All firmware upgrade stages in the network with their start time. + - products (object): Contains firmware upgrade settings """ - kwargs = locals() + kwargs.update(locals()) metadata = { "tags": ["networks", "configure", "firmwareUpgrades", "staged", "events"], @@ -1212,6 +1213,7 @@ def updateNetworkFirmwareUpgradesStagedEvents(self, networkId: str, stages: list resource = f"/networks/{networkId}/firmwareUpgrades/staged/events" body_params = [ + "products", "stages", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/api/switch.py b/meraki/api/switch.py index 1f65cc6..71fbe24 100644 --- a/meraki/api/switch.py +++ b/meraki/api/switch.py @@ -150,6 +150,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): - tags (array): The list of tags of the switch port. - enabled (boolean): The status of the switch port. - poeEnabled (boolean): The PoE status of the switch port. + - perpetualPoe (object): Perpetual PoE settings for the switch port. + - fastPoe (object): Fast PoE settings for the switch port. - type (string): The type of the switch port ('access', 'trunk', 'stack', 'routed', 'svl' or 'dad'). - vlan (integer): The VLAN of the switch port. For a trunk port, this is the native VLAN. A null value will clear the value set for trunk ports. - voiceVlan (integer): The voice VLAN of the switch port. Only applicable to access ports. @@ -210,6 +212,8 @@ def updateDeviceSwitchPort(self, serial: str, portId: str, **kwargs): "tags", "enabled", "poeEnabled", + "perpetualPoe", + "fastPoe", "type", "vlan", "voiceVlan", @@ -295,9 +299,9 @@ def createDeviceSwitchRoutingInterface(self, serial: str, name: str, **kwargs): - serial (string): Serial - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -380,7 +384,7 @@ def updateDeviceSwitchRoutingInterface(self, serial: str, interfaceId: str, **kw - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -2423,9 +2427,9 @@ def createNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - networkId (string): Network ID - switchStackId (string): Switch stack ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'. CS 17.18 or higher is required for 'routed' mode. + - mode (string): L3 Interface mode, can be one of 'vlan', 'routed', 'loopback', or 'oob_management'. Default is 'vlan'. IOS XE firmware 17.18 or higher is required for 'routed' mode; IOS XE firmware 26.1.2 or higher is required for 'oob_management' mode. - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. @@ -2514,7 +2518,7 @@ def updateNetworkSwitchStackRoutingInterface(self, networkId: str, switchStackId - interfaceId (string): Interface ID - name (string): A friendly name or description for the interface or VLAN (max length 128 characters). - subnet (string): The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24). - - switchPortId (string): Switch Port ID when in Routed mode (CS 17.18 or higher required) + - switchPortId (string): Switch Port ID when in Routed mode (IOS XE firmware 17.18 or higher required) - interfaceIp (string): The IP address that will be used for Layer 3 routing on this VLAN or subnet. This cannot be the same as the device management IP. - mtu (integer): The interface MTU. Applies to native switch layer 3 interfaces, including VLAN and routed modes. - multicastRouting (string): Enable multicast support if, multicast routing between VLANs is required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'. Default is 'disabled'. diff --git a/meraki/api/wireless.py b/meraki/api/wireless.py index 349077a..050e2fa 100644 --- a/meraki/api/wireless.py +++ b/meraki/api/wireless.py @@ -248,6 +248,56 @@ def getDeviceWirelessLatencyStats(self, serial: str, **kwargs): return self._session.get(metadata, resource, params) + def getDeviceWirelessRadioOverrides(self, serial: str): + """ + **Return the radio overrides of a device** + https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-radio-overrides + + - serial (string): Serial + """ + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides"], + "operation": "getDeviceWirelessRadioOverrides", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/wireless/radio/overrides" + + return self._session.get(metadata, resource) + + def updateDeviceWirelessRadioOverrides(self, serial: str, **kwargs): + """ + **Update 2.4 GHz, 5 GHz, and 6 GHz radio settings (channel, channel width, power, and enable/disable) that override RF profiles** + https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-radio-overrides + + - serial (string): Serial + - rfProfile (object): This device's RF profile. If omitted, the existing RF profile assignment remains unchanged. + - radios (array): Radio overrides. If omitted, existing per-radio override settings remain unchanged. If provided, only the radios included in the array are updated; the array does not replace the device's full existing set of radio overrides. Read-only response fields for each radio, such as 'band', may be included in the request body and are ignored. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides"], + "operation": "updateDeviceWirelessRadioOverrides", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/wireless/radio/overrides" + + body_params = [ + "rfProfile", + "radios", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"updateDeviceWirelessRadioOverrides: ignoring unrecognized kwargs: {invalid}") + + return self._session.put(metadata, resource, payload) + def getDeviceWirelessRadioSettings(self, serial: str): """ **Return the manually configured radio settings overrides of a device, which take precedence over RF profiles.** @@ -1933,6 +1983,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -1967,6 +2018,7 @@ def createNetworkWirelessRfProfile(self, networkId: str, name: str, bandSelectio "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -1998,6 +2050,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa - transmission (object): Settings related to radio transmission. - perSsidSettings (object): Per-SSID radio settings by number. - flexRadios (object): Flex radio settings. + - dot11be (object): 802.11be settings """ kwargs.update(locals()) @@ -2035,6 +2088,7 @@ def updateNetworkWirelessRfProfile(self, networkId: str, rfProfileId: str, **kwa "transmission", "perSsidSettings", "flexRadios", + "dot11be", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -5183,6 +5237,58 @@ def recalculateOrganizationWirelessRadioAutoRfChannels(self, organizationId: str return self._session.post(metadata, resource, payload) + def getOrganizationWirelessRadioOverridesByDevice(self, organizationId: str, total_pages=1, direction="next", **kwargs): + """ + **Return a list of radio overrides** + https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-radio-overrides-by-device + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): The number of entries per page returned. Acceptable range is 3 - 100. Default is 100. + - startingAfter (string): A token used by the server to indicate the start of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - endingBefore (string): A token used by the server to indicate the end of the page. Often this is a timestamp or an ID but it is not limited to those. This parameter should not be defined by client applications. The link for the first, last, prev, or next page in the HTTP Link header should define it. + - networkIds (array): A list of network IDs. The returned radio overrides will be filtered to only include these networks. + - serials (array): A list of serial numbers. The returned radio overrides will be filtered to only include these serials. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["wireless", "configure", "radio", "overrides", "byDevice"], + "operation": "getOrganizationWirelessRadioOverridesByDevice", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/wireless/radio/overrides/byDevice" + + query_params = [ + "perPage", + "startingAfter", + "endingBefore", + "networkIds", + "serials", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + array_params = [ + "networkIds", + "serials", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + + if self._session._validate_kwargs: + all_params = query_params + array_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationWirelessRadioOverridesByDevice: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationWirelessRadioRrmByNetwork(self, organizationId: str, total_pages=1, direction="next", **kwargs): """ **List the AutoRF settings of an organization by network** diff --git a/pyproject.toml b/pyproject.toml index 8917b14..2a2cc70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "meraki" -version = "4.4.0" +version = "4.5.0" description = "Cisco Meraki Dashboard API library" authors = [ {name = "Cisco Meraki", email = "api-feedback@meraki.net"} diff --git a/uv.lock b/uv.lock index a5681f9..467d706 100644 --- a/uv.lock +++ b/uv.lock @@ -363,7 +363,7 @@ wheels = [ [[package]] name = "meraki" -version = "4.4.0" +version = "4.5.0" source = { editable = "." } dependencies = [ { name = "httpx" },