Public/limit.ps1

# Resource-count recalculation. CloudStack tracks how much of each limit an
# owner has used; this recomputes those counts from what actually exists.

function Update-CSResourceCount {
    <#
    .SYNOPSIS
        Recalculates the tracked resource usage for an account, domain, or project.

    .DESCRIPTION
        Wraps updateResourceCount. CloudStack keeps a running count of each owner's
        resource usage to enforce limits; if that count drifts from reality (for
        example after a failed cleanup) this recounts what actually exists and
        returns the corrected numbers. -DomainId is required; narrow it further
        with -Account, -ProjectId, or -ResourceType. Accepts account, domain, and
        project objects on the pipeline.

    .PARAMETER DomainId
        The domain to recount (required). With -Account or -ProjectId, the scope of
        that owner.

    .PARAMETER Account
        Recount only this account. Used with -DomainId.

    .PARAMETER ProjectId
        Recount only this project

    .PARAMETER ResourceType
        Recount only this resource type. One of VirtualMachine, PublicIp, Volume,
        Snapshot, Template, Project, Network, Vpc, Cpu, Memory, PrimaryStorage,
        or SecondaryStorage. Omit to recount every type.

    .PARAMETER Tag
        Recount only the tagged resource limit for this resource tag

    .EXAMPLE
        Update-CSResourceCount -DomainId domain-uuid
        Recounts every resource type for a whole domain.

    .EXAMPLE
        Update-CSResourceCount -DomainId domain-uuid -Account 'engineering'
        Recounts one account after a limit looked wrong.

    .EXAMPLE
        Get-CSAccount -Name 'engineering' -DomainId domain-uuid | Update-CSResourceCount -ResourceType Volume
        Pipes an account in and recounts just its volumes.
    #>

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

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Alias('Name')]
        [string]$Account,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [string]$ProjectId,

        [ValidateSet('VirtualMachine', 'PublicIp', 'Volume', 'Snapshot', 'Template', 'Project',
            'Network', 'Vpc', 'Cpu', 'Memory', 'PrimaryStorage', 'SecondaryStorage')]
        [string]$ResourceType,

        [string]$Tag
    )

    process {
        $apiParams = @{ domainid = $DomainId }
        if ($PSBoundParameters.ContainsKey('ResourceType')) {
            $apiParams['resourcetype'] = ConvertTo-CSResourceTypeId -ResourceType $ResourceType
        }
        Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{
            Account = 'account'; ProjectId = 'projectid'; Tag = 'tag'
        })

        $owner = if ($ProjectId) { "project $ProjectId" } elseif ($Account) { "account $Account" } else { "domain $DomainId" }
        if ($PSCmdlet.ShouldProcess($owner, 'Recalculate resource counts')) {
            ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'updateResourceCount' -Parameters $apiParams) -Command 'updateResourceCount'
        }
    }
}