fiftyone.geolocation 4.3.1 → 4.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/ci/build-and-test.yml +5 -5
  2. package/ci/common-ci/.github/labels.yml +45 -1
  3. package/ci/common-ci/.github/workflows/sync-labels.yml +5 -0
  4. package/ci/common-ci/CiTips.md +30 -1
  5. package/ci/common-ci/README.md +73 -12
  6. package/ci/common-ci/build-and-test.yml +6 -1
  7. package/ci/common-ci/c/shared-variables.yml +15 -0
  8. package/ci/common-ci/check-merge-commit-format.yml +7 -1
  9. package/ci/common-ci/cloud-release-config.json +51 -0
  10. package/ci/common-ci/dotnet/shared-extract-and-publish-packages.yml +1 -5
  11. package/ci/common-ci/go/shared-go-list-stage.yml +64 -0
  12. package/ci/common-ci/java/readme.md +15 -1
  13. package/ci/common-ci/java/shared-package-signing-steps.yml +17 -0
  14. package/ci/common-ci/php/readme.md +15 -0
  15. package/ci/common-ci/release-config-schema.json +52 -0
  16. package/ci/common-ci/release-config-template.json +50 -1
  17. package/ci/common-ci/release-config.json +48 -123
  18. package/ci/common-ci/scripts/azure/checkSlot.ps1 +28 -0
  19. package/ci/common-ci/scripts/modules/51DAuthorizationModule/51DAuthorizationModule.psm1 +12 -5
  20. package/ci/common-ci/scripts/modules/51DDeployModule/51DDeployModule.psm1 +66 -0
  21. package/ci/common-ci/scripts/modules/51DDownloadDataFileModule/51DDownloadDataFileModule.psm1 +74 -0
  22. package/ci/common-ci/scripts/modules/51DGitModule/51DGitModule.psm1 +25 -21
  23. package/ci/common-ci/scripts/modules/51DPackageModule/51DPackageModule.Tests.ps1 +347 -9
  24. package/ci/common-ci/scripts/modules/51DPackageModule/51DPackageModule.psm1 +285 -54
  25. package/ci/common-ci/scripts/modules/51DReleaseModule/51DReleaseModule.Tests.ps1 +9 -8
  26. package/ci/common-ci/scripts/modules/51DReleaseModule/51DReleaseModule.psm1 +30 -13
  27. package/ci/common-ci/scripts/modules/51DReleaseTestEnvModule/ReleaseVerifier.Tests.ps1 +342 -97
  28. package/ci/common-ci/scripts/modules/51DReleaseTestEnvModule/ReleaseVerifier.psm1 +36 -2
  29. package/ci/common-ci/scripts/modules/51DReleaseTestEnvModule/SharedVariables.psm1 +2 -2
  30. package/ci/common-ci/scripts/modules/51DReleaseTestEnvModule/config/go-deploy-test-env-config.json +290 -0
  31. package/ci/common-ci/scripts/modules/51DReleaseTestEnvModule/config/go-test-env-config.json +260 -0
  32. package/ci/common-ci/scripts/modules/AzurePortalModules/51DApplicationInsightsModule/51DApplicationInsightsModule.psm1 +104 -0
  33. package/ci/common-ci/scripts/modules/AzurePortalModules/51DChecksModule/51DChecksModule.psm1 +68 -0
  34. package/ci/common-ci/scripts/modules/AzurePortalModules/51DCloudModule/51DCloudModule.psm1 +155 -0
  35. package/ci/common-ci/scripts/modules/AzurePortalModules/51DConnectAzureModule/51DConnectAzureModule.psm1 +45 -0
  36. package/ci/common-ci/scripts/modules/AzurePortalModules/51DSSLBindingsModule/51DSSLBIndingsModule.psm1 +100 -0
  37. package/ci/common-ci/scripts/modules/AzurePortalModules/51DStagingSlotModule/51DStagingSlotModule.psm1 +50 -0
  38. package/ci/common-ci/scripts/modules/AzurePortalModules/51DStorageAccountModule/51DStorageAccountModule.psm1 +248 -0
  39. package/ci/common-ci/scripts/modules/AzurePortalModules/51DTrafficManagerModule/51DTrafficManagerModule.psm1 +58 -0
  40. package/ci/common-ci/shared-auto-complete-pr-stage.yml +16 -3
  41. package/ci/common-ci/shared-create-tag-job.yml +9 -0
  42. package/ci/common-ci/shared-docker-build-steps.yml +34 -0
  43. package/ci/common-ci/shared-docker-push-steps.yml +32 -0
  44. package/ci/common-ci/shared-docker-test-http-steps.yml +69 -0
  45. package/ci/common-ci/shared-git-version-job.yml +17 -2
  46. package/ci/common-ci/shared-publish-github-stage.yml +54 -51
  47. package/ci/common-ci/shared-submodule-trigger-stage.yml +56 -4
  48. package/ci/common-ci/shared-variables.yml +5 -1
  49. package/ci/create-packages.yml +7 -7
  50. package/ci/deploy-external.yml +1 -1
  51. package/ci/deploy-internal.yml +1 -1
  52. package/ci/shared-build-and-test-stage.yml +5 -2
  53. package/ci/shared-variables.yml +1 -7
  54. package/examples/examples.test.js +3 -3
  55. package/geoLocationPipelineBuilder.js +9 -16
  56. package/package.json +11 -7
  57. package/setup.js +1 -0
  58. package/ci/common-ci/java/shared-code-signing-steps.yml +0 -17
