Public/physical-network.ps1

function Get-CSPhysicalNetwork {
    <#
    .SYNOPSIS
        Lists physical networks.

    .DESCRIPTION
        Retrieves physical networks (listPhysicalNetworks), optionally filtered by
        ID, name, keyword, or zone.

    .PARAMETER Id
        Filter by physical network ID

    .PARAMETER Name
        Filter by physical network name

    .PARAMETER Keyword
        Filter by keyword (partial match)

    .PARAMETER ZoneId
        Filter by zone ID

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSPhysicalNetwork
        Lists every physical network.

    .EXAMPLE
        Get-CSPhysicalNetwork -ZoneId zone-uuid
        Lists the physical networks in a zone.

    .EXAMPLE
        Get-CSPhysicalNetwork -Name 'Physical Network 1' | Get-CSTrafficType
        Shows the traffic types carried by a physical network found by name.
    #>

    [CmdletBinding()]
    param(
        [string]$Id,

        [string]$Name,

        [string]$Keyword,

        [string]$ZoneId,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Id = 'id'; Name = 'name'; Keyword = 'keyword'; ZoneId = 'zoneid'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listPhysicalNetworks' -Parameters $apiParams) -Command 'listPhysicalNetworks'
}

function New-CSPhysicalNetwork {
    <#
    .SYNOPSIS
        Creates a physical network in a zone.

    .DESCRIPTION
        Creates a physical network (createPhysicalNetwork). After creating it, add
        traffic types with Add-CSTrafficType, enable providers with
        Set-CSNetworkServiceProvider, and enable the network with
        Set-CSPhysicalNetwork -State Enabled. This is an asynchronous job; use
        -Wait to get the new physical network back instead of the job handle.

    .PARAMETER Name
        The name of the physical network (required)

    .PARAMETER ZoneId
        The zone ID for the physical network (required)

    .PARAMETER IsolationMethods
        Isolation method(s) for the physical network, e.g. VLAN, VXLAN, GRE, L3

    .PARAMETER Vlan
        The VLAN range for the physical network, e.g. 100-199 or 100-199,300-399

    .PARAMETER NetworkSpeed
        The speed of the physical network, e.g. 1G or 10G

    .PARAMETER BroadcastDomainRange
        The broadcast domain range: Zone (advanced zones) or Pod (basic zones)

    .PARAMETER Tags
        Tag(s) for the physical network, matched against network offering tags

    .PARAMETER DomainId
        Domain ID of the account owning the physical network

    .PARAMETER Wait
        Wait for the async job to finish and return the new physical network

    .EXAMPLE
        New-CSPhysicalNetwork -Name 'guest-pn' -ZoneId zone-uuid -IsolationMethods VLAN -Vlan '1000-1999' -Wait
        Creates a VLAN-isolated physical network with a guest VLAN range and returns it.

    .EXAMPLE
        New-CSPhysicalNetwork -Name 'vxlan-pn' -ZoneId zone-uuid -IsolationMethods VXLAN -Vlan '5000-5999' -NetworkSpeed 10G -Tags 'vxlan'
        Creates a tagged VXLAN physical network.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,

        [Parameter(Mandatory = $true)]
        [string]$ZoneId,

        [string[]]$IsolationMethods,

        [string]$Vlan,

        [string]$NetworkSpeed,

        [ValidateSet('Zone', 'Pod')]
        [string]$BroadcastDomainRange,

        [string[]]$Tags,

        [string]$DomainId,

        [switch]$Wait
    )

    $apiParams = @{ name = $Name; zoneid = $ZoneId }
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        IsolationMethods = 'isolationmethods'; Vlan = 'vlan'; NetworkSpeed = 'networkspeed'
        BroadcastDomainRange = 'broadcastdomainrange'; Tags = 'tags'; DomainId = 'domainid'
    })
    if ($PSCmdlet.ShouldProcess("physical network $Name in zone $ZoneId", 'Create')) {
        Invoke-CSAsyncApiRequest -Command 'createPhysicalNetwork' -Parameters $apiParams -Wait:$Wait
    }
}

