-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAzureResourceManagementService.cs
134 lines (120 loc) · 6.44 KB
/
AzureResourceManagementService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Azure.ResourceManager.Resources;
using azman_v2.Model;
using azman_v2.Auth;
namespace azman_v2
{
public class AzureResourceManagementService : IResourceManagementService
{
private readonly HttpClient _httpClient;
private readonly ILogger<AzureResourceManagementService> _log;
private readonly ITokenProvider _tokenProvider;
private readonly Azure.Core.TokenCredential _tokenCredential;
public AzureResourceManagementService(IHttpClientFactory httpFactory, ILoggerFactory loggerFactory, ITokenProvider tokenProvider)
{
_httpClient = httpFactory.CreateClient();
_log = loggerFactory.CreateLogger<AzureResourceManagementService>();
_tokenProvider = tokenProvider;
_tokenCredential = new ExternalAzureTokenCredential(_tokenProvider);
}
public TagSuiteModel? ProcessAlert(dynamic alert)
{
if (!string.Equals(alert.data.context.activityLog.status.ToString(), "Succeeded", StringComparison.OrdinalIgnoreCase) ||
!string.Equals(alert.data.context.activityLog.subStatus.ToString(), "Created", StringComparison.OrdinalIgnoreCase))
{
_log.LogTrace($"status: {alert.data.context.activityLog.status}");
_log.LogTrace($"subStatus: {alert.data.context.activityLog.subStatus}");
//return new OkResult(); // return 200, we're done here since it hasn't succeeded yet
return null;
}
_log.LogTrace($"{alert.data.context.activityLog.resourceGroupName}");
// handles queueing up new resource groups to be tagged
return new TagSuiteModel(
groupName: alert.data.context.activityLog.resourceGroupName,
subscriptionId: alert.data.context.activityLog.subscriptionId,
user: alert.data.context.activityLog.caller,
managementDate: alert.data.context.activityLog.eventTimestamp
);
}
public async Task AddTagSuite(TagSuiteModel request)
{
request.GenerateBaseTags();
await AddTags(request);
}
public async Task AddTags(TagModel request)
{
var resourceManagerClient = new ResourcesManagementClient(request.SubscriptionId, _tokenCredential);
var resourceGroupRequest = await resourceManagerClient.ResourceGroups.GetAsync(request.ResourceGroupName);
if (resourceGroupRequest == null) return;
var resourceGroup = resourceGroupRequest.Value;
try
{
foreach (var t in request.Tags)
{
resourceGroup.Tags.TryAdd(t.Key, t.Value);
}
await resourceManagerClient.ResourceGroups.CreateOrUpdateAsync(resourceGroup.Name, resourceGroup);
}
catch (Exception ex)
{
// todo: what happens when tagging fails? what's recoverable? what's not?
_log.LogError(ex, ex.Message);
}
}
public async Task AddTags(string resourceGroup, string subscriptionId, params KeyValuePair<string, string>[] tags)
{
await AddTags(new TagModel(resourceGroup, subscriptionId, tags));
}
// todo: explore changes required for using resource ID for _any_ resource
public async Task DeleteResource(string subscriptionId, string resourceGroupName)
{
// todo: what-if? --> log deletion, but don't execute
// connect to azure
_log.LogInformation($"Request to delete {resourceGroupName} from subscription {subscriptionId}");
var resourceManagerClient = new ResourcesManagementClient(subscriptionId, _tokenCredential);
await resourceManagerClient.ResourceGroups.StartDeleteAsync(resourceGroupName);
}
public async Task<string> GetRawTagValue(string subscriptionId, string resourceGroupName, string tagName)
{
var resourceManagerClient = new ResourcesManagementClient(subscriptionId, _tokenCredential);
var resourceGroupRequest = await resourceManagerClient.ResourceGroups.GetAsync(resourceGroupName);
if (resourceGroupRequest == null) return string.Empty;
var resourceGroup = resourceGroupRequest.Value;
resourceGroup.Tags.TryGetValue(tagName, out var tagValue);
return tagValue ?? string.Empty;
}
public async Task<T> GetTagValue<T>(string subscriptionId, string resourceGroupName, string tagName, Func<string, T> converter, Func<T> error)
{
var resourceManagerClient = new ResourcesManagementClient(subscriptionId, _tokenCredential);
var resourceGroupRequest = await resourceManagerClient.ResourceGroups.GetAsync(resourceGroupName);
if (resourceGroupRequest == null) return error();
var resourceGroup = resourceGroupRequest.Value;
if (resourceGroup.Tags.TryGetValue(tagName, out var tagValue))
{
return converter(tagValue);
}
return error();
}
public async Task<string> ExportResourceGroupTemplateByName(string subscriptionId, string groupName)
{
// POST https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/exportTemplate?api-version=2020-06-01
var resourceManagerClient = new ResourcesManagementClient(subscriptionId, _tokenCredential);
var resourceTypesToExport = new Azure.ResourceManager.Resources.Models.ExportTemplateRequest();
resourceTypesToExport.Resources.Add("*");
var exportedTemplate = await resourceManagerClient.ResourceGroups.StartExportTemplateAsync(groupName, resourceTypesToExport);
if (exportedTemplate.HasValue) return (string)exportedTemplate.Value.Template;
return string.Empty;
}
public async Task<Azure.ResourceManager.Resources.Models.ResourceGroup> GetResourceGroup(string subscriptionId,
string resourceGroupName)
{
var resourceManagerClient = new ResourcesManagementClient(subscriptionId, _tokenCredential);
var groupResponse = await resourceManagerClient.ResourceGroups.GetAsync(resourceGroupName);
return groupResponse.Value;
}
}
}