Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#Source: https://stackoverflow.com/questions/52722373/create-database-and-collection-on-cosmos-db-sql-api-inside-azuredevopps-vsts
param($endpoint, $masterKey, $databaseName, $collectionName, $collectionRUs, $partitionKey)
Add-Type -AssemblyName System.Web
Add-Type -TypeDefinition @"
public enum CosmosResourceType
{
Database,
Collection
}
"@
Function Create-Resource
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$endPoint,
[Parameter(Mandatory=$true)][String]$masterKey,
[Parameter(Mandatory=$true)][String]$dataBaseName,
[Parameter(Mandatory=$true)][String]$collectionName,
[Parameter(Mandatory=$true)][CosmosResourceType]$cosmosResourceType
)
$verb = "POST";
$resourceType = "dbs";
$resourceLink = "dbs";
$header = "";
$idValue = "";
$contentType = "application/json";
$queryUri = "$endPoint$resourceLink"
if($cosmosResourceType -eq "Database")
{
$header = Generate-Headers -verb $verb -resourceType $resourceType -key $masterKey
$idValue = $dataBaseName
}
elseif($cosmosResourceType -eq "Collection")
{
$resourceType = "colls";
$resourceLink = "dbs/$dataBaseName"
$header = Generate-Headers -verb $verb -resourceType $resourceType -resourceLink $resourceLink -key $masterKey
# Not sure why but at this moment Cosmos Db ignores this setting
$header | Add-Member -Name 'x-ms-offer-throughput' -Type NoteProperty -Value "5000"
$idValue = $collectionName
$queryUri = "$endPoint$resourceLink/colls"
}
else
{
Write-Host "Invalid Cosmos Resource Type:"$cosmosResourceType -ForeGroundColor Red
}
#$bodyMessage = @{id = $idValue }
#$jsonDoc = [pscustomobject]$bodyMessage
#$jsonDoc = $jsonDoc | ConvertTo-Json
Write-Host "Body: " $jsonDoc
$response = InvokeRest -verb $Verb -ContentType $contentType -uri $queryUri -headers $header -body $jsonDoc
if($response.code.ToLowerInvariant() -eq "Conflict".ToLowerInvariant())
{
Write-Host "Warning: $cosmosResourceType already existing" -ForeGroundColor Yellow
}
elseif($response.code.ToLowerInvariant() -eq "Ok".ToLowerInvariant())
{
Write-Host "$cosmosResourceType Created" -ForeGroundColor Green
}
else
{
Write-Host "response:"$response -ForeGroundColor Red
}
}
Function InvokeRest
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]$verb,
[Parameter(Mandatory=$true)]$contentType,
[Parameter(Mandatory=$true)]$uri,
[Parameter(Mandatory=$true)]$headers,
[Parameter(Mandatory=$false)]$body
)
Try {
$result = Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $uri -Headers $headers -Body $body
Write-Host "InvokeRest: "$result -ForeGroundColor Green
$response = [pscustomobject]@{
code = "OK"
body = $result
}
return $response
}
Catch {
# Check if there is a response.
if ($_.Exception.Response -eq $null) {
$expMessage = $_.Exception.Message
$failedItem = $_.Exception.Source
$line = $_.InvocationInfo.ScriptLineNumber
Write-Host "At $($line):`r`n$expMessage `r`n$failedItem" -ForeGroundColor Red
throw $_.Exception
}
else {
# Get the response body with more error detail.
$respStream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$response = $reader.ReadToEnd() | ConvertFrom-Json
return $response
}
}
}
Function Generate-Headers
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$key
)
$dateTime = [DateTime]::UtcNow.ToString("r")
$authHeader = Generate-MasterKeyAuthorizationSignature -verb $verb -resourceLink $resourceLink -resourceType $resourceType -key $masterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
Write-Host $authHeader
$header = @{authorization=$authHeader;"x-ms-version"="2017-02-22";"x-ms-date"=$dateTime;"x-ms-offer-throughput"=$collectionRUs}
return $header
}
Function Generate-MasterKeyAuthorizationSignature
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$key,
[Parameter(Mandatory=$true)][String]$keyType,
[Parameter(Mandatory=$true)][String]$tokenVersion,
[Parameter(Mandatory=$true)][String]$dateTime
)
$hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
$hmacSha256.Key = [System.Convert]::FromBase64String($key)
$payLoad = Generate-Payload -verb $verb -resourceLink $resourceLink -resourceType $resourceType -dateTime $dateTime
$hashPayLoad = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payLoad))
$signature = [System.Convert]::ToBase64String($hashPayLoad);
[System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$signature")
}
Function Generate-Payload
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$verb,
[Parameter(Mandatory=$false)][String]$resourceLink,
[Parameter(Mandatory=$true)][String]$resourceType,
[Parameter(Mandatory=$true)][String]$dateTime
)
$payLoad = ""
if ( [string]::IsNullOrEmpty($resourceLink) )
{
$payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n`n$($dateTime.ToLowerInvariant())`n`n"
}
else
{
$payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n$resourceLink`n$($dateTime.ToLowerInvariant())`n`n"
}
return $payLoad
}
$jsonDoc = @"
{
"id": "$databaseName",
"partitionKey": {
"paths": [
"$partitionKey"
],
"kind": "Hash"
}
}
"@
# Create Database
$cosmosResourceType = [CosmosResourceType]::Database
Create-Resource -endPoint $endpoint -masterKey $masterKey -dataBaseName $databaseName -collectionName $collectionName -cosmosResourceType $cosmosResourceType
# Create Collection
$cosmosResourceType = [CosmosResourceType]::Collection
Create-Resource -endPoint $endpoint -masterKey $masterKey -dataBaseName $databaseName -collectionName $collectionName -cosmosResourceType $cosmosResourceType
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment