Azure PowerShell Az module: generate bearer token for Databricks - azure-powershell

I need to generate token for Databricks usage (it will be used to generate Databricks token)
In Azure CLI az account get-access-token --resource '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d' --out tsv --query '[accessToken]' worked perfectly well
I know that there's no alternative in Azure PowerShell Az module so I did research and found the following:
$context = Get-AzContext
$profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($profile)
$token = $profileClient.AcquireAccessToken($context.Subscription.TenantId)
$token.AccessToken
It does work, but generated token has https://management.core.windows.net/ claim instead of 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d required for Databricks
Any ideas how to run alternative to az account get-access-token --resource '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d' in Azure PowerShell with Az module?
I have service principal with certificate auth protected by password and can't use az cli / python /etc, just Azure PowerShell Az module

If you want to call Azure Databricks REST API with Azure Powershell, please refer to the following script
$teantId
$subId="the id of the subscription which contains the databrick"
Connect-AzAccount -Subscription $subId -Tenant $teantId
$context= Get-AzContext
$resource="2ff814a6-3304-4ab8-85cb-cd0e6f879c1d"
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account,
$context.Environment,
$context.Tenant.Id.ToString(),
$null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $resource).AccessToken
$groupName="the databrick resource group name"
$workSpaceName="the databrick workspace name"
$headers=#{
"Authorization"= "Bearer " + $token;
"X-Databricks-Azure-Workspace-Resource-Id" = "/subscriptions/$($subId)/resourceGroups/$($groupName)/providers/Microsoft.Databricks/workspaces/$($workSpaceName)"
}
$databricksInstance="" # such as adb-976301816870846.6.azuredatabricks.net
$url="https://$($databricksInstance)/api/2.0/clusters/list"
$result=Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType "application/json" -UseBasicParsing
$result| ConvertTo-Json
For more details about how to call Azure Databricks REST API, please refer to the document

Related

Azure management api in Data Factory

