Public/network-devices.ps1

function Add-CSGloboDnsHost {
    <#
    .SYNOPSIS
        Registers a GloboDNS host with a physical network.

    .DESCRIPTION
        Adds the external GloboDNS server that provides DNS for networks on a
        physical network (addGloboDnsHost). The GloboDns network service provider
        must already exist on the physical network. This is an asynchronous job;
        use -Wait to get the result back instead of the job handle. Accepts
        objects from Get-CSPhysicalNetwork on the pipeline.

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

    .PARAMETER Url
        The GloboDNS API URL (required)

    .PARAMETER Credential
        Username and password for the GloboDNS API (required)

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

    .EXAMPLE
        Add-CSGloboDnsHost -PhysicalNetworkId pn-uuid -Url 'https://globodns.example.com' -Credential (Get-Credential)
        Registers a GloboDNS server, prompting for its credentials.

    .EXAMPLE
        $cred = [pscredential]::new('cloudstack', (Read-Host -AsSecureString 'GloboDNS password'))
        Get-CSPhysicalNetwork -Name 'guest-pn' | Add-CSGloboDnsHost -Url 'https://globodns.example.com' -Credential $cred -Wait
        Registers a GloboDNS server on a physical network found by name and waits for the result.
    #>

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

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

        [Parameter(Mandatory = $true)]
        [pscredential]$Credential,

        [switch]$Wait
    )

    process {
        $apiParams = @{
            physicalnetworkid = $PhysicalNetworkId
            url               = $Url
            username          = $Credential.UserName
            password          = $Credential.GetNetworkCredential().Password
        }
        if ($PSCmdlet.ShouldProcess("physical network $PhysicalNetworkId", "Add GloboDNS host $Url")) {
            Invoke-CSAsyncApiRequest -Command 'addGloboDnsHost' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Get-CSOpenDaylightController {
    <#
    .SYNOPSIS
        Lists OpenDaylight controllers.

    .DESCRIPTION
        Returns the OpenDaylight SDN controllers registered with CloudStack
        (listOpenDaylightControllers).

    .PARAMETER Id
        Filter by controller ID

    .PARAMETER PhysicalNetworkId
        Filter by physical network ID

    .EXAMPLE
        Get-CSOpenDaylightController
        Lists every OpenDaylight controller.

    .EXAMPLE
        Get-CSOpenDaylightController -PhysicalNetworkId pn-uuid
        Lists the controllers attached to one physical network.
    #>

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

        [string]$PhysicalNetworkId
    )

    $apiParams = @{}
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Id = 'id'; PhysicalNetworkId = 'physicalnetworkid'
    })
    ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listOpenDaylightControllers' -Parameters $apiParams) -Command 'listOpenDaylightControllers'
}

function Add-CSOpenDaylightController {
    <#
    .SYNOPSIS
        Registers an OpenDaylight controller with a physical network.

    .DESCRIPTION
        Adds an OpenDaylight SDN controller to a physical network
        (addOpenDaylightController). The Opendaylight network service provider
        must already exist on the physical network. This is an asynchronous job;
        use -Wait to get the new controller 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 Url
        The OpenDaylight controller API URL (required)

    .PARAMETER Credential
        Username and password for the OpenDaylight API (required)

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

    .EXAMPLE
        Add-CSOpenDaylightController -PhysicalNetworkId pn-uuid -Url 'https://odl.example.com:8181' -Credential (Get-Credential) -Wait
        Registers an OpenDaylight controller, prompting for its credentials, and returns it.
    #>

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

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

        [Parameter(Mandatory = $true)]
        [pscredential]$Credential,

        [switch]$Wait
    )

    process {
        $apiParams = @{
            physicalnetworkid = $PhysicalNetworkId
            url               = $Url
            username          = $Credential.UserName
            password          = $Credential.GetNetworkCredential().Password
        }
        if ($PSCmdlet.ShouldProcess("physical network $PhysicalNetworkId", "Add OpenDaylight controller $Url")) {
            Invoke-CSAsyncApiRequest -Command 'addOpenDaylightController' -Parameters $apiParams -Wait:$Wait
        }
    }
}

