@spinnaker/amazon 0.12.2 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/domain/IAmazonLaunchTemplate.d.ts +1 -1
- package/dist/domain/IAmazonServerGroup.d.ts +10 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/reactShims/aws.react.injector.d.ts +2 -1
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +17 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +28 -2
- package/dist/serverGroup/serverGroup.transformer.d.ts +2 -1
- package/package.json +3 -3
- package/src/domain/IAmazonLaunchTemplate.ts +1 -1
- package/src/domain/IAmazonServerGroup.ts +11 -0
- package/src/reactShims/aws.react.injector.ts +2 -1
- package/src/serverGroup/configure/{serverGroupCommandBuilder.service.js → serverGroupCommandBuilder.service.ts} +101 -64
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +30 -2
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.tsx +3 -2
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +2 -1
- package/src/serverGroup/serverGroup.transformer.ts +24 -22
|
@@ -3,11 +3,12 @@ import IInjectorService = angular.auto.IInjectorService;
|
|
|
3
3
|
import type { FunctionReader } from '@spinnaker/core';
|
|
4
4
|
import { ReactInject } from '@spinnaker/core';
|
|
5
5
|
import type { EvaluateCloudFormationChangeSetExecutionService } from '../pipeline/stages/deployCloudFormation/evaluateCloudFormationChangeSetExecution.service';
|
|
6
|
+
import type { AwsServerGroupCommandBuilder } from '../serverGroup/configure/serverGroupCommandBuilder.service';
|
|
6
7
|
import type { AwsServerGroupConfigurationService } from '../serverGroup/configure/serverGroupConfiguration.service';
|
|
7
8
|
import type { AwsServerGroupTransformer } from '../serverGroup/serverGroup.transformer';
|
|
8
9
|
export declare class AwsReactInject extends ReactInject {
|
|
9
10
|
get awsInstanceTypeService(): any;
|
|
10
|
-
get awsServerGroupCommandBuilder():
|
|
11
|
+
get awsServerGroupCommandBuilder(): AwsServerGroupCommandBuilder;
|
|
11
12
|
get awsServerGroupConfigurationService(): AwsServerGroupConfigurationService;
|
|
12
13
|
get awsServerGroupTransformer(): AwsServerGroupTransformer;
|
|
13
14
|
get functionReader(): FunctionReader;
|
|
@@ -1,2 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { Application } from '@spinnaker/core';
|
|
2
|
+
import type { IAmazonServerGroup, IAmazonServerGroupView } from '../../domain';
|
|
3
|
+
import type { IAmazonServerGroupCommand, IAmazonServerGroupDeployConfiguration } from './serverGroupConfiguration.service';
|
|
4
|
+
export declare const AMAZON_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE = "spinnaker.amazon.serverGroupCommandBuilder.service";
|
|
5
|
+
export declare const name = "spinnaker.amazon.serverGroupCommandBuilder.service";
|
|
6
|
+
export interface AwsServerGroupCommandBuilder {
|
|
7
|
+
buildNewServerGroupCommand(application: Application, defaults?: {
|
|
8
|
+
account?: string;
|
|
9
|
+
region?: string;
|
|
10
|
+
subnet?: string;
|
|
11
|
+
mode?: string;
|
|
12
|
+
}): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
13
|
+
buildServerGroupCommandFromExisting(application: Application, serverGroup: IAmazonServerGroupView, mode?: string): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
14
|
+
buildNewServerGroupCommandForPipeline(): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
15
|
+
buildServerGroupCommandFromPipeline(application: Application, originalCluster: IAmazonServerGroupDeployConfiguration): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
16
|
+
buildUpdateServerGroupCommand(serverGroup: IAmazonServerGroup): Partial<IAmazonServerGroupCommand>;
|
|
17
|
+
}
|
|
@@ -19,6 +19,7 @@ export interface IAmazonServerGroupCommandBackingData extends IServerGroupComman
|
|
|
19
19
|
scalingProcesses: IScalingProcess[];
|
|
20
20
|
}
|
|
21
21
|
export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandViewState {
|
|
22
|
+
isNew: boolean;
|
|
22
23
|
dirty: IAmazonServerGroupCommandDirty;
|
|
23
24
|
spelTargetGroups: string[];
|
|
24
25
|
spelLoadBalancers: string[];
|
|
@@ -26,14 +27,31 @@ export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandV
|
|
|
26
27
|
}
|
|
27
28
|
export interface IAmazonInstanceTypeOverride {
|
|
28
29
|
instanceType: string;
|
|
29
|
-
weightedCapacity?:
|
|
30
|
+
weightedCapacity?: string;
|
|
30
31
|
priority?: number;
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* We model server group commands in two subtly different ways.
|
|
35
|
+
* It's unclear what the intention is, but we should converge on a single model eventually.
|
|
36
|
+
*
|
|
37
|
+
* This model is stored in a Aws Deploy Stage under `clusters[]`.
|
|
38
|
+
* It is also sent across the wire during a deploy task from infrastructure view
|
|
39
|
+
* (i.e., "clone server group", "create server group")
|
|
40
|
+
*/
|
|
41
|
+
export interface IAmazonServerGroupDeployConfiguration extends IAmazonServerGroupCommand_Internal {
|
|
42
|
+
account: string;
|
|
43
|
+
availabilityZones: {
|
|
44
|
+
[region: string]: string[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
interface IAmazonServerGroupCommand_Internal extends IAmazonServerGroupCommand {
|
|
48
|
+
availabilityZones: any;
|
|
49
|
+
}
|
|
32
50
|
export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
33
|
-
viewState: IAmazonServerGroupCommandViewState;
|
|
34
51
|
associateIPv6Address?: boolean;
|
|
35
52
|
associatePublicIpAddress: boolean;
|
|
36
53
|
backingData: IAmazonServerGroupCommandBackingData;
|
|
54
|
+
base64UserData: string;
|
|
37
55
|
copySourceCustomBlockDeviceMappings: boolean;
|
|
38
56
|
ebsOptimized: boolean;
|
|
39
57
|
healthCheckGracePeriod: number;
|
|
@@ -48,6 +66,13 @@ export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
|
48
66
|
setLaunchTemplate?: boolean;
|
|
49
67
|
unlimitedCpuCredits?: boolean;
|
|
50
68
|
capacityRebalance?: boolean;
|
|
69
|
+
ramdiskId?: string;
|
|
70
|
+
viewState: IAmazonServerGroupCommandViewState;
|
|
71
|
+
source: {
|
|
72
|
+
account: string;
|
|
73
|
+
region: string;
|
|
74
|
+
asgName: string;
|
|
75
|
+
};
|
|
51
76
|
onDemandAllocationStrategy?: string;
|
|
52
77
|
onDemandBaseCapacity?: number;
|
|
53
78
|
onDemandPercentageAboveBaseCapacity?: number;
|
|
@@ -93,3 +118,4 @@ export declare class AwsServerGroupConfigurationService {
|
|
|
93
118
|
attachEventHandlers(cmd: IAmazonServerGroupCommand): void;
|
|
94
119
|
}
|
|
95
120
|
export declare const AWS_SERVER_GROUP_CONFIGURATION_SERVICE = "spinnaker.amazon.serverGroup.configure.service";
|
|
121
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IAmazonServerGroupCommand, IAmazonServerGroupDeployConfiguration } from './configure';
|
|
1
2
|
import type { IAmazonServerGroup, IAmazonServerGroupView, IScalingPolicy, IScalingPolicyView, ITargetTrackingPolicy } from '../domain';
|
|
2
3
|
export declare class AwsServerGroupTransformer {
|
|
3
4
|
private addComparator;
|
|
@@ -6,7 +7,7 @@ export declare class AwsServerGroupTransformer {
|
|
|
6
7
|
normalizeServerGroupDetails(serverGroup: IAmazonServerGroup): IAmazonServerGroupView;
|
|
7
8
|
normalizeServerGroup(serverGroup: IAmazonServerGroup): PromiseLike<IAmazonServerGroup>;
|
|
8
9
|
private addVpcNameToServerGroup;
|
|
9
|
-
convertServerGroupCommandToDeployConfiguration(base:
|
|
10
|
+
convertServerGroupCommandToDeployConfiguration(base: IAmazonServerGroupCommand): IAmazonServerGroupDeployConfiguration;
|
|
10
11
|
constructNewStepScalingPolicyTemplate(serverGroup: IAmazonServerGroup): IScalingPolicy;
|
|
11
12
|
constructNewTargetTrackingPolicyTemplate(): ITargetTrackingPolicy;
|
|
12
13
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spinnaker/amazon",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.6",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"lib": "npm run build"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@spinnaker/core": "^0.
|
|
16
|
+
"@spinnaker/core": "^0.19.0",
|
|
17
17
|
"@uirouter/angularjs": "1.0.26",
|
|
18
18
|
"@uirouter/core": "6.0.8",
|
|
19
19
|
"@uirouter/react": "1.0.7",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"shx": "0.3.3",
|
|
56
56
|
"typescript": "4.3.5"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "9f35728cf0ae71f5b28422920e4f802d92193845"
|
|
59
59
|
}
|
|
@@ -39,7 +39,7 @@ export interface ILicenseConfig {
|
|
|
39
39
|
export interface IMetadataOptions {
|
|
40
40
|
httpEndpoint?: 'disabled' | 'enabled';
|
|
41
41
|
httpPutResponseHopLimit?: number;
|
|
42
|
-
|
|
42
|
+
httpTokens?: 'required' | 'optional';
|
|
43
43
|
state?: 'pending' | 'applied';
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -5,16 +5,27 @@ import type { IScalingPolicyView } from './IAmazonScalingPolicy';
|
|
|
5
5
|
import type { IScalingPolicy } from './IScalingPolicy';
|
|
6
6
|
import type { ISuspendedProcess } from './IScalingProcess';
|
|
7
7
|
|
|
8
|
+
export interface IAmazonAsgTag {
|
|
9
|
+
key: string;
|
|
10
|
+
value: string;
|
|
11
|
+
propagateAtLaunch: boolean;
|
|
12
|
+
resourceId: string;
|
|
13
|
+
resourceType: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
export interface IAmazonAsg extends IAsg {
|
|
9
17
|
availabilityZones: string[];
|
|
18
|
+
autoScalingGroupName: string;
|
|
10
19
|
defaultCooldown: number;
|
|
11
20
|
healthCheckType: string;
|
|
12
21
|
healthCheckGracePeriod: number;
|
|
22
|
+
loadBalancerNames: string[];
|
|
13
23
|
terminationPolicies: string[];
|
|
14
24
|
enabledMetrics: Array<{ metric: string }>;
|
|
15
25
|
vpczoneIdentifier?: string;
|
|
16
26
|
suspendedProcesses?: ISuspendedProcess[];
|
|
17
27
|
capacityRebalance?: boolean;
|
|
28
|
+
tags: IAmazonAsgTag[];
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
export interface IAmazonServerGroup extends IServerGroup {
|
|
@@ -3,6 +3,7 @@ import IInjectorService = angular.auto.IInjectorService;
|
|
|
3
3
|
import type { FunctionReader } from '@spinnaker/core';
|
|
4
4
|
import { ReactInject } from '@spinnaker/core';
|
|
5
5
|
import type { EvaluateCloudFormationChangeSetExecutionService } from '../pipeline/stages/deployCloudFormation/evaluateCloudFormationChangeSetExecution.service';
|
|
6
|
+
import type { AwsServerGroupCommandBuilder } from '../serverGroup/configure/serverGroupCommandBuilder.service';
|
|
6
7
|
|
|
7
8
|
import type { AwsServerGroupConfigurationService } from '../serverGroup/configure/serverGroupConfiguration.service';
|
|
8
9
|
import type { AwsServerGroupTransformer } from '../serverGroup/serverGroup.transformer';
|
|
@@ -10,7 +11,7 @@ import type { AwsServerGroupTransformer } from '../serverGroup/serverGroup.trans
|
|
|
10
11
|
// prettier-ignore
|
|
11
12
|
export class AwsReactInject extends ReactInject {
|
|
12
13
|
public get awsInstanceTypeService() { return this.$injector.get('awsInstanceTypeService') as any; }
|
|
13
|
-
public get awsServerGroupCommandBuilder() { return this.$injector.get('awsServerGroupCommandBuilder') as
|
|
14
|
+
public get awsServerGroupCommandBuilder() { return this.$injector.get('awsServerGroupCommandBuilder') as AwsServerGroupCommandBuilder; }
|
|
14
15
|
public get awsServerGroupConfigurationService() { return this.$injector.get('awsServerGroupConfigurationService') as AwsServerGroupConfigurationService; }
|
|
15
16
|
public get awsServerGroupTransformer() { return this.$injector.get('awsServerGroupTransformer') as AwsServerGroupTransformer; }
|
|
16
17
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { IQService } from 'angular';
|
|
1
2
|
import * as angular from 'angular';
|
|
2
3
|
import _ from 'lodash';
|
|
3
4
|
|
|
5
|
+
import type { Application, InstanceTypeService } from '@spinnaker/core';
|
|
4
6
|
import {
|
|
5
7
|
AccountService,
|
|
6
8
|
DeploymentStrategyRegistry,
|
|
@@ -8,13 +10,45 @@ import {
|
|
|
8
10
|
NameUtils,
|
|
9
11
|
SubnetReader,
|
|
10
12
|
} from '@spinnaker/core';
|
|
11
|
-
import { AWSProviderSettings } from '../../aws.settings';
|
|
12
13
|
|
|
14
|
+
import { AWSProviderSettings } from '../../aws.settings';
|
|
15
|
+
import type { IAmazonLaunchTemplateOverrides, ILaunchTemplateData } from '../../domain';
|
|
16
|
+
import type { IAmazonServerGroup, IAmazonServerGroupView, INetworkInterface } from '../../domain';
|
|
17
|
+
import type {
|
|
18
|
+
AwsServerGroupConfigurationService,
|
|
19
|
+
IAmazonInstanceTypeOverride,
|
|
20
|
+
IAmazonServerGroupCommand,
|
|
21
|
+
IAmazonServerGroupCommandViewState,
|
|
22
|
+
IAmazonServerGroupDeployConfiguration,
|
|
23
|
+
} from './serverGroupConfiguration.service';
|
|
13
24
|
import { AWS_SERVER_GROUP_CONFIGURATION_SERVICE } from './serverGroupConfiguration.service';
|
|
14
25
|
|
|
15
26
|
export const AMAZON_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE =
|
|
16
27
|
'spinnaker.amazon.serverGroupCommandBuilder.service';
|
|
17
28
|
export const name = AMAZON_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE; // for backwards compatibility
|
|
29
|
+
|
|
30
|
+
export interface AwsServerGroupCommandBuilder {
|
|
31
|
+
buildNewServerGroupCommand(
|
|
32
|
+
application: Application,
|
|
33
|
+
defaults?: { account?: string; region?: string; subnet?: string; mode?: string },
|
|
34
|
+
): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
35
|
+
|
|
36
|
+
buildServerGroupCommandFromExisting(
|
|
37
|
+
application: Application,
|
|
38
|
+
serverGroup: IAmazonServerGroupView,
|
|
39
|
+
mode?: string,
|
|
40
|
+
): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
41
|
+
|
|
42
|
+
buildNewServerGroupCommandForPipeline(): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
43
|
+
|
|
44
|
+
buildServerGroupCommandFromPipeline(
|
|
45
|
+
application: Application,
|
|
46
|
+
originalCluster: IAmazonServerGroupDeployConfiguration,
|
|
47
|
+
): PromiseLike<Partial<IAmazonServerGroupCommand>>;
|
|
48
|
+
|
|
49
|
+
buildUpdateServerGroupCommand(serverGroup: IAmazonServerGroup): Partial<IAmazonServerGroupCommand>;
|
|
50
|
+
}
|
|
51
|
+
|
|
18
52
|
angular
|
|
19
53
|
.module(AMAZON_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE, [
|
|
20
54
|
INSTANCE_TYPE_SERVICE,
|
|
@@ -24,9 +58,15 @@ angular
|
|
|
24
58
|
'$q',
|
|
25
59
|
'instanceTypeService',
|
|
26
60
|
'awsServerGroupConfigurationService',
|
|
27
|
-
function (
|
|
28
|
-
|
|
29
|
-
|
|
61
|
+
function (
|
|
62
|
+
$q: IQService,
|
|
63
|
+
instanceTypeService: InstanceTypeService,
|
|
64
|
+
awsServerGroupConfigurationService: AwsServerGroupConfigurationService,
|
|
65
|
+
) {
|
|
66
|
+
function buildNewServerGroupCommand(
|
|
67
|
+
application: Application,
|
|
68
|
+
defaults: { account?: string; region?: string; subnet?: string; mode?: string } = {},
|
|
69
|
+
) {
|
|
30
70
|
const credentialsLoader = AccountService.getCredentialsKeyedByAccount('aws');
|
|
31
71
|
|
|
32
72
|
const defaultCredentials =
|
|
@@ -45,14 +85,14 @@ angular
|
|
|
45
85
|
.then(function ([preferredZones, credentialsKeyedByAccount]) {
|
|
46
86
|
const credentials = credentialsKeyedByAccount[defaultCredentials];
|
|
47
87
|
const keyPair = credentials ? credentials.defaultKeyPair : null;
|
|
48
|
-
const applicationAwsSettings =
|
|
88
|
+
const applicationAwsSettings = application.attributes?.providerSettings?.aws ?? {};
|
|
49
89
|
|
|
50
90
|
let defaultIamRole = AWSProviderSettings.defaults.iamRole || 'BaseIAMRole';
|
|
51
91
|
defaultIamRole = defaultIamRole.replace('{{application}}', application.name);
|
|
52
92
|
|
|
53
93
|
const useAmiBlockDeviceMappings = applicationAwsSettings.useAmiBlockDeviceMappings || false;
|
|
54
94
|
|
|
55
|
-
const command = {
|
|
95
|
+
const command: Partial<IAmazonServerGroupCommand> = {
|
|
56
96
|
application: application.name,
|
|
57
97
|
credentials: defaultCredentials,
|
|
58
98
|
region: defaultRegion,
|
|
@@ -94,45 +134,39 @@ angular
|
|
|
94
134
|
disableStrategySelection: true,
|
|
95
135
|
dirty: {},
|
|
96
136
|
submitButtonLabel: getSubmitButtonLabel(defaults.mode || 'create'),
|
|
97
|
-
},
|
|
137
|
+
} as IAmazonServerGroupCommandViewState,
|
|
98
138
|
};
|
|
99
139
|
|
|
100
|
-
if (
|
|
101
|
-
application.attributes &&
|
|
102
|
-
application.attributes.platformHealthOnlyShowOverride &&
|
|
103
|
-
application.attributes.platformHealthOnly
|
|
104
|
-
) {
|
|
140
|
+
if (application.attributes?.platformHealthOnlyShowOverride && application.attributes?.platformHealthOnly) {
|
|
105
141
|
command.interestingHealthProviderNames = ['Amazon'];
|
|
106
142
|
}
|
|
107
143
|
|
|
108
|
-
if (
|
|
109
|
-
defaultCredentials === 'test' &&
|
|
110
|
-
AWSProviderSettings.serverGroups &&
|
|
111
|
-
AWSProviderSettings.serverGroups.enableIPv6
|
|
112
|
-
) {
|
|
144
|
+
if (defaultCredentials === 'test' && AWSProviderSettings.serverGroups?.enableIPv6) {
|
|
113
145
|
command.associateIPv6Address = true;
|
|
114
146
|
}
|
|
115
147
|
|
|
116
|
-
if (AWSProviderSettings.serverGroups
|
|
148
|
+
if (AWSProviderSettings.serverGroups?.enableIMDSv2) {
|
|
117
149
|
/**
|
|
118
150
|
* Older SDKs do not support IMDSv2. A timestamp can be optionally configured at which any apps created after can safely default to using IMDSv2.
|
|
119
151
|
*/
|
|
120
152
|
const appAgeRequirement = AWSProviderSettings.serverGroups.defaultIMDSv2AppAgeLimit;
|
|
121
|
-
const creationDate = application.attributes
|
|
153
|
+
const creationDate = application.attributes?.createTs;
|
|
122
154
|
|
|
123
|
-
command.requireIMDSv2 =
|
|
124
|
-
appAgeRequirement && creationDate && Number(creationDate) > appAgeRequirement ? true : false;
|
|
155
|
+
command.requireIMDSv2 = appAgeRequirement && creationDate && Number(creationDate) > appAgeRequirement;
|
|
125
156
|
}
|
|
126
157
|
|
|
127
158
|
return command;
|
|
128
159
|
});
|
|
129
160
|
}
|
|
130
161
|
|
|
131
|
-
function buildServerGroupCommandFromPipeline(
|
|
162
|
+
function buildServerGroupCommandFromPipeline(
|
|
163
|
+
application: Application,
|
|
164
|
+
originalCluster: IAmazonServerGroupDeployConfiguration,
|
|
165
|
+
) {
|
|
132
166
|
const pipelineCluster = _.cloneDeep(originalCluster);
|
|
133
167
|
const region = Object.keys(pipelineCluster.availabilityZones)[0];
|
|
134
168
|
|
|
135
|
-
|
|
169
|
+
const instanceTypes = pipelineCluster.launchTemplateOverridesForInstanceType
|
|
136
170
|
? pipelineCluster.launchTemplateOverridesForInstanceType.map((o) => o.instanceType)
|
|
137
171
|
: [pipelineCluster.instanceType];
|
|
138
172
|
const instanceTypeCategoryLoader = instanceTypeService.getCategoryForMultipleInstanceTypes(
|
|
@@ -184,11 +218,11 @@ angular
|
|
|
184
218
|
return $q.when({
|
|
185
219
|
viewState: {
|
|
186
220
|
requiresTemplateSelection: true,
|
|
187
|
-
},
|
|
221
|
+
} as IAmazonServerGroupCommandViewState,
|
|
188
222
|
});
|
|
189
223
|
}
|
|
190
224
|
|
|
191
|
-
function getSubmitButtonLabel(mode) {
|
|
225
|
+
function getSubmitButtonLabel(mode: string) {
|
|
192
226
|
switch (mode) {
|
|
193
227
|
case 'createPipeline':
|
|
194
228
|
return 'Add';
|
|
@@ -201,33 +235,39 @@ angular
|
|
|
201
235
|
}
|
|
202
236
|
}
|
|
203
237
|
|
|
204
|
-
function buildUpdateServerGroupCommand(serverGroup) {
|
|
205
|
-
const command = {
|
|
238
|
+
function buildUpdateServerGroupCommand(serverGroup: IAmazonServerGroup) {
|
|
239
|
+
const command = ({
|
|
206
240
|
type: 'modifyAsg',
|
|
207
241
|
asgs: [{ asgName: serverGroup.name, region: serverGroup.region }],
|
|
208
242
|
cooldown: serverGroup.asg.defaultCooldown,
|
|
209
|
-
enabledMetrics:
|
|
243
|
+
enabledMetrics: (serverGroup.asg?.enabledMetrics ?? []).map((m) => m.metric),
|
|
210
244
|
healthCheckGracePeriod: serverGroup.asg.healthCheckGracePeriod,
|
|
211
245
|
healthCheckType: serverGroup.asg.healthCheckType,
|
|
212
246
|
terminationPolicies: angular.copy(serverGroup.asg.terminationPolicies),
|
|
213
247
|
credentials: serverGroup.account,
|
|
214
248
|
capacityRebalance: serverGroup.asg.capacityRebalance,
|
|
215
|
-
};
|
|
249
|
+
} as Partial<IAmazonServerGroupCommand>) as IAmazonServerGroupCommand;
|
|
216
250
|
awsServerGroupConfigurationService.configureUpdateCommand(command);
|
|
217
251
|
return command;
|
|
218
252
|
}
|
|
219
253
|
|
|
220
|
-
function buildServerGroupCommandFromExisting(
|
|
254
|
+
function buildServerGroupCommandFromExisting(
|
|
255
|
+
application: Application,
|
|
256
|
+
serverGroup: IAmazonServerGroupView,
|
|
257
|
+
mode = 'clone',
|
|
258
|
+
) {
|
|
221
259
|
const preferredZonesLoader = AccountService.getPreferredZonesByAccount('aws');
|
|
222
260
|
const subnetsLoader = SubnetReader.listSubnets();
|
|
261
|
+
|
|
223
262
|
const serverGroupName = NameUtils.parseServerGroupName(serverGroup.asg.autoScalingGroupName);
|
|
224
263
|
|
|
225
264
|
let instanceTypes;
|
|
226
265
|
if (serverGroup.mixedInstancesPolicy) {
|
|
227
|
-
const ltOverrides =
|
|
266
|
+
const ltOverrides = serverGroup.mixedInstancesPolicy?.launchTemplateOverridesForInstanceType;
|
|
267
|
+
// note: single launch template case is currently the only supported case for mixed instances policy
|
|
228
268
|
instanceTypes = ltOverrides
|
|
229
269
|
? ltOverrides.map((o) => o.instanceType)
|
|
230
|
-
: [
|
|
270
|
+
: [serverGroup.mixedInstancesPolicy?.launchTemplates[0]?.launchTemplateData?.instanceType];
|
|
231
271
|
} else if (serverGroup.launchTemplate) {
|
|
232
272
|
instanceTypes = [_.get(serverGroup, 'launchTemplate.launchTemplateData.instanceType')];
|
|
233
273
|
} else if (serverGroup.launchConfig) {
|
|
@@ -240,7 +280,7 @@ angular
|
|
|
240
280
|
|
|
241
281
|
return $q
|
|
242
282
|
.all([preferredZonesLoader, subnetsLoader, instanceTypeCategoryLoader])
|
|
243
|
-
.then(
|
|
283
|
+
.then(([preferredZones, subnets, instanceProfile]) => {
|
|
244
284
|
const zones = serverGroup.asg.availabilityZones.sort();
|
|
245
285
|
let usePreferredZones = false;
|
|
246
286
|
const preferredZonesForAccount = preferredZones[serverGroup.account];
|
|
@@ -252,10 +292,10 @@ angular
|
|
|
252
292
|
// These processes should never be copied over, as the affect launching instances and enabling traffic
|
|
253
293
|
const enabledProcesses = ['Launch', 'Terminate', 'AddToLoadBalancer'];
|
|
254
294
|
|
|
255
|
-
const applicationAwsSettings =
|
|
295
|
+
const applicationAwsSettings = application.attributes?.providerSettings?.aws ?? {};
|
|
256
296
|
const useAmiBlockDeviceMappings = applicationAwsSettings.useAmiBlockDeviceMappings || false;
|
|
257
297
|
|
|
258
|
-
const existingTags = {};
|
|
298
|
+
const existingTags: { [key: string]: string } = {};
|
|
259
299
|
// These tags are applied by Clouddriver (if configured to do so), regardless of what the user might enter
|
|
260
300
|
// Might be worth feature flagging this if it turns out other folks are hard-coding these values
|
|
261
301
|
const reservedTags = ['spinnaker:application', 'spinnaker:stack', 'spinnaker:details'];
|
|
@@ -267,7 +307,7 @@ angular
|
|
|
267
307
|
});
|
|
268
308
|
}
|
|
269
309
|
|
|
270
|
-
const command = {
|
|
310
|
+
const command: Partial<IAmazonServerGroupCommand> = {
|
|
271
311
|
application: application.name,
|
|
272
312
|
strategy: '',
|
|
273
313
|
stack: serverGroupName.stack,
|
|
@@ -310,14 +350,10 @@ angular
|
|
|
310
350
|
submitButtonLabel: getSubmitButtonLabel(mode),
|
|
311
351
|
isNew: false,
|
|
312
352
|
dirty: {},
|
|
313
|
-
},
|
|
353
|
+
} as IAmazonServerGroupCommandViewState,
|
|
314
354
|
};
|
|
315
355
|
|
|
316
|
-
if (
|
|
317
|
-
application.attributes &&
|
|
318
|
-
application.attributes.platformHealthOnlyShowOverride &&
|
|
319
|
-
application.attributes.platformHealthOnly
|
|
320
|
-
) {
|
|
356
|
+
if (application.attributes?.platformHealthOnlyShowOverride && application.attributes?.platformHealthOnly) {
|
|
321
357
|
command.interestingHealthProviderNames = ['Amazon'];
|
|
322
358
|
}
|
|
323
359
|
|
|
@@ -333,7 +369,7 @@ angular
|
|
|
333
369
|
const vpcZoneIdentifier = serverGroup.asg.vpczoneIdentifier;
|
|
334
370
|
if (vpcZoneIdentifier !== '') {
|
|
335
371
|
const subnetId = vpcZoneIdentifier.split(',')[0];
|
|
336
|
-
const subnet =
|
|
372
|
+
const subnet = subnets.find((x) => x.id === subnetId);
|
|
337
373
|
command.subnetType = subnet.purpose;
|
|
338
374
|
command.vpcId = subnet.vpcId;
|
|
339
375
|
} else {
|
|
@@ -361,23 +397,22 @@ angular
|
|
|
361
397
|
}
|
|
362
398
|
|
|
363
399
|
if (serverGroup.launchTemplate || serverGroup.mixedInstancesPolicy) {
|
|
364
|
-
let launchTemplateData, spotMaxPrice;
|
|
400
|
+
let launchTemplateData: ILaunchTemplateData, spotMaxPrice: string;
|
|
365
401
|
if (serverGroup.launchTemplate) {
|
|
366
402
|
launchTemplateData = serverGroup.launchTemplate.launchTemplateData;
|
|
367
|
-
spotMaxPrice =
|
|
368
|
-
|
|
403
|
+
spotMaxPrice = launchTemplateData.instanceMarketOptions?.spotOptions?.maxPrice;
|
|
369
404
|
command.instanceType = launchTemplateData.instanceType;
|
|
370
405
|
command.viewState.useSimpleInstanceTypeSelector = true;
|
|
371
406
|
}
|
|
372
407
|
|
|
373
408
|
if (serverGroup.mixedInstancesPolicy) {
|
|
374
409
|
const mip = serverGroup.mixedInstancesPolicy;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
410
|
+
// note: single launch template case is currently the only supported case for mixed instances policy
|
|
411
|
+
launchTemplateData = mip?.launchTemplates?.[0]?.launchTemplateData;
|
|
412
|
+
spotMaxPrice = mip?.instancesDistribution?.spotMaxPrice;
|
|
378
413
|
command.securityGroups = launchTemplateData.networkInterfaces
|
|
379
|
-
? (launchTemplateData.networkInterfaces.find((ni) => ni.deviceIndex === 0)
|
|
380
|
-
:
|
|
414
|
+
? (launchTemplateData.networkInterfaces.find((ni) => ni.deviceIndex === 0) ?? {}).groups
|
|
415
|
+
: launchTemplateData.securityGroups;
|
|
381
416
|
command.onDemandAllocationStrategy = mip.instancesDistribution.onDemandAllocationStrategy;
|
|
382
417
|
command.onDemandBaseCapacity = mip.instancesDistribution.onDemandBaseCapacity;
|
|
383
418
|
command.onDemandPercentageAboveBaseCapacity =
|
|
@@ -412,9 +447,7 @@ angular
|
|
|
412
447
|
instanceMonitoring: launchTemplateData.monitoring && launchTemplateData.monitoring.enabled,
|
|
413
448
|
ebsOptimized: launchTemplateData.ebsOptimized,
|
|
414
449
|
spotPrice: spotMaxPrice || undefined,
|
|
415
|
-
requireIMDSv2: Boolean(
|
|
416
|
-
launchTemplateData.metadataOptions && launchTemplateData.metadataOptions.httpsTokens === 'required',
|
|
417
|
-
),
|
|
450
|
+
requireIMDSv2: Boolean(launchTemplateData.metadataOptions?.httpTokens === 'required'),
|
|
418
451
|
unlimitedCpuCredits: launchTemplateData.creditSpecification
|
|
419
452
|
? launchTemplateData.creditSpecification.cpuCredits === 'unlimited'
|
|
420
453
|
: undefined,
|
|
@@ -437,8 +470,8 @@ angular
|
|
|
437
470
|
|
|
438
471
|
if (serverGroup.launchTemplate && serverGroup.launchTemplate.launchTemplateData.networkInterfaces) {
|
|
439
472
|
const networkInterface =
|
|
440
|
-
serverGroup.launchTemplate.launchTemplateData.networkInterfaces.find((ni) => ni.deviceIndex === 0)
|
|
441
|
-
{};
|
|
473
|
+
serverGroup.launchTemplate.launchTemplateData.networkInterfaces.find((ni) => ni.deviceIndex === 0) ??
|
|
474
|
+
({} as INetworkInterface);
|
|
442
475
|
command.securityGroups = networkInterface.groups;
|
|
443
476
|
}
|
|
444
477
|
|
|
@@ -447,7 +480,9 @@ angular
|
|
|
447
480
|
}
|
|
448
481
|
|
|
449
482
|
// Since Deck allows changing priority of instance types via drag handle, fill priority field explicitly if empty
|
|
450
|
-
function getInstanceTypesWithPriority(
|
|
483
|
+
function getInstanceTypesWithPriority(
|
|
484
|
+
instanceTypeOverrides: IAmazonLaunchTemplateOverrides[],
|
|
485
|
+
): IAmazonInstanceTypeOverride[] {
|
|
451
486
|
let explicitPriority = 1;
|
|
452
487
|
return _.sortBy(instanceTypeOverrides, ['priority']).map((override) => {
|
|
453
488
|
const { instanceType, weightedCapacity } = override;
|
|
@@ -462,7 +497,9 @@ angular
|
|
|
462
497
|
});
|
|
463
498
|
}
|
|
464
499
|
|
|
465
|
-
function isSimpleModeEnabled(
|
|
500
|
+
function isSimpleModeEnabled(
|
|
501
|
+
command: IAmazonServerGroupDeployConfiguration | Partial<IAmazonServerGroupCommand>,
|
|
502
|
+
) {
|
|
466
503
|
const isAdvancedModeEnabledInCommand =
|
|
467
504
|
command.onDemandAllocationStrategy ||
|
|
468
505
|
command.onDemandBaseCapacity ||
|
|
@@ -475,11 +512,11 @@ angular
|
|
|
475
512
|
}
|
|
476
513
|
|
|
477
514
|
return {
|
|
478
|
-
buildNewServerGroupCommand
|
|
479
|
-
buildServerGroupCommandFromExisting
|
|
480
|
-
buildNewServerGroupCommandForPipeline
|
|
481
|
-
buildServerGroupCommandFromPipeline
|
|
482
|
-
buildUpdateServerGroupCommand
|
|
483
|
-
};
|
|
515
|
+
buildNewServerGroupCommand,
|
|
516
|
+
buildServerGroupCommandFromExisting,
|
|
517
|
+
buildNewServerGroupCommandForPipeline,
|
|
518
|
+
buildServerGroupCommandFromPipeline,
|
|
519
|
+
buildUpdateServerGroupCommand,
|
|
520
|
+
} as AwsServerGroupCommandBuilder;
|
|
484
521
|
},
|
|
485
522
|
]);
|
|
@@ -80,6 +80,7 @@ export interface IAmazonServerGroupCommandBackingData extends IServerGroupComman
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandViewState {
|
|
83
|
+
isNew: boolean;
|
|
83
84
|
dirty: IAmazonServerGroupCommandDirty;
|
|
84
85
|
spelTargetGroups: string[];
|
|
85
86
|
spelLoadBalancers: string[];
|
|
@@ -88,15 +89,35 @@ export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandV
|
|
|
88
89
|
|
|
89
90
|
export interface IAmazonInstanceTypeOverride {
|
|
90
91
|
instanceType: string;
|
|
91
|
-
weightedCapacity?:
|
|
92
|
+
weightedCapacity?: string;
|
|
92
93
|
priority?: number;
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
/**
|
|
97
|
+
* We model server group commands in two subtly different ways.
|
|
98
|
+
* It's unclear what the intention is, but we should converge on a single model eventually.
|
|
99
|
+
*
|
|
100
|
+
* This model is stored in a Aws Deploy Stage under `clusters[]`.
|
|
101
|
+
* It is also sent across the wire during a deploy task from infrastructure view
|
|
102
|
+
* (i.e., "clone server group", "create server group")
|
|
103
|
+
*/
|
|
104
|
+
export interface IAmazonServerGroupDeployConfiguration extends IAmazonServerGroupCommand_Internal {
|
|
105
|
+
account: string;
|
|
106
|
+
availabilityZones: {
|
|
107
|
+
[region: string]: string[];
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
interface IAmazonServerGroupCommand_Internal extends IAmazonServerGroupCommand {
|
|
112
|
+
// widen 'string[]' to 'any' so we can narrow it to an incompatible type in IAmazonServerGroupDeployConfiguration
|
|
113
|
+
availabilityZones: any;
|
|
114
|
+
}
|
|
115
|
+
|
|
95
116
|
export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
96
|
-
viewState: IAmazonServerGroupCommandViewState;
|
|
97
117
|
associateIPv6Address?: boolean;
|
|
98
118
|
associatePublicIpAddress: boolean;
|
|
99
119
|
backingData: IAmazonServerGroupCommandBackingData;
|
|
120
|
+
base64UserData: string;
|
|
100
121
|
copySourceCustomBlockDeviceMappings: boolean;
|
|
101
122
|
ebsOptimized: boolean;
|
|
102
123
|
healthCheckGracePeriod: number;
|
|
@@ -111,6 +132,13 @@ export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
|
111
132
|
setLaunchTemplate?: boolean;
|
|
112
133
|
unlimitedCpuCredits?: boolean;
|
|
113
134
|
capacityRebalance?: boolean;
|
|
135
|
+
ramdiskId?: string;
|
|
136
|
+
viewState: IAmazonServerGroupCommandViewState;
|
|
137
|
+
source: {
|
|
138
|
+
account: string;
|
|
139
|
+
region: string;
|
|
140
|
+
asgName: string;
|
|
141
|
+
};
|
|
114
142
|
onDemandAllocationStrategy?: string;
|
|
115
143
|
onDemandBaseCapacity?: number;
|
|
116
144
|
onDemandPercentageAboveBaseCapacity?: number;
|
|
@@ -52,14 +52,15 @@ export function InstanceTypeTable(props: IInstanceTypeTableProps) {
|
|
|
52
52
|
|
|
53
53
|
const addOrUpdateInstanceType = (type: string, weight: string) => {
|
|
54
54
|
const weightNum = Number(weight);
|
|
55
|
+
const weightedCapacity = isNaN(weightNum) || weightNum === 0 ? undefined : weightNum.toString();
|
|
55
56
|
const itemToUpdate = selectedInstanceTypesMap.has(type)
|
|
56
57
|
? {
|
|
57
58
|
...selectedInstanceTypesMap.get(type), // update existing item
|
|
58
|
-
weightedCapacity
|
|
59
|
+
weightedCapacity,
|
|
59
60
|
}
|
|
60
61
|
: {
|
|
61
62
|
instanceType: type, // new item
|
|
62
|
-
weightedCapacity
|
|
63
|
+
weightedCapacity,
|
|
63
64
|
priority:
|
|
64
65
|
1 +
|
|
65
66
|
Array.from(selectedInstanceTypesMap.values()).reduce(
|
|
@@ -65,7 +65,8 @@ export class ServerGroupInstanceType
|
|
|
65
65
|
}
|
|
66
66
|
if (
|
|
67
67
|
some(weightsSpecified, function (instanceType) {
|
|
68
|
-
|
|
68
|
+
const weightedCapacity = Number(instanceType.weightedCapacity);
|
|
69
|
+
return weightedCapacity < 1 || weightedCapacity > 999;
|
|
69
70
|
})
|
|
70
71
|
) {
|
|
71
72
|
errors.instanceType = 'Weighted capacity must be a number between 1 and 999.';
|