I have deployed a web job to Azure and also have a request/response graphs associated with it (insight). I want to extract the graph information and display it on another web page (as an embedded graph). Please see the attached screenshot for my azure dashboard which have the graph.
Is there a RESTApi or any SDK available to get graph(app insight) from azure and display it in the web page?
(hope this is not related to powerbi)
If you want get the requests and AverageResponseTime metrics We could use the Monitor API or Microsoft.Azure.Management.Monitor to do that. I do a demo to get the Azure WebApp request metrics demo. Other supported metrics supported metrics please refer to Azure Monitor Metrics List.
Preparetion:
Registry Azure Active Directory application and assign Role
Then we can get the tenantId,clientId,clientSecretKey
var azureTenantId = "tenantId";
var azureSecretKey = "clientSecretKey";
var azureAppId = "clientId";
var subscriptionId = "subscriptionId";
var resourceGroup = "ResourceGroup";
var webAppName = "webAppname";
var serviceCreds = ApplicationTokenProvider.LoginSilentAsync(azureTenantId, azureAppId, azureSecretKey).Result;
var client = new MonitorClient(serviceCreds) {SubscriptionId = subscriptionId};
var resourceUrl = $"subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{webAppName}";
var result = client.Metrics.ListWithHttpMessagesAsync(resourceUrl,metric: "Requests",interval:new TimeSpan(0,0,5,0),timespan: "2018-02-19T06:57:56Z/2018-02-20T07:57:56Z").Result;
Related
I have an Azure app registered on Azure portal which is created in .NET Core 2.0 This app reads some config value from the Application settings section from the portal as shown in below image.
Now at some stage I want to update those config value from code. I have searched for many article but not found how to update Azure Application settings from code. Can any one have an idea or suggestion that How can I update Azure Application settings using .NET Core 2.0 C#?
This can be accomplished using Azure.ApplicationModel.Configuration nuget package.
In particular, the SetConfigurationSetting method seems to do what you are after.
string connectionString = "<connection_string>";
var client = new ConfigurationClient(connectionString);
ConfigurationSetting setting = client.SetConfigurationSetting("some_key","new_value");
Note: This package is in preview
You could use c# to call the REST API Web Apps - Update Application Settings manually.
PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/appsettings?api-version=2019-08-01
For more details about how to call Azure REST API in c#, you could refer to this link.
If you want to use c# to do it, you could try with Microsoft.Azure.Management.Fluent package, the below is the sample code, you could have a try.
string tenantId = "*******";
string clientSecret = "********";
string clientId = "********";
string subscriptionId = "*******";
var azureCredentials = new AzureCredentials(new
ServicePrincipalLoginInformation
{
ClientId = clientId,
ClientSecret=clientSecret
}, tenantId, AzureEnvironment.AzureGlobalCloud) ;
var _azure = Azure
.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(azureCredentials)
.WithSubscription(subscriptionId);
var appResourceId = "/subscriptions/**********/resourcegroups/*******/providers/Microsoft.Web/sites/***"; //Get From WebApp -> Properties -> Resource ID
var webapp = _azure.WebApps.GetById(appResourceId);
webapp.Update()
.WithAppSetting("test", "testvalue")
.Apply();
The library has been changed to Azure.Data.AppConfiguration.
Azure.ApplicationModel.Configuration is depracated
This is an addendum to George Chen's answer.
To avoid the "Operation returned an invalid status code 'Forbidden' exception after calling _azure.WebApps.GetById(appResourceId), you need to ensure the service principal associated with the Azure Credential has contributor access to the subscription the web app is in. For more details refer to https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal.
I am running Node.js in Azure Function and I am trying to retrieve the resource group and name of a VM while only knowing the IP that was sent. Is it possible to retrieve all Public IP addresses associated with a subscription using Node.js SDK in Azure?
In powershell I can write az network public-ip list which will provide a JSON which contains information like:
"id": "/subscriptions/444444-4444-43444d8-44444c/resourceGroups/testserver/providers/Microsoft.Network/publicIPAddresses/publicip",
"idleTimeoutInMinutes": 4,
"ipAddress": "55.55.55.55",
However in Node when calling a similar function networkClient.PublicIPAddresses.listAll() I receive a list of id's but not an IP address. ie:
[1/25/2019 7:19:47 PM] publicIPAddressVersion: 'IPv4',
[1/25/2019 7:19:47 PM] ipConfiguration:
[1/25/2019 7:19:47 PM] { id:
[1/25/2019 7:19:47 PM] '/subscriptions/444444-4444-43444d8-44444/resourceGroups/TEST/providers/Microsoft.Network/networkInterfaces/test-vm1968/ipConfigurations/ipconfig1' },
Is it possible in Node to fetch all public IP's and use that to determine the Resource group and associated VM?
Thank you.
Yes, it's possible in Node. On Azure, all SDKs are built by wrapping the REST APIs. So if you can find out the REST API of the feature you want, you also can use the related SDK API for your used language.
There is a REST API PublicIPAddress(Preview) - List All which response is same with the result of the command az network public-ip list. We must note the value of the required parameter api-version is 2018-11-01, and it's a newest version of an ARM API.
Considering for different api-version values used in the different SDK versions, first of all to upgrade the azure-arm-network package version to newest via npm update azure-arm-network --save, then to run the code like below which refer to the sample code vm-sample.js ` in GitHub.
var util = require('util');
var path = require('path');
var msRestAzure = require('ms-rest-azure');
var NetworkManagementClient = require('azure-arm-network');
var FileTokenCache = require('../../lib/util/fileTokenCache');
var tokenCache = new FileTokenCache(path.resolve(path.join(__dirname, '../../test/tmp/tokenstore.json')));
//Environment Setup
_validateEnvironmentVariables();
var clientId = process.env['CLIENT_ID'];
var domain = process.env['DOMAIN'];
var secret = process.env['APPLICATION_SECRET'];
var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
var credentials = new msRestAzure.ApplicationTokenCredentials(clientId, domain, secret, { 'tokenCache': tokenCache });
var networkClient = new NetworkManagementClient(credentials, subscriptionId);
function listAllPublicIP(options, callback) {
return networkClient.publicIPAddresses.listAll(options, callback);
}
You can check the API calling above whether correctly calls the correct REST API with the query paramater api-version=2018-11-01 via Fiddler.
Also, you can directly call the REST API with the Authorization header which value get from the credentials variable of the code above.
Is it possible to use the Azure Fluent API to add a WebJob to a WebApp? I'm not finding any documentation describing this.
I believe the answer is no, and that you are required to use the Azure Kudu WebJob API
More information about that can be found:
https://github.com/projectkudu/kudu/wiki/WebJobs-API
https://blogs.msdn.microsoft.com/benjaminperkins/2016/02/01/using-the-azure-webjob-api/
As Lachie said, it seems that there is no Fluent API support to add WebJobs, you could use WebJobs KUDU API to achieve it.
I do a demo for that. It works correctly in my site. The following is my detail steps:
Preparation:
1.The WebJob API require Basic Authentication using the publishing credentials, you could go to your webapp in azure portal to click Get publish profile and download it to get username and userpassword.
2.Zip the WebJob to be published file.
Steps:
1.Create a C# console project.
2.Add the following code in the Program.cs file.
string userName = "$name";
string userPassword = "pass";
string webAppName = "webappname";
string webJobName = "webjobname";
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{userName}:{userPassword}"));
var file = File.ReadAllBytes(#"webjob zip file path");
MemoryStream stream = new MemoryStream(file);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Auth);
client.DefaultRequestHeaders.Add("ContentType", "application/zip");
var baseUrl = new Uri($"https://{webAppName}.scm.azurewebsites.net/");
var requestURl = baseUrl + "api/continuouswebjobs/"+webJobName;
var httpContent = new StreamContent(stream);
httpContent.Headers.Add("Content-Disposition", "attachement;filename="+ webjob.exe);
var response2 = client.PutAsync(requestURl, httpContent).Result;
}
Note: The filename should be in the Content-Dispostion header. Here I deploy the continuous webjob, if you want to deploy trigger webjob, you could change continuouswebjobs to triggeredwebjobs.
3.Test from the local.
4.Check the published result on azure.
I am trying to connect to Azure Analysis services using ADOMD and authenticated using a Service principal. So I have done following:
Create app in AAD.
Granted the app (Service principal) read permission on the Azure Analysis service.
Below is my code to connect to Azure Analysis service.
var clientId = "******";
var clientSecret = "*****";
var domain = "****.onmicrosoft.com";
var ssasUrl = "northeurope.asazure.windows.net";
var token = await TokenHelper.GetAppOnlyAccessToken(domain, $"https://{ssasUrl}", clientId, clientSecret);
var connectionString = $"Provider=MSOLAP;Data Source=asazure://{ssasUrl}/{modelname};Initial Catalog= adventureworks;User ID=;Password={token};Persist Security Info=True;Impersonation Level=Impersonate";
var ssasConnection = new AdomdConnection(connectionString);
ssasConnection.Open();
var query = #"Evaluate TOPN(10,Customer,Customer[Customer Id],1)";
var cmd = new AdomdCommand(query)
{
Connection = ssasConnection
};
using (var reader = cmd.ExecuteXmlReader())
{
string value = reader.ReadOuterXml();
Console.WriteLine(value);
}
I am able to get a valid access token, but I get following error when trying to open the connection:
AdomdErrorResponseException: Either the user, 'app:xxxxxxx#xxxxxx', does not have access to the 'adventureworks' database, or the database does not exist.
Additional info: :
I have verified that permissions (Reader & also tried with contribute) are given to Service principal to Azure analysis Service thru the Azure portal.
I have tried same code with service account (username & password) and it works.
If I remove "Initial Catalog= adventureworks" from the connection string then my connection will succeed. But I do not see why Analysis services permission is not propagated to the model.
Resolution:
Silly that I got the resolution by myself just after posting this. The point no 3 above gave me a clue.Granting permission on the Azure analysis services through the portal does not propagate to the model for the Service principals (Azuire AD apps).
Steps:
Open the Azure analysis service in Sql server Mgmt Studio.
In the target model, go to Roles.
Add the service principal into required role with permission. Service principal is added in below format:
app:[appid]#[tenantid]
example : app:8249E22B-CFF9-440C-AF27-60064A5743CE#86F119BE-D703-49E2-8B5F-72392615BB97
Silly that I got the resolution by myself just after posting this. The point no 3 above gave me a clue.Granting permission on the Azure analysis services through the portal does not propagate to the model for the Service principals (Azure AD apps).
Steps:
Open the Azure analysis service in Sql server Mgmt Studio.
In the target model, go to Roles.
Add the service principal into required role with permission. Service principal is added in below format:
app:[appid]#[tenantid]
example : app:8249E22B-CFF9-440C-AF27-60064A5743CE#86F119BE-D703-49E2-8B5F-72392615BB97
I have blogged my whole experience here:https://unnieayilliath.com/2017/11/12/connecting-to-azure-analysis-services-using-adomd/
Please refer to this official document.
You need give the service principal Owner or Contributor role.
You could do it on Azure Portal. <your subscription>--><Access Control>--><Add>.
More information about this please refer to this official document.
We use Azure Mobile Services with Javascript (Node.js) back-end. The front-end is HTML/Javascript and runs as Azure Web App. We want to use Azure blob storage to store files (uploaded from front-end). I searched for a working example implementing this scenario, but I can't find it. There are examples with .NET back-end or Android/Windows Phone front-end. As a workaround it's possible to post the file to mobile service and do the storage from there, but the mobile service api body has a 1MB limit. I know I have to use a Shared Access Signature (SAS), but I don't know how to implement that. Generating the url from mobile service works. But it's not accepted when I use it in the client.
This guide is not working anymore: http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/
Thanks in advance for your help!
As usually, custom APIs on mobile services are used in handling logic workflows or event triggers. So Azure mobile service limit the body size of custom APIs requests for better performance. To implement upload files from clients to Azure Storage, we recommend to leverage SAS URIs.
And lots samples use the backend project to generate the SAS URI and return back to front-end.We can leverage Azure Node.js SDK in Mobile service custom APIs scripts to generate SAS URI.
Here is the code snippet:
exports.get = function(request, response) {
var azure = require('azure');
var qs = require('querystring');
var accountName = { accountName };
var accountKey = { accountKey };
var host = accountName + '.blob.core.windows.net';
var blobService = azure.createBlobService(accountName, accountKey, host);
var startDate = new Date();
var expiryDate = new Date(startDate);
expiryDate.setMinutes(startDate.getMinutes() + 30);
startDate.setMinutes(startDate.getMinutes() - 30);
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Start: startDate,
Expiry: expiryDate
},
};
// you can custom send container name and blob name via http get request
/** e.g. var containerName = request.query.container,
blobName = request.query.blob
client side use invokeApi method, e.g.
client.invokeApi('getSAS',{
method:'GET',
parameters:{container:'mycontainer',blob:'myblob'}
})
**/
var blobSAS = blobService.generateSharedAccessSignature('mycontainer', 'myblob', sharedAccessPolicy);
var sasQueryString = qs.stringify(blobSAS.queryString);
var sasUri = blobSAS.baseUrl + blobSAS.path;
response.send(sasUri+"?"+sasQueryString);
};
You can refer to Upload images to Azure Storage from an Android device and Work with a JavaScript backend mobile service for reference.
Furthermore, for a deep understanding of generating SAS URI, you can refer to Constructing a Service SAS and Shared Access Signatures, Part 1: Understanding the SAS Model
Additionally, here is a similar example built in this architecture, Upload files to Microsoft Azure Storage from JavaScript