function Remove-CSOpenDaylightController {
    <#
    .SYNOPSIS
        Removes an OpenDaylight controller.

    .DESCRIPTION
        Deletes an OpenDaylight controller (deleteOpenDaylightController). This is
        an asynchronous job; use -Wait to block until it finishes. Accepts objects
        from Get-CSOpenDaylightController on the pipeline.

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

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

    .EXAMPLE
        Remove-CSOpenDaylightController -Id odl-uuid
        Removes a controller after prompting for confirmation.

    .EXAMPLE
        Get-CSOpenDaylightController -PhysicalNetworkId pn-uuid | Remove-CSOpenDaylightController -Confirm:$false
        Removes every controller 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("OpenDaylight controller $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deleteOpenDaylightController' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSCiscoNexusVSM {
    <#
    .SYNOPSIS
        Lists Cisco Nexus 1000v VSM appliances.

    .DESCRIPTION
        Returns the Cisco Nexus 1000v Virtual Supervisor Modules registered with
        CloudStack for VMware clusters (listCiscoNexusVSMs).

    .PARAMETER ClusterId
        Filter by CloudStack cluster ID

    .PARAMETER ZoneId
        Filter by zone ID

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSCiscoNexusVSM -ZoneId zone-uuid
        Lists the Nexus 1000v VSMs in a zone.

    .EXAMPLE
        Get-CSCiscoNexusVSM -ClusterId cluster-uuid
        Shows the VSM managing one VMware cluster.
    #>

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

        [string]$ZoneId,

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

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

function Enable-CSCiscoNexusVSM {
    <#
    .SYNOPSIS
        Enables a Cisco Nexus 1000v VSM appliance.

    .DESCRIPTION
        Enables a Cisco Nexus 1000v VSM (enableCiscoNexusVSM). This is an
        asynchronous job; use -Wait to get the updated VSM back. Accepts objects
        from Get-CSCiscoNexusVSM on the pipeline.

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

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

    .EXAMPLE
        Enable-CSCiscoNexusVSM -Id vsm-uuid -Wait
        Enables a VSM and returns it.

    .EXAMPLE
        Get-CSCiscoNexusVSM -ZoneId zone-uuid | Enable-CSCiscoNexusVSM
        Enables every VSM in a zone.
    #>

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

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("Cisco Nexus VSM $Id", 'Enable')) {
            Invoke-CSAsyncApiRequest -Command 'enableCiscoNexusVSM' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Disable-CSCiscoNexusVSM {
    <#
    .SYNOPSIS
        Disables a Cisco Nexus 1000v VSM appliance.

    .DESCRIPTION
        Disables a Cisco Nexus 1000v VSM (disableCiscoNexusVSM). This is an
        asynchronous job; use -Wait to get the updated VSM back. Accepts objects
        from Get-CSCiscoNexusVSM on the pipeline.

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

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

    .EXAMPLE
        Disable-CSCiscoNexusVSM -Id vsm-uuid
        Disables a VSM.

    .EXAMPLE
        Get-CSCiscoNexusVSM -ClusterId cluster-uuid | Disable-CSCiscoNexusVSM -Wait
        Disables the VSM of one cluster and waits for the result.
    #>

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

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("Cisco Nexus VSM $Id", 'Disable')) {
            Invoke-CSAsyncApiRequest -Command 'disableCiscoNexusVSM' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Remove-CSCiscoNexusVSM {
    <#
    .SYNOPSIS
        Deletes a Cisco Nexus 1000v VSM appliance.

    .DESCRIPTION
        Removes a Cisco Nexus 1000v VSM from CloudStack (deleteCiscoNexusVSM).
        This is an asynchronous job; use -Wait to block until it finishes. Accepts
        objects from Get-CSCiscoNexusVSM on the pipeline.

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

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

    .EXAMPLE
        Remove-CSCiscoNexusVSM -Id vsm-uuid
        Deletes a VSM after prompting for confirmation.

    .EXAMPLE
        Get-CSCiscoNexusVSM -ClusterId cluster-uuid | Remove-CSCiscoNexusVSM -Confirm:$false -Wait
        Deletes the VSM of one cluster without prompting.
    #>

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

        [switch]$Wait
    )

    process {
        if ($PSCmdlet.ShouldProcess("Cisco Nexus VSM $Id", 'Delete')) {
            Invoke-CSAsyncApiRequest -Command 'deleteCiscoNexusVSM' -Parameters @{ id = $Id } -Wait:$Wait
        }
    }
}

function Get-CSTrafficMonitor {
    <#
    .SYNOPSIS
        Lists traffic monitor hosts in a zone.

    .DESCRIPTION
        Returns the traffic monitor hosts used for direct network usage metering
        in a zone (listTrafficMonitors). Accepts zone objects from Get-CSZone on
        the pipeline.

    .PARAMETER ZoneId
        The zone ID (required; binds from a piped zone's id)

    .PARAMETER Keyword
        Filter by keyword

    .PARAMETER Page
        Page number of results to return

    .PARAMETER PageSize
        Number of results per page

    .EXAMPLE
        Get-CSTrafficMonitor -ZoneId zone-uuid
        Lists the traffic monitors in a zone.

    .EXAMPLE
        Get-CSZone | Get-CSTrafficMonitor
        Lists the traffic monitors in every zone.
    #>

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

        [string]$Keyword,

        [int]$Page,

        [int]$PageSize
    )

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

function Add-CSTrafficMonitor {
    <#
    .SYNOPSIS
        Adds a traffic monitor host for direct network usage metering.

    .DESCRIPTION
        Registers a traffic monitor (e.g. an Inmon sFlow collector) that meters
        direct network usage in a zone (addTrafficMonitor).

    .PARAMETER ZoneId
        The zone to add the traffic monitor to (required)

    .PARAMETER Url
        The URL of the traffic monitor host (required)

    .PARAMETER IncludeZones
        Only meter traffic going to these zones

    .PARAMETER ExcludeZones
        Do not meter traffic going to these zones

    .EXAMPLE
        Add-CSTrafficMonitor -ZoneId zone-uuid -Url 'http://10.0.0.20:8080'
        Adds a traffic monitor to a zone.

    .EXAMPLE
        Add-CSTrafficMonitor -ZoneId zone-uuid -Url 'http://10.0.0.20:8080' -ExcludeZones 'zone-a', 'zone-b'
        Adds a traffic monitor that does not meter traffic going to two other zones.
    #>

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

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

        [string[]]$IncludeZones,

        [string[]]$ExcludeZones
    )

    $apiParams = @{ zoneid = $ZoneId; url = $Url }
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        IncludeZones = 'includezones'; ExcludeZones = 'excludezones'
    })
    if ($PSCmdlet.ShouldProcess("zone $ZoneId", "Add traffic monitor $Url")) {
        ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'addTrafficMonitor' -Parameters $apiParams) -Command 'addTrafficMonitor'
    }
}

