This commit is contained in:
2024-10-13 20:49:50 -05:00
parent 1e9c269f07
commit cd9682379d
9 changed files with 118 additions and 39 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
# ---> VisualStudioCode
.vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
@@ -7,6 +8,8 @@
!.vscode/*.code-snippets
.idea/*
launchsettings.json
# Local History for Visual Studio Code
.history/

View File

@@ -1,37 +1,75 @@
using Azure;
using Azure.Monitor.Query;
using Azure.Monitor.Query.Models;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;
using Microsoft.Extensions.Logging;
using ProperDI.Azure.Endpoints.ResourceGroup.Models;
namespace ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
namespace ProperDI.Azure.Endpoints.ResourceGroup;
public interface IActivityLogReader
{
Task Scan(CancellationToken cancellationToken);
Task ScanAppAsync(string appName, CancellationToken cancellationToken, QueryTimeRange? givenTimeRange);
Task ScanAllAsync(CancellationToken cancellationToken);
}
public class ActivityLogReader(
ILogger<ActivityLogReader> logger,
ArmClient armClient)
: IActivityLogReader
public class ActivityLogReader : IActivityLogReader
{
private readonly ILogger<ActivityLogReader> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
private readonly ArmClient _armClient = armClient ?? throw new ArgumentNullException(nameof(armClient));
private readonly ILogger<ActivityLogReader> _logger;
private readonly ArmClient _armClient;
private readonly LogsQueryClient _logsQueryClient;
public async Task Scan(CancellationToken cancellationToken)
public ActivityLogReader(ILogger<ActivityLogReader> logger, ArmClient armClient, LogsQueryClient logsQueryClient)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_armClient = armClient ?? throw new ArgumentNullException(nameof(armClient));
_logsQueryClient = logsQueryClient ?? throw new ArgumentNullException(nameof(logsQueryClient));
}
public async Task ScanAppAsync(string appName, CancellationToken cancellationToken, QueryTimeRange? givenTimeRange = default)
{
var timeRange = givenTimeRange ?? new QueryTimeRange(DateTime.UtcNow.AddDays(-7), DateTime.UtcNow);
try
{
_logger.LogInformation("Scanning for resources");
var resp = await _armClient.GetDefaultSubscriptionAsync(cancellationToken);
_logger.LogInformation("Found default subscription {sub}", resp.Data.DisplayName);
await ScanLogsForAppActivityAsync();
}
catch (TaskCanceledException)
{
_logger.LogWarning("Task canceled");
}
catch (System.Exception ex)
catch (Exception ex)
{
_logger.LogError(ex, "Http request failed");
throw;
}
}
public async Task ScanAllAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public async Task ScanLogsForAppActivityAsync()
{
}
private async Task<SubscriptionResource> GetDefaultSubscriptionAsync(CancellationToken cancellationToken)
{
try
{
var sub = await _armClient.GetDefaultSubscriptionAsync(cancellationToken);
return sub;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to retrieve default subscription");
throw;
}
}
}

View File

@@ -0,0 +1,3 @@
namespace ProperDI.Azure.Endpoints.ResourceGroup.Models;
public record AppActivitySummary(string AppName, string PermissionsExercised);

View File

@@ -0,0 +1,3 @@
namespace ProperDI.Azure.Endpoints.ResourceGroup.Models;
public record TimeRange(DateTime Start, DateTime End);

View File

@@ -1,7 +1,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
using ProperDI.Azure.Endpoints.ResourceGroup;
public class RoleAssesorBackgroundService : IHostedService, IDisposable
{
@@ -57,7 +57,7 @@ public class RoleAssesorBackgroundService : IHostedService, IDisposable
if (cancellationToken.IsCancellationRequested)
return;
await _activityLogReader.Scan(cancellationToken);
await _activityLogReader.ScanAppAsync("Test", cancellationToken, null);
}
catch (OperationCanceledException)
{

View File

@@ -1,32 +1,56 @@
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
using Microsoft.Extensions.Configuration;
using ProperDI.Azure.Endpoints.ResourceGroup;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHttpClient();
builder.Services.AddTransient<IActivityLogReader, ActivityLogReader>();
builder.Services.AddAzureClients(clientBuilder =>
public class Program
{
// var creds = new ClientSecretCredential(
// "",
// "",
// "");
clientBuilder.UseCredential(new DefaultAzureCredential());
clientBuilder.AddArmClient("2690a5f1-155b-4fa8-896f-92c6bcb62bee");
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddEnvironmentVariables();
// Optionally, you can add JSON configuration if needed
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
// config.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddHttpClient();
services.AddTransient<IActivityLogReader, ActivityLogReader>();
services.AddAzureClients(clientBuilder =>
{
var configuration = hostContext.Configuration;
// Read Azure credentials from environment variables
var tenantId = configuration["AzureTenantId"];
var clientId = configuration["AzureClientId"];
var clientSecret = configuration["AzureClientSecret"];
var subscriptionId = configuration["AzureSubscriptionId"];
System.Console.WriteLine($"Tenant id: {tenantId}\nClientID: {clientId}\nClientSecret: {clientSecret}");
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
clientBuilder.UseCredential(credential);
clientBuilder.AddArmClient(subscriptionId);
clientBuilder.ConfigureDefaults(client =>
{
client.Retry.MaxRetries = 3;
});
clientBuilder.AddLogsQueryClient();
});
builder.Services.Configure<RoleAssesorBackgroundServiceOptions>(builder.Configuration.GetSection("RoleAssessorBackgroundService"));
builder.Services.AddHostedService<RoleAssesorBackgroundService>();
var host = builder.Build();
await host.RunAsync();
services.Configure<RoleAssesorBackgroundServiceOptions>(
hostContext.Configuration.GetSection("RoleAssessorBackgroundService"));
services.AddHostedService<RoleAssesorBackgroundService>();
});
}

View File

@@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.12.1" />
<PackageReference Include="Azure.Monitor.Query" Version="1.5.0" />
<PackageReference Include="Azure.ResourceManager" Version="1.13.0" />
<PackageReference Include="Azure.ResourceManager.Resources" Version="1.9.0" />
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.6" />

View File

View File

@@ -4,11 +4,18 @@
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"System.Net": "Warning"
"System.Net": "Warning",
"Azure.Core": "Warning",
"Azure.Identity": "Warning"
}
},
"RoleAssessorBackgroundService": {
"RunFrequencyInMinutes": 12
},
"DefaultSubscriptionId": "2690a5f1-155b-4fa8-896f-92c6bcb62bee"
"DefaultSubscriptionId": "2690a5f1-155b-4fa8-896f-92c6bcb62bee",
"ASPNETCORE_ENVIRONMENT": "Development",
"AzureSubscriptionId": "2690a5f1-155b-4fa8-896f-92c6bcb62bee",
"AzureTenantId": "11ffe5d3-5e72-4414-8dfd-1eb209497679",
"AzureClientId": "d0870778-24dd-4c87-a449-2c36674035d1",
"AzureClientSecret": "EWX8Q~jpfKab8hB1TzujorzKIeJEV5NKEfCuOaFC"
}