@@ -0,0 +1,68 @@
1
+ <#
2
+ ==================== Checks =====================
3
+ .Description
4
+ This module contains functions to check various aspects of Azure Resources.
5
+ #>
6
+
7
+
8
+ # Check if a service is available by polling an Uri. Returns the status code
9
+ # recevied after a number of retrys. An interval can be specified to wait
10
+ # between retries.
11
+ function Get-UriHTTPStatus {
12
+ param (
13
+ # The URI of the service to test, e.g. https://51degrees.com
14
+ [Parameter(Mandatory=$true)]
15
+ [string]$Uri,
16
+
17
+ # The number of tries before aborting the test.
18
+ [Parameter(Mandatory=$true)]
19
+ [int]$NumberOfTries,
20
+
21
+ # The delay between tries in seconds.
22
+ [Parameter(Mandatory=$true)]
23
+ [int]$SecondsBetweenTries
24
+ )
25
+
26
+ Write-Host -NoNewline "Waiting for response from $Uri"
27
+
28
+ $Tries = 0
29
+ $HTTP_Status = $null
30
+ While ($HTTP_Status -ne 200 -And $Tries -le $NumberOfTries) {
31
+
32
+ # Wait before querying Uri
33
+ Start-Sleep -Seconds $SecondsBetweenTries
34
+
35
+ # Get HTTP status code from invoking a request for the Uri.
36
+ try{
37
+ $HTTP_Status = (Invoke-WebRequest -Uri $Uri -UseBasicParsing -DisableKeepAlive).StatusCode
38
+ }
39
+ catch [Net.WebException]
40
+ {
41
+ # If there is a Web Exception then get the status code
42
+ $HTTP_Status = [int]$_.Exception.Response.StatusCode
43
+ }
44
+ catch [Exception]
45
+ {
46
+ # If there is a general exception then assume a status of null
47
+ # (no response).
48
+ $HTTP_Status = $null
49
+ }
50
+
51
+ $Tries = $Tries +1
52
+ Write-Host -NoNewLine "."
53
+ }
54
+
55
+ Write-Host ""
56
+
57
+ # Return status code if service is not accepting requests else return 0
58
+ if ($HTTP_Status -ne 200 -or $null -eq $HTTP_Status) {
59
+ Write-Host "Service is not accepting requests for Uri '$($Uri)'"
60
+ return $HTTP_Status
61
+ } else {
62
+ Write-Host "Service is responding for Uri '$($Uri)'"
63
+ return 0
64
+ }
65
+
66
+ }
67
+
68
+ Export-ModuleMember -Function Get-UriHTTPStatus
@@ -0,0 +1,155 @@
1
+ <#
2
+ ==================== Cloud =====================
3
+ .Description
4
+ This module contains functions specific to the cloud environment configuration
5
+ #>
6
+
7
+ # Create a new blocklist json file and add it to the provided storage account
8
+ function Add-BlocklistFile {
9
+
10
+ param (
11
+ [Parameter(Mandatory=$true)]
12
+ [Object]$storageAccount, # storage account object
13
+
14
+ [string]$shareName = "cloudconfig", # file share name
15
+ [string]$fileName = "blocklist.json" # blocklist filename
16
+ )
17
+
18
+ # Storage context
19
+ $ctx = $storageAccount.Context
20
+
21
+ $storageFiles = Get-AzStorageFile `
22
+ -ShareName $shareName `
23
+ -Context $ctx
24
+
25
+ $storageFile = $storageFiles | Where-Object {$_.Name -eq $fileName }
26
+
27
+ # If the blocklist file does not exist then create a new one.
28
+ if(-not $storageFile) {
29
+ Write-Host "Adding blocklist file..."
30
+
31
+ # Create the blocklist json object
32
+ $blocklist = @{
33
+ DataPublishedDateTime = (Get-Date).ToString("yyyy-MM-dd")
34
+ UpdateAvailableTime = (Get-Date).ToString("yyyy-MM-dd")
35
+ BlacklistedKeys = @()
36
+ BlacklistedReferers = @()
37
+ BlacklistedIPs = @()
38
+ BlacklistedLicenseIds = @()
39
+ BlacklistedResourceKeys = @()
40
+ }
41
+
42
+ # Convert the object to JSON.
43
+ $content = $blocklist | ConvertTo-Json -depth 32
44
+
45
+ # Create a file with the JSON content on disk.
46
+ $Null = New-Item . -Name $fileName -ItemType "file" -Value $content -Force
47
+
48
+ # Try to get the file share
49
+ $share = $null
50
+ try {
51
+ $share = Get-AzStorageShare `
52
+ -Name $shareName `
53
+ -Context $ctx `
54
+ -ErrorAction SilentlyContinue
55
+ } catch {}
56
+
57
+ # Create the file share if it does not exist.
58
+ if(-not($share)) {
59
+ $share = New-AzStorageShare `
60
+ -Name $shareName `
61
+ -Context $ctx
62
+ }
63
+
64
+ # Add the file to the file share.
65
+ $Null = Set-AzStorageFileContent `
66
+ -ShareName $shareName `
67
+ -Source $fileName `
68
+ -Context $ctx
69
+
70
+ # Cleanup the file on disk.
71
+ $Null = Remove-Item $fileName
72
+ }
73
+
74
+ # Create the shared access signature URI for accessing the file.
75
+ $StartTime = Get-Date
76
+ $EndTime = $StartTime.AddYears(50)
77
+
78
+ $token = New-AzStorageFileSASToken `
79
+ -ShareName $shareName `
80
+ -Path $fileName `
81
+ -Permission "r" `
82
+ -StartTime $StartTime `
83
+ -ExpiryTime $EndTime `
84
+ -Context $ctx
85
+
86
+ $sas = "$($ctx.FileEndPoint)$($shareName)/$($fileName)$($token)"
87
+
88
+ return $sas
89
+ }
90
+
91
+ # Add a Resource key to the entitlement table of a storage account.
92
+ function Add-ResourceKey {
93
+ param (
94
+ [Parameter(Mandatory=$true)]
95
+ [Object]$storageAccount
96
+ )
97
+
98
+ Write-Host "Setting up test resource key..."
99
+
100
+ # Make sure the AzTable module is installed
101
+ if (-not (Get-Module -ListAvailable -Name AzTable)) {
102
+ Write-Host "Az Table module does not exist, installing..."
103
+ Install-Module AzTable
104
+ }
105
+
106
+ # Construct the resource key table row
107
+ $resource = @{
108
+ partitionKey = "AQS5HKcyxmoxU0-q10g"
109
+ rowKey = "2020-02-05T15:23:17.1100358Z"
110
+ properties = @{
111
+ "AgreedToTerms"=$TRUE
112
+ "Domains"=""
113
+ "Email"="engineering@51degrees.com"
114
+ "ProductKeys"="FBVAAAELPALWBBNCEJAGALSAB2ASUP34ZHMR3475Y9SL92L2P7A5X6HUB8JYQFBC7GDNY9AYFYFS5VTYXTB8BNRCA5KXE"
115
+ "Properties"=""
116
+ "ReceiveMarketingEmails"=$FALSE
117
+ }
118
+ }
119
+
120
+ # Storage Account context
121
+ $ctx = $storageAccount.Context
122
+
123
+ # The name of the storage table
124
+ $name = "entitlement"
125
+
126
+ # Try to get the storage table.
127
+ $t = $null
128
+ try {
129
+ $t = Get-AzStorageTable `
130
+ -Name $name `
131
+ -Context $ctx `
132
+ -ErrorAction SilentlyContinue
133
+ } catch { }
134
+
135
+ # If the storage table sodes not exist then create it.
136
+ if (-not ($t)) {
137
+ $t = New-AzStorageTable -Name $name -Context $ctx
138
+ }
139
+
140
+ # Try to get the exisiting Resource Key.
141
+ $table = $t.CloudTable
142
+ $row = Get-AzTableRow -table $table -partitionKey $resource.partitionKey | Format-Table
143
+
144
+ # If it does not exist then create the Resource Key Row in the table.
145
+ if(-not ($row)) {
146
+ Add-AzTableRow `
147
+ -table $table `
148
+ -partitionKey $resource.partitionKey `
149
+ -rowKey $resource.rowKey `
150
+ -property $resource.properties
151
+ }
152
+
153
+ # Log the key to console.
154
+ Write-Host "Resource key for testing: $($resource.partitionKey)"
155
+ }
@@ -0,0 +1,45 @@
1
+ <#
2
+ ==================== ConnectAzure =====================
3
+ .Description
4
+ This module contains functions to connect to an Azure Account and select an
5
+ Azure subscription.
6
+ #>
7
+
8
+ function Connect-AzSubscription {
9
+
10
+ $subscriptionId=''
11
+ $ctx = $null
12
+
13
+ # Connect to the Azure remote management API. Authentication may be required.
14
+ Read-Host -Prompt ("You will be prompted to log in to your Microsoft work account. " +
15
+ "Please choose an account which has access to create new Azure resources. " +
16
+ "Press enter to continue...")
17
+ Connect-AzAccount
18
+
19
+ $subs = Get-AzSubscription
20
+
21
+ if ($subs.Length -eq 0) {
22
+ Write-Host ("No Azure subscriptions for this account could be found." +
23
+ "Please confirm this account has access to azure and try again.")
24
+ exit 1
25
+ }
26
+
27
+ $subs | Format-Table
28
+
29
+ while ($null -eq $ctx) {
30
+ while ('' -eq $subscriptionId) {
31
+ $subscriptionId = Read-Host -Prompt ("Choose the azure subscription id from "+
32
+ "above and paste on this line, then press enter to continue")
33
+ }
34
+
35
+ # Set the context to the subscription Id where the cluster will be created
36
+ try {
37
+ $ctx = Select-AzSubscription -SubscriptionId $subscriptionId -ErrorAction Stop
38
+ }
39
+ catch {
40
+ Write-Host "Invalid subscription selected."
41
+ }
42
+ }
43
+ }
44
+
45
+ Export-ModuleMember -Function Connect-AzSubscription
@@ -0,0 +1,100 @@
1
+ <#
2
+ ==================== SSLBindings =====================
3
+ .Description
4
+ This module contains a function to refresh the custom domains assigned to an
5
+ Azure app service and update the SSL bindings.
6
+
7
+ References:
8
+ https://github.com/uglide/azure-content/blob/master/articles/app-service-web/app-service-web-app-powershell-ssl-binding.md
9
+ https://docs.microsoft.com/en-us/powershell/module/Az.websites/remove-Azwebappsslbinding?view=Azps-6.13.0
10
+ #>
11
+
12
+ # Update hosts and SSL bindings for a web app.
13
+ function Set-SSLBindings {
14
+
15
+ param(
16
+ [Parameter(Mandatory=$true)]
17
+ [Hashtable[]]$Certs,
18
+
19
+ [Parameter(Mandatory=$true)]
20
+ [Hashtable[]]$Hosts,
21
+
22
+ [Parameter(Mandatory=$true)]
23
+ [Object]$Webapp
24
+ )
25
+
26
+ # Remove all the exising SSL bindings.
27
+ foreach ($hostName in $Hosts.Name) {
28
+ Remove-AzWebAppSSLBinding `
29
+ -ResourceGroupName $Webapp.ResourceGroup `
30
+ -WebAppName $Webapp.Name `
31
+ -Name $hostName `
32
+ -Force `
33
+ -DeleteCertificate $false
34
+ }
35
+
36
+ # Replace all the existing host names with the ones in this script.
37
+ Set-AzWebApp `
38
+ -ResourceGroupName $Webapp.ResourceGroup `
39
+ -Name $Webapp.Name `
40
+ -HostNames @($Hosts.Name, $Webapp.DefaultHostName) `
41
+ -Use32BitWorkerProcess $false
42
+
43
+ # # Upload the new SSL certificates if they do not exist and bind them to the
44
+ # # host name. If the SSL certificate does exist then use the existing one.
45
+ foreach($current in $Hosts) {
46
+
47
+ # Use the -like directive to find wildcard certificates that have the
48
+ # *.domain.com format.
49
+ Write-Host "Finding certificates for $($current.Name)"
50
+ $existing = New-Object -TypeName 'System.Collections.ArrayList'
51
+ foreach($cert in (Get-AzWebAppCertificate `
52
+ -ResourceGroupName $Webapp.ResourceGroup) | `
53
+ Where-Object { `
54
+ ($_.Location -eq $Webapp.Location) -and `
55
+ ($_.ExpirationDate -gt (Get-Date))}) {
56
+ foreach($hostName in $cert.HostNames) {
57
+ if ($current.Name -like $hostName) {
58
+ $existing.Add($cert) | Out-Null
59
+ Write-Host "Found" $cert.Thumbprint
60
+ Break
61
+ }
62
+ }
63
+ }
64
+
65
+ if (($null -eq $existing) -OR ($existing.Count -eq 0)) {
66
+
67
+ # There are no available certificates. Find the one that is contained
68
+ # in the same folder as this script and add it to the web app.
69
+ $cert = $Certs |
70
+ Where-Object CertificateFile -eq $current.CertificateFile |
71
+ Select-Object -First 1
72
+ if ($null -ne $cert) {
73
+ Write-Host "Adding certificate for $($current.Name)"
74
+ New-AzWebAppSSLBinding `
75
+ -ResourceGroupName $Webapp.ResourceGroup `
76
+ -WebAppName $Webapp.Name `
77
+ -Name $current.Name `
78
+ -CertificateFilePath (Join-Path $pwd $cert.CertificateFile) `
79
+ -CertificatePassword $cert.Password
80
+ } else {
81
+ Write-Host "No cerificate available for $($current.Name)"
82
+ }
83
+ } else {
84
+
85
+ # Order the list so that the certificate that expires the furthest in the
86
+ # future is used form the domain.
87
+ $existing = $existing | Sort-Object ExpirationDate -Descending
88
+
89
+ # Use the thumbprint from the certicate to set bind to the domain.
90
+ Write-Host "Using existing certificate $($existing[0].Thumbprint) for $($current.Name)"
91
+ New-AzWebAppSSLBinding `
92
+ -ResourceGroupName $Webapp.ResourceGroup `
93
+ -WebAppName $Webapp.Name `
94
+ -Name $current.Name `
95
+ -Thumbprint $existing[0].Thumbprint
96
+ }
97
+ }
98
+ }
99
+
100
+ Export-ModuleMember -Function Set-SSLBindings
@@ -0,0 +1,50 @@
1
+ <#
2
+ ==================== Staging Slots =====================
3
+ .Description
4
+ This module contains a function to refresh or add the staging slot on an
5
+ Azure App Service.
6
+ #>
7
+
8
+
9
+ function Add-WebAppStagingSlot {
10
+
11
+ param(
12
+ [Parameter(Mandatory=$true)]
13
+ [Object]$Webapp,
14
+
15
+ [Hashtable]$AppSettings
16
+ )
17
+
18
+ Write-Host "Adding Staging slot..."
19
+
20
+ # Remove the staging slot ready to rebuild it.
21
+ $null = Remove-AzWebAppSlot `
22
+ -ResourceGroupName $webapp.ResourceGroup `
23
+ -Name $webapp.Name `
24
+ -Slot "Staging" `
25
+ -Force
26
+
27
+ # Adds a new staging slot with fresh configuration.
28
+ $null = New-AzWebAppSlot `
29
+ -ResourceGroupName $webapp.ResourceGroup `
30
+ -Name $webapp.Name `
31
+ -Slot "Staging"
32
+
33
+ if ($null -eq $AppSettings){
34
+ $AppSettings = $webapp.SiteConfig.AppSettings
35
+ }
36
+
37
+ # Config the fresh staging slot. Belt and braces incase the CD script doesn't
38
+ # set the correct parameters.
39
+ $null = Set-AzWebAppSlot `
40
+ -ResourceGroupName $webapp.ResourceGroup `
41
+ -Name $webapp.Name `
42
+ -Slot "Staging" `
43
+ -AppSettings $AppSettings `
44
+ -WebSocketsEnabled $false `
45
+ -Use32BitWorkerProcess $false `
46
+ -AlwaysOn $true `
47
+ -FtpsState "Disabled"
48
+ }
49
+
50
+ Export-ModuleMember -Function Add-WebAppStagingSlot
@@ -0,0 +1,248 @@
1
+ <#
2
+ ==================== Stroage Accounts =====================
3
+ .Description
4
+ This module contains a function to create storage accounts.
5
+ References:
6
+ https://docs.microsoft.com/en-us/azure/cosmos-db/scripts/powershell/table/create
7
+ https://docs.microsoft.com/en-us/powershell/module/az.cosmosdb/new-azcosmosdbaccount
8
+ #>
9
+
10
+ # Create a new Storage Account
11
+ function New-StorageAcc {
12
+ param (
13
+ [Parameter(Mandatory = $true)]
14
+ [string]$storageAccName,
15
+
16
+ [Parameter(Mandatory = $true)]
17
+ [string]$resourceGroupName,
18
+
19
+ [Parameter(Mandatory = $true)]
20
+ [string]$region,
21
+
22
+ [Hashtable]$tags = @{}
23
+ )
24
+ Write-Host ""
25
+
26
+ while ($storageAccName.length -lt 3) {
27
+ $choice = Read-Host -Prompt ("Storage account name '$($storageAccName)' " +
28
+ "is too short, enter a new name here")
29
+ if (-not [string]::IsNullOrWhiteSpace($choice)) {
30
+ $storageAccName = $choice.Replace("-", "").ToLower()
31
+ }
32
+ }
33
+
34
+ while ($storageAccName.length -gt 24) {
35
+ $truncated = $storageAccName.Substring(0, 24)
36
+ $choice = Read-Host -Prompt ("Storage account name '$($storageAccName)' " +
37
+ "is too long, use trunctated name or enter a new name here [$($truncated)]")
38
+ if ([string]::IsNullOrWhiteSpace($choice)) {
39
+ $storageAccName = truncated
40
+ }
41
+ else {
42
+ $storageAccName = $choice.Replace("-", "").ToLower()
43
+ }
44
+ }
45
+
46
+ $sb = $null
47
+
48
+ while (-not $sb) {
49
+ # Check if storage account exists
50
+ $sb = Get-AzStorageAccount `
51
+ -ResourceGroupName $resourceGroupName `
52
+ -Name $storageAccName `
53
+ -ErrorAction SilentlyContinue
54
+
55
+ if(-not $sb) {
56
+ # create sotrage account
57
+ Write-Host "Creating storage account:" $storageAccName
58
+
59
+ $sb = New-AzStorageAccount `
60
+ -ResourceGroupName $resourceGroupName `
61
+ -Name $storageAccName `
62
+ -Location $region `
63
+ -Tag $tags `
64
+ -SkuName Standard_RAGRS `
65
+ -Kind StorageV2
66
+
67
+ if(-not $sb) {
68
+ # If there is still no storage account then the
69
+ # 'New-AzStorageAccount' command has failed. Retreive the last
70
+ # Azure Error.
71
+ $lastError = Resolve-AzError -Last -WarningAction silentlyContinue
72
+
73
+ # Check that the last error is from the expected source, if not
74
+ # we can't handle it. Prompt the user to check the Errors
75
+ # manually.
76
+ if ($lastError.Exception.Source -ne "Microsoft.Azure.PowerShell.Cmdlets.Storage.Management") {
77
+ Write-Host ("Could not resolve error creating storage " +
78
+ "account. Use the PowerShell Cmdlet 'Resolve-AzError -Last' to " +
79
+ "inspect the last Azure error in this session.")
80
+ exit 1
81
+ }
82
+
83
+ # If the stroage account name has already been taken then
84
+ # prompt the user for a new account name.
85
+ if ($lastError.Message.Contains("The storage account named " +
86
+ "$($storageAccName) is already taken. (Parameter 'Name')")) {
87
+ $storageAccName = Read-Host -Prompt ("Storage account name " +
88
+ "'$($storageAccName)' already taken in a different Azure " +
89
+ "subscription, enter a new name here")
90
+ } elseif ($lastError.Message.Contains("$($storageAccName) is not a " +
91
+ "valid storage account name.")) {
92
+ $storageAccName = Read-Host -Prompt ("'$($storageAccName)' is not a " +
93
+ "valid storage account name, enter a new name here")
94
+ # If the Azure error is not the expected error then abort
95
+ # the process and ask the user to review the Azure errors
96
+ # manually.
97
+ } else {
98
+ Write-Host "Error message: $($lastError.Message)"
99
+ Write-Host ("Could not resolve error creating storage " +
100
+ "account. Use the PowerShell Cmdlet 'Resolve-AzError -Last' to " +
101
+ "inspect the last Azure error in this session.")
102
+ exit 1
103
+ }
104
+ }
105
+ } else {
106
+ Write-Host -ForegroundColor Magenta ("Storage account '$($storageAccName)' " +
107
+ "already exists, using exsiting account")
108
+ }
109
+ }
110
+
111
+ return $sb
112
+ }
113
+
114
+ # Function to create a new Cosmos DB account. First check if one with the same
115
+ # account name exists already, if not the create a new one, otherwise prompt the
116
+ # user for a new name.
117
+ function New-CosmosAccount {
118
+
119
+ param (
120
+ # The name of the Cosmos DB Account
121
+ [Parameter(Mandatory = $true)]
122
+ [string]$accountName,
123
+
124
+ # The name of the resource group where the Cosmos DB account is created
125
+ # or located
126
+ [Parameter(Mandatory = $true)]
127
+ [string]$resourceGroupName,
128
+
129
+ # Tags to create the Cosmos DB account with.
130
+ [hashtable]$tags = @{},
131
+
132
+ # The kind of CosmosDB API to use.
133
+ [string]$apiKind = "Table",
134
+ [string]$consistencyLevel = "BoundedStaleness",
135
+ [int]$maxStalenessIntervalInSeconds = 86400,
136
+ [int]$maxStalenessPrefix = 1000000,
137
+ [Array]$locations = @(
138
+ (New-AzCosmosDBLocationObject -LocationName "West Europe" -FailoverPriority 0 -IsZoneRedundant 0),
139
+ (New-AzCosmosDBLocationObject -LocationName "Central US" -FailoverPriority 1 -IsZoneRedundant 0)
140
+ # TODO consider adding central india as a cosmos db region.
141
+ #(New-AzCosmosDBLocationObject -LocationName "Central India" -FailoverPriority 1 -IsZoneRedundant 0)
142
+ )
143
+ )
144
+
145
+ $cosmosDBAccount = $null
146
+
147
+ while (-not $cosmosDBAccount) {
148
+ # Get an existing Cosmos DB account.
149
+ $cosmosDBAccount = Get-AzCosmosDBAccount `
150
+ -ResourceGroupName $resourceGroupName `
151
+ -Name $accountName `
152
+ -ErrorAction SilentlyContinue
153
+
154
+ if (-not $cosmosDBAccount) {
155
+ # If there is no Cosmos DB account then try to create one.
156
+ Write-Host "Creating Cosmos DB account '$($accountName)'"
157
+ $cosmosDBAccount = New-AzCosmosDBAccount `
158
+ -ResourceGroupName $resourceGroupName `
159
+ -Name $accountName `
160
+ -LocationObject $locations `
161
+ -ApiKind $apiKind `
162
+ -DefaultConsistencyLevel $consistencyLevel `
163
+ -MaxStalenessIntervalInSeconds $maxStalenessIntervalInSeconds `
164
+ -MaxStalenessPrefix $maxStalenessPrefix `
165
+ -Tag $tags
166
+
167
+ if (-not $cosmosDBAccount) {
168
+ # If there is still no Cosmos DB account then the
169
+ # 'New-AzCosmosDBAccount' command has failed. Retreive the last
170
+ # Az Error.
171
+ $lastError = Resolve-AzError -Last -WarningAction silentlyContinue
172
+
173
+ # Check that the last error is from the expected source, if not
174
+ # we can't handle it. Prompt the user to check the Errors
175
+ # manually.
176
+ if ($lastError.Exception.Source -ne "Microsoft.Azure.Management.CosmosDB") {
177
+ Write-Host ("Could not resolve error creating cosmos DB " +
178
+ "account. Use the PowerShell Cmdlet 'Resolve-AzError -Last' to " +
179
+ "inspect the last Azure error in this session.")
180
+ exit 1
181
+ }
182
+
183
+ # The Cosmos DB DNS record is determined by the account name.
184
+ # If the error is caused by the DNS record being taken then
185
+ # prompt the user for a new account name.
186
+ if ($lastError.Message.Contains("Dns record for " +
187
+ "$($accountName) under zone Document is already " +
188
+ "taken. Please use a different name for the account")) {
189
+ $suggestion = $accountName + "-1"
190
+ $choice = Read-Host -Prompt ("Cosmos DB account name " +
191
+ "'$($accountName)' already taken in a different Azure " +
192
+ "Subscription, use suggestion or enter a new name here [$($suggestion)]")
193
+
194
+ if ([string]::IsNullOrWhiteSpace($choice)) {
195
+ $accountName = $suggestion
196
+ }
197
+ else {
198
+ $accountName = $choice
199
+ }
200
+ # If the Cosmos DB error is not the expected error then abort
201
+ # the process and ask the user to review the Azure errors
202
+ # manually.
203
+ }
204
+ else {
205
+ Write-Host "Error message: $($lastError.Message)"
206
+ Write-Host ("Could not resolve error creating cosmos DB " +
207
+ "account. Use the PowerShell Cmdlet 'Resolve-AzError -Last' to " +
208
+ "inspect the last Azure error in this session.")
209
+ exit 1
210
+ }
211
+ }
212
+ } else {
213
+ Write-Host -ForegroundColor Magenta ("Cosmos DB account '$($accountName)' " +
214
+ "exists, using existing account.")
215
+ }
216
+ }
217
+
218
+ return $cosmosDBAccount
219
+ }
220
+
221
+ function New-CosmosDbTable {
222
+
223
+ param (
224
+ [Parameter(Mandatory=$true)]
225
+ [object]$cosmosAccount,
226
+
227
+ [Parameter(Mandatory=$true)]
228
+ [string]$tableName,
229
+
230
+ [Parameter(Mandatory=$true)]
231
+ [int]$tableRUs
232
+ )
233
+
234
+ $table = Get-AzCosmosDBTable `
235
+ -Name $tableName `
236
+ -ParentObject $cosmosAccount `
237
+ -ErrorAction SilentlyContinue
238
+
239
+ if(-not $table) {
240
+ Write-Host "Creating Cosmos DB table: $($tableName)"
241
+ New-AzCosmosDBTable `
242
+ -ParentObject $cosmosAccount `
243
+ -Name $tableName `
244
+ -Throughput $tableRUs
245
+ } else {
246
+ Write-Host "Cosmos DB table '$($tableName)' already exists."
247
+ }
248
+ }