function Remove-CSTrafficMonitor {
    <#
    .SYNOPSIS
        Removes a traffic monitor host.

    .DESCRIPTION
        Deletes a traffic monitor host (deleteTrafficMonitor). Accepts objects
        from Get-CSTrafficMonitor on the pipeline.

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

    .EXAMPLE
        Remove-CSTrafficMonitor -Id monitor-uuid
        Removes a traffic monitor after prompting for confirmation.

    .EXAMPLE
        Get-CSTrafficMonitor -ZoneId zone-uuid | Remove-CSTrafficMonitor -Confirm:$false
        Removes every traffic monitor in a zone without prompting.
    #>

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

    process {
        if ($PSCmdlet.ShouldProcess("traffic monitor $Id", 'Delete')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'deleteTrafficMonitor' -Parameters @{ id = $Id }) -Command 'deleteTrafficMonitor'
        }
    }
}

function New-CSServiceInstance {
    <#
    .SYNOPSIS
        Creates a service instance (network service appliance VM).

    .DESCRIPTION
        Deploys a service appliance VM that sits between two networks
        (createServiceInstance), used for service chaining with Tungsten
        Fabric/Contrail. This is an asynchronous job; use -Wait to get the new
        service instance back.

    .PARAMETER Name
        The name of the service instance (required)

    .PARAMETER ZoneId
        The zone to deploy the service instance in (required)

    .PARAMETER LeftNetworkId
        The left (inside) network (required)

    .PARAMETER RightNetworkId
        The right (outside) network (required)

    .PARAMETER ServiceOfferingId
        The service offering that sizes the appliance (required)

    .PARAMETER TemplateId
        The template with the appliance image (required)

    .PARAMETER Account
        The account that will own the appliance. Must be used with -DomainId.

    .PARAMETER DomainId
        The domain of -Account. Required when -Account is used.

    .PARAMETER ProjectId
        The project that will own the appliance

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

    .EXAMPLE
        New-CSServiceInstance -Name 'fw-01' -ZoneId zone-uuid -LeftNetworkId inside-net-uuid -RightNetworkId outside-net-uuid -ServiceOfferingId so-uuid -TemplateId fw-template-uuid -Wait
        Deploys a firewall appliance between an inside and an outside network.
    #>

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

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

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

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

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

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

        [string]$Account,

        [string]$DomainId,

        [string]$ProjectId,

        [switch]$Wait
    )

    if ($Account -and -not $DomainId) {
        throw '-Account must be used together with -DomainId.'
    }
    $apiParams = @{
        name              = $Name
        zoneid            = $ZoneId
        leftnetworkid     = $LeftNetworkId
        rightnetworkid    = $RightNetworkId
        serviceofferingid = $ServiceOfferingId
        templateid        = $TemplateId
    }
    Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
        Account = 'account'; DomainId = 'domainid'; ProjectId = 'projectid'
    })
    if ($PSCmdlet.ShouldProcess("service instance $Name in zone $ZoneId", 'Create')) {
        Invoke-CSAsyncApiRequest -Command 'createServiceInstance' -Parameters $apiParams -Wait:$Wait
    }
}