Skip to content

Commit 8da00d8

Browse files
authored
App Insights API Key Deprecation + Client-Side Updates (#73)
1 parent b918a6c commit 8da00d8

File tree

58 files changed

+16742
-26376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+16742
-26376
lines changed

src/AnalyticsEngine/App.ControlPanel.Engine/ConfigureAzureComponentsTasks.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public ConfigureAzureComponentsTasks(SolutionInstallConfig config, ILogger logge
3838
/// Install configure & software on App Service, update target DB.
3939
/// </summary>
4040
public async Task RunPostCreatePaaSTasks(WebSiteResource webApp, DatabasePaaSInfo dbInfo, StorageAccountResource storage, AutomationAccountResource automationAccount,
41-
AppInsightsInfoWithApiAccess appInsights,
41+
AppInsightsInfo appInsights,
4242
RedisResource redis, CognitiveServicesInfo cognitiveServicesInfo,
4343
KeyVaultResource keyVault, string serviceBusConnectionString, SubscriptionResource subscription)
4444
{
@@ -130,7 +130,7 @@ async Task ConfigureWebApp(WebSiteResource webApp, DatabasePaaSInfo backendInfo,
130130
StorageAccountResource storage,
131131
RedisResource redis,
132132
CognitiveServicesInfo cognitiveServicesInfo,
133-
AppInsightsInfoWithApiAccess appInsights, string serviceBusConnectionString, KeyVaultResource keyVault)
133+
AppInsightsInfo appInsights, string serviceBusConnectionString, KeyVaultResource keyVault)
134134
{
135135
// App settings
136136
var url = $"https://{webApp.Data.HostNames.First()}/";
@@ -148,14 +148,6 @@ async Task ConfigureWebApp(WebSiteResource webApp, DatabasePaaSInfo backendInfo,
148148
{
149149
appSettings.Properties.Add("AppInsightsConnectionString", appInsights.ConnectionString);
150150
}
151-
if (!string.IsNullOrEmpty(appInsights?.ApiKey))
152-
{
153-
appSettings.Properties.Add("AppInsightsApiKey", appInsights.ApiKey);
154-
}
155-
if (!string.IsNullOrEmpty(appInsights?.AppId))
156-
{
157-
appSettings.Properties.Add("AppInsightsAppId", appInsights.AppId);
158-
}
159151

160152
if (this.Config.CognitiveServicesEnabled)
161153
{

src/AnalyticsEngine/App.ControlPanel.Engine/InstallerTasks/AzurePaaSInstallJob.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ public class AzurePaaSInstallJob : BaseAnalyticsSolutionInstallJob
3737

3838
private readonly LogAnalyticsInstallTask _logAnalyticsInstallTask;
3939
private readonly AppInsightsInstallTask _appInsightsInstallTask;
40-
private readonly AppInsightsConfigureApiTask _appInsightsConfigureApiTask;
4140
private readonly TextAnalyticsInstallTask _cognitiveServicesInstallTask;
4241

4342
/// <summary>
@@ -132,8 +131,7 @@ public AzurePaaSInstallJob(ILogger logger, SolutionInstallConfig config, Subscri
132131
var creds = new ClientSecretCredential(config.InstallerAccount.DirectoryId, config.InstallerAccount.ClientId, config.InstallerAccount.Secret);
133132
var appInsightsConfig = TaskConfig.GetConfigForName(config.AppInsightsName);
134133
_appInsightsInstallTask = new AppInsightsInstallTask(appInsightsConfig, logger, Location, tagDic, ResourceGroupName, config.Subscription.SubId, creds);
135-
_appInsightsConfigureApiTask = new AppInsightsConfigureApiTask(appInsightsConfig, logger, Location, creds, _config.Subscription.SubId, ResourceGroupName);
136-
this.AddTask(_logAnalyticsInstallTask, _appInsightsInstallTask, _appInsightsConfigureApiTask);
134+
this.AddTask(_logAnalyticsInstallTask, _appInsightsInstallTask);
137135

138136
// Cognitive
139137
if (config.CognitiveServicesEnabled)
@@ -166,7 +164,7 @@ public AzurePaaSInstallJob(ILogger logger, SolutionInstallConfig config, Subscri
166164
public DatabasePaaSInfo DatabasePaaSInfo => new DatabasePaaSInfo(CreatedSqlServer, CreatedSqlDatabase, _config);
167165
public RedisResource Redis => GetTaskResult<RedisResource>(_redisTask);
168166
public StorageAccountResource Storage => GetTaskResult<StorageAccountResource>(_storageAccountInstallTask);
169-
public AppInsightsInfoWithApiAccess AppInsights => GetTaskResult<AppInsightsInfoWithApiAccess>(_appInsightsConfigureApiTask);
167+
public AppInsightsInfo AppInsights => GetTaskResult<AppInsightsInfo>(_appInsightsInstallTask);
170168
public CognitiveServicesInfo CognitiveServicesInfo => _cognitiveServicesInstallTask != null ? GetTaskResult<CognitiveServicesInfo>(_cognitiveServicesInstallTask) : new CognitiveServicesInfo();
171169
public ServiceBusQueueResourceWithConnectionString SBQueueWithConnectionString => GetTaskResult<ServiceBusQueueResourceWithConnectionString>(_serviceBusQueueWithPolicyInstallTask);
172170
public KeyVaultResource KeyVault => GetTaskResult<KeyVaultResource>(_keyVaultTask);

src/AnalyticsEngine/Common/CloudInstallEngine/AppInsightsManager.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,6 @@ public class AppInsightsInstance
162162

163163
public class AppInsightsInstanceProperties
164164
{
165-
[JsonProperty("InstrumentationKey")]
166-
public string InstrumentationKey { get; set; }
167-
168-
169-
[JsonProperty("AppId")]
170-
public string AppId { get; set; }
171-
172165
[JsonProperty("ConnectionString")]
173166
public string ConnectionString { get; set; }
174167
}

src/AnalyticsEngine/Common/CloudInstallEngine/Azure/InstallTasks/AppInsightsConfigureApiTask.cs

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/AnalyticsEngine/Common/CloudInstallEngine/Azure/InstallTasks/AppInsightsInstallTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public async override Task<AppInsightsInfo> ExecuteTaskReturnResult(object conte
4747

4848
if (resourceCreateInfo.CreatedNew)
4949
{
50-
_logger.LogInformation($"Created new AppInsights with name {name} and instrumentation key {appProps.InstrumentationKey}");
50+
_logger.LogInformation($"Created new AppInsights with name {name}");
5151
}
5252
else
5353
{
54-
_logger.LogInformation($"Found existing AppInsights with name {name} and instrumentation key {appProps.InstrumentationKey}");
54+
_logger.LogInformation($"Found existing AppInsights with name {name}");
5555
}
5656

5757
return new AppInsightsInfo(resourceCreateInfo.ResourceId, name, appProps.ConnectionString);

src/AnalyticsEngine/Common/CloudInstallEngine/Models/AppInsightsInfo.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,6 @@ public AppInsightsInfo(string id, string name, string connectionString)
3030
public string Name { get; internal set; }
3131
}
3232

33-
public class AppInsightsInfoWithApiAccess : AppInsightsInfo
34-
{
35-
public AppInsightsInfoWithApiAccess(string id, string name, string connectionString, string apiKey, string appId) : base(id, name, connectionString)
36-
{
37-
if (string.IsNullOrEmpty(apiKey))
38-
{
39-
throw new ArgumentException($"'{nameof(apiKey)}' cannot be null or empty.", nameof(apiKey));
40-
}
41-
42-
if (string.IsNullOrEmpty(appId))
43-
{
44-
throw new ArgumentException($"'{nameof(appId)}' cannot be null or empty.", nameof(appId));
45-
}
46-
47-
this.ApiKey = apiKey;
48-
this.AppId = appId;
49-
}
50-
public string ApiKey { get; set; }
51-
public string AppId { get; set; }
52-
}
53-
5433
public class LogWorkspaceInfo
5534
{
5635
public string AzureID { get; set; }

src/AnalyticsEngine/Common/Entities/Config/AppConfig.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ public AppConfig()
1717
this.AppInsightsConnectionString = ConfigurationManager.AppSettings.Get(nameof(AppInsightsConnectionString));
1818

1919
this.AppInsightsContainerName = ConfigurationManager.AppSettings["AppInsightsContainerName"];
20-
this.AppInsightsApiKey = ConfigurationManager.AppSettings["AppInsightsApiKey"];
21-
this.AppInsightsAppId = ConfigurationManager.AppSettings["AppInsightsAppId"];
2220

2321
this.BuildLabel = ConfigurationManager.AppSettings["BuildLabel"];
2422

@@ -95,8 +93,6 @@ public AppConfig()
9593

9694
public string BuildLabel { get; set; }
9795
public string AppInsightsContainerName { get; set; }
98-
public string AppInsightsApiKey { get; set; }
99-
public string AppInsightsAppId { get; set; }
10096
public string AppInsightsConnectionString { get; set; }
10197

10298
public int MetadataRefreshMinutes { get; set; } = 24 * 60; // 24 hours
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using Azure.Core;
2+
using Azure.Identity;
3+
using Common.Entities.Config;
4+
using DataUtils;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using System;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using WebJob.AppInsightsImporter.Engine;
11+
12+
namespace Tests.UnitTests
13+
{
14+
[TestClass]
15+
public class AppInsightsAuthTests
16+
{
17+
/// <summary>
18+
/// Verify AppInsightsAPIClient requires a non-null/empty connection string.
19+
/// </summary>
20+
[TestMethod]
21+
[ExpectedException(typeof(ArgumentException))]
22+
public void AppInsightsAPIClient_NullConnectionString_Throws()
23+
{
24+
var credential = new ClientSecretCredential("tenant", "client", "secret");
25+
new AppInsightsAPIClient(null, credential, AnalyticsLogger.ConsoleOnlyTracer());
26+
}
27+
28+
/// <summary>
29+
/// Verify AppInsightsAPIClient requires a non-empty connection string.
30+
/// </summary>
31+
[TestMethod]
32+
[ExpectedException(typeof(ArgumentException))]
33+
public void AppInsightsAPIClient_EmptyConnectionString_Throws()
34+
{
35+
var credential = new ClientSecretCredential("tenant", "client", "secret");
36+
new AppInsightsAPIClient(string.Empty, credential, AnalyticsLogger.ConsoleOnlyTracer());
37+
}
38+
39+
/// <summary>
40+
/// Verify AppInsightsAPIClient requires a non-null credential.
41+
/// </summary>
42+
[TestMethod]
43+
[ExpectedException(typeof(ArgumentNullException))]
44+
public void AppInsightsAPIClient_NullCredential_Throws()
45+
{
46+
new AppInsightsAPIClient("InstrumentationKey=00000000-0000-0000-0000-000000000001;IngestionEndpoint=https://test.in.applicationinsights.azure.com/", null, AnalyticsLogger.ConsoleOnlyTracer());
47+
}
48+
49+
/// <summary>
50+
/// Verify AppInsightsAPIClient rejects a connection string without an InstrumentationKey.
51+
/// </summary>
52+
[TestMethod]
53+
[ExpectedException(typeof(ArgumentException))]
54+
public void AppInsightsAPIClient_ConnectionStringWithoutIKey_Throws()
55+
{
56+
var credential = new ClientSecretCredential("tenant-id", "client-id", "secret");
57+
new AppInsightsAPIClient("IngestionEndpoint=https://test.in.applicationinsights.azure.com/", credential, AnalyticsLogger.ConsoleOnlyTracer());
58+
}
59+
60+
/// <summary>
61+
/// Verify AppInsightsAPIClient can be constructed with a valid connection string.
62+
/// </summary>
63+
[TestMethod]
64+
public void AppInsightsAPIClient_ValidConnectionString_Constructs()
65+
{
66+
var credential = new ClientSecretCredential("tenant-id", "client-id", "secret");
67+
var connStr = "InstrumentationKey=00000000-0000-0000-0000-000000000001;IngestionEndpoint=https://test.in.applicationinsights.azure.com/;LiveEndpoint=https://test.livediagnostics.monitor.azure.com/";
68+
using (var client = new AppInsightsAPIClient(connStr, credential, AnalyticsLogger.ConsoleOnlyTracer()))
69+
{
70+
Assert.IsNotNull(client);
71+
}
72+
}
73+
74+
/// <summary>
75+
/// Verify InstrumentationKey is correctly parsed from a standard connection string.
76+
/// </summary>
77+
[TestMethod]
78+
public void ParseConnectionStringValue_ValidConnectionString()
79+
{
80+
var connStr = "InstrumentationKey=00000000-0000-0000-0000-000000000001;IngestionEndpoint=https://eastus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/";
81+
Assert.AreEqual("00000000-0000-0000-0000-000000000001", AppInsightsAPIClient.ParseConnectionStringValue(connStr, "InstrumentationKey"));
82+
}
83+
84+
/// <summary>
85+
/// Verify ParseConnectionStringValue returns null when connection string is empty.
86+
/// </summary>
87+
[TestMethod]
88+
public void ParseConnectionStringValue_NullOrEmpty_ReturnsNull()
89+
{
90+
Assert.IsNull(AppInsightsAPIClient.ParseConnectionStringValue(null, "InstrumentationKey"));
91+
Assert.IsNull(AppInsightsAPIClient.ParseConnectionStringValue(string.Empty, "InstrumentationKey"));
92+
}
93+
94+
/// <summary>
95+
/// Verify ParseConnectionStringValue returns null when key is missing from connection string.
96+
/// </summary>
97+
[TestMethod]
98+
public void ParseConnectionStringValue_MissingKey_ReturnsNull()
99+
{
100+
var connStr = "IngestionEndpoint=https://eastus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/";
101+
Assert.IsNull(AppInsightsAPIClient.ParseConnectionStringValue(connStr, "InstrumentationKey"));
102+
}
103+
104+
/// <summary>
105+
/// Verify AppConfig no longer has AppInsightsApiKey, AppInsightsAppId, or AppInsightsInstrumentationKey properties.
106+
/// These properties were removed as part of the migration to Entra ID authentication.
107+
/// </summary>
108+
[TestMethod]
109+
public void AppConfig_OldApiKeyProperties_Removed()
110+
{
111+
var configType = typeof(AppConfig);
112+
Assert.IsNull(configType.GetProperty("AppInsightsApiKey"), "AppInsightsApiKey should no longer exist on AppConfig");
113+
Assert.IsNull(configType.GetProperty("AppInsightsAppId"), "AppInsightsAppId should no longer exist on AppConfig");
114+
Assert.IsNull(configType.GetProperty("AppInsightsInstrumentationKey"), "AppInsightsInstrumentationKey should no longer exist on AppConfig");
115+
}
116+
}
117+
}

src/AnalyticsEngine/Tests.UnitTests/Tests.UnitTests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />
44
<PropertyGroup>
@@ -30,6 +30,7 @@
3030
</Target>
3131
<ItemGroup>
3232
<Compile Remove="Generated\**" />
33+
<Compile Include="AppInsightsAuthTests.cs" />
3334
<Compile Include="UserMetadataUpdaterBasicTests.cs" />
3435
<Compile Include="UserMetadataUpdaterInsertTests.cs" />
3536
<Compile Include="UserMetadataUpdaterLicenseTests.cs" />

0 commit comments

Comments
 (0)