v3
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
# ---> VisualStudioCode
|
# ---> VisualStudioCode
|
||||||
|
.vscode
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
@@ -7,6 +8,8 @@
|
|||||||
!.vscode/*.code-snippets
|
!.vscode/*.code-snippets
|
||||||
.idea/*
|
.idea/*
|
||||||
|
|
||||||
|
launchsettings.json
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Local History for Visual Studio Code
|
||||||
.history/
|
.history/
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,75 @@
|
|||||||
|
using Azure;
|
||||||
|
using Azure.Monitor.Query;
|
||||||
|
using Azure.Monitor.Query.Models;
|
||||||
using Azure.ResourceManager;
|
using Azure.ResourceManager;
|
||||||
|
using Azure.ResourceManager.Resources;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using ProperDI.Azure.Endpoints.ResourceGroup.Models;
|
||||||
|
|
||||||
namespace ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
|
namespace ProperDI.Azure.Endpoints.ResourceGroup;
|
||||||
|
|
||||||
public interface IActivityLogReader
|
public interface IActivityLogReader
|
||||||
{
|
{
|
||||||
Task Scan(CancellationToken cancellationToken);
|
Task ScanAppAsync(string appName, CancellationToken cancellationToken, QueryTimeRange? givenTimeRange);
|
||||||
|
Task ScanAllAsync(CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ActivityLogReader(
|
public class ActivityLogReader : IActivityLogReader
|
||||||
ILogger<ActivityLogReader> logger,
|
|
||||||
ArmClient armClient)
|
|
||||||
: IActivityLogReader
|
|
||||||
{
|
{
|
||||||
private readonly ILogger<ActivityLogReader> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
private readonly ILogger<ActivityLogReader> _logger;
|
||||||
private readonly ArmClient _armClient = armClient ?? throw new ArgumentNullException(nameof(armClient));
|
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
|
try
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Scanning for resources");
|
_logger.LogInformation("Scanning for resources");
|
||||||
var resp = await _armClient.GetDefaultSubscriptionAsync(cancellationToken);
|
await ScanLogsForAppActivityAsync();
|
||||||
_logger.LogInformation("Found default subscription {sub}", resp.Data.DisplayName);
|
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException)
|
catch (TaskCanceledException)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Task canceled");
|
_logger.LogWarning("Task canceled");
|
||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Http request failed");
|
_logger.LogError(ex, "Http request failed");
|
||||||
throw;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace ProperDI.Azure.Endpoints.ResourceGroup.Models;
|
||||||
|
|
||||||
|
public record AppActivitySummary(string AppName, string PermissionsExercised);
|
||||||
3
Azure.Endpoints/ResourceGroup/Models/TimeRange.cs
Normal file
3
Azure.Endpoints/ResourceGroup/Models/TimeRange.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
namespace ProperDI.Azure.Endpoints.ResourceGroup.Models;
|
||||||
|
|
||||||
|
public record TimeRange(DateTime Start, DateTime End);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
|
using ProperDI.Azure.Endpoints.ResourceGroup;
|
||||||
|
|
||||||
public class RoleAssesorBackgroundService : IHostedService, IDisposable
|
public class RoleAssesorBackgroundService : IHostedService, IDisposable
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@ public class RoleAssesorBackgroundService : IHostedService, IDisposable
|
|||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await _activityLogReader.Scan(cancellationToken);
|
await _activityLogReader.ScanAppAsync("Test", cancellationToken, null);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|||||||
68
Program.cs
68
Program.cs
@@ -1,32 +1,56 @@
|
|||||||
using Azure.Identity;
|
using Azure.Identity;
|
||||||
using Azure.ResourceManager;
|
|
||||||
using Azure.ResourceManager.Resources;
|
|
||||||
using Microsoft.Extensions.Azure;
|
using Microsoft.Extensions.Azure;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using ProperDI.Azure.Endpoints.ResourceGroup;
|
||||||
|
|
||||||
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
|
public class Program
|
||||||
|
|
||||||
builder.Services.AddHttpClient();
|
|
||||||
builder.Services.AddTransient<IActivityLogReader, ActivityLogReader>();
|
|
||||||
builder.Services.AddAzureClients(clientBuilder =>
|
|
||||||
{
|
{
|
||||||
// var creds = new ClientSecretCredential(
|
public static async Task Main(string[] args)
|
||||||
// "",
|
|
||||||
// "",
|
|
||||||
// "");
|
|
||||||
clientBuilder.UseCredential(new DefaultAzureCredential());
|
|
||||||
clientBuilder.AddArmClient("2690a5f1-155b-4fa8-896f-92c6bcb62bee");
|
|
||||||
clientBuilder.ConfigureDefaults(client =>
|
|
||||||
{
|
{
|
||||||
client.Retry.MaxRetries = 3;
|
var host = CreateHostBuilder(args).Build();
|
||||||
});
|
await host.RunAsync();
|
||||||
});
|
}
|
||||||
|
|
||||||
builder.Services.Configure<RoleAssesorBackgroundServiceOptions>(builder.Configuration.GetSection("RoleAssessorBackgroundService"));
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
builder.Services.AddHostedService<RoleAssesorBackgroundService>();
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
|
{
|
||||||
|
config.AddEnvironmentVariables();
|
||||||
|
|
||||||
var host = builder.Build();
|
// 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>();
|
||||||
|
|
||||||
await host.RunAsync();
|
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();
|
||||||
|
});
|
||||||
|
|
||||||
|
services.Configure<RoleAssesorBackgroundServiceOptions>(
|
||||||
|
hostContext.Configuration.GetSection("RoleAssessorBackgroundService"));
|
||||||
|
services.AddHostedService<RoleAssesorBackgroundService>();
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Azure.Identity" Version="1.12.1" />
|
<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" Version="1.13.0" />
|
||||||
<PackageReference Include="Azure.ResourceManager.Resources" Version="1.9.0" />
|
<PackageReference Include="Azure.ResourceManager.Resources" Version="1.9.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.6" />
|
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.6" />
|
||||||
|
|||||||
0
Utilities/TimerExtensions.cs
Normal file
0
Utilities/TimerExtensions.cs
Normal file
@@ -4,11 +4,18 @@
|
|||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft": "Warning",
|
"Microsoft": "Warning",
|
||||||
"Microsoft.Hosting.Lifetime": "Information",
|
"Microsoft.Hosting.Lifetime": "Information",
|
||||||
"System.Net": "Warning"
|
"System.Net": "Warning",
|
||||||
|
"Azure.Core": "Warning",
|
||||||
|
"Azure.Identity": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RoleAssessorBackgroundService": {
|
"RoleAssessorBackgroundService": {
|
||||||
"RunFrequencyInMinutes": 12
|
"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"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user