Public/cloud-document.ps1

function Get-CloudDocument {
    <#
    .SYNOPSIS
        Gets documents from the Cloud Server.
     
    .DESCRIPTION
        Retrieves a list of documents. Automatically handles token refresh.
         
    .PARAMETER Name
        Optional. Filter by document name
    
    .PARAMETER ID
        Optional. Filter by document ID
     
    .EXAMPLE
        # Get all documents
        Get-CloudDocument
         
    .EXAMPLE
        # Get a document by ID
        Get-CloudDocument -ID 5
         
    .EXAMPLE
        # Get a document by name
        Get-CloudDocument -Name "config.json"
    #>

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

}

function New-CloudDocument {
    <#
    .SYNOPSIS
        Creates a new document in the Cloud Server.
     
    .DESCRIPTION
        Creates a document object in OpenNebula. Documents are generic objects
        that can store arbitrary data in their template.
     
    .PARAMETER Name
        Name of the document
         
    .PARAMETER Type
        Document type (0 = generic, 1 = file)
         
    .PARAMETER Template
        Template content for the document
     
    .EXAMPLE
        # Create a generic document with this template:
        $template = "NAME=`"MyDocument`"`nDESCRIPTION=`"Test document`"`nCUSTOM_DATA=`"Some value`""
        New-CloudDocument -Template $template -Type 0
         
    .EXAMPLE
        # Create a file based on the config saved into a Powershell variable
$template = @"
NAME="config.json"
DESCRIPTION="Configuration file"
TYPE="file"
"@
        New-CloudDocument -Template $template -Type 1
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Template,
        
        [Parameter(Mandatory = $false)]
        [int]$Type = 0
    )
    
    $documentjson = @{
        template = $Template
        type = $Type
    }
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document"
    $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $documentjson
    
    return $response
}

function Remove-CloudDocument {
    <#
    .SYNOPSIS
        Removes a document from the Cloud Server.
     
    .DESCRIPTION
        Removes a document. Automatically handles token refresh.
     
    .PARAMETER ID
        Required. Document ID.
     
    .EXAMPLE
        # Remove a document with confirmation prompt (default behavior)
        Remove-CloudDocument -ID 3
        Confirm
        Are you sure you want to perform this action?
        Performing the operation "Remove Document" on target "Document ID 3 (MyDocument)".
        [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
 
    .EXAMPLE
        # Remove a document without confirmation prompt
        Remove-CloudDocument -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/document/${ID}"
        
        Invoke-CloudResourceRemoval `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Document" `
            -ID $ID `
            -Uri $uri `
            -GetResourceScript { Get-CloudDocument -ID $ID }
    }
}

function Rename-CloudDocument {
    <#
    .SYNOPSIS
        Rename a document in the Cloud Server.
     
    .DESCRIPTION
        Renames a document. Automatically handles token refresh.
     
    .PARAMETER Name
        New name of the document
         
    .PARAMETER ID
        ID of the document
             
    .EXAMPLE
        # Rename a document
        Rename-CloudDocument -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/document/${ID}/name"
       
    $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $newname
    
    return $response
}

function Lock-CloudDocument {
    <#
    .SYNOPSIS
        Lock a document in the Cloud Server.
     
    .DESCRIPTION
        Lock a document. Automatically handles token refresh.
        
    .PARAMETER ID
        ID of the document
 
    .PARAMETER Level
        Lock level (USE, MANAGE, ADMIN, ALL)
 
    .PARAMETER Test
        When set, performs a test lock instead of a real one.
 
    .EXAMPLE
        # Lock a document by restricting administrative operations on it
        Lock-CloudDocument -ID 5 -Level ADMIN
 
    .EXAMPLE
        # Test locking a document at a specific level
        Lock-CloudDocument -ID 5 -Level USE -Test
 
    #>

    
    [CmdletBinding()]
    param(
        
        [Parameter(Mandatory = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $true)]
        [ValidateSet('USE','MANAGE','ADMIN','ALL')]
        [string]$Level,
        
        [switch]$Test
    )

    $lockdata = @{
        level = $Level
        test  = [bool]$Test
    }
    
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}/lock"
    $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $lockdata
    return $response
}

