Public/cluster.ps1

function New-CSCluster {
    <#
    .SYNOPSIS
        Adds a cluster to a pod.

    .DESCRIPTION
        Wraps the addCluster API, creating a compute cluster of a single hypervisor
        type within a pod and zone. For a VMware cluster, supply the vCenter
        connection details (-VsmIpAddress, -VsmUsername, -VsmPassword and the switch
        names).

    .PARAMETER ClusterName
        Name for the new cluster.

    .PARAMETER Hypervisor
        Hypervisor type: KVM, XenServer, VMware, Simulator, or BareMetal.

    .PARAMETER PodId
        The pod the cluster belongs to.

    .PARAMETER ZoneId
        The zone the cluster belongs to.

    .PARAMETER AllocationState
        Initial allocation state: Enabled, Disabled, or Unmanaged.

    .PARAMETER GuestVswitchName
        VMware guest traffic vSwitch name.

    .PARAMETER Name
        VMware cluster path/name in vCenter.

    .PARAMETER PublicVswitchName
        VMware public traffic vSwitch name.

    .PARAMETER VsmIpAddress
        vCenter (VSM) IP address for a VMware cluster.

    .PARAMETER VsmPassword
        vCenter (VSM) password for a VMware cluster.

    .PARAMETER VsmUsername
        vCenter (VSM) username for a VMware cluster.

    .EXAMPLE
        New-CSCluster -ClusterName 'compute-a' -Hypervisor KVM -PodId pod-uuid -ZoneId zone-uuid
        Adds a KVM cluster to a pod.

    .EXAMPLE
        New-CSCluster -ClusterName 'vmw-a' -Hypervisor VMware -PodId $podId -ZoneId $zoneId -Name 'dc/cluster1' -VsmIpAddress '10.0.0.9' -VsmUsername 'administrator@vsphere.local' -VsmPassword $pw
        Adds a VMware cluster with its vCenter connection details.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)][string]$ClusterName,
        [Parameter(Mandatory=$true)][ValidateSet('KVM','XenServer','VMware','Simulator','BareMetal')][string]$Hypervisor,
        [Parameter(Mandatory=$true)][string]$PodId,
        [Parameter(Mandatory=$true)][string]$ZoneId,
        [ValidateSet('Enabled','Disabled','Unmanaged')][string]$AllocationState,
        [string]$GuestVswitchName,
        [string]$Name,
        [string]$PublicVswitchName,
        [string]$VsmIpAddress,
        [string]$VsmPassword,
        [string]$VsmUsername
    )
    $p=@{clustername=$ClusterName;hypervisor=$Hypervisor;podid=$PodId;zoneid=$ZoneId}
    foreach($k in @('AllocationState','GuestVswitchName','Name','PublicVswitchName','VsmIpAddress','VsmPassword','VsmUsername')){if($PSBoundParameters.ContainsKey($k)){$p[$k.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
    Invoke-CSApiRequest -Command addCluster -Parameters $p
}

function Remove-CSCluster {
    <#
    .SYNOPSIS
        Deletes a cluster.

    .DESCRIPTION
        Wraps the deleteCluster API. The cluster must be empty (no hosts) before it
        can be removed. Accepts cluster objects on the pipeline by their id.

    .PARAMETER Id
        The cluster to delete. Binds from a piped cluster's id.

    .EXAMPLE
        Remove-CSCluster -Id cluster-uuid
        Deletes a cluster after prompting for confirmation.

    .EXAMPLE
        Get-CSCluster -Name 'compute-a' | Remove-CSCluster
        Deletes a cluster located by name.
    #>

    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string]$Id
    )
    process {
        if($PSCmdlet.ShouldProcess("cluster $Id",'Delete')){Invoke-CSApiRequest -Command deleteCluster -Parameters @{id=$Id}}
    }
}

