Functions/Public/Tenant.ps1

# Tenant and organization management functions

Function Get-NectarTenantNames {
    <#
        .SYNOPSIS
        Shows all the available Nectar tenants on the cloud host.
         
        .DESCRIPTION
        Shows all the available Nectar tenants on the cloud host. Only available for multi-tenant deployments and not visible to read-only admins.
 
        .EXAMPLE
        Get-NectarTenantNames
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntn")]
    [cmdletbinding()]
    param ()
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NectarCloud/aapi/tenant"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
             
            $TenantList = Foreach ($Item in $JSON) {
                $PSObject = New-Object PSObject -Property @{
                    TenantName = $Item
                }
                $PSObject
            }
            Return $TenantList
        }
        Catch {
            Write-Error "No tenants found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantDetails {
    <#
        .SYNOPSIS
        Shows detailed information about a specific tenant
         
        .DESCRIPTION
        Shows detailed information about a specific tenant. Not visible to read-only admins
 
        .PARAMETER TenantName
        Return information for the specified tenant
 
        .EXAMPLE
        Get-NectarTenantDetails
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntn")]
    [cmdletbinding()]
    param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            $URI = "https://$Global:NectarCloud/aapi/clients/$($TenantName)?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
             
            Return $JSON
        }
        Catch {
            Write-Error "Invalid tenantname or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantProvisioningInfo {
    <#
        .SYNOPSIS
        Shows information about tenant provisioning/deprovisioning status
         
        .DESCRIPTION
        Shows information about tenant provisioning/deprovisioning status. Not visible to tenant admins
 
        .PARAMETER TenantName
        Return information for the specified tenant
 
        .EXAMPLE
        Get-NectarTenantProvisioningInfo
 
        .NOTES
        Version 1.0
    #>


    [cmdletbinding()]
    param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    
    Process {
        Try {
            $URI = "https://$Global:NectarCloud/aapi/provisioning"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            
            If ($TenantName) {
                Return $JSON | Where-Object {$_.tenant -eq $TenantName}
            } Else {
                Return $JSON
            }
        }
        Catch {
            Write-Error "Invalid tenantname or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarServiceProviderInfo {
    <#
        .SYNOPSIS
        Return information about service providers in the environment
         
        .DESCRIPTION
        Return information about service providers in the environment. Returns a list of all service providers and the associated tenants.
 
        .PARAMETER SearchQuery
        A string to search for. Will search for match against all fields
         
        .PARAMETER OrderByField
        Sort the output by the selected field
         
        .PARAMETER OrderDirection
        Sort ordered output in ascending or descending order
         
        .PARAMETER PageSize
        The size of the page used to return data. Defaults to 10000
         
        .PARAMETER ResultSize
        The total number of results to return. Maximum result size is 9,999,999 results
     
        .EXAMPLE
        Get-NectarServiceProviderInfo
        Returns information about all service providers in the environment
 
        .EXAMPLE
        Get-NectarServiceProviderInfo -SearchQuery contoso
        Returns information about the Contoso service provider
 
        .NOTES
        Version 1.0
    #>

    
    Param (
        [Parameter(Mandatory=$False)]
        [string]$SearchQuery,        
        [Parameter(Mandatory=$False)]
        [ValidateSet('name', 'clientsCount', IgnoreCase=$True)]
        [string]$OrderByField = 'name',
        [Parameter(Mandatory=$False)]
        [ValidateSet('asc', 'desc', IgnoreCase=$True)]
        [string]$OrderDirection = 'asc',
        [Parameter(Mandatory=$False)]
        [ValidateRange(1,999999)]
        [int]$PageSize = 10000,
        [Parameter(Mandatory=$False)]
        [ValidateRange(1,999999)]
        [int]$ResultSize,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$Name
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        # Set the page size to the result size if -ResultSize switch is used to limit the number of returned items
        # Otherwise, set page size (defaults to 1000)
        If ($ResultSize) { $PageSize = $ResultSize }

        $Params = @{
            'pageNumber'         = 1
            'pageSize'            = $PageSize
            'orderByField'        = $OrderByField
            'orderDirection'    = $OrderDirection
        }

        If ($SearchQuery) { $Params.Add('searchQuery', $SearchQuery) }

        $URI = "https://$Global:NectarCloud/aapi/service-providers"
        Write-Verbose $URI
        
        $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params
        
        $TotalPages = $JSON.totalPages

        $JSON.elements

        If ($TotalPages -gt 1 -and !($ResultSize)) {
            $PageNum = 2
            Write-Verbose "Page size: $PageSize"
            While ($PageNum -le $TotalPages) {
                Write-Verbose "Working on page $PageNum of $TotalPages"
                $Params.PageNumber = $PageNum
                $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params
                $JSON.elements
                $PageNum++
            }
        }
    }
}


Function Get-NectarServiceProviderTenants {
    <#
        .SYNOPSIS
        Return information about service provider tenants in the environment
         
        .DESCRIPTION
        Return information about service provider tenants in the environment. Returns a list of tenants associated with the given service provider
 
        .PARAMETER ServiceProviderName
        The service provider to return the tenant list
     
        .EXAMPLE
        Get-NectarServiceProviderTenants -ServiceProviderName contoso
        Returns tenant information for the contoso service provider
 
        .NOTES
        Version 1.0
    #>

    
    Param (
        [Parameter(Mandatory=$True)]
        [string]$ServiceProviderName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        $URI = "https://$Global:NectarCloud/aapi/service-provider/clients?tenant=$ServiceProviderName"
        Write-Verbose $URI
        
        $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
        Return $JSON
    }
}


Function Get-NectarRIGAgent {
    <#
        .SYNOPSIS
        Return information about RIG agents connected to the environment
         
        .DESCRIPTION
        Return information about RIG agents connected to the environment
 
        .PARAMETER SearchQuery
        A string to search for. Will search for match against all fields
         
        .PARAMETER OrderByField
        Sort the output by the selected field
         
        .PARAMETER OrderDirection
        Sort ordered output in ascending or descending order
         
        .PARAMETER PageSize
        The size of the page used to return data. Defaults to 10000
         
        .PARAMETER ResultSize
        The total number of results to return. Maximum result size is 9,999,999 results
     
        .EXAMPLE
        Get-NectarRIGAgent
        Returns information about all RIG agents in the environment
 
        .EXAMPLE
        Get-NectarRIGAgent -SearchQuery contoso -OrderByField
        Returns information about gateways from all Cisco clusters
 
        .NOTES
        Version 1.0
    #>

    
    Param (
        [Parameter(Mandatory=$False)]
        [string]$SearchQuery,        
        [Parameter(Mandatory=$False)]
        [ValidateSet('name', 'clientName', 'lastRequestDate', 'cpu', 'memory', 'disk', IgnoreCase=$True)]
        [string]$OrderByField = 'name',
        [Parameter(Mandatory=$False)]
        [ValidateSet('asc', 'desc', IgnoreCase=$True)]
        [string]$OrderDirection = 'asc',
        [Parameter(Mandatory=$False)]
        [ValidateRange(1,999999)]
        [int]$PageSize = 10000,
        [Parameter(Mandatory=$False)]
        [ValidateRange(1,999999)]
        [int]$ResultSize,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$Name
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        # Set the page size to the result size if -ResultSize switch is used to limit the number of returned items
        # Otherwise, set page size (defaults to 1000)
        If ($ResultSize) { $PageSize = $ResultSize }

        $Params = @{
            'pageNumber'         = 1
            'pageSize'            = $PageSize
            'orderByField'        = $OrderByField
            'orderDirection'    = $OrderDirection
        }

        If ($SearchQuery) { $Params.Add('searchQuery', $SearchQuery) }

        $URI = "https://$Global:NectarCloud/aapi/tenant/agents"
        Write-Verbose $URI
        
        $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params
        
        $TotalPages = $JSON.totalPages

        $JSON.elements

        If ($TotalPages -gt 1 -and !($ResultSize)) {
            $PageNum = 2
            Write-Verbose "Page size: $PageSize"
            While ($PageNum -le $TotalPages) {
                Write-Verbose "Working on page $PageNum of $TotalPages"
                $Params.PageNumber = $PageNum
                $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params
                $JSON.elements
                $PageNum++
            }
        }
    }
}


Function Get-NectarTenantSettings {
    <#
        .SYNOPSIS
        Shows all the tenant sizing metrics on the platform
         
        .DESCRIPTION
        Shows all the tenant sizing metrics on the platform. Only available for global admins.
 
        .PARAMETER TenantName
        Return metric values for a single tenant
 
        .EXAMPLE
        Get-NectarTenantMetrics
        Returns all metrics for all tenants
 
        .EXAMPLE
        Get-NectarTenantMetrics -TenantName Contoso
        Returns all metrics for the Contoso tenant
         
        .EXAMPLE
        Get-NectarTenantMetrics | Where {$_.name -like '*USERS' -And $_.value -gt 0} | FT
        Returns all user counts for all tenants where the value is greater than 0
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [ValidateSet('large_tenant','nectar_brand_label','show_nectar_score', IgnoreCase=$True)]
        [string]$Parameter = 'large_tenant',
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { 
                $TenantName = $Global:NectarTenantName 
            } ElseIf ($TenantName) {
                If ($TenantName -NotIn $Global:NectarTenantList) {
                    $TList = $Global:NectarTenantList -join ', '
                    Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)"
                }
            }
            # The JSON format in this API doesn't lend itself to manipulation in PS, so we have to fix it up
            $URI = "https://$Global:NectarCloud/aapi/client/datasource/settings?column=$Parameter&tenant=$TenantName"
            Write-Verbose $URI

            Return Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
        }
        Catch {
            Write-Error "No tenants found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantMetrics {
    <#
        .SYNOPSIS
        Shows all the tenant sizing metrics on the platform
         
        .DESCRIPTION
        Shows all the tenant sizing metrics on the platform. Only available for global admins.
 
        .PARAMETER TenantName
        Return metric values for a single tenant
 
        .EXAMPLE
        Get-NectarTenantMetrics
        Returns all metrics for all tenants
 
        .EXAMPLE
        Get-NectarTenantMetrics -TenantName Contoso
        Returns all metrics for the Contoso tenant
         
        .EXAMPLE
        Get-NectarTenantMetrics | Where {$_.name -like '*USERS' -And $_.value -gt 0} | FT
        Returns all user counts for all tenants where the value is greater than 0
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntm")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            # The JSON format in this API doesn't lend itself to manipulation in PS, so we have to fix it up
            $URI = "https://$Global:NectarCloud/aapi/tenant/datasource/metrics?lastOnly=true"
            Write-Verbose $URI

            $MetricListRaw = (Invoke-WebRequest -Method GET -URI $URI -UseBasicParsing -Headers $Global:NectarAuthHeader).content
            $MetricListRawUpdated = $MetricListRaw -Replace '(\"[a-z_0-9]+\")\ \:\ \[\ \{', '{"tenantName" : $1, "data" : [ {'
            $MetricListRawUpdated = $MetricListRawUpdated -Replace '\{\s+\{', '[{'
            $MetricListRawUpdated = $MetricListRawUpdated -Replace '\]\,', ']},'
            $MetricListRawUpdated = $MetricListRawUpdated -Replace '\}\s+\]\s+\}', '}]}]'
            $MetricList = ConvertFrom-JSON $MetricListRawUpdated
            
            If ($TenantName) {
                Return ($MetricList | Where-Object {$_.TenantName -eq $TenantName}).data
            }
            Else {
                Return $MetricList    
            }
        }
        Catch {
            Write-Error "No tenants found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantMetricTimeline {
    <#
        .SYNOPSIS
        Shows a monthly timeline of specific metric values for a given tenant
         
        .DESCRIPTION
        Shows a monthly timeline of specific metric values for a given tenant. Only available for global admins.
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .PARAMETER Metric
        The specified metric to return data on
 
        .EXAMPLE
        Get-NectarTenantMetricTimeline -Metric CISCO_USERS -TenantName Contoso
        Returns the daily CISCO_USERS count for the past month for the Contoso tenant
         
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntmt")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)]
        [string]$TenantName,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)]
        [Alias("name")]
        [string]$Metric
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NectarCloud/aapi/tenant/datasource/metrics"
            Write-Verbose $URI

            $Params = @{
                lastOnly     = 'false'
                name         = $Metric
                periodCount    = 1
                tenant         = $TenantName
            }
            
            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params

            Return $JSON.$TenantName
        }
        Catch {
            Write-Error "Could not find tenant with name $TenantName or a matching metric called $($Metric). $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantLicenseCount {
    <#
        .SYNOPSIS
        Shows the current and historical license status for a given tenant
         
        .DESCRIPTION
        Shows the current and historical license status for a given tenant
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantLicenseCount
 
        .NOTES
        Version 1.0
    #>

    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            $URI = "https://$Global:NectarCloud/aapi/client/license/user-counts?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON
        }
        Catch {
            Write-Error "No tenant license information found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantRIGDatasources {
    <#
        .SYNOPSIS
        Shows all the RIG datasources available on a given tenant.
         
        .DESCRIPTION
        Shows all the RIG datasources available on a given tenant.
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantRIGDatasources
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntdc")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }
            
            $URI = "https://$Global:NectarCloud/aapi/tenant/datasources?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON.data
        }
        Catch {
            Write-Error "No tenant datasources found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantDatasource {
    <#
        .SYNOPSIS
        Shows all the datasources available on a given tenant.
         
        .DESCRIPTION
        Shows all the datasources available on a given tenant.
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantDatasource
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntdc")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }
            
            $URI = "https://$Global:NectarCloud/aapi/tenant/sources?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON
        }
        Catch {
            Write-Error "No tenant datasources found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantDatasourceDetails {
    <#
        .SYNOPSIS
        Shows details for a given datasource
         
        .DESCRIPTION
        Shows details for a given datasource
 
        .PARAMETER ID
        The Id of the datasource to return details on
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantDatasource | Get-NectarTenantDatasourceDetails
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)]
        [int]$ID,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [Alias('datasource')]
        [string]$DatasourceType,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            If (!$DataSourceType) { Write-Verbose 'Getting datasource type'; $DatasourceType = (Get-NectarTenantDatasource | Where-Object {$_.Id -eq $ID}).dataSource }
            
            $URI = "https://$Global:NectarCloud/aapi/clouddatasources/configuration/$DatasourceType/$($ID)?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON.data
        }
        Catch {
            Write-Error "No tenant datasources found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function New-NectarTenantDatasource {
    <#
        .SYNOPSIS
        Create a new tenant datasource
         
        .DESCRIPTION
        Create a new tenant datasource. Requires a global admin account. Not available to tenant-level admins.
         
        .PARAMETER DatasourceType
        The type of datasource to create. Select from Genesys.
 
        .PARAMETER TenantName
        The name of the Nectar DXP tenant. Used in multi-tenant configurations.
 
        .NOTES
        Version 1.0
    #>

    
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)]
        [ValidateSet('Genesys')]
        [string]$DatasourceType,
        [ValidatePattern("^[a-zA-Z0-9 ]+$")]
        [Parameter(ValueFromPipelineByPropertyName, HelpMessage = "Display name can only contain letters, numbers and spaces", Mandatory=$False)]
        [string]$DisplayName,
        [Parameter(Mandatory=$False)]
        [string]$TenantName
    )

    DynamicParam {
        $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

        Switch ($DatasourceType) {
            'Genesys' {
                $Parameters = @(
                    @{ Name = 'AWSEventBus'; Mandatory = $True; Type = [string] },
                    @{ 
                        Name = 'AWSRegion'; 
                        Mandatory = $True; 
                        Type = [string];
                        ValidateSet = @(
                            "us-east-1", "us-east-2", "us-west-1", "us-west-2",
                            "af-south-1", "ap-east-1", "ap-south-1", "ap-south-2",
                            "ap-southeast-1", "ap-southeast-2", "ap-southeast-3", "ap-southeast-4",
                            "ap-northeast-1", "ap-northeast-2", "ap-northeast-3",
                            "ca-central-1", "ca-west-1",
                            "eu-central-1", "eu-central-2",
                            "eu-west-1", "eu-west-2", "eu-west-3",
                            "eu-north-1", "eu-south-1", "eu-south-2",
                            "il-central-1",
                            "me-central-1", "me-south-1",
                            "sa-east-1",
                            "us-gov-east-1", "us-gov-west-1",
                            "cn-north-1", "cn-northwest-1"
                        )
                    },
                    @{ Name = 'GenesysOAuthClientID'; Mandatory = $True; Type = [string] },
                    @{ Name = 'GenesysOAuthClientSecret'; Mandatory = $True; Type = [string] }
                )
            }
        }

        ForEach ($param in $Parameters) {
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $param.Mandatory
            $AttributeCollection.Add($ParameterAttribute)

            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($param.Name, $param.Type, $AttributeCollection)
            $RuntimeParameterDictionary.Add($param.Name, $RuntimeParameter)
        }
        Return $RuntimeParameterDictionary
    }
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        # Use globally set tenant name, if one was set and not explicitly included in the command
        If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { 
                $TenantName = $Global:NectarTenantName 
            } ElseIf ($TenantName) {
                If ($TenantName -NotIn $Global:NectarTenantList) {
                    $TList = $Global:NectarTenantList -join ', '
                    Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)"
                }
            }
        
        # Get the cloud agent list
        $CloudAgentList = Get-NectarCloudAgent
        
        If ($CloudAgentList.Count -gt 1) { # If there are multiple cloud agents, show a list to pick from
            $CloudAgentName = Select-FromList -Prompt 'Multiple cloud agents found. Pick the desired cloud agent from the below list:' -Items $CloudAgentList.cloudAgentName
        }
        Else {
            $CloudAgentName = $CloudAgentList[0].cloudAgentName
        }

        If (!$PSBoundParameters.ContainsKey('DisplayName')) { 
            $DisplayName = "Genesys Cloud $TenantName" 
        } 

        # Build the JSON body for creating the config
        $Body = @{
            awsApiKey            = ''
            awsEventBus            = $PSBoundParameters['AWSEventBus']
            cloudAgentName        = $CloudAgentName
            cloudRegion            = $PSBoundParameters['AWSRegion'].Replace('-','_')
            displayName         = $DisplayName
            oauthClientId        = $PSBoundParameters['GenesysOAuthClientID']
            oauthClientSecret    = $PSBoundParameters['GenesysOAuthClientSecret']
            tenant                 = $TenantName
        }

        $URI = "https://$($Global:NectarCloud)/aapi/clouddatasources/configuration/genesys?tenant=$TenantName"
        Write-Verbose $URI
        
        $JSONBody = $Body | ConvertTo-Json
        Write-Verbose $JSONBody
        Try {
            $JSON = Invoke-RestMethod -Method POST -URI $URI -Headers $Global:NectarAuthHeader -Body $JSONBody -ContentType 'application/json'
            Return $JSON.data
        } Catch {
            Throw Get-JSONErrorStream -JSONResponse $_
        }
    }
}


Function Remove-NectarTenantDatasource {
    <#
        .SYNOPSIS
        Removes a specified datasource from a tenant.
         
        .DESCRIPTION
        Removes a specified datasource from a tenant.
 
        .PARAMETER ID
        The ID of the datasource to remove
 
        .PARAMETER TenantName
        The tenant to remove the datasource from
 
        .EXAMPLE
        Remove-NectarTenantDatasource -ID 76
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("dntdc")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)]
        [int]$ID,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            $DatasourceType = (Get-NectarTenantDatasource | Where-Object {$_.Id -eq $ID}).dataSource
            
            $URI = "https://$Global:NectarCloud/aapi/clouddatasources/configuration/$DatasourceType/$($ID)?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method DELETE -URI $URI -Headers $Global:NectarAuthHeader
            Return "Datasource ID $ID deleted successfully."
        }
        Catch {
            Write-Error "An error occurred when deleting datasource ID $ID. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantPlatforms {
    <#
        .SYNOPSIS
        Shows all the platforms available on a given tenant.
         
        .DESCRIPTION
        Shows all the platforms available on a given tenant.
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantPlatforms
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntp")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            $URI = "https://$Global:NectarCloud/dapi/info/platforms?showAll=true&tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON
        }
        Catch {
            Write-Error "No tenant platforms found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantEventBridgeConfig {
    <#
        .SYNOPSIS
        Shows the assigned EventBridge configuration for a given tenant
         
        .DESCRIPTION
        Shows the assigned EventBridge configuration for a given tenant
 
        .PARAMETER TenantName
        The tenant to return EventBrigde configuration on
 
        .EXAMPLE
        Get-NectarTenantEventBridgeConfig
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

        Try {
            $URI = "https://$Global:NectarCloud/aapi/client/eventbridge?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            If ($TenantName) {$JSON | Add-Member -Name 'TenantName' -Value $TenantName -MemberType NoteProperty} # Add the tenant name to the output which helps pipelining
            Return $JSON
        }
        Catch {
            Write-Error "No EventBridge configs found. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarEventBridgeConfig {
    <#
        .SYNOPSIS
        Shows the available EventBridge configurations
         
        .DESCRIPTION
        Shows the available EventBridge configurations
 
        .EXAMPLE
        Get-NectarEventBridgeConfig
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    Param ()
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NectarCloud/aapi/cloudstorage/config/eventbridge"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON
        }
        Catch {
            Write-Error "No EventBridge configs found. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NectarTenantSSOConfig {
    <#
        .SYNOPSIS
        Shows the SSO config for a given tenant.
         
        .DESCRIPTION
        Shows the SSO config for a given tenant.
 
        .PARAMETER TenantName
        The tenant to return metrics on
 
        .EXAMPLE
        Get-NectarTenantSSOConfig
 
        .NOTES
        Version 1.0
    #>

    
    [Alias("gntsc")]
    [cmdletbinding()]
    Param (
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName
    )
    
    Begin {
        Connect-NectarCloud
    }
    Process {
        Try {
            If (!$TenantName) { $TenantName = Get-NectarDefaultTenantName }

            $URI = "https://$Global:NectarCloud/aapi/client/sso-config?tenant=$TenantName"
            Write-Verbose $URI

            $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader
            Return $JSON

            ForEach ($Item in $JSON) {
                $PlatformList = [pscustomobject][ordered]@{
                    TenantName = $TenantName
                    Platform = $Item.platform
                    Supported = $Item.supported
                }
                $PlatformList
            }
        }
        Catch {
            Write-Error "No tenant platforms found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}