function Unlock-CloudDocument {
    <#
    .SYNOPSIS
        Unlock a document in the Cloud Server.
         
    .DESCRIPTION
        Unlock a document. Automatically handles token refresh.
        
    .PARAMETER ID
        ID of the document
 
    .EXAMPLE
        # Unlock a document
        Unlock-CloudDocument -ID 5
    #>

    
    [CmdletBinding()]
    param(
        
        [Parameter(Mandatory = $true)]
        [int]$ID        

    )
   
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}/unlock"
    $response = Invoke-CloudApiRequest -Uri $uri -Method Patch
    return $response
}

function Update-CloudDocumentOwner {
    <#
    .SYNOPSIS
        Updates the ownership of a document in the Cloud Server.
     
    .DESCRIPTION
        Changes the user ad/or group ownership of a document. Prompts for confirmation.
     
    .PARAMETER ID
        Required. ID of the document.
     
    .PARAMETER UserID
        Required. ID of the user to own the document.
         
    .PARAMETER GroupID
        Optional. ID of the group to own the document.
         
    .EXAMPLE
        # Update a document's owner
        Update-CloudDocumentOwner -ID 5 -UserID 2
         
    .EXAMPLE
        # Update a document's owner and group ownership
        Update-CloudDocumentOwner -ID 5 -UserID 2 -GroupID 100
         
    .EXAMPLE
        # Update a document's owner and bypass confirmation prompt
        Update-CloudDocumentOwner -ID 5 -UserID 2 -Confirm:$false
    #>

    
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $true)]
        [Alias('User')]
        [int]$UserID,
                
        [Parameter(Mandatory = $false)]
        [Alias('Group')]
        [int]$GroupID
    )
    
    process {
        # Build the update body
        $body = [PSCustomObject]@{
            user = $UserID
        }
        
        if ($PSBoundParameters.ContainsKey('GroupID')) {
            $body | Add-Member -NotePropertyName 'group' -NotePropertyValue $GroupID
        }
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}/ownership"
        
        # Build action description for confirmation
        $actionParts = @("Change owner to User ID $UserID")
        if ($PSBoundParameters.ContainsKey('GroupID')) {
            $actionParts += "Group ID $GroupID"
        }
        $actionDescription = $actionParts -join " ad "
        
        # Use the helper function
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Document" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action $actionDescription `
            -GetResourceScript { Get-CloudDocument -ID $ID } `
            -SuccessMessage "Document $ID ownership updated successfully."
    }
}

function Update-CloudDocumentPermissions {
    <#
    .SYNOPSIS
        Updates the permissions of a document in the Cloud Server.
     
    .DESCRIPTION
        Changes the permission of a document. Prompts for confirmation.
     
    .PARAMETER ID
        Required. ID of the document.
     
    .PARAMETER OwnerUse
        Optional. True or false, enable OwnerUse
 
    .PARAMETER OwnerManage
        Optional. True or false, enable OwnerManage
 
    .PARAMETER OwnerAdmin
        Optional. True or false, enable OwnerAdmin
 
    .PARAMETER GroupUse
        Optional. True or false, enable GroupUse
         
    .PARAMETER GroupManage
        Optional. True or false, enable GroupManage
         
    .PARAMETER GroupAdmin
        Optional. True or false, enable GroupAdmin
         
    .PARAMETER OtherUse
        Optional. True or false, enable OtherUse
         
    .PARAMETER OtherManage
        Optional. True or false, enable OtherManage
         
    .PARAMETER OtherAdmin
        Optional. True or false, enable OtherManage
         
    .EXAMPLE
        # Give group users permission to use the document
        Update-CloudDocumentPermissions -ID 35 -GroupUse $true
         
    .EXAMPLE
        # Deny group admin permission to the document
        Update-CloudDocumentPermissions -ID 35 -GroupAdmin $false
         
    .EXAMPLE
        # Set multiple permissions at once
        Update-CloudDocumentPermissions -ID 35 -GroupUse $true -GroupManage $true -OtherUse $true
    #>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [int]$ID,
        
        [Parameter(Mandatory = $false)]
        [bool]$OwnerUse,
        
        [Parameter(Mandatory = $false)]
        [bool]$OwnerManage,
        
        [Parameter(Mandatory = $false)]
        [bool]$OwnerAdmin,
        
        [Parameter(Mandatory = $false)]
        [bool]$GroupUse,
        
        [Parameter(Mandatory = $false)]
        [bool]$GroupManage,
        
        [Parameter(Mandatory = $false)]
        [bool]$GroupAdmin,
        
        [Parameter(Mandatory = $false)]
        [bool]$OtherUse,
        
        [Parameter(Mandatory = $false)]
        [bool]$OtherManage,
        
        [Parameter(Mandatory = $false)]
        [bool]$OtherAdmin
    )
    
    process {
        # Build the permissions object structure as shown in the API spec
        $permissions = @{}
        
        if ($PSBoundParameters.ContainsKey('OwnerUse')) { $permissions['owner_use'] = $OwnerUse }
        if ($PSBoundParameters.ContainsKey('OwnerManage')) { $permissions['owner_manage'] = $OwnerManage }
        if ($PSBoundParameters.ContainsKey('OwnerAdmin')) { $permissions['owner_admin'] = $OwnerAdmin }
        
        if ($PSBoundParameters.ContainsKey('GroupUse')) { $permissions['group_use'] = $GroupUse }
        if ($PSBoundParameters.ContainsKey('GroupManage')) { $permissions['group_manage'] = $GroupManage }
        if ($PSBoundParameters.ContainsKey('GroupAdmin')) { $permissions['group_admin'] = $GroupAdmin }
        
        if ($PSBoundParameters.ContainsKey('OtherUse')) { $permissions['other_use'] = $OtherUse }
        if ($PSBoundParameters.ContainsKey('OtherManage')) { $permissions['other_manage'] = $OtherManage }
        if ($PSBoundParameters.ContainsKey('OtherAdmin')) { $permissions['other_admin'] = $OtherAdmin }
        
        # Create the body with the permissions nested structure
        $body = @{
            permissions = $permissions
        }
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}/permissions"
        
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Document" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action "Update permissions" `
            -GetResourceScript { Get-CloudDocument -ID $ID }
    }
}

