I have this script that should create Sub-task when certain quota level will be breached.
For Azure resources I auth by Managed Identity.
I have tried 2 methods of auth: token, pass+username.
In both cases (if I use any of those method) I got 401. My user had full admin rights to the project. Other time, I can see no error at all, but sub-task i not created. Can someone tell what is wrong?
----
# Import the required Azure modules
Import-Module Az.Accounts
Import-Module Az.Storage
Import-Module Az.Resources
# Authenticate to Azure
Connect-AzAccount -Identity
# Variables
$env:AZURE_STORAGE_CONNECTION_STRING = "xxx"
$storageAccountName = "yyy"
$subscriptionId = "zzz"
$storageAccountKey = "aaa"
$resourceGroupName = "bbb"
# JIRA Variables
$jiraUrl = "https://vvvvvvv.atlassian.net"
$jiraApiPath = "/rest/api/2/issue"
$jiraProjectKey = "nnn"
$jiraIssueType = "Sub-task" # Specify 'Sub-task' as the issue type
$jiraParentIssueKey = "mmmmm" # Replace with the key of the parent issue
$jiraUsername = "xyz@xyz.com"
$jiraPassword = "password"
$jiraApiToken = "token"
#AUTH
# # $pair = "$jiraUsername?$jiraApiToken"
# # $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
# $pair = "$($jiraUsername):$($jiraApiToken)"
# $encodedCreds = [System.Text.Encoding]::UTF8.GetBytes($pair)
# $encodedBase64 = $authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$jiraUsername`:$jiraApiToken"))
# $basicAuthValue = "Basic $encodedBase64"
# $authHeader = @{
# Authorization = $basicAuthValue
# }
Invoke-WebRequest -uri $($jiraUrl + "/rest/api/latest/search?jql=$jql") -Headers $authHeader -ErrorAction Stop -Verbose
# Authentication using Username and Password
$pair = "$($jiraUsername):$($jiraPassword)"
$encodedCreds = [System.Text.Encoding]::UTF8.GetBytes($pair)
$encodedBase64 = [System.Convert]::ToBase64String($encodedCreds)
$basicAuthValue = "Basic $encodedBase64"
$authHeader = @{
"Authorization" = $basicAuthValue
"Content-Type" = "application/json"
}
# Get the storage account context
$storageAccount = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey
$ctx = $storageAccount.Context
# Get the list of file shares
$fileShares = az storage share list --account-name $storageAccountName --query "[].name" -o tsv
# Loop through each file share and retrieve quota and usage
foreach ($shareName in $fileShares) {
try {
$usage = Get-AzRmStorageShare -ResourceGroupName $resourceGroupName -StorageAccountName $storageAccountName -Name $shareName -GetShareUsage
Write-Output $usage
Write-Output "-----------------------------"
# Check if usage data is returned
if ($usage -ne $null) {
# Extract the ShareUsageBytes property (update the property name if necessary)
$usageInBytes = $usage.ShareUsageBytes # Adjust property name as needed
# Convert bytes to gigabytes
$usageInGB = $usageInBytes / 1GB
# Example quota value (you should replace this with actual quota retrieval logic)
$quotaInBytes = 10GB # Adjust the quota value as needed
$quotaInGB = $quotaInBytes / 1GB
# Calculate usage percentage
$usagePercentage = ($usageInGB / $quotaInGB) * 100
# Format and output the result
Write-Output "File Share: $shareName"
Write-Output "Usage: $([math]::Round($usageInGB, 2)) GB"
Write-Output "Quota: $([math]::Round($quotaInGB, 2)) GB"
Write-Output "Usage Percentage: $([math]::Round($usagePercentage, 2))%"
Write-Output "-----------------------------"
# Check if usage exceeds 80% of quota
if ($usagePercentage -gt 80) {
# Create a new JIRA subtask
$issue = @{
fields = @{
project = @{
key = $jiraProjectKey
}
parent = @{
key = $jiraParentIssueKey
}
summary = "File Share Usage Alert: $shareName"
description = "The file share '$shareName' has exceeded 80% of its quota. Current usage: $([math]::Round($usageInGB, 2)) GB."
issuetype = @{
name = $jiraIssueType
}
}
}
$issueJson = $issue | ConvertTo-Json -Depth 10
# Send the request to JIRA API
$response = Invoke-RestMethod -Uri "$jiraUrl$jiraApiPath" `
-Method Post `
-Headers $authHeader `
-Body $issueJson -Verbose
Write-Output "JIRA Sub-task Created: $($response.key)"
}
}
else {
Write-Output "No usage data found for file share: $shareName"
}
} catch {
Write-Error "An error occurred: $($_.Exception.Message)"
Write-Output "StatusCode: $($_.Exception.Response.StatusCode.value__)"
Write-Output "Response: $($_.Exception.Response.Content)"
}
}
----
# JIRA Variables
$jiraUrl = "https://vvvvv.atlassian.net/"
$jiraUsername = "zzzzz"
$jiraApiToken = "bbbbb"
$jiraApiPath = "/rest/api/2/issue" # JIRA API endpoint for creating issues
# Authentication
$pair = "$jiraUsername?$jiraApiToken"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
$cred = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$jiraUsername`:$pass"))
# Define the sub-task details
$subTask = @{
fields = @{
project = @{
key = "xyz" # Replace with your project key
}
parent = @{
key = "xyz-xyz1234" # Replace with the parent issue key
}
summary = "This is a sub-task created from PowerShell"
description = "Detailed description of the sub-task."
issuetype = @{
name = "Sub-task" # Issue type must be "Sub-task"
}
}
}
# Convert the sub-task details to JSON
$subTaskJson = $subTask | ConvertTo-Json -Depth 10
# Create the sub-task
try {
$response = Invoke-RestMethod -Uri "$jiraUrl" `
-Method Post `
-Headers @{
"Content-Type" = "application/json"
"Authorization" = "Basic $base64AuthInfo"
} `
-Body $subTaskJson -Verbose
Write-Output "JIRA Sub-task Created: $($response.key)"
}
catch {
$errorResponse = $_.Exception.Response
$statusCode = $errorResponse.StatusCode.value__
$content = $errorResponse.Content.ReadAsStringAsync().Result
Write-Error "An error occurred: $($_.Exception.Message)"
Write-Output "StatusCode: $statusCode"
Write-Output "Response: $content"
}
If I use that last above script in powershell ISE (locally) I get:
PS C:\Windows\system32>
VERBOSE: POST https://vvvvvvv.atlassian.net/ with -1-byte payload
VERBOSE: received 7333-byte response of content type text/html
JIRA Sub-task Created:
PS C:\Windows\system32>
EDIT:
Trying also from POSTMAN with API v2/3 and got this: