Public/cloud-zone.ps1

function Get-CloudZone {
    <#
    .SYNOPSIS
        Gets zones from the Cloud Server.
     
    .DESCRIPTION
        Retrieves a list of zones. Automatically handles token refresh.
     
    .PARAMETER Name
        Optional. Filter by zone name.
     
    .PARAMETER ID
        Optional. Filter by zone ID
     
    .EXAMPLE
        # Get all cloud zones
        Get-CloudZone
         
    .EXAMPLE
        # Get zone by ID
        Get-CloudZone -ID 5
         
    .EXAMPLE
        # Get zones matching a specific name string
        Get-CloudZone -Name "zone-1"
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $false)]
        [string]$Name,
        
        [Parameter(Mandatory = $false)]
        [int]$ID
    )
    
    # Build the URI
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/zone"
    
    # Filter by ID if specified
    if ($ID) {
        #$zoneuri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/zone/${ID}"
        $zoneuri = "$uri/${ID}"
        $response = Invoke-CloudApiRequest -Uri $zoneuri -Method Get
        
        # Extract zone from the response
        $zone = $response.zone  # Likely singular when querying by ID
        return $zone
    }
    else {
        # Use the helper function which handles token refresh automatically
        $response = Invoke-CloudApiRequest -Uri $uri -Method Get
        
        # Extract zones from the response
        $zones = $response.zones
        
        # Filter by name if specified
        if ($Name) {
            $zones = $zones | Where-Object { $_.name -like "*$Name*" }
        }
        
        return $zones
    }
}

function Get-CloudZoneRaft {
    <#
    .SYNOPSIS
        Gets zone rafts from the Cloud Server.
     
    .DESCRIPTION
        Retrieves a list of zone rafts. Automatically handles token refresh.
 
    .EXAMPLE
        # Get all zone rafts
        Get-CloudZoneRaft
    #>


    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/zone/raft"
    $response = Invoke-CloudApiRequest -Uri $uri -Method Get
    $zones = $response.status
    return $zones
}

function Rename-CloudZone {
    <#
    .SYNOPSIS
        Rename a zone in the Cloud Server.
     
    .DESCRIPTION
        Renames a zone. Automatically handles token refresh.
     
    .PARAMETER Name
        Required. New name of the zone
         
    .PARAMETER ID
        Required. ID of the zone
             
    .EXAMPLE
        # Rename cloud zone with the ID 5 to "new-name"
        Rename-CloudZone -Name "new-name" -ID 5
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,
        
        [Parameter(Mandatory = $true)]
        [int]$ID
    )
        
    $body = @{
        name = $Name
    }
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/zone/${ID}/name"
       
    #$response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $newname
    
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Zone" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action "Rename" `
            -GetResourceScript { Get-CloudZone -ID $ID }
}

function Enable-CloudZone {
    <#
    .SYNOPSIS
        Enable a zone in the Cloud Server.
     
    .DESCRIPTION
        Enables a zone. Automatically handles token refresh.
 
    .PARAMETER ID
        Required. ID of the zone
             
    .EXAMPLE
        # Enable cloud zone with the ID 5
        Enable-CloudZone -ID 5
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
      
        [Parameter(Mandatory = $true)]
        [int]$ID
    )
        
    $body = @{
        enable = $true
    }
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/zone/${ID}/enable"
           
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Zone" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action "Enable" `
            -GetResourceScript { Get-CloudZone -ID $ID }
}

function New-CloudZone {
    <#
    .SYNOPSIS
        Creates a new zone on the Cloud Server.
     
    .DESCRIPTION
        Creates a new zone with specified name and endpoint configuration.
     
    .PARAMETER Name
        Required. Name of the new zone.
     
    .PARAMETER Endpoint
        Required. RPC endpoint URL for the zone (e.g., "http://localhost:2633/RPC2").
     
    .PARAMETER Template
        Optional. Additional template configuration as a string.
     
    .EXAMPLE
        # Create basic zone
        New-CloudZone -Name "Production" -Endpoint "http://prod-host:2633/RPC2"
         
    .EXAMPLE
        # Create zone with custom template
        $template = @"
ENDPOINT = http://prod-host:2633/RPC2
PROVISION_DRIVER = ec2
"@
        New-CloudZone -Name "AWS-Zone" -Template $template
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,
        
        [Parameter(Mandatory = $false)]
        [string]$Endpoint,
        
        [Parameter(Mandatory = $false)]
        [string]$Template
    )
    
    # Build the template string
    $templateParts = @()
    
    # Name is required
    $templateParts += "NAME = $Name"
    
    # Add endpoint if provided
    if ($PSBoundParameters.ContainsKey('Endpoint')) {
        $templateParts += "ENDPOINT = $Endpoint"
    }
    
    # If custom template provided, use it instead
    if ($PSBoundParameters.ContainsKey('Template')) {
        $templateString = $Template
    } else {
        # Join all parts with newlines
        $templateString = $templateParts -join "`n"
    }
    
    # Build the configuration
    $config = [PSCustomObject]@{
        template = $templateString
    }
    
    # Build the URI
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v3-preview/cloud/zone"
    
    Write-Verbose "Creating zone '$Name'"
    Write-Verbose "Request body: $($config | ConvertTo-Json -Compress)"
    Write-Verbose "Template:`n$templateString"
    
    try {
        $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $config
        
        Write-Host "Zone '$Name' created successfully (ID: $($response.zone))." -ForegroundColor Green
        return $response
    }
    catch {
        Write-Error "Failed to create zone: $_"
        throw
    }
}

