"""ActionBatchSwitch API endpoints.

This file is automatically @generated from the Meraki API specification.
Do not edit this file manually.

"""

import urllib.parse
from typing import Any

from meraki_client.schemas import (
    CreateDeviceSwitchRoutingInterfaceIpv6,
    CreateDeviceSwitchRoutingInterfaceOspfSettings,
    CreateDeviceSwitchRoutingInterfaceVrf,
    CreateDeviceSwitchRoutingStaticRouteVrf,
    CreateNetworkSwitchAccessPolicyDot1x,
    CreateNetworkSwitchAccessPolicyRadius,
    CreateNetworkSwitchAccessPolicyRadiusAccountingServersItem,
    CreateNetworkSwitchAccessPolicyRadiusServersItem,
    CreateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServerIpv4,
    CreateNetworkSwitchLinkAggregationSwitchPortsItem,
    CreateNetworkSwitchLinkAggregationSwitchProfilePortsItem,
    CreateNetworkSwitchRoutingMulticastRendezvousPointVrf,
    CreateNetworkSwitchStackRoutingInterfaceIpv6,
    CreateNetworkSwitchStackRoutingInterfaceOspfSettings,
    CreateNetworkSwitchStackRoutingInterfaceVrf,
    CreateNetworkSwitchStackRoutingStaticRouteVrf,
    CreateOrganizationActionBatchActionsItem,
    UpdateDeviceSwitchPortDot3az,
    UpdateDeviceSwitchPortHighSpeed,
    UpdateDeviceSwitchPortProfile,
    UpdateDeviceSwitchRoutingInterfaceDhcpDhcpOptionsItem,
    UpdateDeviceSwitchRoutingInterfaceDhcpFixedIpAssignmentsItem,
    UpdateDeviceSwitchRoutingInterfaceDhcpReservedIpRangesItem,
    UpdateDeviceSwitchRoutingInterfaceIpv6,
    UpdateDeviceSwitchRoutingInterfaceOspfSettings,
    UpdateDeviceSwitchRoutingInterfaceVrf,
    UpdateDeviceSwitchRoutingStaticRouteVrf,
    UpdateNetworkSwitchAccessPolicyDot1x,
    UpdateNetworkSwitchAccessPolicyRadius,
    UpdateNetworkSwitchAccessPolicyRadiusAccountingServersItem,
    UpdateNetworkSwitchAccessPolicyRadiusServersItem,
    UpdateNetworkSwitchAlternateManagementInterfaceSwitchesItem,
    UpdateNetworkSwitchDhcpServerPolicyAlerts,
    UpdateNetworkSwitchDhcpServerPolicyArpInspection,
    UpdateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServerIpv4,
    UpdateNetworkSwitchDscpToCosMappingsMappingsItem,
    UpdateNetworkSwitchLinkAggregationSwitchPortsItem,
    UpdateNetworkSwitchLinkAggregationSwitchProfilePortsItem,
    UpdateNetworkSwitchMtuOverridesItem,
    UpdateNetworkSwitchPortSchedulePortSchedule,
    UpdateNetworkSwitchRoutingMulticastDefaultSettings,
    UpdateNetworkSwitchRoutingMulticastOverridesItem,
    UpdateNetworkSwitchRoutingMulticastRendezvousPointVrf,
    UpdateNetworkSwitchRoutingOspfAreasItem,
    UpdateNetworkSwitchRoutingOspfMd5AuthenticationKey,
    UpdateNetworkSwitchRoutingOspfV3,
    UpdateNetworkSwitchSettingsMacBlocklist,
    UpdateNetworkSwitchSettingsPowerExceptionsItem,
    UpdateNetworkSwitchSettingsUplinkClientSampling,
    UpdateNetworkSwitchSettingsUplinkSelection,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpOptionsItem,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpFixedIpAssignmentsItem,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpReservedIpRangesItem,
    UpdateNetworkSwitchStackRoutingInterfaceIpv6,
    UpdateNetworkSwitchStackRoutingInterfaceOspfSettings,
    UpdateNetworkSwitchStackRoutingInterfaceVrf,
    UpdateNetworkSwitchStackRoutingStaticRouteVrf,
    UpdateNetworkSwitchStpStpBridgePriorityItem,
    UpdateOrganizationConfigTemplateSwitchProfilePortDot3az,
    UpdateOrganizationConfigTemplateSwitchProfilePortHighSpeed,
    UpdateOrganizationConfigTemplateSwitchProfilePortProfile,
)
from meraki_client.types import (
    CreateDeviceSwitchRoutingInterfaceMode,
    CreateDeviceSwitchRoutingInterfaceMulticastRouting,
    CreateNetworkSwitchAccessPolicyAccessPolicyType,
    CreateNetworkSwitchAccessPolicyHostMode,
    CreateNetworkSwitchQosRuleProtocol,
    CreateNetworkSwitchStackRoutingInterfaceMode,
    CreateNetworkSwitchStackRoutingInterfaceMulticastRouting,
    UpdateDeviceSwitchPortAccessPolicyType,
    UpdateDeviceSwitchPortStpGuard,
    UpdateDeviceSwitchPortType,
    UpdateDeviceSwitchPortUdld,
    UpdateDeviceSwitchRoutingInterfaceDhcpDhcpLeaseTime,
    UpdateDeviceSwitchRoutingInterfaceDhcpDhcpMode,
    UpdateDeviceSwitchRoutingInterfaceDhcpDnsNameserversOption,
    UpdateDeviceSwitchRoutingInterfaceMulticastRouting,
    UpdateNetworkSwitchAccessPolicyAccessPolicyType,
    UpdateNetworkSwitchAccessPolicyHostMode,
    UpdateNetworkSwitchAlternateManagementInterfaceProtocols,
    UpdateNetworkSwitchDhcpServerPolicyDefaultPolicy,
    UpdateNetworkSwitchQosRuleProtocol,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpLeaseTime,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpMode,
    UpdateNetworkSwitchStackRoutingInterfaceDhcpDnsNameserversOption,
    UpdateNetworkSwitchStackRoutingInterfaceMulticastRouting,
    UpdateOrganizationConfigTemplateSwitchProfilePortAccessPolicyType,
    UpdateOrganizationConfigTemplateSwitchProfilePortStpGuard,
    UpdateOrganizationConfigTemplateSwitchProfilePortType,
    UpdateOrganizationConfigTemplateSwitchProfilePortUdld,
)