function Copy-CloudDocument {
    <#
    .SYNOPSIS
        Clone a document in the Cloud Server.
     
    .DESCRIPTION
        Creates a clone document. Automatically handles token refresh.
     
    .PARAMETER Name
        Required. Name of the new document
         
    .PARAMETER ID
        Required. ID of the the document you wish to clone
     
    .EXAMPLE
        # Clone the document, defining the name for the clone
        Copy-CloudDocument -Name "new-document" -ID 5
    #>

    
    [CmdletBinding(DefaultParameterSetName='Individual')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,
        
        [Parameter(Mandatory = $true)]
        [int]$ID
    )


$documentData = [PSCustomObject]@{
NAME=$Name
}
 
    $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}/clone"
    
    Write-Verbose "Request URI: $uri"
    Write-Verbose "Document:`n$DocumentData"
    
    $response = Invoke-CloudApiRequest -Uri $uri -Method POST -Body $documentData
    
    return $response
}

function Update-CloudDocument {
    <#
    .SYNOPSIS
        Updates a document on the Cloud Server.
     
    .DESCRIPTION
        Creates a document object in OpenNebula. Documents are generic objects
        that can store arbitrary data in their template.
     
    .PARAMETER ID
        Required. ID of the document
         
    .PARAMETER Type
        Optional. Document type (0 = generic, 1 = file)
         
    .PARAMETER Template
        Required. Template content for the document
 
    .PARAMETER Merge
        Optional. If the flag -merge is used, will merge with the existing document. Default is to overwrite.
         
    .EXAMPLE
        # Update a document from a parameterized variable
        $template = "NAME=`"MyDocument`"`nDESCRIPTION=`"Test document`"`nCUSTOM_DATA=`"Some value`""
        Update-CloudDocument -ID 8 -Template $template
         
    .EXAMPLE
        # Update a document from a JSON array
$template = @"
NAME="config.json"
DESCRIPTION="Configuration file"
TYPE="file"
"@
        Update-CloudDocument -ID 8 -Template $template
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Template,
        
        [Parameter(Mandatory = $true)]
        [string]$ID,
        
        [Parameter(Mandatory = $false)]
        [switch]$Merge
    )
    
    process {
    if ($merge){    
        $body = @{
            template = $Template
            merge = $false
        }
    }
    else {
        $body = @{
            template = $Template
            merge = $false
        }
    }
        
        $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/document/${ID}"
        $actionParts = @("Update document $ID")

        $actionDescription = $actionParts -join " ad "
        $action = "Update"
        
        # Use the helper function
        Invoke-CloudResourceUpdate `
            -CallerPSCmdlet $PSCmdlet `
            -ResourceType "Document" `
            -ID $ID `
            -Uri $uri `
            -Body $body `
            -Action $action `
            -GetResourceScript { Get-CloudDocument -ID $ID } `
            -SuccessMessage "Document $ID updated successfully."
    }
}