Public/diskoffering.ps1

function Get-CSDiskOffering {
    <#
    .SYNOPSIS
        Lists disk offerings in CloudStack.
    
    .DESCRIPTION
        Retrieves a list of disk offerings with optional filtering by ID, name,
        state, storage type, or other parameters.
    
    .PARAMETER Id
        Filter by disk offering ID
    
    .PARAMETER Name
        Filter by disk offering name (exact match)
    
    .PARAMETER Keyword
        Filter by keyword (partial match on name)
    
    .PARAMETER State
        Filter by state of the disk offering. Defaults to 'Active'.
        If set to 'all' shows both Active & Inactive offerings.
    
    .PARAMETER StorageType
        The storage type of the disk offering. Values are local and shared.
    
    .PARAMETER ZoneId
        Filter by zone ID
    
    .PARAMETER DomainId
        Filter by domain ID
    
    .PARAMETER Encrypt
        Filter offerings that support disk encryption
    
    .PARAMETER StorageId
        The ID of the storage pool, tags of the storage pool are used to filter the offerings
    
    .PARAMETER VirtualMachineId
        The ID of a virtual machine. Returns suitable disk offerings for the VM.
    
    .PARAMETER VolumeId
        The ID of the volume, tags of the volume are used to filter the offerings
    
    .PARAMETER ListAll
        If set to true - list resources that the caller is authorized to see.
        Default value is false.
    
    .EXAMPLE
        Get-CSDiskOffering
        Lists all active disk offerings
    
    .EXAMPLE
        Get-CSDiskOffering -Name "Standard Disk"
        Gets a specific disk offering by name
    
    .EXAMPLE
        Get-CSDiskOffering -State all
        Lists all disk offerings including inactive ones
    
    .EXAMPLE
        Get-CSDiskOffering -StorageType shared -Encrypt $true
        Lists shared storage offerings that support encryption
    #>

    [CmdletBinding(DefaultParameterSetName='Default')]
    param(
        [Parameter(ParameterSetName='ById')]
        [string]$Id,
        
        [Parameter(ParameterSetName='ByName')]
        [string]$Name,
        
        [Parameter(ParameterSetName='Default')]
        [string]$Keyword,
        
        [Parameter(ParameterSetName='Default')]
        [string]$State,
        
        [Parameter(ParameterSetName='Default')]
        [ValidateSet('local', 'shared')]
        [string]$StorageType,
        
        [Parameter(ParameterSetName='Default')]
        [string]$ZoneId,
        
        [Parameter(ParameterSetName='Default')]
        [string]$DomainId,
        
        [Parameter(ParameterSetName='Default')]
        [bool]$Encrypt,
        
        [Parameter(ParameterSetName='Default')]
        [string]$StorageId,
        
        [Parameter(ParameterSetName='Default')]
        [string]$VirtualMachineId,
        
        [Parameter(ParameterSetName='Default')]
        [string]$VolumeId,
        
        [Parameter(ParameterSetName='Default')]
        [switch]$ListAll
    )
    
    # Build parameters
    $apiParams = @{}
    
    if ($PSBoundParameters.ContainsKey('Id')) {
        $apiParams['id'] = $Id
    }
    
    if ($PSBoundParameters.ContainsKey('Name')) {
        $apiParams['name'] = $Name
    }
    
    if ($PSBoundParameters.ContainsKey('Keyword')) {
        $apiParams['keyword'] = $Keyword
    }
    
    if ($PSBoundParameters.ContainsKey('State')) {
        $apiParams['state'] = $State
    }
    
    if ($PSBoundParameters.ContainsKey('StorageType')) {
        $apiParams['storagetype'] = $StorageType
    }
    
    if ($PSBoundParameters.ContainsKey('ZoneId')) {
        $apiParams['zoneid'] = $ZoneId
    }
    
    if ($PSBoundParameters.ContainsKey('DomainId')) {
        $apiParams['domainid'] = $DomainId
    }
    
    if ($PSBoundParameters.ContainsKey('Encrypt')) {
        $apiParams['encrypt'] = $Encrypt.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('StorageId')) {
        $apiParams['storageid'] = $StorageId
    }
    
    if ($PSBoundParameters.ContainsKey('VirtualMachineId')) {
        $apiParams['virtualmachineid'] = $VirtualMachineId
    }
    
    if ($PSBoundParameters.ContainsKey('VolumeId')) {
        $apiParams['volumeid'] = $VolumeId
    }
    
    if ($ListAll) {
        $apiParams['listall'] = 'true'
    }
    
    # Make the API call
    $response = Invoke-CSApiRequest -Command 'listDiskOfferings' -Parameters $apiParams
    Write-Verbose "API Parameters: $($apiParams | Out-String)"
    
    # Return the disk offering list
    if ($response.listdiskofferingsresponse.diskoffering) {
        return $response.listdiskofferingsresponse.diskoffering
    }
    else {
        Write-Verbose "No disk offerings found matching the criteria."
        return $null
    }
}

