-
Notifications
You must be signed in to change notification settings - Fork 188
/
types.ts
326 lines (288 loc) · 10.1 KB
/
types.ts
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
import * as assert from "assert";
import * as cdk from 'aws-cdk-lib';
import { AutoScalingGroup } from 'aws-cdk-lib/aws-autoscaling';
import * as eks from 'aws-cdk-lib/aws-eks';
import { Construct, IConstruct } from 'constructs';
import { ResourceProvider } from '.';
import { EksBlueprintProps } from '../stacks';
import { logger } from "../utils/log-utils";
import * as constraints from '../utils/constraints-utils';
import { EbsDeviceVolumeType } from 'aws-cdk-lib/aws-ec2';
/**
* Data type defining helm repositories for GitOps bootstrapping.
*/
export interface HelmRepository {
repoUrl: string,
name: string,
username?: string,
password?: string
}
/**
* Utility type for values passed to Helm or GitOps applications.
*/
export type Values = {
[key: string]: any;
};
/**
* Utility type for Kubernetes taints passed to Helm or GitOps applications.
*/
export type Taint = {
key: string,
value?: string,
effect: "NoSchedule" | "PreferNoSchedule" | "NoExecute",
};
// simple types for various time-bound property values
export type Sec = `${number}s`;
export type Min = `${number}m`;
export type Hour = `${number}h`;
// Specific interface for Block Device Mapping and EBS Volume Mapping
export interface BlockDeviceMapping {
deviceName?: string;
virtualName?: string;
ebs?: EbsVolumeMapping;
noDevice?: string;
}
export interface EbsVolumeMapping {
deleteOnTermination?: boolean;
iops?: number;
snapshotId?: string;
volumeSize?: string;
volumeType?: EbsDeviceVolumeType;
kmsKeyId?: string;
throughput?: number;
outpostArn?: string;
encrypted?: boolean;
}
/**
* Interface that includes a reference to a Git repository for reuse, without credentials
* and other access information.
*/
export interface GitRepositoryReference {
/**
* Expected to support helm style repo at the moment
*/
repoUrl: string,
/**
* Path within the repository
*/
path?: string,
/**
* Optional name for the bootstrap application
*/
name?: string,
/**
* Optional target revision for the repository.
* TargetRevision defines the revision of the source
* to sync the application to. In case of Git, this can be
* commit, tag, or branch. If omitted, will equal to HEAD.
* In case of Helm, this is a semver tag for the Chart's version.
*/
targetRevision?: string
}
/**
* Data type defining an application repository (git).
*/
export interface ApplicationRepository extends GitRepositoryReference {
/**
* Secret from AWS Secrets Manager to import credentials to access the specified git repository.
* The secret must exist in the same region and account where the stack will run.
*/
credentialsSecretName?: string,
/**
* Depending on credentials type the arn should either point to an SSH key (plain text value)
* or a json file with username/password attributes.
* For TOKEN type username can be any non-empty username and token value as password.
*/
credentialsType?: "USERNAME" | "TOKEN" | "SSH"
}
/**
* Adds Constraints to application repository
*/
export class ApplicationRepositoryConstraints implements constraints.ConstraintsType<ApplicationRepository> {
credentialsSecretName = new constraints.InternetHostStringConstraint();
}
/**
* Provides API to register resource providers and get access to the provided resources.
*/
export class ResourceContext {
private readonly resources: Map<string, IConstruct> = new Map();
constructor(public readonly scope: cdk.Stack, public readonly blueprintProps: EksBlueprintProps) { }
/**
* Adds a new resource provider and specifies the name under which the provided resource will be registered,
* @param name Specifies the name key under which the provided resources will be registered for subsequent look-ups.
* @param provider Implementation of the resource provider interface
* @returns the provided resource
*/
public add<T extends IConstruct>(name: string, provider: ResourceProvider<T>): T {
const resource = provider.provide(this);
assert(!this.resources.has(name), `Overwriting ${name} resource during execution is not allowed.`);
this.resources.set(name, resource);
return resource;
}
/**
* Gets the provided resource by the supplied name.
* @param name under which the resource provider was registered
* @returns the resource or undefined if the specified resource was not found
*/
public get<T extends IConstruct = IConstruct>(name: string): T | undefined {
return <T>this.resources.get(name);
}
}
export enum GlobalResources {
Vpc = 'vpc',
HostedZone = 'hosted-zone',
Certificate = 'certificate',
KmsKey = 'kms-key',
Amp = 'amp',
}
/**
* Cluster info supplies required information on the cluster configuration, registered resources and add-ons
* which could be leveraged by the framework, add-on implementations and teams.
*/
export class ClusterInfo {
private readonly provisionedAddOns: Map<string, Construct>;
private readonly scheduledAddOns: Map<string, Promise<Construct>>;
private readonly orderedAddOns: string[];
private resourceContext: ResourceContext;
private addonContext: Map<string, Values>;
/**
* Constructor for ClusterInfo
* @param props
*/
constructor(readonly cluster: eks.ICluster, readonly version: eks.KubernetesVersion,
readonly nodeGroups?: eks.Nodegroup[], readonly autoscalingGroups?: AutoScalingGroup[], readonly fargateProfiles?: eks.FargateProfile[]) {
this.cluster = cluster;
this.provisionedAddOns = new Map<string, Construct>();
this.scheduledAddOns = new Map<string, Promise<Construct>>();
this.orderedAddOns = [];
this.addonContext = new Map<string, Values>();
}
/**
* Provides the resource context object associated with this instance of the EKS Blueprint.
* @returns resource context object
*/
public getResourceContext(): ResourceContext {
return this.resourceContext;
}
/**
* Injection method to provide resource context.
* @param resourceContext
*/
public setResourceContext(resourceContext: ResourceContext) {
this.resourceContext = resourceContext;
}
/**
* Update provisionedAddOns map
* @param addOn
* @param construct
*/
public addProvisionedAddOn(addOn: string, construct: Construct) {
this.orderedAddOns.forEach(e => {
const provisionedOrdered = this.provisionedAddOns.get(e);
if(provisionedOrdered) {
logger.debug(`Adding dependency from ${addOn} to ${e}`);
construct.node.addDependency(provisionedOrdered);
}
});
this.provisionedAddOns.set(addOn, construct);
}
/**
* Given the addOn name, return the provisioned addOn construct
* @param addOn
* @returns undefined
*/
public getProvisionedAddOn(addOn: string): Construct | undefined {
return this.provisionedAddOns.get(addOn);
}
/**
* Returns all provisioned addons
* @returns scheduledAddOns: Map<string, cdk.Construct>
*/
public getAllProvisionedAddons(): Map<string, Construct> {
return this.provisionedAddOns;
}
/**
* Set the preProvisionedAddOn map with the promise for the construct
* of the addon being provisioned
* @param addOn
* @param promise
* @param ordered if addon depends on previous addons for completion (runs serially)
*/
public addScheduledAddOn(addOn: string, promise: Promise<Construct>, ordered: boolean) {
this.scheduledAddOns.set(addOn, promise);
if (ordered) {
this.orderedAddOns.push(addOn);
}
}
/**
* Indicates if strict ordering is applied to the addon
* @param addOn addOn key
* @returns
*/
public isOrderedAddOn(addOn: string) {
return this.orderedAddOns.includes(addOn);
}
/**
* Returns the promise for the Addon construct
* @param addOn
* @returns Promise<cdk.Construct>
*/
public getScheduledAddOn(addOn: string): Promise<Construct> | undefined {
return this.scheduledAddOns.get(addOn);
}
/**
* Returns all scheduled addons
* @returns scheduledAddOns: Map<string, Promise<cdk.Construct>>
*/
public getAllScheduledAddons(): Map<string, Promise<Construct>> {
return this.scheduledAddOns;
}
/**
* Provides the resource registered under supplied name
* @param name of the resource to be returned
* @returns Resource object or undefined if no resource was found
*/
public getResource<T extends cdk.IResource>(name: string): T | undefined {
return this.resourceContext.get<T>(name);
}
/**
* Same as {@link getResource} but will fail if the specified resource is not found
* @param name of the resource to be returned
* @returns Resource object (fails if not found)
*/
public getRequiredResource<T extends cdk.IResource>(name: string): T {
const result = this.resourceContext.get<T>(name);
assert(result, 'Required resource ' + name + ' is missing.');
return result!;
}
/**
* Update addonContext map
* @param addOn
* @param Values
*/
public addAddOnContext(addOn: string, values: Values) {
this.addonContext.set(addOn, values);
}
/**
* Returns all addon contexts
* @returns addonContext: Map<string, Values>
*/
public getAddOnContexts(): Map<string, Values> {
return this.addonContext;
}
}
/**
* Enum type for two different GitOps operating modes
*/
export enum GitOpsMode {
/**
* CDK deploys the `Application` resource for each AddOn enabled or customer workloads,
* and ArgoCD deploys the actual AddOn and workloads via GitOps based on the `Application` resource.
*/
APPLICATION,
/**
* CDK deploys only one `Application` resource for the App of Apps, aka `bootstrap-apps`,
* and ArgoCD deploys all the AddOns based on the child `Application` defined in `bootstrap-apps`.
*/
APP_OF_APPS
}