function Disable-CSClusterHA {
    <#
    .SYNOPSIS
        Disables host high availability for a cluster.

    .DESCRIPTION
        Wraps the disableHAForCluster API, turning off HA for every host in the
        cluster. Accepts cluster objects on the pipeline by their id.

    .PARAMETER Id
        The cluster to disable HA on. Binds from a piped cluster's id.

    .EXAMPLE
        Disable-CSClusterHA -Id cluster-uuid
        Disables HA for a cluster.

    .EXAMPLE
        Get-CSCluster -Name 'compute-a' | Disable-CSClusterHA
        Disables HA for a cluster located by name.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string]$Id
    )
    process {
        Invoke-CSApiRequest -Command disableHAForCluster -Parameters @{id=$Id}
    }
}

function Enable-CSClusterHA {
    <#
    .SYNOPSIS
        Enables host high availability for a cluster.

    .DESCRIPTION
        Wraps the enableHAForCluster API, turning on HA for every host in the
        cluster. Accepts cluster objects on the pipeline by their id.

    .PARAMETER Id
        The cluster to enable HA on. Binds from a piped cluster's id.

    .EXAMPLE
        Enable-CSClusterHA -Id cluster-uuid
        Enables HA for a cluster.

    .EXAMPLE
        Get-CSCluster -Name 'compute-a' | Enable-CSClusterHA
        Enables HA for a cluster located by name.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string]$Id
    )
    process {
        Invoke-CSApiRequest -Command enableHAForCluster -Parameters @{id=$Id}
    }
}

function Set-CSCluster {
    <#
    .SYNOPSIS
        Updates a cluster.

    .DESCRIPTION
        Wraps the updateCluster API. Only the attributes you supply are changed; use
        -ManagedState to put the cluster into or out of managed mode. Accepts cluster
        objects on the pipeline by their id.

    .PARAMETER Id
        The cluster to update. Binds from a piped cluster's id.

    .PARAMETER AllocationState
        New allocation state: Enabled, Disabled, or Unmanaged.

    .PARAMETER ClusterName
        New name for the cluster.

    .PARAMETER Hypervisor
        Hypervisor type: KVM, XenServer, VMware, Hyperv, BareMetal, or Simulator.

    .PARAMETER ManagedState
        Managed or Unmanaged.

    .PARAMETER Arch
        CPU architecture: x86_64 or aarch64.

    .EXAMPLE
        Set-CSCluster -Id cluster-uuid -AllocationState Enabled
        Enables a cluster for allocation.

    .EXAMPLE
        Get-CSCluster -Name 'compute-a' | Set-CSCluster -ManagedState Unmanaged
        Puts a cluster into unmanaged mode.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string]$Id,
        [ValidateSet('Enabled','Disabled','Unmanaged')][string]$AllocationState,
        [string]$ClusterName,
        [ValidateSet('KVM','XenServer','VMware','Hyperv','BareMetal','Simulator')][string]$Hypervisor,
        [ValidateSet('Managed','Unmanaged')][string]$ManagedState,
        [ValidateSet('x86_64','aarch64')][string]$Arch
    )
    process {
        $p=@{id=$Id}
        foreach($k in @('AllocationState','ClusterName','Hypervisor','ManagedState','Arch')){if($PSBoundParameters.ContainsKey($k)){$n=$k.ToLowerInvariant();$p[$n]=(Get-Variable $k -ValueOnly)}}
        Invoke-CSApiRequest -Command updateCluster -Parameters $p
    }
}

