Public/cloud-group.ps1

# Define aliases
Set-Alias -Name Add-CloudGroupAdmin -value New-CloudGroupAdmin

function Get-CloudGroup {
    <#
    .SYNOPSIS
        Gets groups from the Cloud Server.
     
    .DESCRIPTION
        Retrieves a list of groups. Automatically handles token refresh.
     
    .PARAMETER Name
        Optional. Filter by group name.
     
    .PARAMETER ID
        Optional. Filter by group ID
     
    .EXAMPLE
        # Get all groups
        Get-CloudGroup
         
    .EXAMPLE
        # Get a group by ID
        Get-CloudGroup -ID 5
         
    .EXAMPLE
        # Get groups that match a specific name string
        Get-CloudGroup -Name "admins"
 
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $false)]
        [string]$Name,
        
        [Parameter(Mandatory = $false)]
        [Nullable[int]]$ID
    )
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group"
    
    if ($PSBoundParameters.ContainsKey('ID')) {
        $response = Invoke-CloudApiRequest -Uri $uri -Method Get
        
        $group = $response.groups | Where-Object {($_.id -eq $ID) -and ($null -ne $_.id)}
        return $group
    }
    else {
        $response = Invoke-CloudApiRequest -Uri $uri -Method Get
        $groups = $response.groups
        
        if ($Name) {
            $groups = $groups | Where-Object { $_.name -like "*$Name*" }
        }
        
        return $groups
    }
}

function Get-CloudGroupQuota {
    <#
    .SYNOPSIS
        Gets the default group quota from the Cloud Server.
     
    .DESCRIPTION
        Retrieves the quota for the default group. Automatically handles token refresh.
         
    .EXAMPLE
        # Get the quota for the default group
        Get-CloudGroupQuota
    #>

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

#function Update-CloudGroupQuota2 {
# <#
# .SYNOPSIS
# Updates the default group quota limits on the Cloud Server.
#
# .DESCRIPTION
# Updates quota limits for the default group. You can update instance quotas,
# datastore quotas, and network quotas. Automatically handles token refresh.
#
# .PARAMETER InstanceQuota
# Hashtable containing instance quota limits (cpu, memory, running_cpu, running_memory,
# running_instances, system_disk_size, instances).
#
# .PARAMETER DatastoreQuota
# Hashtable containing datastore quota limits.
#
# .PARAMETER NetworkQuota
# Hashtable containing network quota limits.
#
# .EXAMPLE
# Update-CloudGroupQuota -InstanceQuota @{
# cpu = 100
# memory = 204800
# running_cpu = 50
# running_memory = 102400
# running_instances = 10
# system_disk_size = 1000000
# instances = 20
# }
#
# .EXAMPLE
# # Update only specific quota values
# Update-CloudGroupQuota -InstanceQuota @{
# running_instances = 15
# instances = 30
# }
# #>
#
# [CmdletBinding(SupportsShouldProcess)]
# param(
# [Parameter()]
# [hashtable]$InstanceQuota,
#
# [Parameter()]
# [hashtable]$DatastoreQuota,
#
# [Parameter()]
# [hashtable]$NetworkQuota
# )
#
# # Build the quota object
# $quotaBody = @{}
#
# if ($InstanceQuota) {
# $quotaBody['instance_quota'] = $InstanceQuota
# }
#
# if ($DatastoreQuota) {
# $quotaBody['datastore_quota'] = $DatastoreQuota
# }
#
# if ($NetworkQuota) {
# $quotaBody['network_quota'] = $NetworkQuota
# }
#
# if ($quotaBody.Count -eq 0) {
# Write-Error "At least one quota type must be specified (InstanceQuota, DatastoreQuota, or NetworkQuota)"
# return
# }
#
# $body = @{
# quota = $quotaBody
# } #| ConvertTo-Json -Depth 10
#
#
# $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/quota"
#
# if ($PSCmdlet.ShouldProcess("Default group quota", "Update")) {
# $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $body
# write-host $body
# return $response#.quota
# }
#}
#
function New-CloudGroup {
    <#
    .SYNOPSIS
        Creates a group on the Cloud Server.
         
    .DESCRIPTION
        Creates a new cloud group. Automatically handles token refresh.
     
    .PARAMETER Name
        Required. Name of the group to be created
         
    .EXAMPLE
        # Create a new group
        New-CloudGroup -Name "Accounting"
         
    #>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name
        
    )
    
    process {
        # Build the group object
        $body = @{
            name = $Name
        }
        
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group"
        
        if ($PSCmdlet.ShouldProcess("Group '$Name'", "Create new group")) {
            try {
                $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $body
                
                Write-Verbose "Successfully created group '$Groupname' with ID: $($response.id)"
                # Return the newly created group
                Get-CloudGroup -ID $response.group
            }
            catch {
                Write-Error "Failed to create group '$Groupname': $_"
                throw
            }
        }
    }
}