I am trying to get response back from Azure management api in Data Factory for instance use this api (https://learn.microsoft.com/en-us/rest/api/resources/resource-groups/list) to get the resource group name in my pipeline. I am able to get the response back in Postman but not sure how to replicate it in Data Factory. I tried using the POST method by passing in the Client ID & Client Credentials like below and no luck. But, Not sure how to achieve this is Data Factory. What am I missing here.
$cmd = { .\curl.exe -X POST https://login.microsoftonline.com/common/oauth2/authorize -F grant_type=client_credentials -F resource=https://management.core.windows.net/ -F client_id=$client_id -F client_secret=$client_secret };
$responseToken = Invoke-Command -scriptblock $cmd;
$accessToken = (ConvertFrom-Json $responseToken).access_token;
(ConvertFrom-Json $responseToken)
Thank you.
I am confused what is the API you are refering to ? Can you please share the Azure docs about that ? . I see that there is a subscriptionid which needs to be put forward as part of the API call .
Here is how the normal flow goes , get the bearer token ( make sure that the you pass the right SCOPE ) , once you have the a bearer token you can use that to call the azure API , bearer token should also be part of the parameter with other parameter( if any ) .

how to construct header for (REST API) azure storage SAS (shared accesss signature)

I am debugging a client application calling REST API embedded with AZURE storage SAS-shared access signature to access azure storage resource. However, it is not getting through. The azure threw out an error stating that the mandatory header is missing, and abort the operation.
The REST API is fairly simple, although it is embedded with the SAS token generated by the azure storage account. The client application uses the REST API to write data into an azure blob.
is there anywhere I can find a good example showing how to generate the header for the REST API (SAS)? I need to find out the exact layout of the header (such as the type of information that needs to be embedded in the header.
Also, do I need to register my client application with the Azure AD?
I didn't think my client application needs to be registered with the AZURE since that is why we have client-side SAS. But, I could be wrong. Therefore, any input will be appreciated.
Thanks in advance.
If you use sas token to call Azure blob rest api, the request URL should be like
https://myaccount.blob.core.windows.net/<cantianer>/<blob>?<sastoken>
For example
$accountName=""
$accountKey=""
$containerName="output"
$blobName="test.txt"
$context= New-AzStorageContext -StorageAccountName $accountName -StorageAccountKey $accountKey
$sas = New-AzStorageAccountSASToken -Service Blob -ResourceType Service,Container,Object -Permission "rwdlacx" -Context $context
$body = "Hello"
$headers=#{"x-ms-blob-type"="BlockBlob"; "Content-Type"="text/plain"}
$url="https://$accountName.blob.core.windows.net/$containerName/$blobName$sas"
Invoke-WebRequest -Uri $url -Method Put -Headers $headers -Body $body -UseBasicParsing

Invoke-Sqlcmd with account that uses MFA in Azure

Anyone of you knows an option to execute a SQL command using PowerShell with Azure AD account that has MFA enabled? What is an alternative? Do I need to create a service principal for that?
I had no luck but only found this cmdlet,
Add-SqlAzureAuthenticationContext
but when I try to run Invoke-Sqlcmd I am getting the following error:
Invoke-Sqlcmd : The target principal name is incorrect. Cannot
generate SSPI context.
To connect to an azure database using AAD credential (mfa or not), you need to provide the -AccessToken parameter with a token of the authenticated user or service principal.
Take this for instance.
Connect to Azure SQL Database using an access token
# Obtain the Access Token: this will bring up the login dialog
Connect-AzAccount -TenantId 'Tenant where your server is'
#AZ Module
$AccessToken = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
$SQLInfos = #{
ServerInstance = 'SERVERNAME.database.windows.net'
Database = 'DBNAME'
AccessToken = $AccessToken
}
Invoke-Sqlcmd #SQLInfos -Query 'select * from sys.tables'
If you don't need or want the manual credentials entry, you can make use of a service principal that is configured with proper access to the server / database and use this instead to obtain your token.
Using service principal client ID / secret to get the access token
$clientid = "enter application id that corresponds to the Service Principal" # Do not confuse with its display name
$tenantid = "enter the tenant ID of the Service Principal"
$secret = "enter the secret associated with the Service Principal"
$request = Invoke-RestMethod -Method POST `
-Uri "https://login.microsoftonline.com/$tenantid/oauth2/token"`
-Body #{ resource="https://database.windows.net/"; grant_type="client_credentials"; client_id=$clientid; client_secret=$secret }`
-ContentType "application/x-www-form-urlencoded"
$AccessToken = $request.access_token
References
MSdoc - Invoke-Sqlcmd
SecretManagement / SecretStore modules
(This second link is not directly related but if you go the Client ID / Secret route, consider storing your credentials in a secret vault rather than in your script directly.)
Not really an answer.
Tried the following
Add-SqlAzureAuthenticationContext -Interactive
$sql = 'SELECT ##SERVERNAME AS ServerName';
$ConnectionString = 'Data Source=tcp:azSERVER.database.windows.net,1433;Initial Catalog=DBNAME;Authentication="Active Directory Interactive";User ID=USERXX#DOMAINYY.COM'
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query $sql -Verbose
and got
Invoke-Sqlcmd : One or more errors occurred.
At line:4 char:5
Please notice that I want to use the interactive flag,

How to authenticate with a Google Service Account in Jenkins pipeline

I want to use gcloud in Jenkins pipeline and therefore I have to authenticate first with the Google Service account. I'm using the https://wiki.jenkins.io/display/JENKINS/Google+OAuth+Plugin which holds my Private Key Credentials. I'm stuck with loading the credentials into the pipeline:
withCredentials([[$class: 'MultiBinding', credentialsId: 'my-creds', variable: 'GCSKEY']]) {
sh "gcloud auth activate-service-account --key-file=${GCSKEY}"
}
I also tried it with from file, but without luck.
withCredentials([file(credentialsId:'my-creds', variable: 'GCSKEY')]) {
The log says:
org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: Credentials 'my-creds' is of type 'Google Service Account from private key' ....
You need to upload your Sevice Account JSON file as a secret file.
Then:
withCredentials([file(credentialsId: 'key-sa', variable: 'GC_KEY')]) {
sh("gcloud auth activate-service-account --key-file=${GC_KEY}")
sh("gcloud container clusters get-credentials prod --zone northamerica-northeast1-a --project ${project}")
}
I couldn't get the 'Google Service Account from private key' working, but using the 'Secret File' type of credential in Jenkins, and uploaded my google service account JSON works.

Interacting with an API using JWT

How do I interact with an API using JWT.
I've been given an API url, an integration key and a bearer, and I've been told to get my token with "POST integration key"
I need to get data out of there system and into our MS SQL database, preferably using an SSIS package.
I've used a REST API using curl before to update and get my IP address, I just had to set up an API key through the website and run a command like the below.
curl -u abcdabcd-abcd-abcd-abcd-abcdabcdabcd:x -X GET https://web.site.com/api/v1/addresses.json
I understand what JWT is a little, as in it's encoded as header.payload.signature, but i'm confused as to how do I get the data out of there system into mine using one.
What is the bearer I've been given?
Will I have to use my integration key and bearer to get a JWT from there system?
Will I then use that JWT to interact with there API?
Will it be as simple as the curl command above or will I need to write a script using one of the libraries on jwt.io
Eventually after about 10 emails between the supplier/developer asking for proper documentation and him telling me his system uses JWT, he sent me screenshots of how he tests the API using postman. From his screenshots I was able to figure out what needs to be done, below is my powershell implementation if it benefits anyone.
#$fromdate = (Get-Date).AddDays(-7)
$fromdate = '01/01/2016'
[string]$body = '{"IntegrationKey":"abcdabcd-abcd-abcd-abcd-abcdabcdabcd"}'
$URI = "https://web.site.com/api/token"
# -ProxyUseDefaultCredentials
(New-Object System.Net.WebClient).Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
[string]$jwt = Invoke-WebRequest $uri -Method post -ContentType 'application/json; charset=UTF-8' -Body $body
$headers = #{"Authorization"="Bearer "+ $jwt.replace("`"","")}
$uri = "https://web.site.com/api/GetData?startDate=" + $fromdate
$response = ".\ResponseData.json"
Invoke-WebRequest $uri -Method get -Headers $headers -TimeoutSec 6000 -OutFile $response