function Set-CSClusterDedicated {
    <#
    .SYNOPSIS
        Dedicates a cluster to a domain or account.

    .DESCRIPTION
        Wraps the dedicateCluster API, reserving a cluster so only the given domain
        (or -Account within it) can run instances on it. Release it again with
        Clear-CSClusterDedicated. Accepts cluster objects on the pipeline by their id.

    .PARAMETER ClusterId
        The cluster to dedicate. Binds from a piped cluster's id.

    .PARAMETER DomainId
        The domain to dedicate the cluster to.

    .PARAMETER Account
        Dedicate the cluster to this account within -DomainId.

    .PARAMETER ProjectId
        Dedicate the cluster to this project.

    .EXAMPLE
        Set-CSClusterDedicated -ClusterId cluster-uuid -DomainId domain-uuid
        Dedicates a cluster to a domain.

    .EXAMPLE
        Get-CSCluster -Name 'compute-a' | Set-CSClusterDedicated -DomainId $domainId -Account 'engineering'
        Dedicates a cluster piped in by object to one account.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][Alias('Id')][string]$ClusterId,
        [Parameter(Mandatory=$true)][string]$DomainId,
        [string]$Account,
        [string]$ProjectId
    )
    process {
        $p=@{clusterid=$ClusterId;domainid=$DomainId}
        foreach($k in @('Account','ProjectId')){if($PSBoundParameters.ContainsKey($k)){$p[$k.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
        Invoke-CSApiRequest -Command dedicateCluster -Parameters $p
    }
}

function Clear-CSClusterDedicated {
    <#
    .SYNOPSIS
        Releases a cluster's dedication back to the system.

    .DESCRIPTION
        Wraps the releaseDedicatedCluster API, undoing a dedication made with
        Set-CSClusterDedicated so any account can run instances on the cluster again.
        Accepts cluster objects on the pipeline by their id.

    .PARAMETER ClusterId
        The cluster to release. Binds from a piped cluster's id.

    .EXAMPLE
        Clear-CSClusterDedicated -ClusterId cluster-uuid
        Releases a cluster's dedication.

    .EXAMPLE
        Get-CSClusterDedicated -DomainId $domainId | Clear-CSClusterDedicated
        Releases every cluster dedicated to a domain.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][Alias('Id')][string]$ClusterId
    )
    process {
        Invoke-CSApiRequest -Command releaseDedicatedCluster -Parameters @{clusterid=$ClusterId}
    }
}

function Get-CSCluster {
    <#
    .SYNOPSIS
        Lists clusters with optional filters.

    .DESCRIPTION
        Wraps the listClusters API. Filter by id, name, pod, zone, hypervisor, or
        allocation state.

    .PARAMETER Id
        Filter by cluster ID.

    .PARAMETER Name
        Filter by cluster name.

    .PARAMETER PodId
        Filter by pod ID.

    .PARAMETER ZoneId
        Filter by zone ID.

    .PARAMETER Hypervisor
        Filter by hypervisor type.

    .PARAMETER Keyword
        Filter by keyword.

    .PARAMETER AllocationState
        Filter by allocation state.

    .PARAMETER ListAll
        List all clusters the caller is allowed to see.

    .PARAMETER Page
        Page number of results to return.

    .PARAMETER PageSize
        Number of results per page.

    .EXAMPLE
        Get-CSCluster -ZoneId zone-uuid
        Lists the clusters in a zone.

    .EXAMPLE
        Get-CSCluster -Hypervisor KVM -ListAll
        Lists every KVM cluster the caller can see.
    #>

    [CmdletBinding()]
    param(
        [string]$Id,
        [string]$Name,
        [string]$PodId,
        [string]$ZoneId,
        [string]$Hypervisor,
        [string]$Keyword,
        [string]$AllocationState,
        [switch]$ListAll,
        [int]$Page,
        [int]$PageSize
    )
    $p=@{}
    foreach($k in @('Id','Name','PodId','ZoneId','Hypervisor','Keyword','AllocationState','Page','PageSize')){if($PSBoundParameters.ContainsKey($k)){$n=$k.ToLowerInvariant();if($k -eq 'Id'){$n='id'};$p[$n]=(Get-Variable $k -ValueOnly)}}
    if($ListAll){$p.listall='true'}
    $r=Invoke-CSApiRequest -Command listClusters -Parameters $p
    if($r.listclustersresponse.cluster){$r.listclustersresponse.cluster}
}