function Remove-CloudGroup {
    <#
    .SYNOPSIS
        Removes a group from the Cloud Server.
     
    .DESCRIPTION
        Removes a group. Automatically handles token refresh.
     
    .PARAMETER ID
        Required. Group ID.
     
    .EXAMPLE
        # Remove group with confirmation prompt (default behavior):
        Remove-CloudGroup -ID 3
        Confirm
        Are you sure you want to perform this action?
        Performing the operation "Remove Group" on target "Group ID 3 (MyGroup)".
        [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
 
    .EXAMPLE
        # Remove group without confirmation prompt:
        Remove-CloudGroup -ID 3 -Confirm:$false
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$ID
    )
    
    process {
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}"
        
        Invoke-CloudResourceRemoval `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Group" `
            -ID $ID `
            -Uri $uri `
            -GetResourceScript { Get-CloudGroup -ID $ID }
    }
}

function Update-CloudGroupQuota {
    <#
    .SYNOPSIS
        Updates the default group quota limits on the Cloud Server.
     
    .DESCRIPTION
        Updates quota limits for the default group. You can update instance quotas,
        datastore quotas, and network quotas. Automatically handles token refresh.
         
    .PARAMETER InstanceQuota
        Hashtable containing instance quota limits (cpu, memory, running_cpu, running_memory,
        running_instances, system_disk_size, instances).
         
    .PARAMETER DatastoreQuota
        Hashtable containing datastore quota limits.
         
    .PARAMETER NetworkQuota
        Hashtable containing network quota limits.
         
    .EXAMPLE
        # Update a group's quota
        Update-CloudGroupQuota -InstanceQuota @{
            cpu = 100
            memory = 204800
            running_cpu = 50
            running_memory = 102400
            running_instances = 10
            system_disk_size = 1000000
            instances = 20
        }
 
    .EXAMPLE
        # Update only specific quota values
        Update-CloudGroupQuota -InstanceQuota @{
            running_instances = 15
            instances = 30
        }
    #>

    
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter()]
        [hashtable]$InstanceQuota,
        
        [Parameter()]
        [hashtable]$DatastoreQuota,
        
        [Parameter()]
        [hashtable]$NetworkQuota
    )
    
    # Build the template string in OpenNebula format
    $templateLines = @()
    
    if ($InstanceQuota) {
        $quotaItems = $InstanceQuota.GetEnumerator() | ForEach-Object { 
            " $($_.Key.ToUpper()) = `"$($_.Value)`"" 
        }
        $templateLines += "INSTANCE_QUOTA = ["
        $templateLines += $quotaItems -join ",`n"
        $templateLines += "]"
    }
    
    if ($DatastoreQuota) {
        $quotaItems = $DatastoreQuota.GetEnumerator() | ForEach-Object { 
            " $($_.Key.ToUpper()) = `"$($_.Value)`"" 
        }
        $templateLines += "DATASTORE_QUOTA = ["
        $templateLines += $quotaItems -join ",`n"
        $templateLines += "]"
    }
    
    if ($NetworkQuota) {
        $quotaItems = $NetworkQuota.GetEnumerator() | ForEach-Object { 
            " $($_.Key.ToUpper()) = `"$($_.Value)`"" 
        }
        $templateLines += "NETWORK_QUOTA = ["
        $templateLines += $quotaItems -join ",`n"
        $templateLines += "]"
    }
    
    if ($templateLines.Count -eq 0) {
        Write-Error "At least one quota type must be specified (InstanceQuota, DatastoreQuota, or NetworkQuota)"
        return
    }
    
    $templateString = $templateLines -join "`n"
    
    # Create body hashtable
    $body = @{
        template = $templateString
    }
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/quota"
    
    if ($PSCmdlet.ShouldProcess("Default group quota", "Update")) {
        $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $body
        return $response.quota
    }
}

function New-CloudGroupAdmin {
    <#
    .SYNOPSIS
        Defines an admin in a group on the Cloud Server.
         
    .DESCRIPTION
         Defines an admin in a group. Automatically handles token refresh.
     
    .PARAMETER ID
        Required. ID of the group to be created
         
    .PARAMETER User
        Required. ID of the user to make group admin
         
    .EXAMPLE
        # Define a user a group admin
        New-CloudGroupAdmin -ID 102 -User 12
         
    #>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
    param(
        [Parameter(Mandatory = $true)]
        [int]$ID,

        [Parameter(Mandatory = $true)]
        [int]$User
    )
    
    process {
        # Build the group object
        $body = @{
            user = $User
        }
        
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}/admin"
        
        if ($PSCmdlet.ShouldProcess("Group '$Name'", "Create new group")) {
            try {
                $response = Invoke-CloudApiRequest -Uri $uri -Method PATCH -Body $body
                
                Write-Verbose "Successfully promoted user '$User' to admin of group '$ID'"
                # Return the newly created group
                # Get-CloudGroup -ID $ID
                }
            catch {
                Write-Error "Failed to create group '$Groupname': $_"
                throw
            }
        }
    }
}

function Update-CloudGroup {
    <#
    .SYNOPSIS
        Updates a group on the Cloud Server.
     
    .DESCRIPTION
        Updates a group's template. You can choose to merge with the existing template
        or replace it entirely. Automatically handles token refresh.
         
    .PARAMETER ID
        Required. ID of the group to update.
         
    .PARAMETER Template
        Required. Template content for the group in OpenNebula format.
         
    .PARAMETER Merge
        Optional. If true, merges with existing template. If false or not specified,
        replaces the template entirely.
         
    .EXAMPLE
        # Update a group with a JSON variable, overwriting the current configuration
        $template = @"
FIREEDGE = [
  DEFAULT_VIEW = admin,
  GROUP_ADMIN_DEFAULT_VIEW = admin
]
OPENNEBULA = [
  DEFAULT_IMAGE_PERSISTENT = YES
]
"@
        Update-CloudGroup -ID 102 -Template $template
         
    .EXAMPLE
        # Update a group, merging the new configuration with the existing values
        $template = "CUSTOM_ATTRIBUTE = value"
        Update-CloudGroup -ID 102 -Template $template -Merge
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
    param(
        [Parameter(Mandatory = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $true)]
        [string]$Template,
        
        [Parameter(Mandatory = $false)]
        [switch]$Merge
    )
    
    process {
        # Build the request body
        $body = @{
            template = $Template
        }
        
        if ($Merge) {
            $body['merge'] = $true
        }
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}"
        
        if ($PSCmdlet.ShouldProcess("Group ID '$ID'", "Update group")) {
            try {
                $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $body
                
                Write-Verbose "Successfully updated group ID: $ID"
                # Return the updated group
                return $response.group
            }
            catch {
                Write-Error "Failed to update group '$ID': $_"
                throw
            }
        }
    }
}

