-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Expand file tree
/
Copy pathStorageAccountFeature.cs
More file actions
163 lines (138 loc) · 6.05 KB
/
Copy pathStorageAccountFeature.cs
File metadata and controls
163 lines (138 loc) · 6.05 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using Azure.Projects.Core;
using Azure.Provisioning.Expressions;
using Azure.Provisioning.Resources;
using Azure.Provisioning.Storage;
namespace Azure.Projects;
public class StorageAccountFeature : AzureProjectFeature
{
private readonly StorageSkuName _skuName;
public string Name { get; }
public StorageAccountFeature(string accountName, StorageSkuName sku = StorageSkuName.StandardLrs)
{
_skuName = sku;
Name = accountName;
}
protected internal override void EmitConstructs(ProjectInfrastructure infrastructure)
{
var storageAccount = new StorageAccount("storageAccount", StorageAccount.ResourceVersions.V2023_01_01)
{
Name = Name,
Kind = StorageKind.StorageV2,
Sku = new StorageSku { Name = _skuName },
IsHnsEnabled = true,
AllowBlobPublicAccess = false,
AllowSharedKeyAccess = false,
Identity = new()
{
ManagedServiceIdentityType = ManagedServiceIdentityType.UserAssigned,
UserAssignedIdentities = { { BicepFunction.Interpolate($"{infrastructure.Identity.Id}").Compile().ToString(), new UserAssignedIdentityDetails() } }
}
};
infrastructure.AddConstruct(Id, storageAccount);
infrastructure.AddSystemRole(
storageAccount,
StorageBuiltInRole.GetBuiltInRoleName(StorageBuiltInRole.StorageBlobDataContributor),
StorageBuiltInRole.StorageBlobDataContributor.ToString()
);
infrastructure.AddSystemRole(
storageAccount,
StorageBuiltInRole.GetBuiltInRoleName(StorageBuiltInRole.StorageTableDataContributor),
StorageBuiltInRole.StorageTableDataContributor.ToString()
);
}
public override string ToString() => $"{this.GetType().Name} {this.Id} {Name}";
}
public class BlobServiceFeature : AzureProjectFeature
{
public BlobServiceFeature()
{}
public StorageAccountFeature? Account { get; set; }
protected internal override void EmitFeatures(ProjectInfrastructure infrastructure)
{
FeatureCollection features = infrastructure.Features;
if (!features.TryGet(out StorageAccountFeature? storageAccount))
{
storageAccount = new(infrastructure.ProjectId);
features.Append(storageAccount);
}
Account = storageAccount;
features.Append(this);
}
protected internal override void EmitConstructs(ProjectInfrastructure infrastructure)
{
if (Account == null)
{
throw new InvalidOperationException("Account is not set.");
}
StorageAccount storageAccount = infrastructure.GetConstruct<StorageAccount>(Account.Id);
BlobService blobService = new("storageBlobService", BlobService.ResourceVersions.V2024_01_01)
{
Parent = storageAccount
};
infrastructure.AddConstruct(Id, blobService);
}
public override string ToString() => $"{this.GetType().Name} {this.Id}";
}
public class BlobContainerFeature : AzureProjectFeature
{
private readonly bool _isObservable;
public string ContainerName { get; }
public BlobServiceFeature? Service { get; set; }
public BlobContainerFeature(string containerName, bool isObservable = true)
: base($"{typeof(BlobContainerFeature).FullName}_{containerName}")
{
ContainerName = containerName;
_isObservable = isObservable;
}
protected internal override void EmitFeatures(ProjectInfrastructure infrastructure)
{
FeatureCollection features = infrastructure.Features;
string projectId = infrastructure.ProjectId;
if (!features.TryGet(out StorageAccountFeature? storageAccount))
{
storageAccount = new(projectId);
features.Append(storageAccount);
}
if (!features.TryGet(out BlobServiceFeature? blobBervice))
{
blobBervice = new BlobServiceFeature() { Account = storageAccount };
features.Append(blobBervice);
}
Service = blobBervice;
features.Append(this);
if (_isObservable)
{
string namespaceName = infrastructure.ProjectId;
string topicName = "cm_servicebus_topic_private";
string subscriptionName = "cm_servicebus_subscription_private";
var sb = infrastructure.AddFeature(new ServiceBusNamespaceFeature(namespaceName));
var sbTopicPrivate = infrastructure.AddFeature(new ServiceBusTopicFeature(namespaceName, topicName));
var systemTopic = infrastructure.AddFeature(new EventGridSystemTopicFeature(namespaceName, storageAccount!, "Microsoft.Storage.StorageAccounts"));
infrastructure.AddFeature(new SystemTopicEventSubscriptionFeature("cm-eventgrid-subscription-blob", systemTopic, sbTopicPrivate, sb));
// TODO: should private connections not be in the Connections collection?
infrastructure.AddFeature(new ServiceBusSubscriptionFeature(namespaceName, topicName, subscriptionName));
}
}
protected internal override void EmitConstructs(ProjectInfrastructure infrastructure)
{
if (Service == null || Service.Account == null)
{
throw new InvalidOperationException("Service or Account is not set.");
}
BlobService blobService = infrastructure.GetConstruct<BlobService>(Service.Id);
BlobContainer blobContainer = new($"storageBlobContainer_{ContainerName}", BlobContainer.ResourceVersions.V2023_01_01)
{
Parent = blobService,
Name = ContainerName
};
infrastructure.AddConstruct(Id, blobContainer);
EmitConnection(infrastructure,
$"Azure.Storage.Blobs.BlobContainerClient@{ContainerName}",
$"https://{Service.Account.Name}.blob.core.windows.net/{ContainerName}"
);
}
public override string ToString() => $"{this.GetType().Name} {this.Id} {ContainerName}";
}