class ActionBatchSwitch:
    """ActionBatchSwitch class."""

    def __init__(self) -> None:
        pass

    def cycle_device_switch_ports(
        self, *, serial: str, ports: list[str]
    ) -> CreateOrganizationActionBatchActionsItem:
        """Cycle a set of switch ports.

        [API documentation: cycleDeviceSwitchPorts](https://developer.cisco.com/meraki/api-v1/#!cycle-device-switch-ports)

        Args:
            serial: Serial.
            ports: List of switch ports.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/switch/ports/cycle"

        payload: dict[str, Any] = {}
        if ports is not None:
            payload["ports"] = ports

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="cycle",
            body=payload,
        )

    def update_device_switch_port(
        self,
        *,
        serial: str,
        port_id: str,
        name: str | None = None,
        tags: list[str] | None = None,
        enabled: bool | None = None,
        poe_enabled: bool | None = None,
        type_: UpdateDeviceSwitchPortType | None = None,
        vlan: int | None = None,
        voice_vlan: int | None = None,
        allowed_vlans: str | None = None,
        isolation_enabled: bool | None = None,
        rstp_enabled: bool | None = None,
        stp_guard: UpdateDeviceSwitchPortStpGuard | None = None,
        stp_port_fast_trunk: bool | None = None,
        link_negotiation: str | None = None,
        port_schedule_id: str | None = None,
        udld: UpdateDeviceSwitchPortUdld | None = None,
        access_policy_type: UpdateDeviceSwitchPortAccessPolicyType | None = None,
        access_policy_number: int | None = None,
        mac_allow_list: list[str] | None = None,
        mac_whitelist_limit: int | None = None,
        sticky_mac_allow_list: list[str] | None = None,
        sticky_mac_allow_list_limit: int | None = None,
        storm_control_enabled: bool | None = None,
        adaptive_policy_group_id: str | None = None,
        peer_sgt_capable: bool | None = None,
        flexible_stacking_enabled: bool | None = None,
        dai_trusted: bool | None = None,
        profile: UpdateDeviceSwitchPortProfile | None = None,
        dot3az: UpdateDeviceSwitchPortDot3az | None = None,
        high_speed: UpdateDeviceSwitchPortHighSpeed | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a switch port.

        [API documentation: updateDeviceSwitchPort](https://developer.cisco.com/meraki/api-v1/#!update-device-switch-port)

        Args:
            serial: Serial.
            port_id: Port ID.
            name: The name of the switch port.
            tags: The list of tags of the switch port.
            enabled: The status of the switch port.
            poe_enabled: The PoE status of the switch port.
            type_: The type of the switch port ('access', 'trunk', 'stack', 'routed', 'svl' or
                'dad').
            vlan: 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.
            voice_vlan: The voice VLAN of the switch port. Only applicable to access ports.
            allowed_vlans: The VLANs allowed on the switch port. Only applicable to trunk ports.
            isolation_enabled: The isolation status of the switch port.
            rstp_enabled: The rapid spanning tree protocol status.
            stp_guard: The state of the STP guard ('disabled', 'root guard', 'bpdu guard' or 'loop
                guard').
            stp_port_fast_trunk: The state of STP PortFast Trunk on the switch port.
            link_negotiation: The link speed for the switch port.
            port_schedule_id: The ID of the port schedule. A value of null will clear the port
                schedule.
            udld: The action to take when Unidirectional Link is detected (Alert only, Enforce).
                Default configuration is Alert only.
            access_policy_type: The type of the access policy of the switch port. Only applicable to
                access ports. Can be one of 'Open', 'Custom access policy', 'MAC allow
                list' or 'Sticky MAC allow list'.
            access_policy_number: The number of a custom access policy to configure on the switch
                port. Only applicable when 'accessPolicyType' is 'Custom access policy'.
            mac_allow_list: Only devices with MAC addresses specified in this list will have access
                to this port. Up to 20 MAC addresses can be defined. Only applicable
                when 'accessPolicyType' is 'MAC allow list'.
            mac_whitelist_limit: The maximum number of MAC addresses for regular MAC allow list.
                Only applicable when 'accessPolicyType' is 'MAC allow list'. Note:
                Config only supported on verions greater than ms18 only for classic
                switches.
            sticky_mac_allow_list: The initial list of MAC addresses for sticky Mac allow list. Only
                applicable when 'accessPolicyType' is 'Sticky MAC allow list'.
            sticky_mac_allow_list_limit: The maximum number of MAC addresses for sticky MAC allow
                list. Only applicable when 'accessPolicyType' is 'Sticky MAC allow
                list'.
            storm_control_enabled: The storm control status of the switch port.
            adaptive_policy_group_id: The adaptive policy group ID that will be used to tag traffic
                through this switch port. This ID must pre-exist during the
                configuration, else needs to be created using adaptivePolicy/groups API.
                Cannot be applied to a port on a switch bound to profile.
            peer_sgt_capable: If true, Peer SGT is enabled for traffic through this switch port.
                Applicable to trunk port only, not access port. Cannot be applied to a
                port on a switch bound to profile.
            flexible_stacking_enabled: For supported switches (e.g. MS420/MS425), whether or not the
                port has flexible stacking enabled.
            dai_trusted: If true, ARP packets for this port will be considered trusted, and Dynamic
                ARP Inspection will allow the traffic.
            profile: Profile attributes.
            dot3az: dot3az settings for the port.
            high_speed: High speed port enablement settings for C9500-32QC.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        port_id = urllib.parse.quote(str(port_id), safe="")
        path = f"/devices/{serial}/switch/ports/{port_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if tags is not None:
            payload["tags"] = tags
        if enabled is not None:
            payload["enabled"] = enabled
        if poe_enabled is not None:
            payload["poeEnabled"] = poe_enabled
        if type_ is not None:
            payload["type"] = type_
        if vlan is not None:
            payload["vlan"] = vlan
        if voice_vlan is not None:
            payload["voiceVlan"] = voice_vlan
        if allowed_vlans is not None:
            payload["allowedVlans"] = allowed_vlans
        if isolation_enabled is not None:
            payload["isolationEnabled"] = isolation_enabled
        if rstp_enabled is not None:
            payload["rstpEnabled"] = rstp_enabled
        if stp_guard is not None:
            payload["stpGuard"] = stp_guard
        if stp_port_fast_trunk is not None:
            payload["stpPortFastTrunk"] = stp_port_fast_trunk
        if link_negotiation is not None:
            payload["linkNegotiation"] = link_negotiation
        if port_schedule_id is not None:
            payload["portScheduleId"] = port_schedule_id
        if udld is not None:
            payload["udld"] = udld
        if access_policy_type is not None:
            payload["accessPolicyType"] = access_policy_type
        if access_policy_number is not None:
            payload["accessPolicyNumber"] = access_policy_number
        if mac_allow_list is not None:
            payload["macAllowList"] = mac_allow_list
        if mac_whitelist_limit is not None:
            payload["macWhitelistLimit"] = mac_whitelist_limit
        if sticky_mac_allow_list is not None:
            payload["stickyMacAllowList"] = sticky_mac_allow_list
        if sticky_mac_allow_list_limit is not None:
            payload["stickyMacAllowListLimit"] = sticky_mac_allow_list_limit
        if storm_control_enabled is not None:
            payload["stormControlEnabled"] = storm_control_enabled
        if adaptive_policy_group_id is not None:
            payload["adaptivePolicyGroupId"] = adaptive_policy_group_id
        if peer_sgt_capable is not None:
            payload["peerSgtCapable"] = peer_sgt_capable
        if flexible_stacking_enabled is not None:
            payload["flexibleStackingEnabled"] = flexible_stacking_enabled
        if dai_trusted is not None:
            payload["daiTrusted"] = dai_trusted
        if profile is not None:
            payload["profile"] = profile.model_dump(by_alias=True, exclude_none=True)
        if dot3az is not None:
            payload["dot3az"] = dot3az.model_dump(by_alias=True, exclude_none=True)
        if high_speed is not None:
            payload["highSpeed"] = high_speed.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_device_switch_routing_interface(
        self,
        *,
        serial: str,
        name: str,
        mode: CreateDeviceSwitchRoutingInterfaceMode | None = None,
        subnet: str | None = None,
        switch_port_id: str | None = None,
        interface_ip: str | None = None,
        multicast_routing: CreateDeviceSwitchRoutingInterfaceMulticastRouting | None = None,
        vlan_id: int | None = None,
        default_gateway: str | None = None,
        ospf_settings: CreateDeviceSwitchRoutingInterfaceOspfSettings | None = None,
        ipv6: CreateDeviceSwitchRoutingInterfaceIpv6 | None = None,
        vrf: CreateDeviceSwitchRoutingInterfaceVrf | None = None,
        loopback: dict[str, Any] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a layer 3 interface for a switch.

        [API documentation: createDeviceSwitchRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!create-device-switch-routing-interface)

        Args:
            serial: Serial.
            name: A friendly name or description for the interface or VLAN (max length 128
                characters).
            mode: L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'.
                CS 17.18 or higher is required for 'routed' mode.
            subnet: The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24).
            switch_port_id: Switch Port ID when in Routed mode (CS 17.18 or higher required).
            interface_ip: 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.
            multicast_routing: Enable multicast support if, multicast routing between VLANs is
                required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'.
                Default is 'disabled'.
            vlan_id: The VLAN this L3 interface is on. VLAN must be between 1 and 4094.
            default_gateway: The next hop for any traffic that isn't going to a directly connected
                subnet or over a static route. This IP address must exist in a subnet
                with a L3 interface. Required if this is the first IPv4 interface.
            ospf_settings: The OSPF routing settings of the interface.
            ipv6: The IPv6 settings of the interface.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.
            loopback: The loopback settings of the interface.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/switch/routing/interfaces"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if mode is not None:
            payload["mode"] = mode
        if subnet is not None:
            payload["subnet"] = subnet
        if switch_port_id is not None:
            payload["switchPortId"] = switch_port_id
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_routing is not None:
            payload["multicastRouting"] = multicast_routing
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if default_gateway is not None:
            payload["defaultGateway"] = default_gateway
        if ospf_settings is not None:
            payload["ospfSettings"] = ospf_settings.model_dump(by_alias=True, exclude_none=True)
        if ipv6 is not None:
            payload["ipv6"] = ipv6.model_dump(by_alias=True, exclude_none=True)
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)
        if loopback is not None:
            payload["loopback"] = loopback

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_device_switch_routing_interface(
        self,
        *,
        serial: str,
        interface_id: str,
        name: str | None = None,
        subnet: str | None = None,
        switch_port_id: str | None = None,
        interface_ip: str | None = None,
        multicast_routing: UpdateDeviceSwitchRoutingInterfaceMulticastRouting | None = None,
        vlan_id: int | None = None,
        default_gateway: str | None = None,
        ospf_settings: UpdateDeviceSwitchRoutingInterfaceOspfSettings | None = None,
        ipv6: UpdateDeviceSwitchRoutingInterfaceIpv6 | None = None,
        vrf: UpdateDeviceSwitchRoutingInterfaceVrf | None = None,
        loopback: dict[str, Any] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 interface for a switch.

        [API documentation: updateDeviceSwitchRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!update-device-switch-routing-interface)

        Args:
            serial: Serial.
            interface_id: Interface ID.
            name: A friendly name or description for the interface or VLAN (max length 128
                characters).
            subnet: The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24).
            switch_port_id: Switch Port ID when in Routed mode (CS 17.18 or higher required).
            interface_ip: 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.
            multicast_routing: Enable multicast support if, multicast routing between VLANs is
                required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'.
                Default is 'disabled'.
            vlan_id: The VLAN this L3 interface is on. VLAN must be between 1 and 4094.
            default_gateway: The next hop for any traffic that isn't going to a directly connected
                subnet or over a static route. This IP address must exist in a subnet
                with a L3 interface. Required if this is the first IPv4 interface.
            ospf_settings: The OSPF routing settings of the interface.
            ipv6: The IPv6 settings of the interface.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.
            loopback: The loopback settings of the interface.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/devices/{serial}/switch/routing/interfaces/{interface_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if switch_port_id is not None:
            payload["switchPortId"] = switch_port_id
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_routing is not None:
            payload["multicastRouting"] = multicast_routing
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if default_gateway is not None:
            payload["defaultGateway"] = default_gateway
        if ospf_settings is not None:
            payload["ospfSettings"] = ospf_settings.model_dump(by_alias=True, exclude_none=True)
        if ipv6 is not None:
            payload["ipv6"] = ipv6.model_dump(by_alias=True, exclude_none=True)
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)
        if loopback is not None:
            payload["loopback"] = loopback

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_device_switch_routing_interface(
        self, *, serial: str, interface_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a layer 3 interface from the switch.

        [API documentation: deleteDeviceSwitchRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!delete-device-switch-routing-interface)

        Args:
            serial: Serial.
            interface_id: Interface ID.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/devices/{serial}/switch/routing/interfaces/{interface_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_device_switch_routing_interface_dhcp(
        self,
        *,
        serial: str,
        interface_id: str,
        dhcp_mode: UpdateDeviceSwitchRoutingInterfaceDhcpDhcpMode | None = None,
        dhcp_relay_server_ips: list[str] | None = None,
        dhcp_lease_time: UpdateDeviceSwitchRoutingInterfaceDhcpDhcpLeaseTime | None = None,
        dns_nameservers_option: UpdateDeviceSwitchRoutingInterfaceDhcpDnsNameserversOption
        | None = None,
        dns_custom_nameservers: list[str] | None = None,
        boot_options_enabled: bool | None = None,
        boot_next_server: str | None = None,
        boot_file_name: str | None = None,
        dhcp_options: list[UpdateDeviceSwitchRoutingInterfaceDhcpDhcpOptionsItem] | None = None,
        reserved_ip_ranges: list[UpdateDeviceSwitchRoutingInterfaceDhcpReservedIpRangesItem]
        | None = None,
        fixed_ip_assignments: list[UpdateDeviceSwitchRoutingInterfaceDhcpFixedIpAssignmentsItem]
        | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 interface DHCP configuration for a switch.

        [API documentation: updateDeviceSwitchRoutingInterfaceDhcp](https://developer.cisco.com/meraki/api-v1/#!update-device-switch-routing-interface-dhcp)

        Args:
            serial: Serial.
            interface_id: Interface ID.
            dhcp_mode: The DHCP mode options for the switch interface ('dhcpDisabled', 'dhcpRelay'
                or 'dhcpServer').
            dhcp_relay_server_ips: The DHCP relay server IPs to which DHCP packets would get relayed
                for the switch interface.
            dhcp_lease_time: The DHCP lease time config for the dhcp server running on switch
                interface ('30 minutes', '1 hour', '4 hours', '12 hours', '1 day' or '1
                week').
            dns_nameservers_option: The DHCP name server option for the dhcp server running on the
                switch interface ('googlePublicDns', 'openDns' or 'custom').
            dns_custom_nameservers: The DHCP name server IPs when DHCP name server option is
                'custom'.
            boot_options_enabled: Enable DHCP boot options to provide PXE boot options configs for
                the dhcp server running on the switch interface.
            boot_next_server: The PXE boot server IP for the DHCP server running on the switch
                interface.
            boot_file_name: The PXE boot server filename for the DHCP server running on the switch
                interface.
            dhcp_options: Array of DHCP options consisting of code, type and value for the DHCP
                server running on the switch interface.
            reserved_ip_ranges: Array of DHCP reserved IP assignments for the DHCP server running on
                the switch interface.
            fixed_ip_assignments: Array of DHCP fixed IP assignments for the DHCP server running on
                the switch interface.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/devices/{serial}/switch/routing/interfaces/{interface_id}/dhcp"

        payload: dict[str, Any] = {}
        if dhcp_mode is not None:
            payload["dhcpMode"] = dhcp_mode
        if dhcp_relay_server_ips is not None:
            payload["dhcpRelayServerIps"] = dhcp_relay_server_ips
        if dhcp_lease_time is not None:
            payload["dhcpLeaseTime"] = dhcp_lease_time
        if dns_nameservers_option is not None:
            payload["dnsNameserversOption"] = dns_nameservers_option
        if dns_custom_nameservers is not None:
            payload["dnsCustomNameservers"] = dns_custom_nameservers
        if boot_options_enabled is not None:
            payload["bootOptionsEnabled"] = boot_options_enabled
        if boot_next_server is not None:
            payload["bootNextServer"] = boot_next_server
        if boot_file_name is not None:
            payload["bootFileName"] = boot_file_name
        if dhcp_options is not None:
            payload["dhcpOptions"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in dhcp_options
            ]
        if reserved_ip_ranges is not None:
            payload["reservedIpRanges"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in reserved_ip_ranges
            ]
        if fixed_ip_assignments is not None:
            payload["fixedIpAssignments"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in fixed_ip_assignments
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_device_switch_routing_static_route(
        self,
        *,
        serial: str,
        subnet: str,
        next_hop_ip: str,
        name: str | None = None,
        advertise_via_ospf_enabled: bool | None = None,
        prefer_over_ospf_routes_enabled: bool | None = None,
        vrf: CreateDeviceSwitchRoutingStaticRouteVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a layer 3 static route for a switch.

        [API documentation: createDeviceSwitchRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!create-device-switch-routing-static-route)

        Args:
            serial: Serial.
            name: Name or description for layer 3 static route.
            subnet: The subnet which is routed via this static route and should be specified in CIDR
                notation (ex. 1.2.3.0/24).
            next_hop_ip: IP address of the next hop device to which the device sends its traffic for
                the subnet.
            advertise_via_ospf_enabled: Option to advertise static route via OSPF.
            prefer_over_ospf_routes_enabled: Option to prefer static route over OSPF routes.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/switch/routing/staticRoutes"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if next_hop_ip is not None:
            payload["nextHopIp"] = next_hop_ip
        if advertise_via_ospf_enabled is not None:
            payload["advertiseViaOspfEnabled"] = advertise_via_ospf_enabled
        if prefer_over_ospf_routes_enabled is not None:
            payload["preferOverOspfRoutesEnabled"] = prefer_over_ospf_routes_enabled
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_device_switch_routing_static_route(
        self,
        *,
        serial: str,
        static_route_id: str,
        name: str | None = None,
        subnet: str | None = None,
        next_hop_ip: str | None = None,
        management_next_hop: str | None = None,
        advertise_via_ospf_enabled: bool | None = None,
        prefer_over_ospf_routes_enabled: bool | None = None,
        vrf: UpdateDeviceSwitchRoutingStaticRouteVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 static route for a switch.

        [API documentation: updateDeviceSwitchRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!update-device-switch-routing-static-route)

        Args:
            serial: Serial.
            static_route_id: Static route ID.
            name: Name or description for layer 3 static route.
            subnet: The subnet which is routed via this static route and should be specified in CIDR
                notation (ex. 1.2.3.0/24).
            next_hop_ip: IP address of the next hop device to which the device sends its traffic for
                the subnet.
            management_next_hop: Optional fallback IP address for management traffic.
            advertise_via_ospf_enabled: Option to advertise static route via OSPF.
            prefer_over_ospf_routes_enabled: Option to prefer static route over OSPF routes.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        static_route_id = urllib.parse.quote(str(static_route_id), safe="")
        path = f"/devices/{serial}/switch/routing/staticRoutes/{static_route_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if next_hop_ip is not None:
            payload["nextHopIp"] = next_hop_ip
        if management_next_hop is not None:
            payload["managementNextHop"] = management_next_hop
        if advertise_via_ospf_enabled is not None:
            payload["advertiseViaOspfEnabled"] = advertise_via_ospf_enabled
        if prefer_over_ospf_routes_enabled is not None:
            payload["preferOverOspfRoutesEnabled"] = prefer_over_ospf_routes_enabled
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_device_switch_routing_static_route(
        self, *, serial: str, static_route_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a layer 3 static route for a switch.

        [API documentation: deleteDeviceSwitchRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!delete-device-switch-routing-static-route)

        Args:
            serial: Serial.
            static_route_id: Static route ID.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        static_route_id = urllib.parse.quote(str(static_route_id), safe="")
        path = f"/devices/{serial}/switch/routing/staticRoutes/{static_route_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_device_switch_warm_spare(
        self, *, serial: str, enabled: bool, spare_serial: str | None = None
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update warm spare configuration for a switch.

        [API documentation: updateDeviceSwitchWarmSpare](https://developer.cisco.com/meraki/api-v1/#!update-device-switch-warm-spare)

        Args:
            serial: Serial.
            enabled: Enable or disable warm spare for a switch.
            spare_serial: Serial number of the warm spare switch.

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/switch/warmSpare"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if spare_serial is not None:
            payload["spareSerial"] = spare_serial

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_access_policy(
        self,
        *,
        network_id: str,
        name: str,
        radius_servers: list[CreateNetworkSwitchAccessPolicyRadiusServersItem],
        radius_accounting_enabled: bool,
        radius: CreateNetworkSwitchAccessPolicyRadius | None = None,
        guest_port_bouncing: bool | None = None,
        radius_testing_enabled: bool | None = None,
        radius_coa_support_enabled: bool | None = None,
        radius_accounting_servers: list[CreateNetworkSwitchAccessPolicyRadiusAccountingServersItem]
        | None = None,
        radius_group_attribute: str | None = None,
        host_mode: CreateNetworkSwitchAccessPolicyHostMode | None = None,
        access_policy_type: CreateNetworkSwitchAccessPolicyAccessPolicyType | None = None,
        increase_access_speed: bool | None = None,
        guest_vlan_id: int | None = None,
        dot1x: CreateNetworkSwitchAccessPolicyDot1x | None = None,
        voice_vlan_clients: bool | None = None,
        url_redirect_walled_garden_enabled: bool | None = None,
        url_redirect_walled_garden_ranges: list[str] | None = None,
        guest_group_policy_id: str | None = None,
        guest_sgt_id: int | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create an access policy for a switch network.

        [API documentation: createNetworkSwitchAccessPolicy](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-access-policy)

        Args:
            network_id: Network ID.
            name: Name of the access policy(max length 255).
            radius_servers: List of RADIUS servers to require connecting devices to authenticate
                against before granting network access.
            radius: Object for RADIUS Settings.
            guest_port_bouncing: If enabled, Meraki devices will periodically send access-request
                messages to these RADIUS servers.
            radius_testing_enabled: If enabled, Meraki devices will periodically send access-request
                messages to these RADIUS servers.
            radius_coa_support_enabled: Change of authentication for RADIUS re-authentication and
                disconnection.
            radius_accounting_enabled: Enable to send start, interim-update and stop messages to a
                configured RADIUS accounting server for tracking connected clients.
            radius_accounting_servers: List of RADIUS accounting servers to require connecting
                devices to authenticate against before granting network access.
            radius_group_attribute: Acceptable values are `""` for None, or `"11"` for Group
                Policies ACL.
            host_mode: Choose the Host Mode for the access policy.
            access_policy_type: Access Type of the policy. Automatically 'Hybrid authentication'
                when hostMode is 'Multi-Domain'.
            increase_access_speed: Enabling this option will make switches execute 802.1X and MAC-
                bypass authentication simultaneously so that clients authenticate
                faster. Only required when accessPolicyType is 'Hybrid Authentication.
            guest_vlan_id: ID for the guest VLAN allow unauthorized devices access to limited
                network resources.
            dot1x: 802.1x Settings.
            voice_vlan_clients: CDP/LLDP capable voice clients will be able to use this VLAN.
                Automatically true when hostMode is 'Multi-Domain'.
            url_redirect_walled_garden_enabled: Enable to restrict access for clients to a specific
                set of IP addresses or hostnames prior to authentication.
            url_redirect_walled_garden_ranges: IP address ranges, in CIDR notation, to restrict
                access for clients to a specific set of IP addresses or hostnames prior
                to authentication.
            guest_group_policy_id: Group policy Number for guest group policy.
            guest_sgt_id: Security Group Tag ID for guest group policy.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/accessPolicies"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if radius_servers is not None:
            payload["radiusServers"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in radius_servers
            ]
        if radius is not None:
            payload["radius"] = radius.model_dump(by_alias=True, exclude_none=True)
        if guest_port_bouncing is not None:
            payload["guestPortBouncing"] = guest_port_bouncing
        if radius_testing_enabled is not None:
            payload["radiusTestingEnabled"] = radius_testing_enabled
        if radius_coa_support_enabled is not None:
            payload["radiusCoaSupportEnabled"] = radius_coa_support_enabled
        if radius_accounting_enabled is not None:
            payload["radiusAccountingEnabled"] = radius_accounting_enabled
        if radius_accounting_servers is not None:
            payload["radiusAccountingServers"] = [
                item.model_dump(by_alias=True, exclude_none=True)
                for item in radius_accounting_servers
            ]
        if radius_group_attribute is not None:
            payload["radiusGroupAttribute"] = radius_group_attribute
        if host_mode is not None:
            payload["hostMode"] = host_mode
        if access_policy_type is not None:
            payload["accessPolicyType"] = access_policy_type
        if increase_access_speed is not None:
            payload["increaseAccessSpeed"] = increase_access_speed
        if guest_vlan_id is not None:
            payload["guestVlanId"] = guest_vlan_id
        if dot1x is not None:
            payload["dot1x"] = dot1x.model_dump(by_alias=True, exclude_none=True)
        if voice_vlan_clients is not None:
            payload["voiceVlanClients"] = voice_vlan_clients
        if url_redirect_walled_garden_enabled is not None:
            payload["urlRedirectWalledGardenEnabled"] = url_redirect_walled_garden_enabled
        if url_redirect_walled_garden_ranges is not None:
            payload["urlRedirectWalledGardenRanges"] = url_redirect_walled_garden_ranges
        if guest_group_policy_id is not None:
            payload["guestGroupPolicyId"] = guest_group_policy_id
        if guest_sgt_id is not None:
            payload["guestSgtId"] = guest_sgt_id

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_access_policy(
        self,
        *,
        network_id: str,
        access_policy_number: str,
        name: str | None = None,
        radius_servers: list[UpdateNetworkSwitchAccessPolicyRadiusServersItem] | None = None,
        radius: UpdateNetworkSwitchAccessPolicyRadius | None = None,
        guest_port_bouncing: bool | None = None,
        radius_testing_enabled: bool | None = None,
        radius_coa_support_enabled: bool | None = None,
        radius_accounting_enabled: bool | None = None,
        radius_accounting_servers: list[UpdateNetworkSwitchAccessPolicyRadiusAccountingServersItem]
        | None = None,
        radius_group_attribute: str | None = None,
        host_mode: UpdateNetworkSwitchAccessPolicyHostMode | None = None,
        access_policy_type: UpdateNetworkSwitchAccessPolicyAccessPolicyType | None = None,
        increase_access_speed: bool | None = None,
        guest_vlan_id: int | None = None,
        dot1x: UpdateNetworkSwitchAccessPolicyDot1x | None = None,
        voice_vlan_clients: bool | None = None,
        url_redirect_walled_garden_enabled: bool | None = None,
        url_redirect_walled_garden_ranges: list[str] | None = None,
        guest_group_policy_id: str | None = None,
        guest_sgt_id: int | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update an access policy for a switch network.

        [API documentation: updateNetworkSwitchAccessPolicy](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-access-policy)

        Args:
            network_id: Network ID.
            access_policy_number: Access policy number.
            name: Name of the access policy(max length 255).
            radius_servers: List of RADIUS servers to require connecting devices to authenticate
                against before granting network access.
            radius: Object for RADIUS Settings.
            guest_port_bouncing: If enabled, Meraki devices will periodically send access-request
                messages to these RADIUS servers.
            radius_testing_enabled: If enabled, Meraki devices will periodically send access-request
                messages to these RADIUS servers.
            radius_coa_support_enabled: Change of authentication for RADIUS re-authentication and
                disconnection.
            radius_accounting_enabled: Enable to send start, interim-update and stop messages to a
                configured RADIUS accounting server for tracking connected clients.
            radius_accounting_servers: List of RADIUS accounting servers to require connecting
                devices to authenticate against before granting network access.
            radius_group_attribute: Acceptable values are `""` for None, or `"11"` for Group
                Policies ACL.
            host_mode: Choose the Host Mode for the access policy.
            access_policy_type: Access Type of the policy. Automatically 'Hybrid authentication'
                when hostMode is 'Multi-Domain'.
            increase_access_speed: Enabling this option will make switches execute 802.1X and MAC-
                bypass authentication simultaneously so that clients authenticate
                faster. Only required when accessPolicyType is 'Hybrid Authentication.
            guest_vlan_id: ID for the guest VLAN allow unauthorized devices access to limited
                network resources.
            dot1x: 802.1x Settings.
            voice_vlan_clients: CDP/LLDP capable voice clients will be able to use this VLAN.
                Automatically true when hostMode is 'Multi-Domain'.
            url_redirect_walled_garden_enabled: Enable to restrict access for clients to a specific
                set of IP addresses or hostnames prior to authentication.
            url_redirect_walled_garden_ranges: IP address ranges, in CIDR notation, to restrict
                access for clients to a specific set of IP addresses or hostnames prior
                to authentication.
            guest_group_policy_id: Group policy Number for guest group policy.
            guest_sgt_id: Security Group Tag ID for guest group policy.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        access_policy_number = urllib.parse.quote(str(access_policy_number), safe="")
        path = f"/networks/{network_id}/switch/accessPolicies/{access_policy_number}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if radius_servers is not None:
            payload["radiusServers"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in radius_servers
            ]
        if radius is not None:
            payload["radius"] = radius.model_dump(by_alias=True, exclude_none=True)
        if guest_port_bouncing is not None:
            payload["guestPortBouncing"] = guest_port_bouncing
        if radius_testing_enabled is not None:
            payload["radiusTestingEnabled"] = radius_testing_enabled
        if radius_coa_support_enabled is not None:
            payload["radiusCoaSupportEnabled"] = radius_coa_support_enabled
        if radius_accounting_enabled is not None:
            payload["radiusAccountingEnabled"] = radius_accounting_enabled
        if radius_accounting_servers is not None:
            payload["radiusAccountingServers"] = [
                item.model_dump(by_alias=True, exclude_none=True)
                for item in radius_accounting_servers
            ]
        if radius_group_attribute is not None:
            payload["radiusGroupAttribute"] = radius_group_attribute
        if host_mode is not None:
            payload["hostMode"] = host_mode
        if access_policy_type is not None:
            payload["accessPolicyType"] = access_policy_type
        if increase_access_speed is not None:
            payload["increaseAccessSpeed"] = increase_access_speed
        if guest_vlan_id is not None:
            payload["guestVlanId"] = guest_vlan_id
        if dot1x is not None:
            payload["dot1x"] = dot1x.model_dump(by_alias=True, exclude_none=True)
        if voice_vlan_clients is not None:
            payload["voiceVlanClients"] = voice_vlan_clients
        if url_redirect_walled_garden_enabled is not None:
            payload["urlRedirectWalledGardenEnabled"] = url_redirect_walled_garden_enabled
        if url_redirect_walled_garden_ranges is not None:
            payload["urlRedirectWalledGardenRanges"] = url_redirect_walled_garden_ranges
        if guest_group_policy_id is not None:
            payload["guestGroupPolicyId"] = guest_group_policy_id
        if guest_sgt_id is not None:
            payload["guestSgtId"] = guest_sgt_id

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_access_policy(
        self, *, network_id: str, access_policy_number: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete an access policy for a switch network.

        [API documentation: deleteNetworkSwitchAccessPolicy](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-access-policy)

        Args:
            network_id: Network ID.
            access_policy_number: Access policy number.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        access_policy_number = urllib.parse.quote(str(access_policy_number), safe="")
        path = f"/networks/{network_id}/switch/accessPolicies/{access_policy_number}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_alternate_management_interface(
        self,
        network_id: str,
        *,
        enabled: bool | None = None,
        vlan_id: int | None = None,
        protocols: UpdateNetworkSwitchAlternateManagementInterfaceProtocols | None = None,
        switches: list[UpdateNetworkSwitchAlternateManagementInterfaceSwitchesItem] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the switch alternate management interface for the network.

        [API documentation: updateNetworkSwitchAlternateManagementInterface](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-alternate-management-interface)

        Args:
            network_id: Network ID.
            enabled: Boolean value to enable or disable AMI configuration. If enabled, VLAN and
                protocols must be set.
            vlan_id: Alternate management VLAN, must be between 1 and 4094.
            protocols: Can be one or more of the following values: 'radius', 'snmp' or 'syslog'.
            switches: Array of switch serial number and IP assignment. If parameter is present, it
                cannot have empty body. Note: switches parameter is not applicable for
                template networks, in other words, do not put 'switches' in the body
                when updating template networks. Also, an empty 'switches' array will
                remove all previous assignments.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/alternateManagementInterface"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if protocols is not None:
            payload["protocols"] = protocols
        if switches is not None:
            payload["switches"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in switches
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def update_network_switch_dhcp_server_policy(
        self,
        network_id: str,
        *,
        alerts: UpdateNetworkSwitchDhcpServerPolicyAlerts | None = None,
        default_policy: UpdateNetworkSwitchDhcpServerPolicyDefaultPolicy | None = None,
        allowed_servers: list[str] | None = None,
        blocked_servers: list[str] | None = None,
        arp_inspection: UpdateNetworkSwitchDhcpServerPolicyArpInspection | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the DHCP server settings.

        [API documentation: updateNetworkSwitchDhcpServerPolicy](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-dhcp-server-policy)

        Args:
            network_id: Network ID.
            alerts: Alert settings for DHCP servers.
            default_policy: 'allow' or 'block' new DHCP servers. Default value is 'allow'.
            allowed_servers: List the MAC addresses of DHCP servers to permit on the network when
                defaultPolicy is set to block. An empty array will clear the entries.
            blocked_servers: List the MAC addresses of DHCP servers to block on the network when
                defaultPolicy is set to allow. An empty array will clear the entries.
            arp_inspection: Dynamic ARP Inspection settings.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/dhcpServerPolicy"

        payload: dict[str, Any] = {}
        if alerts is not None:
            payload["alerts"] = alerts.model_dump(by_alias=True, exclude_none=True)
        if default_policy is not None:
            payload["defaultPolicy"] = default_policy
        if allowed_servers is not None:
            payload["allowedServers"] = allowed_servers
        if blocked_servers is not None:
            payload["blockedServers"] = blocked_servers
        if arp_inspection is not None:
            payload["arpInspection"] = arp_inspection.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_dhcp_server_policy_arp_inspection_trusted_server(
        self,
        *,
        network_id: str,
        mac: str,
        vlan: int,
        ipv4: CreateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServerIpv4,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Add a server to be trusted by Dynamic ARP Inspection on this network.

        [API documentation: createNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-dhcp-server-policy-arp-inspection-trusted-server)

        Args:
            network_id: Network ID.
            mac: The mac address of the trusted server being added.
            vlan: The VLAN of the trusted server being added. It must be between 1 and 4094.
            ipv4: The IPv4 attributes of the trusted server being added.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/dhcpServerPolicy/arpInspection/trustedServers"

        payload: dict[str, Any] = {}
        if mac is not None:
            payload["mac"] = mac
        if vlan is not None:
            payload["vlan"] = vlan
        if ipv4 is not None:
            payload["ipv4"] = ipv4.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_dhcp_server_policy_arp_inspection_trusted_server(
        self,
        *,
        network_id: str,
        trusted_server_id: str,
        mac: str | None = None,
        vlan: int | None = None,
        ipv4: UpdateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServerIpv4 | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a server that is trusted by Dynamic ARP Inspection on this network.

        [API documentation: updateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-dhcp-server-policy-arp-inspection-trusted-server)

        Args:
            network_id: Network ID.
            trusted_server_id: Trusted server ID.
            mac: The updated mac address of the trusted server.
            vlan: The updated VLAN of the trusted server. It must be between 1 and 4094.
            ipv4: The updated IPv4 attributes of the trusted server.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        trusted_server_id = urllib.parse.quote(str(trusted_server_id), safe="")
        path = f"/networks/{network_id}/switch/dhcpServerPolicy/arpInspection/trustedServers/{trusted_server_id}"

        payload: dict[str, Any] = {}
        if mac is not None:
            payload["mac"] = mac
        if vlan is not None:
            payload["vlan"] = vlan
        if ipv4 is not None:
            payload["ipv4"] = ipv4.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_dhcp_server_policy_arp_inspection_trusted_server(
        self, *, network_id: str, trusted_server_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Remove a server from being trusted by Dynamic ARP Inspection on this network.

        [API documentation: deleteNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-dhcp-server-policy-arp-inspection-trusted-server)

        Args:
            network_id: Network ID.
            trusted_server_id: Trusted server ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        trusted_server_id = urllib.parse.quote(str(trusted_server_id), safe="")
        path = f"/networks/{network_id}/switch/dhcpServerPolicy/arpInspection/trustedServers/{trusted_server_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_dscp_to_cos_mappings(
        self, *, network_id: str, mappings: list[UpdateNetworkSwitchDscpToCosMappingsMappingsItem]
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the DSCP to CoS mappings.

        [API documentation: updateNetworkSwitchDscpToCosMappings](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-dscp-to-cos-mappings)

        Args:
            network_id: Network ID.
            mappings: An array of DSCP to CoS mappings. An empty array will reset the mappings to
                default.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/dscpToCosMappings"

        payload: dict[str, Any] = {}
        if mappings is not None:
            payload["mappings"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in mappings
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_link_aggregation(
        self,
        network_id: str,
        *,
        switch_ports: list[CreateNetworkSwitchLinkAggregationSwitchPortsItem] | None = None,
        switch_profile_ports: list[CreateNetworkSwitchLinkAggregationSwitchProfilePortsItem]
        | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a link aggregation group.

        [API documentation: createNetworkSwitchLinkAggregation](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-link-aggregation)

        Args:
            network_id: Network ID.
            switch_ports: Array of switch or stack ports for creating aggregation group. Minimum 2
                and maximum 8 ports are supported.
            switch_profile_ports: Array of switch profile ports for creating aggregation group.
                Minimum 2 and maximum 8 ports are supported.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/linkAggregations"

        payload: dict[str, Any] = {}
        if switch_ports is not None:
            payload["switchPorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in switch_ports
            ]
        if switch_profile_ports is not None:
            payload["switchProfilePorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in switch_profile_ports
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_link_aggregation(
        self,
        *,
        network_id: str,
        link_aggregation_id: str,
        switch_ports: list[UpdateNetworkSwitchLinkAggregationSwitchPortsItem] | None = None,
        switch_profile_ports: list[UpdateNetworkSwitchLinkAggregationSwitchProfilePortsItem]
        | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a link aggregation group.

        [API documentation: updateNetworkSwitchLinkAggregation](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-link-aggregation)

        Args:
            network_id: Network ID.
            link_aggregation_id: Link aggregation ID.
            switch_ports: Array of switch or stack ports for updating aggregation group. Minimum 2
                and maximum 8 ports are supported.
            switch_profile_ports: Array of switch profile ports for updating aggregation group.
                Minimum 2 and maximum 8 ports are supported.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        link_aggregation_id = urllib.parse.quote(str(link_aggregation_id), safe="")
        path = f"/networks/{network_id}/switch/linkAggregations/{link_aggregation_id}"

        payload: dict[str, Any] = {}
        if switch_ports is not None:
            payload["switchPorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in switch_ports
            ]
        if switch_profile_ports is not None:
            payload["switchProfilePorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in switch_profile_ports
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_link_aggregation(
        self, *, network_id: str, link_aggregation_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Split a link aggregation group into separate ports.

        [API documentation: deleteNetworkSwitchLinkAggregation](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-link-aggregation)

        Args:
            network_id: Network ID.
            link_aggregation_id: Link aggregation ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        link_aggregation_id = urllib.parse.quote(str(link_aggregation_id), safe="")
        path = f"/networks/{network_id}/switch/linkAggregations/{link_aggregation_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_mtu(
        self,
        network_id: str,
        *,
        default_mtu_size: int | None = None,
        overrides: list[UpdateNetworkSwitchMtuOverridesItem] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the MTU configuration.

        [API documentation: updateNetworkSwitchMtu](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-mtu)

        Args:
            network_id: Network ID.
            default_mtu_size: MTU size for the entire network. Default value is 9578.
            overrides: Override MTU size for individual switches or switch templates. An empty array
                will clear overrides.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/mtu"

        payload: dict[str, Any] = {}
        if default_mtu_size is not None:
            payload["defaultMtuSize"] = default_mtu_size
        if overrides is not None:
            payload["overrides"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in overrides
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def update_network_switch_port_schedule(
        self,
        *,
        network_id: str,
        port_schedule_id: str,
        name: str | None = None,
        port_schedule: UpdateNetworkSwitchPortSchedulePortSchedule | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a switch port schedule.

        [API documentation: updateNetworkSwitchPortSchedule](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-port-schedule)

        Args:
            network_id: Network ID.
            port_schedule_id: Port schedule ID.
            name: The name for your port schedule.
            port_schedule: 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.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        port_schedule_id = urllib.parse.quote(str(port_schedule_id), safe="")
        path = f"/networks/{network_id}/switch/portSchedules/{port_schedule_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if port_schedule is not None:
            payload["portSchedule"] = port_schedule.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_qos_rule(
        self,
        *,
        network_id: str,
        vlan: int,
        protocol: CreateNetworkSwitchQosRuleProtocol | None = None,
        src_port: int | None = None,
        src_port_range: str | None = None,
        dst_port: int | None = None,
        dst_port_range: str | None = None,
        dscp: int | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Add a quality of service rule.

        [API documentation: createNetworkSwitchQosRule](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-qos-rule)

        Args:
            network_id: Network ID.
            vlan: The VLAN of the incoming packet. A null value will match any VLAN.
            protocol: The protocol of the incoming packet. Default value is "ANY".
            src_port: The source port of the incoming packet. Applicable only if protocol is TCP or
                UDP.
            src_port_range: The source port range of the incoming packet. Applicable only if
                protocol is set to TCP or UDP.
            dst_port: The destination port of the incoming packet. Applicable only if protocol is
                TCP or UDP.
            dst_port_range: The destination port range of the incoming packet. Applicable only if
                protocol is set to TCP or UDP.
            dscp: DSCP tag for the incoming packet. Set this to -1 to trust incoming DSCP. Default
                value is 0.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/qosRules"

        payload: dict[str, Any] = {}
        if vlan is not None:
            payload["vlan"] = vlan
        if protocol is not None:
            payload["protocol"] = protocol
        if src_port is not None:
            payload["srcPort"] = src_port
        if src_port_range is not None:
            payload["srcPortRange"] = src_port_range
        if dst_port is not None:
            payload["dstPort"] = dst_port
        if dst_port_range is not None:
            payload["dstPortRange"] = dst_port_range
        if dscp is not None:
            payload["dscp"] = dscp

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_qos_rules_order(
        self, *, network_id: str, rule_ids: list[str]
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the order in which the rules should be processed by the switch.

        [API documentation: updateNetworkSwitchQosRulesOrder](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-qos-rules-order)

        Args:
            network_id: Network ID.
            rule_ids: A list of quality of service rule IDs arranged in order in which they should
                be processed by the switch.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/qosRules/order"

        payload: dict[str, Any] = {}
        if rule_ids is not None:
            payload["ruleIds"] = rule_ids

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update_order",
            body=payload,
        )

    def update_network_switch_qos_rule(
        self,
        *,
        network_id: str,
        qos_rule_id: str,
        vlan: int | None = None,
        protocol: UpdateNetworkSwitchQosRuleProtocol | None = None,
        src_port: int | None = None,
        src_port_range: str | None = None,
        dst_port: int | None = None,
        dst_port_range: str | None = None,
        dscp: int | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a quality of service rule.

        [API documentation: updateNetworkSwitchQosRule](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-qos-rule)

        Args:
            network_id: Network ID.
            qos_rule_id: Qos rule ID.
            vlan: The VLAN of the incoming packet. A null value will match any VLAN.
            protocol: The protocol of the incoming packet. Default value is "ANY".
            src_port: The source port of the incoming packet. Applicable only if protocol is TCP or
                UDP.
            src_port_range: The source port range of the incoming packet. Applicable only if
                protocol is set to TCP or UDP.
            dst_port: The destination port of the incoming packet. Applicable only if protocol is
                TCP or UDP.
            dst_port_range: The destination port range of the incoming packet. Applicable only if
                protocol is set to TCP or UDP.
            dscp: DSCP tag that should be assigned to incoming packet. Set this to -1 to trust
                incoming DSCP. Default value is 0.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        qos_rule_id = urllib.parse.quote(str(qos_rule_id), safe="")
        path = f"/networks/{network_id}/switch/qosRules/{qos_rule_id}"

        payload: dict[str, Any] = {}
        if vlan is not None:
            payload["vlan"] = vlan
        if protocol is not None:
            payload["protocol"] = protocol
        if src_port is not None:
            payload["srcPort"] = src_port
        if src_port_range is not None:
            payload["srcPortRange"] = src_port_range
        if dst_port is not None:
            payload["dstPort"] = dst_port
        if dst_port_range is not None:
            payload["dstPortRange"] = dst_port_range
        if dscp is not None:
            payload["dscp"] = dscp

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_qos_rule(
        self, *, network_id: str, qos_rule_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a quality of service rule.

        [API documentation: deleteNetworkSwitchQosRule](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-qos-rule)

        Args:
            network_id: Network ID.
            qos_rule_id: Qos rule ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        qos_rule_id = urllib.parse.quote(str(qos_rule_id), safe="")
        path = f"/networks/{network_id}/switch/qosRules/{qos_rule_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_routing_multicast(
        self,
        network_id: str,
        *,
        default_settings: UpdateNetworkSwitchRoutingMulticastDefaultSettings | None = None,
        overrides: list[UpdateNetworkSwitchRoutingMulticastOverridesItem] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update multicast settings for a network.

        [API documentation: updateNetworkSwitchRoutingMulticast](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-routing-multicast)

        Args:
            network_id: Network ID.
            default_settings: Default multicast setting for entire network. IGMP snooping and Flood
                unknown multicast traffic settings are enabled by default.
            overrides: Array of paired switches/stacks/profiles and corresponding multicast
                settings. An empty array will clear the multicast settings.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/routing/multicast"

        payload: dict[str, Any] = {}
        if default_settings is not None:
            payload["defaultSettings"] = default_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if overrides is not None:
            payload["overrides"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in overrides
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_routing_multicast_rendezvous_point(
        self,
        *,
        network_id: str,
        interface_ip: str,
        multicast_group: str,
        vrf: CreateNetworkSwitchRoutingMulticastRendezvousPointVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a multicast rendezvous point.

        [API documentation: createNetworkSwitchRoutingMulticastRendezvousPoint](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-routing-multicast-rendezvous-point)

        Args:
            network_id: Network ID.
            interface_ip: The IP address of the interface where the RP needs to be created.
            multicast_group: 'Any', or the IP address of a multicast group.
            vrf: The VRF with PIM enabled L3 interface.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/routing/multicast/rendezvousPoints"

        payload: dict[str, Any] = {}
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_group is not None:
            payload["multicastGroup"] = multicast_group
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_routing_multicast_rendezvous_point(
        self,
        *,
        network_id: str,
        rendezvous_point_id: str,
        interface_ip: str,
        multicast_group: str,
        vrf: UpdateNetworkSwitchRoutingMulticastRendezvousPointVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a multicast rendezvous point.

        [API documentation: updateNetworkSwitchRoutingMulticastRendezvousPoint](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-routing-multicast-rendezvous-point)

        Args:
            network_id: Network ID.
            rendezvous_point_id: Rendezvous point ID.
            interface_ip: The IP address of the interface where the RP needs to be created.
            multicast_group: 'Any', or the IP address of a multicast group.
            vrf: The VRF with PIM enabled L3 interface.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rendezvous_point_id = urllib.parse.quote(str(rendezvous_point_id), safe="")
        path = f"/networks/{network_id}/switch/routing/multicast/rendezvousPoints/{rendezvous_point_id}"

        payload: dict[str, Any] = {}
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_group is not None:
            payload["multicastGroup"] = multicast_group
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_routing_multicast_rendezvous_point(
        self, *, network_id: str, rendezvous_point_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a multicast rendezvous point.

        [API documentation: deleteNetworkSwitchRoutingMulticastRendezvousPoint](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-routing-multicast-rendezvous-point)

        Args:
            network_id: Network ID.
            rendezvous_point_id: Rendezvous point ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rendezvous_point_id = urllib.parse.quote(str(rendezvous_point_id), safe="")
        path = f"/networks/{network_id}/switch/routing/multicast/rendezvousPoints/{rendezvous_point_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_routing_ospf(
        self,
        network_id: str,
        *,
        vrf: str | None = None,
        enabled: bool | None = None,
        hello_timer_in_seconds: int | None = None,
        dead_timer_in_seconds: int | None = None,
        areas: list[UpdateNetworkSwitchRoutingOspfAreasItem] | None = None,
        v3: UpdateNetworkSwitchRoutingOspfV3 | None = None,
        md5_authentication_enabled: bool | None = None,
        md5_authentication_key: UpdateNetworkSwitchRoutingOspfMd5AuthenticationKey | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update layer 3 OSPF routing configuration.

        [API documentation: updateNetworkSwitchRoutingOspf](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-routing-ospf)

        Args:
            network_id: Network ID.
            vrf: The VRF to return the OSPF routing configuration for. When not provided, the
                default VRF is used. Requires IOS XE 17.18 or higher.
            enabled: Boolean value to enable or disable OSPF routing. OSPF routing is disabled by
                default.
            hello_timer_in_seconds: Time interval in seconds at which hello packet will be sent to
                OSPF neighbors to maintain connectivity. Value must be between 1 and
                255. Default is 10 seconds.
            dead_timer_in_seconds: Time interval to determine when the peer will be declared
                inactive/dead. Value must be between 1 and 65535.
            areas: OSPF areas.
            v3: OSPF v3 configuration.
            md5_authentication_enabled: Boolean value to enable or disable MD5 authentication. MD5
                authentication is disabled by default.
            md5_authentication_key: MD5 authentication credentials. This param is only relevant if
                md5AuthenticationEnabled is true.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/routing/ospf"

        params: dict[str, Any] = {}
        if vrf is not None:
            params["vrf"] = vrf

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if hello_timer_in_seconds is not None:
            payload["helloTimerInSeconds"] = hello_timer_in_seconds
        if dead_timer_in_seconds is not None:
            payload["deadTimerInSeconds"] = dead_timer_in_seconds
        if areas is not None:
            payload["areas"] = [item.model_dump(by_alias=True, exclude_none=True) for item in areas]
        if v3 is not None:
            payload["v3"] = v3.model_dump(by_alias=True, exclude_none=True)
        if md5_authentication_enabled is not None:
            payload["md5AuthenticationEnabled"] = md5_authentication_enabled
        if md5_authentication_key is not None:
            payload["md5AuthenticationKey"] = md5_authentication_key.model_dump(
                by_alias=True, exclude_none=True
            )

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def update_network_switch_settings(
        self,
        network_id: str,
        *,
        vlan: int | None = None,
        use_combined_power: bool | None = None,
        power_exceptions: list[UpdateNetworkSwitchSettingsPowerExceptionsItem] | None = None,
        uplink_client_sampling: UpdateNetworkSwitchSettingsUplinkClientSampling | None = None,
        mac_blocklist: UpdateNetworkSwitchSettingsMacBlocklist | None = None,
        uplink_selection: UpdateNetworkSwitchSettingsUplinkSelection | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update switch network settings.

        [API documentation: updateNetworkSwitchSettings](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-settings)

        Args:
            network_id: Network ID.
            vlan: Management VLAN.
            use_combined_power: The use Combined Power as the default behavior of secondary power
                supplies on supported devices.
            power_exceptions: Exceptions on a per switch basis to "useCombinedPower".
            uplink_client_sampling: Uplink client sampling.
            mac_blocklist: MAC blocklist.
            uplink_selection: Settings related to uplink selection on IOS-XE switches.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/settings"

        payload: dict[str, Any] = {}
        if vlan is not None:
            payload["vlan"] = vlan
        if use_combined_power is not None:
            payload["useCombinedPower"] = use_combined_power
        if power_exceptions is not None:
            payload["powerExceptions"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in power_exceptions
            ]
        if uplink_client_sampling is not None:
            payload["uplinkClientSampling"] = uplink_client_sampling.model_dump(
                by_alias=True, exclude_none=True
            )
        if mac_blocklist is not None:
            payload["macBlocklist"] = mac_blocklist.model_dump(by_alias=True, exclude_none=True)
        if uplink_selection is not None:
            payload["uplinkSelection"] = uplink_selection.model_dump(
                by_alias=True, exclude_none=True
            )

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="settings/actions/update",
            body=payload,
        )

    def create_network_switch_stack_routing_interface(
        self,
        *,
        network_id: str,
        switch_stack_id: str,
        name: str,
        mode: CreateNetworkSwitchStackRoutingInterfaceMode | None = None,
        subnet: str | None = None,
        switch_port_id: str | None = None,
        interface_ip: str | None = None,
        multicast_routing: CreateNetworkSwitchStackRoutingInterfaceMulticastRouting | None = None,
        vlan_id: int | None = None,
        default_gateway: str | None = None,
        ospf_settings: CreateNetworkSwitchStackRoutingInterfaceOspfSettings | None = None,
        ipv6: CreateNetworkSwitchStackRoutingInterfaceIpv6 | None = None,
        vrf: CreateNetworkSwitchStackRoutingInterfaceVrf | None = None,
        loopback: dict[str, Any] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a layer 3 interface for a switch stack.

        [API documentation: createNetworkSwitchStackRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-stack-routing-interface)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            name: A friendly name or description for the interface or VLAN (max length 128
                characters).
            mode: L3 Interface mode, can be one of 'vlan', 'routed', 'loopback'. Default is 'vlan'.
                CS 17.18 or higher is required for 'routed' mode.
            subnet: The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24).
            switch_port_id: Switch Port ID when in Routed mode (CS 17.18 or higher required).
            interface_ip: 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.
            multicast_routing: Enable multicast support if, multicast routing between VLANs is
                required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'.
                Default is 'disabled'.
            vlan_id: The VLAN this L3 interface is on. VLAN must be between 1 and 4094.
            default_gateway: The next hop for any traffic that isn't going to a directly connected
                subnet or over a static route. This IP address must exist in a subnet
                with a L3 interface. Required if this is the first IPv4 interface.
            ospf_settings: The OSPF routing settings of the interface.
            ipv6: The IPv6 settings of the interface.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.
            loopback: The loopback settings of the interface.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/interfaces"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if mode is not None:
            payload["mode"] = mode
        if subnet is not None:
            payload["subnet"] = subnet
        if switch_port_id is not None:
            payload["switchPortId"] = switch_port_id
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_routing is not None:
            payload["multicastRouting"] = multicast_routing
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if default_gateway is not None:
            payload["defaultGateway"] = default_gateway
        if ospf_settings is not None:
            payload["ospfSettings"] = ospf_settings.model_dump(by_alias=True, exclude_none=True)
        if ipv6 is not None:
            payload["ipv6"] = ipv6.model_dump(by_alias=True, exclude_none=True)
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)
        if loopback is not None:
            payload["loopback"] = loopback

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_stack_routing_interface(
        self,
        *,
        network_id: str,
        switch_stack_id: str,
        interface_id: str,
        name: str | None = None,
        subnet: str | None = None,
        switch_port_id: str | None = None,
        interface_ip: str | None = None,
        multicast_routing: UpdateNetworkSwitchStackRoutingInterfaceMulticastRouting | None = None,
        vlan_id: int | None = None,
        default_gateway: str | None = None,
        ospf_settings: UpdateNetworkSwitchStackRoutingInterfaceOspfSettings | None = None,
        ipv6: UpdateNetworkSwitchStackRoutingInterfaceIpv6 | None = None,
        vrf: UpdateNetworkSwitchStackRoutingInterfaceVrf | None = None,
        loopback: dict[str, Any] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 interface for a switch stack.

        [API documentation: updateNetworkSwitchStackRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-stack-routing-interface)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            interface_id: Interface ID.
            name: A friendly name or description for the interface or VLAN (max length 128
                characters).
            subnet: The network that this L3 interface is on, in CIDR notation (ex. 10.1.1.0/24).
            switch_port_id: Switch Port ID when in Routed mode (CS 17.18 or higher required).
            interface_ip: 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.
            multicast_routing: Enable multicast support if, multicast routing between VLANs is
                required. Options are: 'disabled', 'enabled' or 'IGMP snooping querier'.
                Default is 'disabled'.
            vlan_id: The VLAN this L3 interface is on. VLAN must be between 1 and 4094.
            default_gateway: The next hop for any traffic that isn't going to a directly connected
                subnet or over a static route. This IP address must exist in a subnet
                with a L3 interface. Required if this is the first IPv4 interface.
            ospf_settings: The OSPF routing settings of the interface.
            ipv6: The IPv6 settings of the interface.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.
            loopback: The loopback settings of the interface.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/interfaces/{interface_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if switch_port_id is not None:
            payload["switchPortId"] = switch_port_id
        if interface_ip is not None:
            payload["interfaceIp"] = interface_ip
        if multicast_routing is not None:
            payload["multicastRouting"] = multicast_routing
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if default_gateway is not None:
            payload["defaultGateway"] = default_gateway
        if ospf_settings is not None:
            payload["ospfSettings"] = ospf_settings.model_dump(by_alias=True, exclude_none=True)
        if ipv6 is not None:
            payload["ipv6"] = ipv6.model_dump(by_alias=True, exclude_none=True)
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)
        if loopback is not None:
            payload["loopback"] = loopback

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_stack_routing_interface(
        self, *, network_id: str, switch_stack_id: str, interface_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a layer 3 interface from a switch stack.

        [API documentation: deleteNetworkSwitchStackRoutingInterface](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-stack-routing-interface)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            interface_id: Interface ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/interfaces/{interface_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_stack_routing_interface_dhcp(
        self,
        *,
        network_id: str,
        switch_stack_id: str,
        interface_id: str,
        dhcp_mode: UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpMode | None = None,
        dhcp_relay_server_ips: list[str] | None = None,
        dhcp_lease_time: UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpLeaseTime | None = None,
        dns_nameservers_option: UpdateNetworkSwitchStackRoutingInterfaceDhcpDnsNameserversOption
        | None = None,
        dns_custom_nameservers: list[str] | None = None,
        boot_options_enabled: bool | None = None,
        boot_next_server: str | None = None,
        boot_file_name: str | None = None,
        dhcp_options: list[UpdateNetworkSwitchStackRoutingInterfaceDhcpDhcpOptionsItem]
        | None = None,
        reserved_ip_ranges: list[UpdateNetworkSwitchStackRoutingInterfaceDhcpReservedIpRangesItem]
        | None = None,
        fixed_ip_assignments: list[
            UpdateNetworkSwitchStackRoutingInterfaceDhcpFixedIpAssignmentsItem
        ]
        | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 interface DHCP configuration for a switch stack.

        [API documentation: updateNetworkSwitchStackRoutingInterfaceDhcp](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-stack-routing-interface-dhcp)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            interface_id: Interface ID.
            dhcp_mode: The DHCP mode options for the switch stack interface ('dhcpDisabled',
                'dhcpRelay' or 'dhcpServer').
            dhcp_relay_server_ips: The DHCP relay server IPs to which DHCP packets would get relayed
                for the switch stack interface.
            dhcp_lease_time: The DHCP lease time config for the dhcp server running on switch stack
                interface ('30 minutes', '1 hour', '4 hours', '12 hours', '1 day' or '1
                week').
            dns_nameservers_option: The DHCP name server option for the dhcp server running on the
                switch stack interface ('googlePublicDns', 'openDns' or 'custom').
            dns_custom_nameservers: The DHCP name server IPs when DHCP name server option is '
                custom'.
            boot_options_enabled: Enable DHCP boot options to provide PXE boot options configs for
                the dhcp server running on the switch stack interface.
            boot_next_server: The PXE boot server IP for the DHCP server running on the switch stack
                interface.
            boot_file_name: The PXE boot server file name for the DHCP server running on the switch
                stack interface.
            dhcp_options: Array of DHCP options consisting of code, type and value for the DHCP
                server running on the switch stack interface.
            reserved_ip_ranges: Array of DHCP reserved IP assignments for the DHCP server running on
                the switch stack interface.
            fixed_ip_assignments: Array of DHCP fixed IP assignments for the DHCP server running on
                the switch stack interface.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        interface_id = urllib.parse.quote(str(interface_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/interfaces/{interface_id}/dhcp"

        payload: dict[str, Any] = {}
        if dhcp_mode is not None:
            payload["dhcpMode"] = dhcp_mode
        if dhcp_relay_server_ips is not None:
            payload["dhcpRelayServerIps"] = dhcp_relay_server_ips
        if dhcp_lease_time is not None:
            payload["dhcpLeaseTime"] = dhcp_lease_time
        if dns_nameservers_option is not None:
            payload["dnsNameserversOption"] = dns_nameservers_option
        if dns_custom_nameservers is not None:
            payload["dnsCustomNameservers"] = dns_custom_nameservers
        if boot_options_enabled is not None:
            payload["bootOptionsEnabled"] = boot_options_enabled
        if boot_next_server is not None:
            payload["bootNextServer"] = boot_next_server
        if boot_file_name is not None:
            payload["bootFileName"] = boot_file_name
        if dhcp_options is not None:
            payload["dhcpOptions"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in dhcp_options
            ]
        if reserved_ip_ranges is not None:
            payload["reservedIpRanges"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in reserved_ip_ranges
            ]
        if fixed_ip_assignments is not None:
            payload["fixedIpAssignments"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in fixed_ip_assignments
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def create_network_switch_stack_routing_static_route(
        self,
        *,
        network_id: str,
        switch_stack_id: str,
        subnet: str,
        next_hop_ip: str,
        name: str | None = None,
        advertise_via_ospf_enabled: bool | None = None,
        prefer_over_ospf_routes_enabled: bool | None = None,
        vrf: CreateNetworkSwitchStackRoutingStaticRouteVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Create a layer 3 static route for a switch stack.

        [API documentation: createNetworkSwitchStackRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!create-network-switch-stack-routing-static-route)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            name: Name or description for layer 3 static route.
            subnet: The subnet which is routed via this static route and should be specified in CIDR
                notation (ex. 1.2.3.0/24).
            next_hop_ip: IP address of the next hop device to which the device sends its traffic for
                the subnet.
            advertise_via_ospf_enabled: Option to advertise static route via OSPF.
            prefer_over_ospf_routes_enabled: Option to prefer static route over OSPF routes.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/staticRoutes"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if next_hop_ip is not None:
            payload["nextHopIp"] = next_hop_ip
        if advertise_via_ospf_enabled is not None:
            payload["advertiseViaOspfEnabled"] = advertise_via_ospf_enabled
        if prefer_over_ospf_routes_enabled is not None:
            payload["preferOverOspfRoutesEnabled"] = prefer_over_ospf_routes_enabled
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="create",
            body=payload,
        )

    def update_network_switch_stack_routing_static_route(
        self,
        *,
        network_id: str,
        switch_stack_id: str,
        static_route_id: str,
        name: str | None = None,
        subnet: str | None = None,
        next_hop_ip: str | None = None,
        management_next_hop: str | None = None,
        advertise_via_ospf_enabled: bool | None = None,
        prefer_over_ospf_routes_enabled: bool | None = None,
        vrf: UpdateNetworkSwitchStackRoutingStaticRouteVrf | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a layer 3 static route for a switch stack.

        [API documentation: updateNetworkSwitchStackRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-stack-routing-static-route)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            static_route_id: Static route ID.
            name: Name or description for layer 3 static route.
            subnet: The subnet which is routed via this static route and should be specified in CIDR
                notation (ex. 1.2.3.0/24).
            next_hop_ip: IP address of the next hop device to which the device sends its traffic for
                the subnet.
            management_next_hop: Optional fallback IP address for management traffic.
            advertise_via_ospf_enabled: Option to advertise static route via OSPF.
            prefer_over_ospf_routes_enabled: Option to prefer static route over OSPF routes.
            vrf: The VRF settings of the interface. Requires IOS XE 17.18 or higher.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        static_route_id = urllib.parse.quote(str(static_route_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/staticRoutes/{static_route_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if subnet is not None:
            payload["subnet"] = subnet
        if next_hop_ip is not None:
            payload["nextHopIp"] = next_hop_ip
        if management_next_hop is not None:
            payload["managementNextHop"] = management_next_hop
        if advertise_via_ospf_enabled is not None:
            payload["advertiseViaOspfEnabled"] = advertise_via_ospf_enabled
        if prefer_over_ospf_routes_enabled is not None:
            payload["preferOverOspfRoutesEnabled"] = prefer_over_ospf_routes_enabled
        if vrf is not None:
            payload["vrf"] = vrf.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def delete_network_switch_stack_routing_static_route(
        self, *, network_id: str, switch_stack_id: str, static_route_id: str
    ) -> CreateOrganizationActionBatchActionsItem:
        """Delete a layer 3 static route for a switch stack.

        [API documentation: deleteNetworkSwitchStackRoutingStaticRoute](https://developer.cisco.com/meraki/api-v1/#!delete-network-switch-stack-routing-static-route)

        Args:
            network_id: Network ID.
            switch_stack_id: Switch stack ID.
            static_route_id: Static route ID.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        switch_stack_id = urllib.parse.quote(str(switch_stack_id), safe="")
        static_route_id = urllib.parse.quote(str(static_route_id), safe="")
        path = f"/networks/{network_id}/switch/stacks/{switch_stack_id}/routing/staticRoutes/{static_route_id}"

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="destroy",
        )

    def update_network_switch_storm_control(
        self,
        network_id: str,
        *,
        broadcast_threshold: int | None = None,
        multicast_threshold: int | None = None,
        unknown_unicast_threshold: int | None = None,
        treat_these_traffic_types_as_one_threshold: list[str] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update the storm control configuration for a switch network.

        [API documentation: updateNetworkSwitchStormControl](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-storm-control)

        Args:
            network_id: Network ID.
            broadcast_threshold: Percentage (1 to 99) of total available port bandwidth for
                broadcast traffic type. Default value 100 percent rate is to clear the
                configuration.
            multicast_threshold: Percentage (1 to 99) of total available port bandwidth for
                multicast traffic type. Default value 100 percent rate is to clear the
                configuration.
            unknown_unicast_threshold: Percentage (1 to 99) of total available port bandwidth for
                unknown unicast (dlf-destination lookup failure) traffic type. Default
                value 100 percent rate is to clear the configuration.
            treat_these_traffic_types_as_one_threshold: Grouped traffic types.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/stormControl"

        payload: dict[str, Any] = {}
        if broadcast_threshold is not None:
            payload["broadcastThreshold"] = broadcast_threshold
        if multicast_threshold is not None:
            payload["multicastThreshold"] = multicast_threshold
        if unknown_unicast_threshold is not None:
            payload["unknownUnicastThreshold"] = unknown_unicast_threshold
        if treat_these_traffic_types_as_one_threshold is not None:
            payload["treatTheseTrafficTypesAsOneThreshold"] = (
                treat_these_traffic_types_as_one_threshold
            )

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def update_network_switch_stp(
        self,
        network_id: str,
        *,
        rstp_enabled: bool | None = None,
        stp_bridge_priority: list[UpdateNetworkSwitchStpStpBridgePriorityItem] | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Updates STP settings.

        [API documentation: updateNetworkSwitchStp](https://developer.cisco.com/meraki/api-v1/#!update-network-switch-stp)

        Args:
            network_id: Network ID.
            rstp_enabled: The spanning tree protocol status in network.
            stp_bridge_priority: STP bridge priority for switches/stacks or switch templates. An
                empty array will clear the STP bridge priority settings.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/switch/stp"

        payload: dict[str, Any] = {}
        if rstp_enabled is not None:
            payload["rstpEnabled"] = rstp_enabled
        if stp_bridge_priority is not None:
            payload["stpBridgePriority"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in stp_bridge_priority
            ]

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def update_organization_config_template_switch_profile_port(
        self,
        *,
        organization_id: str,
        config_template_id: str,
        profile_id: str,
        port_id: str,
        name: str | None = None,
        tags: list[str] | None = None,
        enabled: bool | None = None,
        poe_enabled: bool | None = None,
        type_: UpdateOrganizationConfigTemplateSwitchProfilePortType | None = None,
        vlan: int | None = None,
        voice_vlan: int | None = None,
        allowed_vlans: str | None = None,
        isolation_enabled: bool | None = None,
        rstp_enabled: bool | None = None,
        stp_guard: UpdateOrganizationConfigTemplateSwitchProfilePortStpGuard | None = None,
        stp_port_fast_trunk: bool | None = None,
        link_negotiation: str | None = None,
        port_schedule_id: str | None = None,
        udld: UpdateOrganizationConfigTemplateSwitchProfilePortUdld | None = None,
        access_policy_type: UpdateOrganizationConfigTemplateSwitchProfilePortAccessPolicyType
        | None = None,
        access_policy_number: int | None = None,
        mac_allow_list: list[str] | None = None,
        mac_whitelist_limit: int | None = None,
        sticky_mac_allow_list: list[str] | None = None,
        sticky_mac_allow_list_limit: int | None = None,
        storm_control_enabled: bool | None = None,
        flexible_stacking_enabled: bool | None = None,
        dai_trusted: bool | None = None,
        profile: UpdateOrganizationConfigTemplateSwitchProfilePortProfile | None = None,
        dot3az: UpdateOrganizationConfigTemplateSwitchProfilePortDot3az | None = None,
        high_speed: UpdateOrganizationConfigTemplateSwitchProfilePortHighSpeed | None = None,
    ) -> CreateOrganizationActionBatchActionsItem:
        """Update a switch template port.

        [API documentation: updateOrganizationConfigTemplateSwitchProfilePort](https://developer.cisco.com/meraki/api-v1/#!update-organization-config-template-switch-profile-port)

        Args:
            organization_id: Organization ID.
            config_template_id: Config template ID.
            profile_id: Profile ID.
            port_id: Port ID.
            name: The name of the switch template port.
            tags: The list of tags of the switch template port.
            enabled: The status of the switch template port.
            poe_enabled: The PoE status of the switch template port.
            type_: The type of the switch template port ('access', 'trunk', 'stack', 'routed', 'svl'
                or 'dad').
            vlan: The VLAN of the switch template port. For a trunk port, this is the native VLAN. A
                null value will clear the value set for trunk ports.
            voice_vlan: The voice VLAN of the switch template port. Only applicable to access ports.
            allowed_vlans: The VLANs allowed on the switch template port. Only applicable to trunk
                ports.
            isolation_enabled: The isolation status of the switch template port.
            rstp_enabled: The rapid spanning tree protocol status.
            stp_guard: The state of the STP guard ('disabled', 'root guard', 'bpdu guard' or 'loop
                guard').
            stp_port_fast_trunk: The state of STP PortFast Trunk on the switch template port.
            link_negotiation: The link speed for the switch template port.
            port_schedule_id: The ID of the port schedule. A value of null will clear the port
                schedule.
            udld: The action to take when Unidirectional Link is detected (Alert only, Enforce).
                Default configuration is Alert only.
            access_policy_type: The type of the access policy of the switch template port. Only
                applicable to access ports. Can be one of 'Open', 'Custom access
                policy', 'MAC allow list' or 'Sticky MAC allow list'.
            access_policy_number: The number of a custom access policy to configure on the switch
                template port. Only applicable when 'accessPolicyType' is 'Custom access
                policy'.
            mac_allow_list: Only devices with MAC addresses specified in this list will have access
                to this port. Up to 20 MAC addresses can be defined. Only applicable
                when 'accessPolicyType' is 'MAC allow list'.
            mac_whitelist_limit: The maximum number of MAC addresses for regular MAC allow list.
                Only applicable when 'accessPolicyType' is 'MAC allow list'. Note:
                Config only supported on verions greater than ms18 only for classic
                switches.
            sticky_mac_allow_list: The initial list of MAC addresses for sticky Mac allow list. Only
                applicable when 'accessPolicyType' is 'Sticky MAC allow list'.
            sticky_mac_allow_list_limit: The maximum number of MAC addresses for sticky MAC allow
                list. Only applicable when 'accessPolicyType' is 'Sticky MAC allow
                list'.
            storm_control_enabled: The storm control status of the switch template port.
            flexible_stacking_enabled: For supported switches (e.g. MS420/MS425), whether or not the
                port has flexible stacking enabled.
            dai_trusted: If true, ARP packets for this port will be considered trusted, and Dynamic
                ARP Inspection will allow the traffic.
            profile: Profile attributes.
            dot3az: dot3az settings for the port.
            high_speed: High speed port enablement settings for C9500-32QC.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        config_template_id = urllib.parse.quote(str(config_template_id), safe="")
        profile_id = urllib.parse.quote(str(profile_id), safe="")
        port_id = urllib.parse.quote(str(port_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates/{config_template_id}/switch/profiles/{profile_id}/ports/{port_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if tags is not None:
            payload["tags"] = tags
        if enabled is not None:
            payload["enabled"] = enabled
        if poe_enabled is not None:
            payload["poeEnabled"] = poe_enabled
        if type_ is not None:
            payload["type"] = type_
        if vlan is not None:
            payload["vlan"] = vlan
        if voice_vlan is not None:
            payload["voiceVlan"] = voice_vlan
        if allowed_vlans is not None:
            payload["allowedVlans"] = allowed_vlans
        if isolation_enabled is not None:
            payload["isolationEnabled"] = isolation_enabled
        if rstp_enabled is not None:
            payload["rstpEnabled"] = rstp_enabled
        if stp_guard is not None:
            payload["stpGuard"] = stp_guard
        if stp_port_fast_trunk is not None:
            payload["stpPortFastTrunk"] = stp_port_fast_trunk
        if link_negotiation is not None:
            payload["linkNegotiation"] = link_negotiation
        if port_schedule_id is not None:
            payload["portScheduleId"] = port_schedule_id
        if udld is not None:
            payload["udld"] = udld
        if access_policy_type is not None:
            payload["accessPolicyType"] = access_policy_type
        if access_policy_number is not None:
            payload["accessPolicyNumber"] = access_policy_number
        if mac_allow_list is not None:
            payload["macAllowList"] = mac_allow_list
        if mac_whitelist_limit is not None:
            payload["macWhitelistLimit"] = mac_whitelist_limit
        if sticky_mac_allow_list is not None:
            payload["stickyMacAllowList"] = sticky_mac_allow_list
        if sticky_mac_allow_list_limit is not None:
            payload["stickyMacAllowListLimit"] = sticky_mac_allow_list_limit
        if storm_control_enabled is not None:
            payload["stormControlEnabled"] = storm_control_enabled
        if flexible_stacking_enabled is not None:
            payload["flexibleStackingEnabled"] = flexible_stacking_enabled
        if dai_trusted is not None:
            payload["daiTrusted"] = dai_trusted
        if profile is not None:
            payload["profile"] = profile.model_dump(by_alias=True, exclude_none=True)
        if dot3az is not None:
            payload["dot3az"] = dot3az.model_dump(by_alias=True, exclude_none=True)
        if high_speed is not None:
            payload["highSpeed"] = high_speed.model_dump(by_alias=True, exclude_none=True)

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="update",
            body=payload,
        )

    def clone_organization_switch_devices(
        self, *, organization_id: str, source_serial: str, target_serials: list[str]
    ) -> CreateOrganizationActionBatchActionsItem:
        """Clone port-level and some switch-level configuration settings from a source switch to one or more target switches.

        [API documentation: cloneOrganizationSwitchDevices](https://developer.cisco.com/meraki/api-v1/#!clone-organization-switch-devices)

        Args:
            organization_id: Organization ID.
            source_serial: Serial number of the source switch (must be on a network not bound to a
                template).
            target_serials: Array of serial numbers of one or more target switches (must be on a
                network not bound to a template).

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/switch/devices/clone"

        payload: dict[str, Any] = {}
        if source_serial is not None:
            payload["sourceSerial"] = source_serial
        if target_serials is not None:
            payload["targetSerials"] = target_serials

        return CreateOrganizationActionBatchActionsItem(
            resource=path,
            operation="settings/actions/clone",
            body=payload,
        )