function Get-CSClusterMetrics {
    <#
    .SYNOPSIS
        Lists cluster metrics.

    .DESCRIPTION
        Wraps the listClustersMetrics API: the same rows as Get-CSCluster plus
        rolled-up CPU, memory, and storage usage and thresholds.

    .PARAMETER Id
        Filter by cluster ID.

    .PARAMETER Name
        Filter by cluster name.

    .PARAMETER ZoneId
        Filter by zone ID.

    .PARAMETER Page
        Page number of results to return.

    .PARAMETER PageSize
        Number of results per page.

    .EXAMPLE
        Get-CSClusterMetrics -ZoneId zone-uuid
        Lists cluster metrics for a zone.

    .EXAMPLE
        Get-CSClusterMetrics | Sort-Object cpuused -Descending
        Ranks clusters by CPU usage.
    #>

    [CmdletBinding()]
    param(
        [string]$Id,
        [string]$Name,
        [string]$ZoneId,
        [int]$Page,
        [int]$PageSize
    )
    $p=@{}
    foreach($k in @('Id','Name','ZoneId','Page','PageSize')){if($PSBoundParameters.ContainsKey($k)){$p[$k.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
    $r=Invoke-CSApiRequest -Command listClustersMetrics -Parameters $p
    if($r.listclustersmetricsresponse.cluster){$r.listclustersmetricsresponse.cluster}
}

function Get-CSClusterDedicated {
    <#
    .SYNOPSIS
        Lists clusters dedicated to domains or accounts.

    .DESCRIPTION
        Wraps the listDedicatedClusters API, showing which clusters have been
        reserved for which accounts or domains.

    .PARAMETER ClusterId
        Filter by cluster ID.

    .PARAMETER Name
        Filter by name.

    .PARAMETER ZoneId
        Filter by zone ID.

    .PARAMETER Account
        Filter by account name.

    .PARAMETER DomainId
        Filter by domain ID.

    .PARAMETER Page
        Page number of results to return.

    .PARAMETER PageSize
        Number of results per page.

    .EXAMPLE
        Get-CSClusterDedicated -ZoneId zone-uuid
        Lists the dedicated clusters in a zone.

    .EXAMPLE
        Get-CSClusterDedicated -DomainId domain-uuid
        Lists the clusters dedicated to a domain.
    #>

    [CmdletBinding()]
    param(
        [string]$ClusterId,
        [string]$Name,
        [string]$ZoneId,
        [string]$Account,
        [string]$DomainId,
        [int]$Page,
        [int]$PageSize
    )
    $p=@{}
    foreach($k in @('ClusterId','Name','ZoneId','Account','DomainId','Page','PageSize')){if($PSBoundParameters.ContainsKey($k)){$n=$k -replace 'ClusterId$','clusterid' -replace 'ZoneId$','zoneid' -replace 'DomainId$','domainid';$p[$n.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
    $r=Invoke-CSApiRequest -Command listDedicatedClusters -Parameters $p
    if($r.listdedicatedclustersresponse.cluster){$r.listdedicatedclustersresponse.cluster}
}

function New-CSClusterDrsPlan {
    <#
    .SYNOPSIS
        Generates a DRS (load-balancing) migration plan for a cluster.

    .DESCRIPTION
        Wraps the generateClusterDrsPlan API, returning the VM-to-host migrations DRS
        would perform to balance a cluster, without executing them. Run the plan with
        Invoke-CSClusterDrsPlan.

    .PARAMETER ClusterId
        The cluster to generate a plan for.

    .PARAMETER Action
        The DRS action to plan.

    .PARAMETER Plan
        The DRS plan type.

    .PARAMETER Preference
        The DRS balancing preference.

    .PARAMETER VirtualMachineId
        Limit the plan to a single virtual machine.

    .EXAMPLE
        New-CSClusterDrsPlan -ClusterId cluster-uuid
        Generates a DRS migration plan for a cluster.

    .EXAMPLE
        New-CSClusterDrsPlan -ClusterId $clusterId -VirtualMachineId $vmId
        Generates a plan focused on one virtual machine.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)][string]$ClusterId,
        [string]$Action,
        [string]$Plan,
        [string]$Preference,
        [string]$VirtualMachineId
    )
    $p=@{clusterid=$ClusterId}
    foreach($k in @('Action','Plan','Preference','VirtualMachineId')){if($PSBoundParameters.ContainsKey($k)){$p[$k.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
    Invoke-CSApiRequest -Command generateClusterDrsPlan -Parameters $p
}

function Invoke-CSClusterDrsPlan {
    <#
    .SYNOPSIS
        Executes a DRS migration plan for a cluster.

    .DESCRIPTION
        Wraps the executeClusterDrsPlan API, carrying out VM-to-host migrations to
        balance a cluster. Supply -MigrateTo as a hashtable whose entries each have a
        VirtualMachineId and a HostId; with no -MigrateTo, CloudStack runs its own
        generated plan. Accepts cluster objects on the pipeline by their id.

    .PARAMETER ClusterId
        The cluster to balance. Binds from a piped cluster's id.

    .PARAMETER MigrateTo
        A hashtable of migrations, each entry exposing VirtualMachineId and HostId.

    .EXAMPLE
        Invoke-CSClusterDrsPlan -ClusterId cluster-uuid
        Executes CloudStack's generated DRS plan for a cluster.

    .EXAMPLE
        Invoke-CSClusterDrsPlan -ClusterId $clusterId -MigrateTo @{ 0 = @{ VirtualMachineId = $vmId; HostId = $hostId } }
        Executes an explicit VM-to-host migration.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][Alias('Id')][string]$ClusterId,
        [hashtable]$MigrateTo
    )
    process {
        $p=@{id=$ClusterId}
        if($PSBoundParameters.ContainsKey('MigrateTo')){foreach($key in $MigrateTo.Keys){$p["migrateto[$key].vm"]=$MigrateTo[$key].VirtualMachineId;$p["migrateto[$key].host"]=$MigrateTo[$key].HostId}}
        Invoke-CSApiRequest -Command executeClusterDrsPlan -Parameters $p
    }
}

function Get-CSClusterDrsPlan {
    <#
    .SYNOPSIS
        Lists DRS plans for a cluster.

    .DESCRIPTION
        Wraps the listClusterDrsPlan API, returning the DRS migration plans generated
        or executed for a cluster.

    .PARAMETER ClusterId
        The cluster whose DRS plans to list.

    .PARAMETER Id
        Filter by DRS plan ID.

    .PARAMETER Keyword
        Filter by keyword.

    .PARAMETER Page
        Page number of results to return.

    .PARAMETER PageSize
        Number of results per page.

    .EXAMPLE
        Get-CSClusterDrsPlan -ClusterId cluster-uuid
        Lists the DRS plans for a cluster.

    .EXAMPLE
        Get-CSClusterDrsPlan -ClusterId $clusterId -Id plan-uuid
        Gets a single DRS plan by ID.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)][string]$ClusterId,
        [string]$Id,
        [string]$Keyword,
        [int]$Page,
        [int]$PageSize
    )
    $p=@{clusterid=$ClusterId}
    foreach($k in @('Id','Keyword','Page','PageSize')){if($PSBoundParameters.ContainsKey($k)){$p[$k.ToLowerInvariant()]=(Get-Variable $k -ValueOnly)}}
    $r=Invoke-CSApiRequest -Command listClusterDrsPlan -Parameters $p
    if($r.listclusterdrsplanresponse.clusterdrsplan){$r.listclusterdrsplanresponse.clusterdrsplan}
}