function New-CSDiskOffering {
    <#
    .SYNOPSIS
        Creates a disk offering in CloudStack.
    
    .DESCRIPTION
        Creates a new disk offering with specified size, IOPS, and other configuration options.
    
    .PARAMETER Name
        The name of the disk offering (required)
    
    .PARAMETER DisplayText
        The display text of the disk offering, defaults to Name if not specified
    
    .PARAMETER DiskSize
        Size of the disk offering in GB
    
    .PARAMETER Customized
        Whether disk offering size is custom or not
    
    .PARAMETER CustomizedIops
        Whether disk offering IOPS is custom or not
    
    .PARAMETER StorageType
        The storage type of the disk offering. Values are local and shared.
    
    .PARAMETER ProvisioningType
        Provisioning type used to create volumes. Valid values are thin, sparse, fat.
    
    .PARAMETER Encrypt
        Volumes using this offering should be encrypted
    
    .PARAMETER DiskSizeStrictness
        To allow or disallow the resize operation on disks created from this offering
    
    .PARAMETER DisplayOffering
        Whether to display the offering to the end user or not
    
    .PARAMETER Tags
        Tags for the disk offering (comma-separated)
    
    .PARAMETER CacheMode
        The cache mode to use. Values: none, writeback, writethrough, hypervisor default
    
    .PARAMETER MinIops
        Min IOPS of the disk offering
    
    .PARAMETER MaxIops
        Max IOPS of the disk offering
    
    .PARAMETER BytesReadRate
        Bytes read rate of the disk offering
    
    .PARAMETER BytesReadRateMax
        Burst bytes read rate of the disk offering
    
    .PARAMETER BytesReadRateMaxLength
        Length (in seconds) of the read burst
    
    .PARAMETER BytesWriteRate
        Bytes write rate of the disk offering
    
    .PARAMETER BytesWriteRateMax
        Burst bytes write rate of the disk offering
    
    .PARAMETER BytesWriteRateMaxLength
        Length (in seconds) of the write burst
    
    .PARAMETER IopsReadRate
        IO requests read rate of the disk offering
    
    .PARAMETER IopsReadRateMax
        Burst IO requests read rate of the disk offering
    
    .PARAMETER IopsReadRateMaxLength
        Length (in seconds) of the read IOPS burst
    
    .PARAMETER IopsWriteRate
        IO requests write rate of the disk offering
    
    .PARAMETER IopsWriteRateMax
        Burst IO requests write rate of the disk offering
    
    .PARAMETER IopsWriteRateMaxLength
        Length (in seconds) of the write IOPS burst
    
    .PARAMETER HypervisorSnapshotReserve
        Hypervisor snapshot reserve space as a percent of a volume (for Xen or VMware)
    
    .PARAMETER ZoneId
        The ID of the containing zone(s), null for public offerings
    
    .PARAMETER DomainId
        The ID of the containing domain(s), null for public offerings
    
    .EXAMPLE
        New-CSDiskOffering -IopsReadRateMax 5000 -IopsWriteRateMax 5000 -Name "TV-IO-API-TEST" -StorageType "shared" -ProvisioningType "thin" -Customized $true -DisplayText "TV API Disk Offering Test"
        Creates a new disk offering with limited IO

    .EXAMPLE
        New-CSDiskOffering -Name "Standard-100GB" -DiskSize 100 -StorageType shared
        Creates a 100GB shared storage disk offering
    
    .EXAMPLE
        New-CSDiskOffering -Name "Custom-Disk" -Customized $true -DisplayText "Custom Size Disk"
        Creates a customized disk offering where users can specify size
    
    .EXAMPLE
        New-CSDiskOffering -Name "Fast-SSD" -DiskSize 50 -MinIops 1000 -MaxIops 5000 -Encrypt $true
        Creates an encrypted 50GB disk offering with IOPS limits
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory=$true)]
        [string]$Name,
        
        [string]$DisplayText,
        
        [int]$DiskSize,
        
        [bool]$Customized,
        
        [bool]$CustomizedIops,
        
        [ValidateSet('local', 'shared')]
        [string]$StorageType,
        
        [ValidateSet('thin', 'sparse', 'fat')]
        [string]$ProvisioningType,
        
        [bool]$Encrypt,
        
        [bool]$DiskSizeStrictness,
        
        [bool]$DisplayOffering,
        
        [string]$Tags,
        
        [ValidateSet('none', 'writeback', 'writethrough', 'hypervisor default')]
        [string]$CacheMode,
        
        [int]$MinIops,
        
        [int]$MaxIops,
        
        [int]$BytesReadRate,
        
        [int]$BytesReadRateMax,
        
        [int]$BytesReadRateMaxLength,
        
        [int]$BytesWriteRate,
        
        [int]$BytesWriteRateMax,
        
        [int]$BytesWriteRateMaxLength,
        
        [int]$IopsReadRate,
        
        [int]$IopsReadRateMax,
        
        [int]$IopsReadRateMaxLength,
        
        [int]$IopsWriteRate,
        
        [int]$IopsWriteRateMax,
        
        [int]$IopsWriteRateMaxLength,
        
        [int]$HypervisorSnapshotReserve,
        
        [string]$ZoneId,
        
        [string]$DomainId
    )
    
    # Build parameters
    $apiParams = @{
        'name' = $Name
    }
    
    if ($PSBoundParameters.ContainsKey('DisplayText')) {
        $apiParams['displaytext'] = $DisplayText
    }
    
    if ($PSBoundParameters.ContainsKey('DiskSize')) {
        $apiParams['disksize'] = $DiskSize
    }
    
    if ($PSBoundParameters.ContainsKey('Customized')) {
        $apiParams['customized'] = $Customized.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('CustomizedIops')) {
        $apiParams['customizediops'] = $CustomizedIops.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('StorageType')) {
        $apiParams['storagetype'] = $StorageType
    }
    
    if ($PSBoundParameters.ContainsKey('ProvisioningType')) {
        $apiParams['provisioningtype'] = $ProvisioningType
    }
    
    if ($PSBoundParameters.ContainsKey('Encrypt')) {
        $apiParams['encrypt'] = $Encrypt.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('DiskSizeStrictness')) {
        $apiParams['disksizestrictness'] = $DiskSizeStrictness.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('DisplayOffering')) {
        $apiParams['displayoffering'] = $DisplayOffering.ToString().ToLower()
    }
    
    if ($PSBoundParameters.ContainsKey('Tags')) {
        $apiParams['tags'] = $Tags
    }
    
    if ($PSBoundParameters.ContainsKey('CacheMode')) {
        $apiParams['cachemode'] = $CacheMode
    }
    
    if ($PSBoundParameters.ContainsKey('MinIops')) {
        $apiParams['miniops'] = $MinIops
    }
    
    if ($PSBoundParameters.ContainsKey('MaxIops')) {
        $apiParams['maxiops'] = $MaxIops
    }
    
    if ($PSBoundParameters.ContainsKey('BytesReadRate')) {
        $apiParams['bytesreadrate'] = $BytesReadRate
    }
    
    if ($PSBoundParameters.ContainsKey('BytesReadRateMax')) {
        $apiParams['bytesreadratemax'] = $BytesReadRateMax
    }
    
    if ($PSBoundParameters.ContainsKey('BytesReadRateMaxLength')) {
        $apiParams['bytesreadratemaxlength'] = $BytesReadRateMaxLength
    }
    
    if ($PSBoundParameters.ContainsKey('BytesWriteRate')) {
        $apiParams['byteswriterate'] = $BytesWriteRate
    }
    
    if ($PSBoundParameters.ContainsKey('BytesWriteRateMax')) {
        $apiParams['byteswriteratemax'] = $BytesWriteRateMax
    }
    
    if ($PSBoundParameters.ContainsKey('BytesWriteRateMaxLength')) {
        $apiParams['byteswriteratemaxlength'] = $BytesWriteRateMaxLength
    }
    
    if ($PSBoundParameters.ContainsKey('IopsReadRate')) {
        $apiParams['iopsreadrate'] = $IopsReadRate
    }
    
    if ($PSBoundParameters.ContainsKey('IopsReadRateMax')) {
        $apiParams['iopsreadratemax'] = $IopsReadRateMax
    }
    
    if ($PSBoundParameters.ContainsKey('IopsReadRateMaxLength')) {
        $apiParams['iopsreadratemaxlength'] = $IopsReadRateMaxLength
    }
    
    if ($PSBoundParameters.ContainsKey('IopsWriteRate')) {
        $apiParams['iopswriterate'] = $IopsWriteRate
    }
    
    if ($PSBoundParameters.ContainsKey('IopsWriteRateMax')) {
        $apiParams['iopswriteratemax'] = $IopsWriteRateMax
    }
    
    if ($PSBoundParameters.ContainsKey('IopsWriteRateMaxLength')) {
        $apiParams['iopswriteratemaxlength'] = $IopsWriteRateMaxLength
    }
    
    if ($PSBoundParameters.ContainsKey('HypervisorSnapshotReserve')) {
        $apiParams['hypervisorsnapshotreserve'] = $HypervisorSnapshotReserve
    }
    
    if ($PSBoundParameters.ContainsKey('ZoneId')) {
        $apiParams['zoneid'] = $ZoneId
    }
    
    if ($PSBoundParameters.ContainsKey('DomainId')) {
        $apiParams['domainid'] = $DomainId
    }
    
    # Make the API call
    if ($PSCmdlet.ShouldProcess($Name, "Create disk offering")) {
        $response = Invoke-CSApiRequest -Command 'createDiskOffering' -Parameters $apiParams
        Write-Verbose "API Parameters: $($apiParams | Out-String)"
        
        # Return the created disk offering
        if ($response.creatediskofferingresponse.diskoffering) {
            return $response.creatediskofferingresponse.diskoffering
        }
        else {
            Write-Error "Failed to create disk offering."
            return $null
        }
    }
}