#function Update-CloudGroup2 {
# <#
# .SYNOPSIS
# Updates a group on the Cloud Server.
#
# .DESCRIPTION
# Updates a group's name and/or template. You can choose to merge with the existing template
# or replace it entirely. Automatically handles token refresh.
#
# .PARAMETER ID
# Required. ID of the group to update.
#
# .PARAMETER Name
# Optional. New name for the group.
#
# .PARAMETER Template
# Optional. Template content for the group in OpenNebula format.
#
# .PARAMETER Merge
# Optional. If true, merges with existing template. If false or not specified,
# replaces the template entirely.
#
# .EXAMPLE
# # Update just the name
# Update-CloudGroup -ID 102 -Name "NewGroupName"
#
# .EXAMPLE
# # Update template only
# $template = @"
#FIREEDGE = [
# DEFAULT_VIEW = admin
#]
#"@
# Update-CloudGroup -ID 102 -Template $template
#
# .EXAMPLE
# # Update both name and template
# Update-CloudGroup -ID 102 -Name "NewName" -Template "CUSTOM = value" -Merge
# #>
#
# [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
# param(
# [Parameter(Mandatory = $true)]
# [int]$ID,
#
# [Parameter(Mandatory = $false)]
# [string]$Name,
#
# [Parameter(Mandatory = $false)]
# [string]$Template,
#
# [Parameter(Mandatory = $false)]
# [switch]$Merge
# )
#
# process {
# # Require at least one parameter to update
# if (-not $Name -and -not $Template) {
# Write-Error "At least one of Name or Template must be specified"
# return
# }
#
# # Build the request body
# $body = @{}
#
# if ($Name) {
# $body['name'] = $Name
# }
#
# if ($Template) {
# $body['template'] = $Template
# }
#
# if ($Merge) {
# $body['merge'] = $true
# }
#
# $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}"
#
# if ($PSCmdlet.ShouldProcess("Group ID '$ID'", "Update group")) {
# try {
# $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $body
#
# Write-Verbose "Successfully updated group ID: $ID"
# # Return the updated group
# return $response.group
# }
# catch {
# Write-Error "Failed to update group '$ID': $_"
# throw
# }
# }
# }
#}
#
#function Rename-CloudGroup {
# <#
# .SYNOPSIS
# Rename a group in the Cloud Server.
#
# .DESCRIPTION
# Renames a group. Automatically handles token refresh.
#
# .PARAMETER Name
# New name of the group
#
# .PARAMETER ID
# ID of the group
#
# .EXAMPLE
# Rename-CloudGroup -Name "new-name" -ID 5
# #>
#
# [CmdletBinding()]
# param(
# [Parameter(Mandatory = $true)]
# [string]$Name,
#
# [Parameter(Mandatory = $true)]
# [int]$ID
# )
#
# $newname = @{
# name = $Name
# }
#
# $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}/name"
#
# $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $newname
#
# return $response
#}

function Remove-CloudGroupAdmin {
    <#
    .SYNOPSIS
        Removes a group admin from the Cloud Server.
     
    .DESCRIPTION
        Removes a group admin. Automatically handles token refresh.
     
    .PARAMETER ID
        Required. Group ID.
         
    .PARAMETER User
        Required. User ID
     
    .EXAMPLE
        # Remove group admin with confirmation prompt (default behavior):
        Remove-CloudGroupAdmin -ID 3 -User 12
        Confirm
        Are you sure you want to perform this action?
        Performing the operation "Remove Group Admin" on target "Group ID 3 (MyGroup)".
        [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
 
    .EXAMPLE
        # Remove group admin without confirmation prompt:
        Remove-CloudGroupAdmin -ID 3 -User 12 -Confirm:$false
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$User
    )
    
    process {
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/group/${ID}/admin/${User}"
        
        Invoke-CloudResourceRemoval `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Group Admin" `
            -ID $ID `
            -Uri $uri `
            -GetResourceScript { Get-CloudGroup -ID $ID }
    }
}