function Update-CloudZone {
    <#
    .SYNOPSIS
        Updates a zone on the Cloud Server.
     
    .DESCRIPTION
        Updates a zone's configuration. You can choose to merge with the existing configuration
        or replace it entirely. Merge is enabled by default.
         
    .PARAMETER ID
        Required. ID of the zone to update.
     
    .PARAMETER Name
        Optional. New name for the zone.
     
    .PARAMETER Endpoint
        Optional. New RPC endpoint URL for the zone.
     
    .PARAMETER Template
        Optional. Template configuration string to apply.
     
    .PARAMETER Merge
        Optional. If true (default), merges with existing configuration. If false, replaces entirely.
        Use -Merge:$false to completely replace the zone configuration.
         
    .EXAMPLE
        # Update zone endpoint
        Update-CloudZone -ID 0 -Endpoint "http://new-host:2633/RPC2"
         
    .EXAMPLE
        # Update zone name
        Update-CloudZone -ID 0 -Name "Production-Zone"
         
    .EXAMPLE
        # Replace entire zone configuration
        $template = @"
NAME = NewZone
ENDPOINT = http://new-host:2633/RPC2
PROVISION_DRIVER = ec2
"@
        Update-CloudZone -ID 0 -Template $template -Merge:$false
         
    .EXAMPLE
        # Update without confirmation
        Update-CloudZone -ID 0 -Endpoint "http://updated:2633/RPC2" -Confirm:$false
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $false)]
        [string]$Name,
        
        [Parameter(Mandatory = $false)]
        [string]$Endpoint,
        
        [Parameter(Mandatory = $false)]
        [string]$Template,
        
        [Parameter()]
        [bool]$Merge = $true
    )
    
    # Build the template string - only include specified parameters
    $templateParts = @()
    
    # If custom template provided, use it
    if ($PSBoundParameters.ContainsKey('Template')) {
        $templateString = $Template
    }
    else {
        # Build from individual parameters
        if ($PSBoundParameters.ContainsKey('Name')) {
            $templateParts += "NAME = $Name"
        }
        
        if ($PSBoundParameters.ContainsKey('Endpoint')) {
            $templateParts += "ENDPOINT = $Endpoint"
        }
        
        # Only proceed if there are changes to make
        if ($templateParts.Count -eq 0) {
            Write-Warning "No parameters specified for update. Please specify at least one parameter to update."
            return
        }
        
        # Join all parts with newlines
        $templateString = $templateParts -join "`n"
    }
    
    # Build the request body
    $body = @{
        merge = $Merge
        template = $templateString
    }
    
    # Build the URI
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v3-preview/cloud/zone/${ID}"
    
    Write-Verbose "Request URI: $uri"
    Write-Verbose "Merge: $Merge"
    Write-Verbose "Template:`n$templateString"
    
    try {
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Zone" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action "Update" `
            -GetResourceScript { Get-CloudZone -ID $ID }
        Write-Verbose "Successfully updated zone ID: $ID"
        Write-Host "Zone ID $ID updated successfully." -ForegroundColor Green
    }
    catch {
        Write-Error "Failed to update zone '$ID': $_"
        throw
    }
}

function Remove-CloudZone {
    <#
    .SYNOPSIS
        Deletes a zone from the Cloud Server.
     
    .DESCRIPTION
        Permanently deletes a zone. This operation cannot be undone and will prompt
        for confirmation unless -Confirm:$false is specified.
         
    .PARAMETER ID
        Required. ID of the zone to delete.
         
    .EXAMPLE
        # Delete a zone (will prompt for confirmation)
        Remove-CloudZone -ID 5
         
    .EXAMPLE
        # Delete without confirmation
        Remove-CloudZone -ID 5 -Confirm:$false
         
    .EXAMPLE
        # Delete multiple zones
        5,6,7 | Remove-CloudZone
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$ID
    )
    
    process {
        # Build the URI
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v3-preview/cloud/zone/${ID}"
        
        # Get zone info for confirmation message
        try {
            $zone = Get-CloudZone -ID $ID
            $zoneName = $zone.name
        }
        catch {
            $zoneName = "ID $ID"
        }
        
        if ($PSCmdlet.ShouldProcess("Zone '$zoneName' (ID: $ID)", "Delete")) {
            Write-Verbose "Deleting zone ID: $ID"
            
            try {
                $response = Invoke-CloudApiRequest -Uri $uri -Method Delete
                
                Write-Host "Zone '$zoneName' (ID: $ID) deleted successfully." -ForegroundColor Green
                return $response
            }
            catch {
                Write-Error "Failed to delete zone '$ID': $_"
                throw
            }
        }
    }
}