function Set-CSDiskOffering {
    <#
    .SYNOPSIS
        Updates a disk offering in CloudStack.
    
    .DESCRIPTION
        Updates properties of an existing disk offering such as name,
        display text, state, or tags.
    
    .PARAMETER Id
        The ID of the disk offering to be updated (required)
    
    .PARAMETER Name
        The new name of the disk offering
    
    .PARAMETER DisplayText
        The new display text of the disk offering
    
    .PARAMETER State
        The new state of the disk offering
    
    .PARAMETER Tags
        Comma-separated list of tags for the disk offering
    
    .PARAMETER SortKey
        Sort key of the disk offering (integer)
    
    .PARAMETER DisplayOffering
        Whether to display the offering to the end user or not
    
    .PARAMETER CacheMode
        The cache mode to use for this disk offering
    
    .PARAMETER BytesReadRate
        Bytes read rate of the disk offering
    
    .PARAMETER BytesReadRateMax
        Burst bytes read rate of the disk offering
    
    .PARAMETER BytesReadRateMaxLength
        Length (in seconds) of the read burst
    
    .PARAMETER BytesWriteRate
        Bytes write rate of the disk offering
    
    .PARAMETER BytesWriteRateMax
        Burst bytes write rate of the disk offering
    
    .PARAMETER BytesWriteRateMaxLength
        Length (in seconds) of the write burst
    
    .PARAMETER IopsReadRate
        IO requests read rate of the disk offering
    
    .PARAMETER IopsReadRateMax
        Burst IO requests read rate of the disk offering
    
    .PARAMETER IopsReadRateMaxLength
        Length (in seconds) of the read IOPS burst
    
    .PARAMETER IopsWriteRate
        IO requests write rate of the disk offering
    
    .PARAMETER IopsWriteRateMax
        Burst IO requests write rate of the disk offering
    
    .PARAMETER IopsWriteRateMaxLength
        Length (in seconds) of the write IOPS burst
    
    .PARAMETER ZoneId
        The ID of the containing zone(s) as comma separated string,
        "all" for all zones offerings
    
    .PARAMETER DomainId
        The ID of the containing domain(s) as comma separated string,
        "public" for public offerings
    
    .EXAMPLE
        Set-CSDiskOffering -Id "abc-123" -Name "NewName"
        Updates the name of a disk offering
    
    .EXAMPLE
        Set-CSDiskOffering -Id "abc-123" -State "Inactive"
        Disables a disk offering
    
    .EXAMPLE
        Set-CSDiskOffering -Id "abc-123" -DisplayText "Updated description" -Tags "ssd,fast"
        Updates display text and tags
    #>

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

        [string]$Name,

        [string]$DisplayText,

        [string]$State,

        [string]$Tags,

        [int]$SortKey,

        [bool]$DisplayOffering,

        [string]$CacheMode,

        [int]$BytesReadRate,

        [int]$BytesReadRateMax,

        [int]$BytesReadRateMaxLength,

        [int]$BytesWriteRate,

        [int]$BytesWriteRateMax,

        [int]$BytesWriteRateMaxLength,

        [int]$IopsReadRate,

        [int]$IopsReadRateMax,

        [int]$IopsReadRateMaxLength,

        [int]$IopsWriteRate,

        [int]$IopsWriteRateMax,

        [int]$IopsWriteRateMaxLength,

        [string]$ZoneId,

        [string]$DomainId
    )

    process {
        # Build parameters
        $apiParams = @{
            'id' = $Id
        }

        if ($PSBoundParameters.ContainsKey('Name')) {
            $apiParams['name'] = $Name
        }

        if ($PSBoundParameters.ContainsKey('DisplayText')) {
            $apiParams['displaytext'] = $DisplayText
        }

        if ($PSBoundParameters.ContainsKey('State')) {
            $apiParams['state'] = $State
        }

        if ($PSBoundParameters.ContainsKey('Tags')) {
            $apiParams['tags'] = $Tags
        }

        if ($PSBoundParameters.ContainsKey('SortKey')) {
            $apiParams['sortkey'] = $SortKey
        }

        if ($PSBoundParameters.ContainsKey('DisplayOffering')) {
            $apiParams['displayoffering'] = $DisplayOffering.ToString().ToLower()
        }

        if ($PSBoundParameters.ContainsKey('CacheMode')) {
            $apiParams['cachemode'] = $CacheMode
        }

        if ($PSBoundParameters.ContainsKey('BytesReadRate')) {
            $apiParams['bytesreadrate'] = $BytesReadRate
        }

        if ($PSBoundParameters.ContainsKey('BytesReadRateMax')) {
            $apiParams['bytesreadratemax'] = $BytesReadRateMax
        }

        if ($PSBoundParameters.ContainsKey('BytesReadRateMaxLength')) {
            $apiParams['bytesreadratemaxlength'] = $BytesReadRateMaxLength
        }

        if ($PSBoundParameters.ContainsKey('BytesWriteRate')) {
            $apiParams['byteswriterate'] = $BytesWriteRate
        }

        if ($PSBoundParameters.ContainsKey('BytesWriteRateMax')) {
            $apiParams['byteswriteratemax'] = $BytesWriteRateMax
        }

        if ($PSBoundParameters.ContainsKey('BytesWriteRateMaxLength')) {
            $apiParams['byteswriteratemaxlength'] = $BytesWriteRateMaxLength
        }

        if ($PSBoundParameters.ContainsKey('IopsReadRate')) {
            $apiParams['iopsreadrate'] = $IopsReadRate
        }

        if ($PSBoundParameters.ContainsKey('IopsReadRateMax')) {
            $apiParams['iopsreadratemax'] = $IopsReadRateMax
        }

        if ($PSBoundParameters.ContainsKey('IopsReadRateMaxLength')) {
            $apiParams['iopsreadratemaxlength'] = $IopsReadRateMaxLength
        }

        if ($PSBoundParameters.ContainsKey('IopsWriteRate')) {
            $apiParams['iopswriterate'] = $IopsWriteRate
        }

        if ($PSBoundParameters.ContainsKey('IopsWriteRateMax')) {
            $apiParams['iopswriteratemax'] = $IopsWriteRateMax
        }

        if ($PSBoundParameters.ContainsKey('IopsWriteRateMaxLength')) {
            $apiParams['iopswriteratemaxlength'] = $IopsWriteRateMaxLength
        }

        if ($PSBoundParameters.ContainsKey('ZoneId')) {
            $apiParams['zoneid'] = $ZoneId
        }

        if ($PSBoundParameters.ContainsKey('DomainId')) {
            $apiParams['domainid'] = $DomainId
        }

        # Make the API call
        if ($PSCmdlet.ShouldProcess($Id, "Update disk offering")) {
            $response = Invoke-CSApiRequest -Command 'updateDiskOffering' -Parameters $apiParams
            Write-Verbose "API Parameters: $($apiParams | Out-String)"

            # Return the updated disk offering
            if ($response.updatediskofferingresponse.diskoffering) {
                return $response.updatediskofferingresponse.diskoffering
            }
            else {
                Write-Error "Failed to update disk offering."
                return $null
            }
        }
    }
}

