scripts/settings.ps1 (461 lines of code) (raw):
<#
.SYNOPSIS
Token Setting Script
.DESCRIPTION
This script performs the tasks of getting a Refresh Token and creating the .vscode settings.json file.
.PARAMETER SubscriptionId
Specify a particular SubscriptionId to use.
.PARAMETER ApplicationId
Specify the ApplicationId to use.
.PARAMETER ApplicationSecret
Specify the ApplicationSecret to use.
.PARAMETER ResourceGroup
Specify the ResourceGroup to use.
.PARAMETER Help
Print help message and exit.
.NOTES
The AUTH_CODE environment variable must be set for the script to run successfully. This variable is required to obtain a Refresh Token.
.EXAMPLE
.\settings.ps1 -SubscriptionId <SubscriptionId> -ApplicationId <ApplicationId> -ApplicationSecret <ApplicationSecret> -ResourceGroup <ResourceGroup>
#>
#Requires -Version 7.4
param (
[ValidateNotNullOrEmpty()]
[string]$SubscriptionId = $env:AZURE_SUBSCRIPTION_ID,
[ValidateNotNullOrEmpty()]
[string]$ResourceGroup = $env:AZURE_RESOURCE_GROUP,
[ValidateNotNullOrEmpty()]
[string]$ApplicationId = $env:AZURE_CLIENT_ID,
[ValidateNotNullOrEmpty()]
[string]$ApplicationSecret = $env:AZURE_CLIENT_SECRET,
[switch]$Help
)
function Show-Help {
Write-Host "Usage: .\settings.ps1 [-SubscriptionId SUBSCRIPTION_ID] [-ApplicationId APPLICATION_ID] [-ApplicationSecret APPLICATION_SECRET] [-ResourceGroup RESOURCE_GROUP]"
Write-Host "Options:"
Write-Host " -SubscriptionId : Specify a particular Subscription ID to use."
Write-Host " -ResourceGroup : Specify the Resource Group to use."
Write-Host " -ApplicationId : Specify the Application ID to use."
Write-Host " -ApplicationSecret : Specify the Application Secret to use."
Write-Host " -Help : Print this help message and exit"
}
function Get-AKSName {
try {
# Check if AKS_NAME is provided, if not retrieve it
if (-not $env:AKS_NAME) {
Write-Host " AKS_NAME not provided. Retrieving AKS name."
$aksList = az aks list -g $ResourceGroup --query '[0].name' -o tsv
if ($aksList) {
return $aksList
} else {
Write-Host " No AKS cluster found in the resource group."
exit 1
}
} else {
return $env:AKS_NAME
}
} catch {
Write-Host "Error retrieving AKS name: $_"
exit 1
}
}
function Set-AuthIngress {
if (-not $env:AUTH_INGRESS) {
Write-Host "`n=================================================================="
Write-Host "Azure Kubernetes Cluster: $AKS_NAME"
Write-Host "=================================================================="
Write-Host " Fetching Ingress IP Address..."
$nodeResourceGroup = az aks show -g $ResourceGroup -n $AKS_NAME --query nodeResourceGroup -o tsv
if ($env:INGRESS -eq 'internal') {
$env:AUTH_INGRESS = az network lb frontend-ip list --lb-name kubernetes-internal -g $nodeResourceGroup --query '[].privateIPAddress' -o tsv
} else {
$env:AUTH_INGRESS = az network public-ip list -g $nodeResourceGroup --query "[?contains(name, 'kubernetes')].ipAddress" -o tsv
}
azd env set AUTH_INGRESS $env:AUTH_INGRESS
} else {
Write-Host "`n=================================================================="
Write-Host "Ingress IP: $env:AUTH_INGRESS"
Write-Host "=================================================================="
}
}
function Get-RefreshToken {
if (-not $env:AUTH_REFRESH) {
if (-not $env:AUTH_CODE) {
Write-Output "Error: Neither AUTH_CODE nor AUTH_REFRESH is available."
exit 1
} else {
Write-Output "`n=================================================================="
Write-Output "Azure Application: $ApplicationId"
Write-Output "=================================================================="
Write-Output "Getting a Refresh Token using the Authorization Code..."
$body = @{
grant_type = "authorization_code"
redirect_uri = "https://$env:AUTH_INGRESS/auth/"
client_id = $ApplicationId
client_secret = $ApplicationSecret
scope = "$ApplicationId/.default openid profile offline_access"
code = $env:AUTH_CODE
}
try {
$response = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$env:AZURE_TENANT_ID/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $body
Write-Output "Request successful."
$refresh_token = $response.refresh_token
azd env set AUTH_REFRESH $refresh_token
azd env set AUTH_CODE ""
} catch {
Write-Output "Request failed. Status: $($_.Exception.Response.StatusCode). Body: $($_.Exception.Response.Content)"
Write-Output "Error Message: $($_.Exception.Message)"
Write-Output "Response Content: $($_.Exception.Response.Content.ReadAsStringAsync().Result)"
exit 1
}
}
}
}
function New-EnvFile {
Write-Host "`n=================================================================="
Write-Host "Creating File: ../src/.envrc"
Write-Host "=================================================================="
$templatePath = "./scripts/envrc_template"
$outputPath = "./src/.envrc"
if (-not (Test-Path $templatePath)) {
Write-Host "Error: Template file not found at $templatePath"
exit 1
}
$content = Get-Content $templatePath -Raw
$variablePattern = '%(\w+)%'
$foundMatches = [regex]::Matches($content, $variablePattern)
foreach ($match in $foundMatches) {
$variableName = $match.Groups[1].Value
$environmentValue = [Environment]::GetEnvironmentVariable($variableName)
if ($null -eq $environmentValue) {
Write-Host "Warning: Environment variable $variableName not found. Leaving as is in the output."
} else {
$content = $content -replace "%$variableName%", $environmentValue
}
}
New-Item -Path (Split-Path $outputPath) -ItemType Directory -Force | Out-Null
$content | Out-File -FilePath $outputPath -Encoding utf8
Write-Host "File created successfully at $outputPath"
}
function New-VSCodeSettings {
Write-Host "`n=================================================================="
Write-Host "Creating File: .vscode/settings.json"
Write-Host "=================================================================="
$output = azd env get-values
$envValues = @{}
$output | ForEach-Object {
if ($_ -match '^(.*?)="(.*)"$') {
$name = $matches[1]
$value = $matches[2]
$envValues[$name] = $value
}
}
$AZURE_TENANT_ID = $envValues["AZURE_TENANT_ID"]
$AUTH_INGRESS = $envValues["AUTH_INGRESS"]
$AUTH_REFRESH = $envValues["AUTH_REFRESH"]
New-Item -Path .vscode -ItemType Directory -Force | Out-Null
@"
{
"rest-client.environmentVariables": {
"${ResourceGroup}": {
"TENANT_ID": "${AZURE_TENANT_ID}",
"CLIENT_ID": "${ApplicationId}",
"CLIENT_SECRET": "${ApplicationSecret}",
"HOST": "http://${AUTH_INGRESS}",
"REFRESH_TOKEN": "${AUTH_REFRESH}",
"DATA_PARTITION": "opendes"
}
},
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"src/lib/os-core-common": true,
"src/lib/os-core-lib-azure": true,
"src/lib/os-core-lib-azure-spring-6": true,
"src/core/partition": true,
"src/core/entitlements": true,
"src/core/legal": true,
"src/core/schema-service": true,
"src/core/indexer-service": true,
"src/core/indexer-queue": true,
"src/core/storage": true,
"src/core/search-service": true,
"src/core/file": true,
"src/core/ingestion-workflow": true,
"src/reference/unit-service": true,
"src/reference/crs-catalog-service": true,
"src/reference/crs-conversion-service": true
}
}
"@ > .vscode/settings.json
}
function New-YamlFile {
Write-Host "`n=================================================================="
Write-Host "Processing YAML file: ./scripts/template.yaml"
Write-Host "=================================================================="
# Read the YAML file
$yamlContent = Get-Content "./scripts/template.yaml" -Raw
# Find all levels of nodes using regex
$nodeMatches = [regex]::Matches($yamlContent, '(?m)^(\s*)(\w+):(.*)')
# Initialize variables
$currentLevel = -1
$nodePath = @()
$osduGroupNode = ""
$serviceNameNode = "" # This will hold the service name (e.g., partition, entitlements, unit)
$projectTaskNode = "" # This will be RUN or TEST
$contentBuffer = @()
$captureContent = $false
# Function to write buffered content to file
function WriteBufferToFile {
if ($captureContent -and $contentBuffer.Count -gt 0) {
# Changed the order here: project task first, then service name
$outputFileName = "${projectTaskNode}_${serviceNameNode}.yaml".ToLower()
$outputPath = Join-Path $outputDirectory $outputFileName
$contentBuffer | Out-File -FilePath $outputPath -Encoding utf8
$contentBuffer.Clear()
}
}
# Function to replace environment variable placeholders
function Replace-EnvironmentVariables($value) {
return [regex]::Replace($value, '%(\w+)%', {
param($match)
$envVar = $match.Groups[1].Value
$envValue = [Environment]::GetEnvironmentVariable($envVar)
if ($null -ne $envValue) {
return $envValue
}
return $match.Value # Return original value if environment variable not found
})
}
# Process each line in the YAML file
foreach ($match in $nodeMatches) {
$indent = $match.Groups[1].Value.Length / 2 # Convert indent to level
$nodeName = $match.Groups[2].Value # Keep original case
$nodeValue = $match.Groups[3].Value.Trim()
# Process top-level categories in the YAML (e.g., CORE, REFERENCE)
if ($indent -eq 0) {
WriteBufferToFile # Write any existing buffer
$currentLevel = 0
$nodePath = @($nodeName)
$osduGroupNode = $nodeName
# Create output directory for the new OSDU group node
$outputDirectory = "./src/$osduGroupNode".ToLower()
New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null
$captureContent = $false
}
# Process node at a deeper level than current
elseif ($indent -gt $currentLevel) {
if ($indent -eq 1) {
# This is where services (partition, entitlements, unit, etc.) are parsed
$serviceNameNode = $nodeName
}
elseif ($indent -eq 2) {
WriteBufferToFile # Write any existing buffer
$projectTaskNode = $nodeName # This will be RUN or TEST
$captureContent = $true # Start capturing content for this node
}
$currentLevel = $indent
$nodePath += $nodeName
}
# Process node at the same level
elseif ($indent -eq $currentLevel) {
if ($indent -eq 1) {
# This is also where services are parsed when moving to a new service at the same level
WriteBufferToFile # Write any existing buffer
$serviceNameNode = $nodeName
}
elseif ($indent -eq 2) {
WriteBufferToFile # Write any existing buffer
$projectTaskNode = $nodeName # This will be RUN or TEST
$captureContent = $true # Start capturing content for this node
}
$nodePath[-1] = $nodeName
}
# Process node at a higher level (less indented)
else {
WriteBufferToFile # Write any existing buffer
$nodePath = $nodePath[0..$indent] + @($nodeName)
$currentLevel = $indent
if ($currentLevel -eq 1) {
# This is where services are parsed when moving back up to the service level
$serviceNameNode = $nodeName
}
elseif ($currentLevel -eq 2) {
$projectTaskNode = $nodeName # This will be RUN or TEST
$captureContent = $true # Start capturing content for this node
}
else {
$captureContent = $false
}
}
# Capture content for child nodes of RUN and TEST (indent level 3)
if ($captureContent -and $indent -eq 3) {
# This is where individual environment settings (key-value pairs) are processed
# These are the actual environment settings that will be written to the file
if ($nodeValue -ne "") {
$replacedValue = Replace-EnvironmentVariables $nodeValue
$contentBuffer += "{0}: {1}" -f $nodeName, $replacedValue
} else {
$contentBuffer += "{0}:" -f $nodeName
}
}
}
# Write the last file if there's content in the buffer
WriteBufferToFile
}
function New-ServiceEnvFile {
Write-Host "`n=================================================================="
Write-Host "Processing YAML file: ./scripts/template.yaml"
Write-Host "=================================================================="
# Read the YAML file
$yamlContent = Get-Content "./scripts/template.yaml" -Raw
# Find all levels of nodes using regex
$nodeMatches = [regex]::Matches($yamlContent, '(?m)^(\s*)(\w+):(.*)')
# Initialize variables
$currentLevel = -1
$nodePath = @()
$osduGroupNode = ""
$serviceNameNode = ""
$projectTaskNode = ""
$contentBuffer = @()
$captureContent = $false
# Function to write buffered content to file
function WriteBufferToFile {
if ($captureContent -and $contentBuffer.Count -gt 0) {
$outputFileName = "${projectTaskNode}_${serviceNameNode}.env".ToLower()
$outputPath = Join-Path $outputDirectory $outputFileName
$contentBuffer | Out-File -FilePath $outputPath -Encoding utf8
$contentBuffer.Clear()
}
}
# Function to replace environment variable placeholders
function Replace-EnvironmentVariables($value) {
return [regex]::Replace($value, '%(\w+)%', {
param($match)
$envVar = $match.Groups[1].Value
$envValue = [Environment]::GetEnvironmentVariable($envVar)
if ($null -ne $envValue) {
return $envValue
}
return $match.Value
})
}
# Process each line in the YAML file
foreach ($match in $nodeMatches) {
$indent = $match.Groups[1].Value.Length / 2
$nodeName = $match.Groups[2].Value
$nodeValue = $match.Groups[3].Value.Trim()
if ($indent -eq 0) {
WriteBufferToFile
$currentLevel = 0
$nodePath = @($nodeName)
$osduGroupNode = $nodeName
$outputDirectory = "./src/$osduGroupNode".ToLower()
New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null
$captureContent = $false
}
elseif ($indent -gt $currentLevel) {
if ($indent -eq 1) {
$serviceNameNode = $nodeName
}
elseif ($indent -eq 2) {
WriteBufferToFile
$projectTaskNode = $nodeName
$captureContent = $true
}
$currentLevel = $indent
$nodePath += $nodeName
}
elseif ($indent -eq $currentLevel) {
if ($indent -eq 1) {
WriteBufferToFile
$serviceNameNode = $nodeName
}
elseif ($indent -eq 2) {
WriteBufferToFile
$projectTaskNode = $nodeName
$captureContent = $true
}
$nodePath[-1] = $nodeName
}
else {
WriteBufferToFile
$nodePath = $nodePath[0..$indent] + @($nodeName)
$currentLevel = $indent
if ($currentLevel -eq 1) {
$serviceNameNode = $nodeName
}
elseif ($currentLevel -eq 2) {
$projectTaskNode = $nodeName
$captureContent = $true
}
else {
$captureContent = $false
}
}
# Capture content for child nodes of RUN and TEST (indent level 3)
if ($captureContent -and $indent -eq 3) {
if ($nodeValue -ne "") {
$replacedValue = Replace-EnvironmentVariables $nodeValue
$contentBuffer += "{0}={1}" -f $nodeName.ToUpper(), $replacedValue
} else {
$contentBuffer += "{0}=" -f $nodeName.ToUpper()
}
}
}
# Write the last file if there's content in the buffer
WriteBufferToFile
}
function Get-AppInsights {
Write-Host "`n=================================================================="
Write-Host "Downloading Application Insights Agent"
Write-Host "=================================================================="
$url = "https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.6.2/applicationinsights-agent-3.6.2.jar"
$outputPath = "./src/applicationinsights-agent.jar"
try {
Invoke-WebRequest -Uri $url -OutFile $outputPath
Write-Host "Application Insights agent downloaded successfully to $outputPath"
} catch {
Write-Host "Error downloading Application Insights agent: $_"
exit 1
}
}
if ($Help) {
Show-Help
exit 0
}
if (-not $SubscriptionId) {
Write-Output "Error: You must provide a SubscriptionId"
Show-Help
exit 1
}
if (-not $ApplicationId) {
Write-Output 'ERROR: ApplicationId not provided'
exit 1
}
if (-not $ApplicationSecret) {
Write-Output 'ERROR: ApplicationSecret not provided'
exit 1
}
if (-not $ResourceGroup) {
Write-Output 'ERROR: ResourceGroup not provided'
exit 1
}
if (-not $env:AZURE_TENANT_ID) {
$env:AZURE_TENANT_ID = az account show --query tenantId -o tsv
azd env set AZURE_TENANT_ID $env:AZURE_TENANT_ID
}
# Ensure the Subscription is set for the Azure CLI
az account set --subscription $SubscriptionId
Write-Host "`n=================================================================="
Write-Host "Azure Subscription: $SubscriptionId"
Write-Host "=================================================================="
$AKS_NAME = Get-AKSName
Set-AuthIngress
Get-RefreshToken
Get-AppInsights
New-EnvFile
New-ServiceEnvFile
# New-YamlFile
New-VSCodeSettings