PlagueHO / CosmosDB

PowerShell Module for working with Azure Cosmos DB databases, collections, documents, attachments, offers, users, permissions, triggers, stored procedures and user defined functions.
http://dscottraynsford.com
MIT License
154 stars 46 forks source link

Allow passing https:// and :port through $URL #381

Closed tamusjroyce closed 4 years ago

tamusjroyce commented 4 years ago

Issue

When using https://mycompaniesabbr.documents.azure.com:443/ I get an exception when trying to get a database context

Conclusion

$URL should match what is shown in portal or cosmos emulator

image

Solution

diff --git a/source/Public/utils/New-CosmosDbContext.ps1 b/source/Public/utils/New-CosmosDbContext.ps1
index af5514d..40d6b84 100644
--- a/source/Public/utils/New-CosmosDbContext.ps1
+++ b/source/Public/utils/New-CosmosDbContext.ps1
@@ -87,7 +87,15 @@ function New-CosmosDbContext
                     -Force
             }

-            $BaseUri = [uri]::new(('https://{0}:{1}' -f $URI, $Port))
+            if ($URI -like '*:*' -And $URI -like '*://*') {
+                $BaseUri = [uri]::new($URI)
+            } else if ($URI -like '*:*') {
+                $BaseUri = [uri]::new(('https://{0}' -f $URI))
+            } else if ($URI -like '*://*') {
+                $BaseUri = [uri]::new(('{0}:{1}' -f $URI, $Port))
+            } else {
+                $BaseUri = [uri]::new(('https://{0}:{1}' -f $URI, $Port))
+            }
         }

         'AzureAccount'

Sorry for the git diff instead of a PR. This is missing a unit test and hasn't been ran. Wouldn't be surprised if a a syntax error is hiding in there somewhere.

Before submitting your issue for the CosmosDB project, please take a moment to provide the following details:

Thanks for contributing your feedback and support! You can optionally submit a Pull Request against this project, if you have a fix you'd like to share.

PlagueHO commented 4 years ago

Hi @tamusjroyce - are you trying to use the module to connect to a CosmosDB emulator? If so, see this method of creating the context: https://github.com/PlagueHO/CosmosDB#create-a-context-for-a-cosmos-db-emulator

Apologies if I've misunderstood the issue.

tamusjroyce commented 4 years ago

Original is

$cosmosDbContext = New-CosmosDbContext -Emulator -Database 'MyDatabase' -URI 'myemulator.local' -Key $primaryKey

From the screenshot put what is shown into $URL

$sourceUrl = 'https://localhost:8081' #URL shown in emulator (what my DevOps guys will know to enter) $useEmulator = $true $sourceDatabaseName = 'yup' # favorite King of the Hill quote (intro fence)

$useEmulator = $false
if ((Read-Host -Prompt "Use Azure Cosmos Emulator? [y/N]") -like "y") {
    $useEmulator = $true
    $cosmosEmulatorPath = Get-Package | Where-Object{ $_.Name -like "Azure Cosmos DB Emulator" } | % { $_.Source }
    if ([string]::IsNullOrEmpty($cosmosEmulatorPath)) {
        Start "https://aka.ms/cosmosdb-emulator"
    }

    while ([string]::IsNullOrEmpty($cosmosEmulatorPath)) {
        if ((Read-Host -Prompt "Has Azure Cosmos Emulator been downloaded and installed? [Press enter to check or y to skip]") -like "y") {
            break
        }
        $cosmosEmulatorPath = Get-Package | Where-Object{ $_.Name -like "*Cosmos*" } | % { $_.Source }
    }

    Start -FilePath (Join-Path -Path $cosmosEmulatorPath -ChildPath "Microsoft.Azure.Cosmos.Emulator.exe")
    Start "https://localhost:8081/_explorer/index.html"
    Write-Output "CosmosDB should be open with the key showing"
} else {
    Start "https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.DocumentDb%2FdatabaseAccounts"
    Write-Output "Please navigate to the CosmosDB resource and open Keys under settings and select Read-only keys"
}

$sourceUrl = Read-Host -Prompt 'Enter source the Cosmos URL'
$sourceKey = Read-Host -Prompt 'Enter the  source Cosmos key'
$sourceDatabaseName = Read-Host -Prompt 'Enter the source database name'
$sourceContainerName = Read-Host -Prompt 'Enter the source container name'

$backoffPolicy = New-CosmosDbBackoffPolicy -MaxRetries 20
$primarySourceKey = ConvertTo-SecureString -String $sourceKey.Trim() -AsPlainText -Force
if ($useEmulator -eq $true) {
    $sourceCosmosDbContext = New-CosmosDbContext -Emulator -Database $sourceDatabaseName -URI $sourceUrl -Key $primarySourceKey -BackoffPolicy $backoffPolicy
} else {
    $sourceCosmosDbContext = New-CosmosDbContext -Database $sourceDatabaseName -URI $sourceUrl -Key $primarySourceKey -BackoffPolicy $backoffPolicy
}

# It breaks here - Context seems ok. But Container breaks on bad URL
$sourceCollection = Get-CosmosDbCollection -Context $sourceCosmosDbContext -Id $sourceContainerName -Verbose
$sourceCollectionId = Get-CosmosDbCollectionResourcePath -Database $sourceDatabaseName -Id $sourceContainerName

This breaks. The DevOps guy's won't know to leave the https:// off or put the port in separately. And this could be typed as many as 20 times during a scheduled window (to make changes through all our collections)

Try it again using Azure $sourceUrl = 'https://mycompaniesabbr.documents.azure.com:443/' #URL shown in emulator (what my DevOps guys will know to enter) $useEmulator = $false $sourceDatabaseName = 'CompaniesDatabase' # favorite King of the Hill quote (intro fence)

Why can't URL shown in the URI of the screenshot be usable?

p.s. Also, Cosmos Clone uses the URL in the screenshot to perform a copy - however that can't be customized or put into a script like your tool

tamusjroyce commented 4 years ago

I did expect the above to break on New-CosmosDbContext instead of waiting to hit Get-CosmosDbCollection

Feel free to close this out as a wont-do. I can work around it. This tool is so slick and helpful. Really glad I came across it!

PlagueHO commented 4 years ago

Hi @tamusjroyce - ah, I see I think. So what you'd like to be able to do is:

$cosmosDbContext = New-CosmosDbContext -Emulator -Database 'MyDatabase' -URI 'https://localhost:8081' -Key $primaryKey

And have that work OK - is that correct? I think I can do this (and it does make sense).