function Set-CSPhysicalNetwork {
    <#
    .SYNOPSIS
        Updates a physical network.

    .DESCRIPTION
        Enables/disables a physical network or changes its VLAN range, speed, or
        tags (updatePhysicalNetwork). This is an asynchronous job; use -Wait to get
        the updated physical network back. Accepts objects from
        Get-CSPhysicalNetwork on the pipeline.

    .PARAMETER Id
        The physical network ID (required; binds from a piped physical network's id)

    .PARAMETER State
        Enabled or Disabled

    .PARAMETER Vlan
        The VLAN range for the physical network, e.g. 1000-1999

    .PARAMETER NetworkSpeed
        The speed of the physical network, e.g. 1G or 10G

    .PARAMETER Tags
        Tag(s) for the physical network

    .PARAMETER Wait
        Wait for the async job to finish and return the updated physical network

    .EXAMPLE
        Set-CSPhysicalNetwork -Id pn-uuid -State Enabled
        Enables a physical network.

    .EXAMPLE
        Get-CSPhysicalNetwork -Name 'guest-pn' | Set-CSPhysicalNetwork -Vlan '1000-2999' -Wait
        Extends the VLAN range of a physical network found by name.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [ValidateSet('Enabled', 'Disabled')]
        [string]$State,

        [string]$Vlan,

        [string]$NetworkSpeed,

        [string[]]$Tags,

        [switch]$Wait
    )

    process {
        $apiParams = @{ id = $Id }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            State = 'state'; Vlan = 'vlan'; NetworkSpeed = 'networkspeed'; Tags = 'tags'
        })
        if ($PSCmdlet.ShouldProcess("physical network $Id", 'Update')) {
            Invoke-CSAsyncApiRequest -Command 'updatePhysicalNetwork' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Remove-CSPhysicalNetwork {
    <#
    .SYNOPSIS
        Deletes a physical network.

    .DESCRIPTION
        Deletes a physical network (deletePhysicalNetwork). This is an
        asynchronous job; use -Wait to block until it finishes. Accepts objects
        from Get-CSPhysicalNetwork on the pipeline.

    .PARAMETER Id
        The physical network ID (required; binds from a piped physical network's id)

    .PARAMETER Wait
        Wait for the async job to finish and return its result

    .EXAMPLE
        Remove-CSPhysicalNetwork -Id pn-uuid
        Deletes a physical network after prompting for confirmation.

    .EXAMPLE
        Get-CSPhysicalNetwork -Name 'old-pn' | Remove-CSPhysicalNetwork -Confirm:$false -Wait
        Deletes a physical network found by name without prompting.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("physical network $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deletePhysicalNetwork' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSNetworkIsolationMethod {
    <#
    .SYNOPSIS
        Lists the supported physical network isolation methods.

    .DESCRIPTION
        Returns the isolation methods (VLAN, VXLAN, GRE, ...) available for
        physical networks on this CloudStack installation (listNetworkIsolationMethods).

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSNetworkIsolationMethod
        Lists every supported isolation method.
    #>

    [CmdletBinding()]
    param(
        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listNetworkIsolationMethods' -Parameters $apiParams) -Command 'listNetworkIsolationMethods'
}

function Get-CSTrafficType {
    <#
    .SYNOPSIS
        Lists the traffic types on a physical network.

    .DESCRIPTION
        Returns the traffic types (Public, Guest, Management, Storage) configured on
        a physical network, including their hypervisor network labels
        (listTrafficTypes). Accepts objects from Get-CSPhysicalNetwork on the pipeline.

    .PARAMETER PhysicalNetworkId
        The physical network ID (required; binds from a piped physical network's id)

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSTrafficType -PhysicalNetworkId pn-uuid
        Lists the traffic types on a physical network.

    .EXAMPLE
        Get-CSPhysicalNetwork -ZoneId zone-uuid | Get-CSTrafficType | Select-Object physicalnetworkid, traffictype, kvmnetworklabel
        Shows the KVM network label of every traffic type in a zone.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$PhysicalNetworkId,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    process {
        $apiParams = @{ physicalnetworkid = $PhysicalNetworkId }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
        })
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listTrafficTypes' -Parameters $apiParams) -Command 'listTrafficTypes'
    }
}

function Add-CSTrafficType {
    <#
    .SYNOPSIS
        Adds a traffic type to a physical network.

    .DESCRIPTION
        Adds Public, Guest, Management or Storage traffic to a physical network
        (addTrafficType), optionally with the hypervisor network label that
        carries it on each host type. This is an asynchronous job; use -Wait to
        get the new traffic type back. Accepts objects from Get-CSPhysicalNetwork
        on the pipeline.

    .PARAMETER PhysicalNetworkId
        The physical network ID (required; binds from a piped physical network's id)

    .PARAMETER TrafficType
        The traffic type to add: Public, Guest, Management, or Storage (required)

    .PARAMETER KvmNetworkLabel
        Name of the bridge carrying this traffic on KVM hosts, e.g. cloudbr0

    .PARAMETER VmwareNetworkLabel
        Name of the vSwitch/port group carrying this traffic on VMware hosts, e.g. vSwitch0

    .PARAMETER XenNetworkLabel
        Name of the network carrying this traffic on XenServer hosts

    .PARAMETER HypervNetworkLabel
        Name of the network carrying this traffic on Hyper-V hosts

    .PARAMETER Ovm3NetworkLabel
        Name of the network carrying this traffic on OVM3 hosts

    .PARAMETER IsolationMethod
        For Public traffic on a physical network with several isolation methods: vlan (default) or vxlan

    .PARAMETER Vlan
        The VLAN ID used for Management traffic by VMware hosts

    .PARAMETER Wait
        Wait for the async job to finish and return the new traffic type

    .EXAMPLE
        Add-CSTrafficType -PhysicalNetworkId pn-uuid -TrafficType Guest -KvmNetworkLabel cloudbr1
        Carries guest traffic over the cloudbr1 bridge on KVM hosts.

    .EXAMPLE
        Get-CSPhysicalNetwork -Name 'public-pn' | Add-CSTrafficType -TrafficType Public -KvmNetworkLabel cloudbr0 -VmwareNetworkLabel vSwitch0 -Wait
        Adds public traffic with labels for both KVM and VMware hosts and returns the result.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$PhysicalNetworkId,

        [Parameter(Mandatory = $true)]
        [ValidateSet('Public', 'Guest', 'Management', 'Storage')]
        [string]$TrafficType,

        [string]$KvmNetworkLabel,

        [string]$VmwareNetworkLabel,

        [string]$XenNetworkLabel,

        [string]$HypervNetworkLabel,

        [string]$Ovm3NetworkLabel,

        [ValidateSet('vlan', 'vxlan')]
        [string]$IsolationMethod,

        [string]$Vlan,

        [switch]$Wait
    )

    process {
        $apiParams = @{ physicalnetworkid = $PhysicalNetworkId; traffictype = $TrafficType }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            KvmNetworkLabel = 'kvmnetworklabel'; VmwareNetworkLabel = 'vmwarenetworklabel'
            XenNetworkLabel = 'xennetworklabel'; HypervNetworkLabel = 'hypervnetworklabel'
            Ovm3NetworkLabel = 'ovm3networklabel'; IsolationMethod = 'isolationmethod'; Vlan = 'vlan'
        })
        if ($PSCmdlet.ShouldProcess("physical network $PhysicalNetworkId", "Add $TrafficType traffic")) {
            Invoke-CSAsyncApiRequest -Command 'addTrafficType' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Set-CSTrafficType {
    <#
    .SYNOPSIS
        Updates the hypervisor network labels of a traffic type.

    .DESCRIPTION
        Changes which hypervisor network carries a traffic type (updateTrafficType).
        This is an asynchronous job; use -Wait to get the updated traffic type
        back. Accepts objects from Get-CSTrafficType on the pipeline.

    .PARAMETER Id
        The traffic type ID (required; binds from a piped traffic type's id)

    .PARAMETER KvmNetworkLabel
        Name of the bridge carrying this traffic on KVM hosts

    .PARAMETER VmwareNetworkLabel
        Name of the vSwitch/port group carrying this traffic on VMware hosts

    .PARAMETER XenNetworkLabel
        Name of the network carrying this traffic on XenServer hosts

    .PARAMETER HypervNetworkLabel
        Name of the network carrying this traffic on Hyper-V hosts

    .PARAMETER Ovm3NetworkLabel
        Name of the network carrying this traffic on OVM3 hosts

    .PARAMETER Wait
        Wait for the async job to finish and return the updated traffic type

    .EXAMPLE
        Set-CSTrafficType -Id tt-uuid -KvmNetworkLabel cloudbr2
        Moves a traffic type to the cloudbr2 bridge on KVM hosts.

    .EXAMPLE
        Get-CSTrafficType -PhysicalNetworkId pn-uuid | Where-Object traffictype -eq 'Guest' | Set-CSTrafficType -VmwareNetworkLabel 'vSwitch1' -Wait
        Changes the VMware label of the guest traffic type on a physical network.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [string]$KvmNetworkLabel,

        [string]$VmwareNetworkLabel,

        [string]$XenNetworkLabel,

        [string]$HypervNetworkLabel,

        [string]$Ovm3NetworkLabel,

        [switch]$Wait
    )

    process {
        $apiParams = @{ id = $Id }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            KvmNetworkLabel = 'kvmnetworklabel'; VmwareNetworkLabel = 'vmwarenetworklabel'
            XenNetworkLabel = 'xennetworklabel'; HypervNetworkLabel = 'hypervnetworklabel'
            Ovm3NetworkLabel = 'ovm3networklabel'
        })
        if ($PSCmdlet.ShouldProcess("traffic type $Id", 'Update')) {
            Invoke-CSAsyncApiRequest -Command 'updateTrafficType' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Remove-CSTrafficType {
    <#
    .SYNOPSIS
        Removes a traffic type from a physical network.

    .DESCRIPTION
        Deletes a traffic type (deleteTrafficType). This is an asynchronous job;
        use -Wait to block until it finishes. Accepts objects from
        Get-CSTrafficType on the pipeline.

    .PARAMETER Id
        The traffic type ID (required; binds from a piped traffic type's id)

    .PARAMETER Wait
        Wait for the async job to finish and return its result

    .EXAMPLE
        Remove-CSTrafficType -Id tt-uuid
        Removes a traffic type after prompting for confirmation.

    .EXAMPLE
        Get-CSTrafficType -PhysicalNetworkId pn-uuid | Where-Object traffictype -eq 'Storage' | Remove-CSTrafficType -Confirm:$false
        Removes storage traffic from a physical network without prompting.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("traffic type $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deleteTrafficType' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSTrafficTypeImplementor {
    <#
    .SYNOPSIS
        Lists which network element implements each traffic type.

    .DESCRIPTION
        Returns the implementor of each traffic type, or of one traffic type when
        -TrafficType is given (listTrafficTypeImplementors).

    .PARAMETER TrafficType
        Return only the implementor of this traffic type

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSTrafficTypeImplementor
        Lists the implementor of every traffic type.

    .EXAMPLE
        Get-CSTrafficTypeImplementor -TrafficType Guest
        Shows which element implements guest traffic.
    #>

    [CmdletBinding()]
    param(
        [ValidateSet('Public', 'Guest', 'Management', 'Storage')]
        [string]$TrafficType,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        TrafficType = 'traffictype'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listTrafficTypeImplementors' -Parameters $apiParams) -Command 'listTrafficTypeImplementors'
}

function Get-CSNetworkServiceProvider {
    <#
    .SYNOPSIS
        Lists network service providers.

    .DESCRIPTION
        Returns the network service providers (VirtualRouter, VpcVirtualRouter,
        InternalLbVm, ConfigDrive, ...) on physical networks
        (listNetworkServiceProviders). Accepts objects from Get-CSPhysicalNetwork
        on the pipeline.

    .PARAMETER PhysicalNetworkId
        Filter by physical network ID (binds from a piped physical network's id)

    .PARAMETER Name
        Filter by provider name, e.g. VirtualRouter

    .PARAMETER State
        Filter by provider state: Enabled, Disabled, or Shutdown

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSNetworkServiceProvider -PhysicalNetworkId pn-uuid
        Lists every provider on a physical network.

    .EXAMPLE
        Get-CSPhysicalNetwork -ZoneId zone-uuid | Get-CSNetworkServiceProvider -State Disabled
        Finds disabled providers on every physical network in a zone.
    #>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$PhysicalNetworkId,

        [string]$Name,

        [ValidateSet('Enabled', 'Disabled', 'Shutdown')]
        [string]$State,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    process {
        $apiParams = @{}
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            PhysicalNetworkId = 'physicalnetworkid'; Name = 'name'; State = 'state'; Keyword = 'keyword'
            Page = 'page'; PageSize = 'pagesize'
        })
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listNetworkServiceProviders' -Parameters $apiParams) -Command 'listNetworkServiceProviders'
    }
}

function Add-CSNetworkServiceProvider {
    <#
    .SYNOPSIS
        Adds a network service provider to a physical network.

    .DESCRIPTION
        Adds a provider such as Netscaler or a third-party SDN element to a
        physical network (addNetworkServiceProvider). New providers start
        Disabled; enable them with Set-CSNetworkServiceProvider -State Enabled.
        This is an asynchronous job; use -Wait to get the new provider back.
        Accepts objects from Get-CSPhysicalNetwork on the pipeline.

    .PARAMETER PhysicalNetworkId
        The physical network to add the provider to (required; binds from a piped physical network's id)

    .PARAMETER Name
        The provider name, e.g. Netscaler, BigSwitchBcf, Opendaylight (required)

    .PARAMETER ServiceList
        The services to enable on the provider, e.g. Lb, Firewall, SourceNat

    .PARAMETER DestinationPhysicalNetworkId
        The destination physical network to bridge to

    .PARAMETER Wait
        Wait for the async job to finish and return the new provider

    .EXAMPLE
        Add-CSNetworkServiceProvider -PhysicalNetworkId pn-uuid -Name Netscaler -ServiceList Lb -Wait
        Adds a Netscaler load-balancer provider and returns it.

    .EXAMPLE
        Get-CSPhysicalNetwork -Name 'guest-pn' | Add-CSNetworkServiceProvider -Name Opendaylight -ServiceList Connectivity
        Adds an OpenDaylight connectivity provider to a physical network found by name.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Id')]
        [string]$PhysicalNetworkId,

        [Parameter(Mandatory = $true)]
        [string]$Name,

        [string[]]$ServiceList,

        [string]$DestinationPhysicalNetworkId,

        [switch]$Wait
    )

    process {
        $apiParams = @{ physicalnetworkid = $PhysicalNetworkId; name = $Name }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            ServiceList = 'servicelist'; DestinationPhysicalNetworkId = 'destinationphysicalnetworkid'
        })
        if ($PSCmdlet.ShouldProcess("physical network $PhysicalNetworkId", "Add provider $Name")) {
            Invoke-CSAsyncApiRequest -Command 'addNetworkServiceProvider' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Set-CSNetworkServiceProvider {
    <#
    .SYNOPSIS
        Enables, disables, or changes the services of a network service provider.

    .DESCRIPTION
        Updates a network service provider's state or service list
        (updateNetworkServiceProvider). This is an asynchronous job; use -Wait to
        get the updated provider back. Accepts objects from
        Get-CSNetworkServiceProvider on the pipeline.

    .PARAMETER Id
        The provider ID (required; binds from a piped provider's id)

    .PARAMETER State
        Enabled, Disabled, or Shutdown

    .PARAMETER ServiceList
        The services to enable on the provider

    .PARAMETER Wait
        Wait for the async job to finish and return the updated provider

    .EXAMPLE
        Set-CSNetworkServiceProvider -Id nsp-uuid -State Enabled
        Enables a network service provider.

    .EXAMPLE
        Get-CSNetworkServiceProvider -PhysicalNetworkId pn-uuid -Name VirtualRouter | Set-CSNetworkServiceProvider -State Enabled -Wait
        Enables the virtual router provider on a physical network (a typical zone-setup step).
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [ValidateSet('Enabled', 'Disabled', 'Shutdown')]
        [string]$State,

        [string[]]$ServiceList,

        [switch]$Wait
    )

    process {
        $apiParams = @{ id = $Id }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            State = 'state'; ServiceList = 'servicelist'
        })
        if ($PSCmdlet.ShouldProcess("network service provider $Id", 'Update')) {
            Invoke-CSAsyncApiRequest -Command 'updateNetworkServiceProvider' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Remove-CSNetworkServiceProvider {
    <#
    .SYNOPSIS
        Deletes a network service provider.

    .DESCRIPTION
        Deletes a network service provider from its physical network
        (deleteNetworkServiceProvider). This is an asynchronous job; use -Wait to
        block until it finishes. Accepts objects from Get-CSNetworkServiceProvider
        on the pipeline.

    .PARAMETER Id
        The provider ID (required; binds from a piped provider's id)

    .PARAMETER Wait
        Wait for the async job to finish and return its result

    .EXAMPLE
        Remove-CSNetworkServiceProvider -Id nsp-uuid
        Deletes a provider after prompting for confirmation.

    .EXAMPLE
        Get-CSNetworkServiceProvider -PhysicalNetworkId pn-uuid -Name Netscaler | Remove-CSNetworkServiceProvider -Confirm:$false -Wait
        Removes the Netscaler provider from a physical network without prompting.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Id,

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("network service provider $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deleteNetworkServiceProvider' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSSupportedNetworkService {
    <#
    .SYNOPSIS
        Lists network services and the providers/capabilities that support them.

    .DESCRIPTION
        Returns every network service (Dhcp, Dns, Firewall, Lb, SourceNat, ...)
        with its providers and capabilities (listSupportedNetworkServices). Useful
        when building network offerings.

    .PARAMETER Service
        Only return this service, e.g. Lb or SourceNat

    .PARAMETER Provider
        Only return services supported by this provider, e.g. VirtualRouter

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSSupportedNetworkService
        Lists every network service with its providers and capabilities.

    .EXAMPLE
        Get-CSSupportedNetworkService -Service Lb | Select-Object -ExpandProperty provider
        Shows which providers can supply load balancing.

    .EXAMPLE
        Get-CSSupportedNetworkService -Provider VirtualRouter | Select-Object name
        Lists the services the virtual router can provide.
    #>

    [CmdletBinding()]
    param(
        [string]$Service,

        [string]$Provider,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Service = 'service'; Provider = 'provider'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listSupportedNetworkServices' -Parameters $apiParams) -Command 'listSupportedNetworkServices'
}

function Get-CSNetworkProtocol {
    <#
    .SYNOPSIS
        Lists IP protocol numbers or ICMP types.

    .DESCRIPTION
        Returns reference data for firewall/ACL rules (listNetworkProtocols):
        either the IP protocol numbers or the ICMP types and codes.

    .PARAMETER Option
        What to list: protocolnumber or icmptype (required)

    .EXAMPLE
        Get-CSNetworkProtocol -Option protocolnumber
        Lists IP protocol numbers and their names.

    .EXAMPLE
        Get-CSNetworkProtocol -Option icmptype
        Lists ICMP types and codes for building ICMP ACL rules.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateSet('protocolnumber', 'icmptype')]
        [string]$Option
    )

    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listNetworkProtocols' -Parameters @{ option = $Option }) -Command 'listNetworkProtocols'
}