function Remove-CSDiskOffering {
    <#
    .SYNOPSIS
        Deletes a disk offering in CloudStack.
    
    .DESCRIPTION
        Deletes a disk offering. The offering must not be in use by any volumes.
    
    .PARAMETER Id
        The ID of the disk offering to delete (required)
    
    .PARAMETER Force
        Skip confirmation prompt
    
    .EXAMPLE
        Remove-CSDiskOffering -Id "abc-123"
        Deletes a disk offering with confirmation
    
    .EXAMPLE
        Remove-CSDiskOffering -Id "abc-123" -Force
        Deletes a disk offering without confirmation
    
    .EXAMPLE
        Get-CSDiskOffering -Name "Old-Disk" | Remove-CSDiskOffering
        Deletes a disk offering via pipeline
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [string]$Id,
        
        [switch]$Force
    )
    
    process {
        # Build parameters
        $apiParams = @{
            'id' = $Id
        }
        
        # Confirmation handling
        $confirmMessage = "Are you sure you want to delete disk offering '$Id'?"
        $shouldProcessMessage = "Delete disk offering"
        
        if ($Force) {
            $ConfirmPreference = 'None'
        }
        
        # Make the API call
        if ($PSCmdlet.ShouldProcess($Id, $shouldProcessMessage)) {
            $response = Invoke-CSApiRequest -Command 'deleteDiskOffering' -Parameters $apiParams
            Write-Verbose "API Parameters: $($apiParams | Out-String)"
            
            # Return the result
            if ($response.deletediskofferingresponse) {
                return $response.deletediskofferingresponse
            }
            else {
                Write-Error "Failed to delete disk offering."
                return $null
            }
        }
    }
}