Export all API names Azure APIM - azure

I am trying to export all the url endpoints of my APIs which are stored in Azure APIM.
I need them listed in the format [POST]: https://apim-resource-name.azure-api.net/api-name/api-function, or something similar, so I am trying to enumerate all the endpoints first and the VERB that can be used much like what SwaggerUI or one of the OpenAPI docs might show.
I have this code so far but cannot get the output I would like, am I on the right track or is there any easier way to do this even via UI? I have also tried exporting the template and parsing the script, but it seemed overly complicated for this task.
#az login
$token = az account get-access-token | ConvertFrom-Json
$token = $token.accessToken -replace "`n","" -replace "`r",""
$headers = #{Authorization="Bearer $token.accessToken"}
$subscriptionId = 'subscriptionid'
$resourceGroupName = 'resourcegroupname'
$resourceName = 'resourcename'
$apiName = 'apiname'
$url_getapiexport = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ApiManagement/service/$resourceName/apis/$apiName`?format=swagger-link&export=true&api-version=2021-08-01" #GET
$url_getapiexport
#Invoke-RestMethod -Uri $url_getapiexport -Method GET -Headers #{Authorization="Bearer $token"} -ContentType "application/json"
$url_getapibytags = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ApiManagement/service/$resourceName/apisByTags?&includeNotTaggedApis=true&api-version=2021-08-01" #GET
$url_getapibytags
$api_tags = Invoke-RestMethod -Uri $url_getapibytags -Method GET -Headers #{Authorization="Bearer $token"} -ContentType "application/json"
$api_tags
foreach ($api in $api_tags) {
write-host API: $api.value.api.name
}

So if you want to export all APIM APIs and their service URLs you can do like this (replace xxx with correct values). Example in PHP
<?php
echo "[INFO] API Names and Service Urls \n\n";
$apiList = shell_exec('az apim api list --resource-group "xxx" --service-name "xxx" ');
$apis = json_decode($apiList, true);
$cli = "az rest --method get --url";
foreach ($apis as $api)
{
$name = $api["name"];
$apiRequest = "$cli " . "\"https://management.azure.com/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.ApiManagement/service/xxx/apis/$name?api-version=2021-08-01\"";
$json = shell_exec($apiRequest);
$apiInfo = json_decode($json, true);
$displayName = $apiInfo["properties"]["displayName"];
$serviceUrl = $apiInfo["properties"]["serviceUrl"];
printf("%s: %s \n", $displayName, $serviceUrl);
}
?>

Related

Can we add label to tiles on Azure Dashboard [duplicate]

Is it possible to show custom information in azure dashboards?
I was searching on how to add custom content in azure dashboards but did not find anything. The only thing close was the markdown tile which allows html to be displayed.
With this in mind and after a lot of digging I found a solution:
Basically we needed a custom tile that displays data retrieved from our REST api.
1. Create a new, empty 'Markdown' tile on a new or existing dashboard, give it a 'Title'
2. Share the dashboard
3. Navigate to All services, Filter by 'dashboards' in the ResourceGroup filter
- Click on the dashboard which contains the 'Markdown' tile
- Take a note of the 'RESOURCE ID'
In our scenario, we used Azure Automation Runbooks. In this scenario we utilized the Azure Resource Manager REST api.
4. Create a new RunBook [Powershell Runbook]
The following steps concern the following:
- Login to the ResourceManagerAPI
- Get Azure Resource by ID [The Resource ID above]
- Update Azure Resource by ID [The Resource ID above]
Before we continue, we need to get our client credentials. To do so:
- Click on Cloud Shell in the Portal Menu bar
- Type 'az'
- Type 'az ad sp create-for-rpac -n "runbooks"' //runbooks is just a name, feel free to input a different string
- The above command should list out the credentials needed. If an error occurs, kindly contact your Azure admin and run it from their account.
5. In your empty powershell runbook, add the following 2 variables:
$ExpectedTileName = "Extension/HubsExtension/PartType/MarkdownPart"
$MarkdownTileTitle = "<The Markdown title you've set in the first step>"
6. Getting the Access_Token [The variables <> represent the values retrieved from the previous step]
#Get Bearer Token
$TenantId = '<Your tenantID>'
$LoginUri = "https://login.microsoftonline.com/"+$TenantId+"/oauth2/token"
$params = #{
"grant_type"="client_credentials";
"client_id"="<appId>";
"client_secret"="<password>";
"resource"="https://management.azure.com";
}
$LoginResponse = Invoke-RestMethod -Uri $LoginUri -Method Post -Body $params
$Access_Token = $LoginResponse.access_token;
$Access_TokenString = "Bearer " + $Access_Token
7. Getting the DashboardResource by ResourceID:
#Get Resource
$RMUri = "https://management.azure.com/"+ $DashboardId +"?api-version=2015-08-01-preview"
$DashboardResource = (Invoke-RestMethod -Uri $RMUri -Method Get -Headers #{'Authorization'=$Access_TokenString}) | ConvertTo-Json -Depth 100 | ConvertFrom-Json
8. Looping through all tiles within the dashboard. Please note that tiles are not contained within an array, thus you may need to increase/decrease the length of the for loop.
#Loop through all tiles within the dashboard
$Parts = $DashboardResource.properties.lenses.0.0.parts
For ($i=0; $i -lt 200; $i++)
{
$Part = $Parts | Select-Object -Property $i.toString()
if($Part.$i)
{
if($Part.$i.metadata.type -eq $ExpectedTileName -And $Part.$i.metadata.settings.content.settings.title -eq $MarkdownTileTitle)
{
$Part.$i.metadata.settings.content.settings.content = <CustomValue ex: invoke a get request to your api>
}
}
else
{
break
}
}
9. Finally we need to update the dashboard resource
#Update Resource
$UpdateUri = "https://management.azure.com/"+ $DashboardId +"?api-version=2015-08-01-preview"
$JsonValue = $DashboardResource | ConvertTo-Json -Depth 100
Invoke-RestMethod -Uri $UpdateUri -Method Put -Headers #{'Authorization'=$Access_TokenString; 'Content-type'='application/json'} -Body $JsonValue
To sum it up:
$ExpectedTileName = "Extension/HubsExtension/PartType/MarkdownPart"
$MarkdownTileTitle = "<The Markdown title you've set in the first step>"
#Get Bearer Token
$TenantId = '<Your subscriptionID>'
$LoginUri = "https://login.microsoftonline.com/"+$TenantId+"/oauth2/token"
$params = #{
"grant_type"="client_credentials";
"client_id"="<appId>";
"client_secret"="<password>";
"resource"="https://management.azure.com";
}
$LoginResponse = Invoke-RestMethod -Uri $LoginUri -Method Post -Body $params
$Access_Token = $LoginResponse.access_token;
$Access_TokenString = "Bearer " + $Access_Token
#Get Resource
$RMUri = "https://management.azure.com/"+ $DashboardId +"?api-version=2015-08-01-preview"
$DashboardResource = (Invoke-RestMethod -Uri $RMUri -Method Get -Headers #{'Authorization'=$Access_TokenString}) | ConvertTo-Json -Depth 100 | ConvertFrom-Json
#Loop through all tiles within the dashboard
$Parts = $DashboardResource.properties.lenses.0.0.parts
For ($i=0; $i -lt 200; $i++)
{
$Part = $Parts | Select-Object -Property $i.toString()
if($Part.$i)
{
if($Part.$i.metadata.type -eq $ExpectedTileName -And $Part.$i.metadata.settings.content.settings.title -eq $MarkdownTileTitle)
{
$Part.$i.metadata.settings.content.settings.content = <CustomValue ex: invoke a get request to your api>
}
}
else
{
break
}
}
#Update Resource
$UpdateUri = "https://management.azure.com/"+ $DashboardId +"?api-version=2015-08-01-preview"
$JsonValue = $DashboardResource | ConvertTo-Json -Depth 100
Invoke-RestMethod -Uri $UpdateUri -Method Put -Headers #{'Authorization'=$Access_TokenString; 'Content-type'='application/json'} -Body $JsonValue
Conclusion
With this newly created runbook we can now schedule it to run every 1 hour. In our case, 1 hour was too much. The following article shows how we can schedule the runbook to run every 1 minute.
https://blogs.technet.microsoft.com/stefan_stranger/2017/06/21/azure-scheduler-schedule-your-runbooks-more-often-than-every-hour/

Powershell invoke-restmethod variable in url

I am new to powershell, and I am trying to create a simple script that will allow me to turn on several Azure VMs using the invoke-restmethod.
My code works when instead of using a variable I directly write the VM name into the url, but I want to use a variable, since eventually this must work for more than one VM.
Relevant part of code:
$body = #{
"$virtualMachines" = "VM1"
} | ConvertTo=Json
$url= "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/" + $virtualMachines + "/start?api-version=2018-09-15"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
If you had a number of VMs, you could put them all into a PowerShell variable like this, an array of strings.
$VMs = "myVm1", "myVm2", "myVm3"
PowerShell has a number of flow control statements, the one you want to use is ForEach, which will step through an array one at a time. We just modify the way you're setting up the URL to be friendlier and easier to read and this should work just fine.
$baseUrl = "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/"
ForEach ($vm in $VMs){
$url = $baseurl + $vm + "/start?api-version=2018-09-15"
Write-host "About to start [$Vm]"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers
$response | ConvertTo-Json
}
I checked the API documentation for the start? REST API endpoint, and it doesn't look like you need the -Body parameter for this endpoint.

List Cloud Service Classic use PowerShell and Azure Rest API

I Have a problem. Could you please help me view list Cloud Service Classic use PowerShell and Azure Rest API. When I used script for Web APP I show list Web APP, but when I used scrip for Cloud Service Classic I show error.
# Variables
$TenantId = "" # Enter Tenant Id.
$ClientId = "" # Enter Client Id.
$ClientSecret = "" # Enter Client Secret.
$Resource = "https://management.core.windows.net/"
$SubscriptionId = "" # Enter Subscription Id.
$RequestAccessTokenUri = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$body = "grant_type=client_credentials&client_id=$ClientId&client_secret=$ClientSecret&resource=$Resource"
$Token = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -Body $body -ContentType 'application/x-www-form-urlencoded'
Write-Host "Print Token" -ForegroundColor Green
Write-Output $Token
# Get Azure Resource Groups
$ResourceGroupApiUri = "https://management.core.windows.net/$SubscriptionId/services/hostedservices"
$Headers = #{}
$Headers.Add("Authorization","$($Token.token_type) "+ " " + "$($Token.access_token)")
$ResourceGroups = Invoke-RestMethod -Method Get -Uri $ResourceGroupApiUri -Headers $Headers
Write-Host "Print Resource groups" -ForegroundColor Green
Write-Output $ResourceGroups
Invoke-RestMethod : ForbiddenErrorThe server failed to authenticate the request. Verify that the certificate is valid and
is associated with this subscription.
Actually, there is a built-in ASM PowerShell to list the cloud services associated with the current subscription.
Get-AzureService
Reference - https://learn.microsoft.com/en-us/powershell/module/servicemanagement/azure/get-azureservice?view=azuresmps-4.0.0
Besides, if you insist on calling the ASM rest api with powershell, you could refer to this article, the sample calls the Get Deployment api, just change it to List Cloud Services.
#Request Headers required to invoke the GET DEPLOYMENT REST API
$method
=
“GET”
$headerDate
= ‘2009-10-01’
$headers
= #{“x-ms-version”=“$headerDate“}
#Retrieving the subscription ID
$subID
= (Get-AzureSubscription
-Current).SubscriptionId
$URI
=
https://management.core.windows.net/$subID/services/hostedservices/kaushalz/deployments/4f006bb7d2874dd4895f77a97b7938d0
#Retrieving the certificate from Local Store
$cert
= (Get-ChildItem
Cert:\CurrentUser\My
|
?{$_.Thumbprint -eq
“B4D460D985F1D07A6B9F8BFD67E36BC53A4490FC”}).GetRawCertData()
#converting the raw cert data to BASE64
body
=
“<Binary>—–BEGIN CERTIFICATE—–`n$([convert]::ToBase64String($cert))`n—–END CERTIFICATE—–</Binary>”
#Retrieving the certificate ThumbPrint
$mgmtCertThumb
= (Get-AzureSubscription
-Current).Certificate.Thumbprint
#Passing all the above parameters to Invoke-RestMethod cmdlet
Invoke-RestMethod
-Uri
$URI
-Method
$method
-Headers
$headers
-CertificateThumbprint
” B4D460D985F1D07A6B9F8BFD67E36BC53A4490FC”
-ContentType
$ContentType

Function Level Authorization Authorize keys in Azure can we manage these keys through CICD

Can we managae keys through CICD?
Means i need to manage these through CICD not portal or Rest Srevice is it possible?
everything is being managed through rest api (ultimately) so this ask makes very little sense. you can manage those only using the rest calls (as far as I know).
function Add-AzureFunctionKey {
Param(
[string]$appName,
[string]$resourceGroup,
[string]$funcKeyName,
[string]$funcKeyValue
)
$AzureContext = Get-AzureRmContext
if(!$AzureContext){
Write-Output "Please login to your Azure Account"
Login-AzureRmAccount
}
$SubscriptionId = (Get-AzureRmSubscription | select Name, State, SubscriptionId, TenantId | Out-GridView -Title "Azure Subscription Selector" -PassThru).SubscriptionId
Get-AzureRmSubscription -SubscriptionId $SubscriptionId | Select-AzureRmSubscription
$PublishingProfile = (Get-AzureRmWebAppPublishingProfile -ResourceGroupName $resourceGroup -Name $appName)
$user = (Select-Xml -Xml $PublishingProfile -XPath "//publishData/publishProfile[contains(#profileName,'Web Deploy')]/#userName").Node.Value
$pass = (Select-Xml -Xml $PublishingProfile -XPath "//publishData/publishProfile[contains(#profileName,'Web Deploy')]/#userPWD").Node.Value
$pair = "$($user):$($pass)"
$kuduCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$authToken = Invoke-RestMethod -Uri "https://$appName.scm.azurewebsites.net/api/functions/admin/token" -Headers #{Authorization = ("Basic {0}" -f $kuduCredentials)} -Method GET
$Functions = Invoke-RestMethod -Method GET -Headers #{Authorization = ("Bearer {0}" -f $authToken)} -Uri "https://$appName.azurewebsites.net/admin/functions"
$Functions = $Functions.Name
ForEach ($functionName in $Functions) {
$data = #{
"name" = "$funcKeyName"
"value" = "$funcKeyValue"
}
$json = $data | ConvertTo-Json;
$keys = Invoke-RestMethod -Method PUT -Headers #{Authorization = ("Bearer {0}" -f $authToken)} -ContentType "application/json" -Uri "https://$appName.azurewebsites.net/admin/functions/$functionName/keys/$funcKeyName" -body $json
Write-Output "Function $FunctionName Key updated $keys"
}
}
here's a sample found online, i didnt test it. there are a few examples online more or less like the one above.
Source: https://www.powershellbros.com/add-azure-function-key/

Azure Function Key Management API - Authentication error

I have two Azure function apps, both in the same Azure subscription. I can retrieve keys for one but not for the other. As far as I can see there is no difference between the two function apps.
I'm using this Powershell code:
function GetHostKey
{
param($webAppName, $resourceGroupName)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Host "Getting master key from $webAppName"
$xml = [xml](Get-AzureRmWebAppPublishingProfile -Name $webAppName -ResourceGroupName $resourceGroupName -Format WebDeploy -OutputFile null)
$msdeployUsername = $xml.SelectNodes("//publishProfile[#publishMethod=`"MSDeploy`"]/#userName").value
$msdeployPassword = $xml.SelectNodes("//publishProfile[#publishMethod=`"MSDeploy`"]/#userPWD").value
$apiBaseUrl = "https://$webAppName.scm.azurewebsites.net/api"
$siteBaseUrl = "https://$webAppName.azurewebsites.net"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $msdeployUsername,$msdeployPassword)))
$jwt = Invoke-RestMethod -Uri "$apiBaseUrl/functions/admin/token" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
$uri = "$siteBaseUrl/admin/host/systemkeys/_master"
$response = Invoke-RestMethod -Uri $uri -Headers #{Authorization=("Bearer {0}" -f $jwt)} -Method GET
return $response.value
}
The call to $siteBaseUrl/admin/host/systemkeys/_master returns the expected json for one function app, but the other one returns a login screen.
Compare both functions settings, versions. Try to get the keys manually from the portal to isolate the source of the problem. I had the same problem till i deleted and recreated the functions.

Resources