@spinnaker/amazon 0.11.0 → 0.12.2
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 +43 -0
- package/dist/aws.settings.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/awsInstanceType.service.d.ts +10 -2
- package/dist/instance/awsInstanceTypes.d.ts +10 -0
- package/dist/instance/details/CostFactor.d.ts +6 -0
- package/dist/search/searchResultFormatter.d.ts +2 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +14 -1
- package/dist/serverGroup/configure/wizard/instanceType/CpuCreditsToggle.d.ts +3 -4
- package/dist/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.d.ts +9 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.d.ts +13 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceProfileSelector.d.ts +9 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.d.ts +11 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.d.ts +14 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.d.ts +12 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.d.ts +15 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/instanceType/simpleMode/SimpleModeSelector.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +9 -6
- package/dist/serverGroup/details/scalingPolicy/ScalingPolicySummary.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/chart/MetricAlarmChart.d.ts +0 -4
- package/dist/serverGroup/details/scalingPolicy/index.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingChart.d.ts +1 -3
- package/package.json +5 -5
- package/src/aws.module.ts +3 -3
- package/src/aws.settings.ts +2 -0
- package/src/function/details/FunctionActions.spec.tsx +15 -12
- package/src/function/details/FunctionActions.tsx +2 -1
- package/src/help/amazon.help.ts +9 -6
- package/src/image/image.reader.spec.ts +75 -0
- package/src/instance/awsInstanceType.service.spec.js +37 -71
- package/src/instance/awsInstanceType.service.ts +191 -0
- package/src/instance/awsInstanceTypes.ts +311 -0
- package/src/instance/details/CostFactor.tsx +29 -0
- package/src/instance/details/InstanceInformation.spec.tsx +2 -1
- package/src/instance/details/instance.details.controller.js +472 -473
- package/src/loadBalancer/details/LoadBalancerActions.tsx +2 -1
- package/src/loadBalancer/details/loadBalancerDetails.controller.spec.ts +5 -3
- package/src/search/{searchResultFormatter.js → searchResultFormatter.ts} +5 -4
- package/src/securityGroup/details/securityGroupDetail.controller.js +2 -1
- package/src/serverGroup/configure/AmazonImageSelectInput.spec.tsx +10 -7
- package/src/serverGroup/configure/serverGroupCommandBuilder.aws.service.spec.js +302 -1
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +96 -24
- package/src/serverGroup/configure/serverGroupCommandBuilder.spec.js +25 -8
- package/src/serverGroup/configure/serverGroupConfiguration.service.spec.ts +6 -13
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +26 -1
- package/src/serverGroup/configure/wizard/AmazonCloneServerGroupModal.tsx +1 -1
- package/src/serverGroup/configure/wizard/instanceType/CpuCreditsToggle.tsx +31 -31
- package/src/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.tsx +133 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.tsx +99 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceProfileSelector.tsx +36 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.tsx +144 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.tsx +137 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.tsx +135 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.tsx +137 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.less +5 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.tsx +108 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/advancedMode.less +110 -0
- package/src/serverGroup/configure/wizard/instanceType/simpleMode/SimpleModeSelector.tsx +62 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +106 -62
- package/src/serverGroup/configure/wizard/pages/advancedSettings/ServerGroupAdvancedSettingsCommon.tsx +1 -1
- package/src/serverGroup/details/AmazonServerGroupActions.tsx +2 -1
- package/src/serverGroup/details/scalingPolicy/ScalingPolicySummary.tsx +7 -3
- package/src/serverGroup/details/scalingPolicy/StepPolicySummary.tsx +26 -28
- package/src/serverGroup/details/scalingPolicy/chart/MetricAlarmChart.tsx +1 -25
- package/src/serverGroup/details/scalingPolicy/index.ts +0 -1
- package/src/serverGroup/details/scalingPolicy/scalingPolicy.module.ts +1 -9
- package/src/serverGroup/details/scalingPolicy/scalingPolicySummary.component.ts +6 -2
- package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingChart.tsx +2 -17
- package/src/serverGroup/details/scalingPolicy/upsert/alarm/AlarmConfigurer.less +1 -1
- package/src/serverGroup/details/scalingProcesses/AutoScalingProcessService.spec.ts +1 -2
- package/src/serverGroup/details/sections/AdvancedSettingsDetailsSection.tsx +3 -2
- package/src/serverGroup/details/sections/AmazonCapacityDetailsSection.tsx +3 -8
- package/src/serverGroup/details/sections/InstancesDistributionDetailsSection.spec.tsx +8 -5
- package/src/serverGroup/details/sections/LaunchTemplateDetailsSection.spec.tsx +8 -5
- package/src/serverGroup/details/sections/ScalingPoliciesDetailsSection.tsx +3 -3
- package/src/serverGroup/details/sections/ScalingProcessesDetailsSection.tsx +3 -10
- package/src/serverGroup/details/sections/ScheduledActionsDetailsSection.tsx +3 -2
- package/src/serverGroup/details/sections/SecurityGroupsDetailsSection.tsx +3 -2
- package/src/serverGroup/serverGroup.transformer.spec.ts +5 -3
- package/src/subnet/SubnetSelectInput.spec.tsx +7 -4
- package/src/vpc/{VpcReader.spec.js → VpcReader.spec.ts} +2 -10
- package/src/vpc/VpcTag.spec.tsx +37 -0
- package/src/vpc/vpc.module.ts +6 -2
- package/dist/reactShims/aws.ngReact.d.ts +0 -11
- package/dist/serverGroup/details/scalingPolicy/ScalingPolicyTypeRegistry.d.ts +0 -10
- package/dist/serverGroup/details/scalingPolicy/alarmBasedSummary.component.d.ts +0 -2
- package/dist/serverGroup/details/scalingPolicy/detailsSummary.component.d.ts +0 -12
- package/dist/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/stepPolicySummary.component.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingPolicy.config.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTracking.module.d.ts +0 -2
- package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTrackingChart.component.d.ts +0 -1
- package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.d.ts +0 -1
- package/dist/vpc/vpcTag.directive.d.ts +0 -2
- package/src/image/image.reader.spec.js +0 -123
- package/src/instance/awsInstanceType.service.js +0 -437
- package/src/reactShims/aws.ngReact.ts +0 -27
- package/src/serverGroup/details/scalingPolicy/ScalingPolicyTypeRegistry.ts +0 -18
- package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html +0 -35
- package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.js +0 -60
- package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html +0 -5
- package/src/serverGroup/details/scalingPolicy/detailsSummary.component.ts +0 -32
- package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html +0 -1
- package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html +0 -107
- package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.ts +0 -31
- package/src/serverGroup/details/scalingPolicy/scalingPolicySummary.component.less +0 -15
- package/src/serverGroup/details/scalingPolicy/stepPolicySummary.component.ts +0 -10
- package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingPolicy.config.ts +0 -6
- package/src/serverGroup/details/scalingPolicy/targetTracking/targetTracking.module.ts +0 -8
- package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingChart.component.ts +0 -16
- package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.ts +0 -14
- package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html +0 -5
- package/src/vpc/vpcTag.directive.js +0 -34
- package/src/vpc/vpcTag.directive.spec.js +0 -60
|
@@ -4,7 +4,11 @@ import { AccountService, SubnetReader } from '@spinnaker/core';
|
|
|
4
4
|
|
|
5
5
|
import { AWSProviderSettings } from '../../aws.settings';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createMockAmazonServerGroupWithLt,
|
|
9
|
+
createCustomMockLaunchTemplate,
|
|
10
|
+
mockLaunchTemplate,
|
|
11
|
+
} from '@spinnaker/mocks';
|
|
8
12
|
|
|
9
13
|
describe('awsServerGroupCommandBuilder', function () {
|
|
10
14
|
const AccountServiceFixture = require('./AccountServiceFixtures');
|
|
@@ -64,7 +68,7 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
64
68
|
|
|
65
69
|
describe('buildServerGroupCommandFromExisting', function () {
|
|
66
70
|
it('sets usePreferredZones flag based on initial value', function () {
|
|
67
|
-
spyOn(this.instanceTypeService, '
|
|
71
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(this.$q.when('custom'));
|
|
68
72
|
const baseServerGroup = {
|
|
69
73
|
account: 'prod',
|
|
70
74
|
region: 'us-west-1',
|
|
@@ -72,6 +76,7 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
72
76
|
availabilityZones: ['g', 'h', 'i'],
|
|
73
77
|
vpczoneIdentifier: '',
|
|
74
78
|
},
|
|
79
|
+
launchTemplate: mockLaunchTemplate,
|
|
75
80
|
};
|
|
76
81
|
let command = null;
|
|
77
82
|
|
|
@@ -101,7 +106,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
101
106
|
});
|
|
102
107
|
|
|
103
108
|
it('sets profile and instance type if available', function () {
|
|
104
|
-
spyOn(this.instanceTypeService, '
|
|
109
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
110
|
+
this.$q.when('selectedProfile'),
|
|
111
|
+
);
|
|
105
112
|
|
|
106
113
|
const baseServerGroup = {
|
|
107
114
|
account: 'prod',
|
|
@@ -131,7 +138,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
131
138
|
});
|
|
132
139
|
|
|
133
140
|
it('copies suspended processes unless the mode is "editPipeline"', function () {
|
|
134
|
-
spyOn(this.instanceTypeService, '
|
|
141
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
142
|
+
this.$q.when('selectedProfile'),
|
|
143
|
+
);
|
|
135
144
|
|
|
136
145
|
const baseServerGroup = {
|
|
137
146
|
account: 'prod',
|
|
@@ -167,7 +176,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
167
176
|
});
|
|
168
177
|
|
|
169
178
|
it('copies tags not in the reserved list:', function () {
|
|
170
|
-
spyOn(this.instanceTypeService, '
|
|
179
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
180
|
+
this.$q.when('selectedProfile'),
|
|
181
|
+
);
|
|
171
182
|
|
|
172
183
|
const baseServerGroup = {
|
|
173
184
|
account: 'prod',
|
|
@@ -208,7 +219,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
208
219
|
});
|
|
209
220
|
|
|
210
221
|
it('sets unlimitedCpuCredits to false when building from source server group with standard credits', function () {
|
|
211
|
-
spyOn(this.instanceTypeService, '
|
|
222
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
223
|
+
this.$q.when('selectedProfile'),
|
|
224
|
+
);
|
|
212
225
|
|
|
213
226
|
const baseServerGroup = createMockAmazonServerGroupWithLt(
|
|
214
227
|
createCustomMockLaunchTemplate('testLtCpuCredits', {
|
|
@@ -229,7 +242,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
229
242
|
});
|
|
230
243
|
|
|
231
244
|
it('sets unlimitedCpuCredits to true when building from source server group with unlimited credits', function () {
|
|
232
|
-
spyOn(this.instanceTypeService, '
|
|
245
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
246
|
+
this.$q.when('selectedProfile'),
|
|
247
|
+
);
|
|
233
248
|
|
|
234
249
|
const baseServerGroup = createMockAmazonServerGroupWithLt(
|
|
235
250
|
createCustomMockLaunchTemplate('testLtCpuCredits', {
|
|
@@ -250,7 +265,9 @@ describe('awsServerGroupCommandBuilder', function () {
|
|
|
250
265
|
});
|
|
251
266
|
|
|
252
267
|
it('sets unlimitedCpuCredits to undefined when building from source server group with cpu credits unset', function () {
|
|
253
|
-
spyOn(this.instanceTypeService, '
|
|
268
|
+
spyOn(this.instanceTypeService, 'getCategoryForMultipleInstanceTypes').and.returnValue(
|
|
269
|
+
this.$q.when('selectedProfile'),
|
|
270
|
+
);
|
|
254
271
|
|
|
255
272
|
const baseServerGroup = createMockAmazonServerGroupWithLt();
|
|
256
273
|
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IQService, IRootScopeService, IScope } from 'angular';
|
|
2
|
+
import { mock } from 'angular';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
ApplicationModelBuilder,
|
|
6
|
-
CacheInitializerService,
|
|
7
|
-
LoadBalancerReader,
|
|
8
|
-
SecurityGroupReader,
|
|
9
|
-
SubnetReader,
|
|
10
|
-
} from '@spinnaker/core';
|
|
4
|
+
import type { CacheInitializerService, LoadBalancerReader, SecurityGroupReader } from '@spinnaker/core';
|
|
5
|
+
import { AccountService, ApplicationModelBuilder, SubnetReader } from '@spinnaker/core';
|
|
11
6
|
|
|
12
7
|
import { KeyPairsReader } from '../../keyPairs';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
AwsServerGroupConfigurationService,
|
|
16
|
-
} from './serverGroupConfiguration.service';
|
|
8
|
+
import type { AwsServerGroupConfigurationService } from './serverGroupConfiguration.service';
|
|
9
|
+
import { AWS_SERVER_GROUP_CONFIGURATION_SERVICE } from './serverGroupConfiguration.service';
|
|
17
10
|
|
|
18
11
|
describe('Service: awsServerGroupConfiguration', function () {
|
|
19
12
|
let service: AwsServerGroupConfigurationService,
|
|
@@ -83,9 +83,17 @@ export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandV
|
|
|
83
83
|
dirty: IAmazonServerGroupCommandDirty;
|
|
84
84
|
spelTargetGroups: string[];
|
|
85
85
|
spelLoadBalancers: string[];
|
|
86
|
+
useSimpleInstanceTypeSelector: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface IAmazonInstanceTypeOverride {
|
|
90
|
+
instanceType: string;
|
|
91
|
+
weightedCapacity?: number;
|
|
92
|
+
priority?: number;
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
96
|
+
viewState: IAmazonServerGroupCommandViewState;
|
|
89
97
|
associateIPv6Address?: boolean;
|
|
90
98
|
associatePublicIpAddress: boolean;
|
|
91
99
|
backingData: IAmazonServerGroupCommandBackingData;
|
|
@@ -103,12 +111,18 @@ export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
|
103
111
|
setLaunchTemplate?: boolean;
|
|
104
112
|
unlimitedCpuCredits?: boolean;
|
|
105
113
|
capacityRebalance?: boolean;
|
|
106
|
-
|
|
114
|
+
onDemandAllocationStrategy?: string;
|
|
115
|
+
onDemandBaseCapacity?: number;
|
|
116
|
+
onDemandPercentageAboveBaseCapacity?: number;
|
|
117
|
+
spotAllocationStrategy?: string;
|
|
118
|
+
spotInstancePools?: number;
|
|
119
|
+
launchTemplateOverridesForInstanceType?: IAmazonInstanceTypeOverride[];
|
|
107
120
|
|
|
108
121
|
getBlockDeviceMappingsSource: (command: IServerGroupCommand) => IBlockDeviceMappingSource;
|
|
109
122
|
selectBlockDeviceMappingsSource: (command: IServerGroupCommand, selection: string) => void;
|
|
110
123
|
usePreferredZonesChanged: (command: IServerGroupCommand) => IAmazonServerGroupCommandResult;
|
|
111
124
|
regionIsDeprecated: (command: IServerGroupCommand) => boolean;
|
|
125
|
+
launchTemplateOverridesChanged: (command: IServerGroupCommand) => void;
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
export class AwsServerGroupConfigurationService {
|
|
@@ -643,10 +657,21 @@ export class AwsServerGroupConfigurationService {
|
|
|
643
657
|
cmd.imageChanged = (command: IAmazonServerGroupCommand): IServerGroupCommandResult =>
|
|
644
658
|
this.configureInstanceTypes(command);
|
|
645
659
|
|
|
660
|
+
// Handles derived values for single instance type case
|
|
646
661
|
cmd.instanceTypeChanged = (command: IAmazonServerGroupCommand): void => {
|
|
647
662
|
command.ebsOptimized = this.awsInstanceTypeService.isEbsOptimized(command.instanceType);
|
|
648
663
|
};
|
|
649
664
|
|
|
665
|
+
// Handles derived values for multiple instance types case
|
|
666
|
+
cmd.launchTemplateOverridesChanged = (command: IAmazonServerGroupCommand): void => {
|
|
667
|
+
// set ebsOptimized to true if all instance types in overrides are included in the hard-coded array in awsInstanceTypeService.
|
|
668
|
+
// this function exists for backwards compatibility with single instance type case, matching behavior in `cmd.instanceTypeChanged`
|
|
669
|
+
// note: this parameter has no effect on instance types with EBS optimization enabled by default.
|
|
670
|
+
command.ebsOptimized = command.launchTemplateOverridesForInstanceType?.every((o) =>
|
|
671
|
+
this.awsInstanceTypeService.isEbsOptimized(o.instanceType),
|
|
672
|
+
);
|
|
673
|
+
};
|
|
674
|
+
|
|
650
675
|
this.applyOverrides('attachEventHandlers', cmd);
|
|
651
676
|
}
|
|
652
677
|
}
|
|
@@ -207,7 +207,7 @@ export class AmazonCloneServerGroupModal extends React.Component<
|
|
|
207
207
|
/>
|
|
208
208
|
|
|
209
209
|
<WizardPage
|
|
210
|
-
label=
|
|
210
|
+
label={command.viewState.useSimpleInstanceTypeSelector ? 'Instance Type' : 'Instance Types'}
|
|
211
211
|
wizard={wizard}
|
|
212
212
|
order={nextIdx()}
|
|
213
213
|
render={({ innerRef }) => <ServerGroupInstanceType ref={innerRef} formik={formik} />}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
3
2
|
import { ToggleButtonGroup, ToggleSize } from '@spinnaker/core';
|
|
4
3
|
import { AwsReactInjector } from '../../../../reactShims';
|
|
5
4
|
|
|
6
|
-
import type { IAmazonServerGroupCommand } from '../../serverGroupConfiguration.service';
|
|
7
|
-
|
|
8
5
|
export interface ICpuCreditsToggleProps {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
unlimitedCpuCredits?: boolean;
|
|
7
|
+
selectedInstanceTypes: string[];
|
|
8
|
+
currentProfile: string;
|
|
12
9
|
setUnlimitedCpuCredits: (unlimitedCpuCredits: boolean | undefined) => void;
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
export function CpuCreditsToggle(props: ICpuCreditsToggleProps) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
const { selectedInstanceTypes, currentProfile } = props;
|
|
14
|
+
const isBurstingSupportedForAllTypes = AwsReactInjector.awsInstanceTypeService.isBurstingSupportedForAllTypes(
|
|
15
|
+
selectedInstanceTypes,
|
|
16
|
+
);
|
|
17
|
+
const isAtleastOneTypeInProfile = AwsReactInjector.awsInstanceTypeService.getInstanceTypesInCategory(
|
|
18
|
+
selectedInstanceTypes,
|
|
19
|
+
currentProfile,
|
|
20
|
+
).length
|
|
21
|
+
? true
|
|
22
|
+
: false;
|
|
23
|
+
|
|
24
|
+
const [showToggle, setShowToggle] = useState(false);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (selectedInstanceTypes && selectedInstanceTypes.length) {
|
|
27
|
+
if (!isBurstingSupportedForAllTypes) {
|
|
23
28
|
props.setUnlimitedCpuCredits(undefined);
|
|
24
29
|
}
|
|
25
|
-
setShowToggle(
|
|
30
|
+
setShowToggle(isBurstingSupportedForAllTypes);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
if (currentProfile) {
|
|
34
|
+
setShowToggle(
|
|
35
|
+
selectedInstanceTypes &&
|
|
36
|
+
selectedInstanceTypes.length > 0 &&
|
|
37
|
+
isBurstingSupportedForAllTypes &&
|
|
38
|
+
isAtleastOneTypeInProfile,
|
|
33
39
|
);
|
|
34
|
-
const isBurstingSupportedForInstance = AwsReactInjector.awsInstanceTypeService.isBurstingSupported(instanceType);
|
|
35
|
-
setShowToggle(instanceType && isTypeInProfile && isBurstingSupportedForInstance);
|
|
36
40
|
}
|
|
37
|
-
}, [
|
|
38
|
-
|
|
39
|
-
const handleToggleChange = (state: boolean) => {
|
|
40
|
-
props.setUnlimitedCpuCredits(state);
|
|
41
|
-
};
|
|
41
|
+
}, [currentProfile, selectedInstanceTypes]);
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<div>
|
|
44
|
+
<div className={'row'} style={{ fontSize: '110%' }}>
|
|
45
45
|
{showToggle && (
|
|
46
|
-
<div
|
|
46
|
+
<div>
|
|
47
47
|
<ToggleButtonGroup
|
|
48
48
|
toggleSize={ToggleSize.XSMALL}
|
|
49
49
|
propLabel={'Unlimited CPU credits '}
|
|
@@ -52,8 +52,8 @@ export function CpuCreditsToggle(props: ICpuCreditsToggleProps) {
|
|
|
52
52
|
displayTextPropOffBtn={'Off'}
|
|
53
53
|
tooltipPropOnBtn={'Toggle to turn ON unlimited CPU credits'}
|
|
54
54
|
displayTextPropOnBtn={'On'}
|
|
55
|
-
onClick={
|
|
56
|
-
isPropertyActive={props.
|
|
55
|
+
onClick={(b) => props.setUnlimitedCpuCredits(b)}
|
|
56
|
+
isPropertyActive={props.unlimitedCpuCredits}
|
|
57
57
|
/>
|
|
58
58
|
</div>
|
|
59
59
|
)}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { FormikProps } from 'formik/dist/types';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import type { IInstanceTypeCategory } from '@spinnaker/core';
|
|
5
|
+
import { HelpField } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { AdvancedModeSelector } from './advancedMode/AdvancedModeSelector';
|
|
8
|
+
import { AWSProviderSettings } from '../../../../aws.settings';
|
|
9
|
+
import type { IAmazonInstanceTypeOverride, IAmazonServerGroupCommand } from '../../serverGroupConfiguration.service';
|
|
10
|
+
import { SimpleModeSelector } from './simpleMode/SimpleModeSelector';
|
|
11
|
+
|
|
12
|
+
export interface IInstanceTypeSelectorProps {
|
|
13
|
+
formik: FormikProps<IAmazonServerGroupCommand>;
|
|
14
|
+
instanceTypeDetails: IInstanceTypeCategory[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function InstanceTypeSelector(props: IInstanceTypeSelectorProps) {
|
|
18
|
+
const { instanceTypeDetails } = props;
|
|
19
|
+
const { values: command, setFieldValue } = props.formik;
|
|
20
|
+
const isLaunchTemplatesEnabled = AWSProviderSettings.serverGroups?.enableLaunchTemplates;
|
|
21
|
+
|
|
22
|
+
const useSimpleMode = command.viewState.useSimpleInstanceTypeSelector;
|
|
23
|
+
const [unlimitedCpuCredits, setUnlimitedCpuCredits] = useState(command.unlimitedCpuCredits);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (command.unlimitedCpuCredits !== unlimitedCpuCredits) {
|
|
27
|
+
setFieldValue('unlimitedCpuCredits', unlimitedCpuCredits);
|
|
28
|
+
}
|
|
29
|
+
}, [unlimitedCpuCredits]);
|
|
30
|
+
|
|
31
|
+
const handleModeChange = (useSimpleModeNew: boolean) => {
|
|
32
|
+
if (useSimpleMode !== useSimpleModeNew) {
|
|
33
|
+
setFieldValue('viewState', {
|
|
34
|
+
...command.viewState,
|
|
35
|
+
useSimpleInstanceTypeSelector: useSimpleModeNew,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// update selected instance type(s) if mode changed.
|
|
39
|
+
// Simple mode uses command.instanceType to track selected type. Advanced mode uses command.launchTemplateOverridesForInstanceType to track selected types.
|
|
40
|
+
const multipleInstanceTypesInProps = command.launchTemplateOverridesForInstanceType;
|
|
41
|
+
const singleInstanceTypeInProps = command.instanceType;
|
|
42
|
+
|
|
43
|
+
const toSimple = useSimpleModeNew && multipleInstanceTypesInProps?.length;
|
|
44
|
+
const toAdvanced = !useSimpleModeNew && singleInstanceTypeInProps;
|
|
45
|
+
if (toSimple) {
|
|
46
|
+
const highestPriorityNum = Math.min(...multipleInstanceTypesInProps.map((it) => it.priority));
|
|
47
|
+
const instanceTypeWithHighestPriority = multipleInstanceTypesInProps.find(
|
|
48
|
+
(it) => it.priority === highestPriorityNum,
|
|
49
|
+
).instanceType;
|
|
50
|
+
|
|
51
|
+
setFieldValue('instanceType', instanceTypeWithHighestPriority);
|
|
52
|
+
setFieldValue('launchTemplateOverridesForInstanceType', []);
|
|
53
|
+
command.instanceTypeChanged(command);
|
|
54
|
+
} else if (toAdvanced) {
|
|
55
|
+
const instanceTypes: IAmazonInstanceTypeOverride[] = [
|
|
56
|
+
{
|
|
57
|
+
instanceType: singleInstanceTypeInProps,
|
|
58
|
+
priority: 1,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
setFieldValue('instanceType', undefined);
|
|
62
|
+
setFieldValue('launchTemplateOverridesForInstanceType', instanceTypes);
|
|
63
|
+
command.launchTemplateOverridesChanged(command);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const showAdvancedMode = isLaunchTemplatesEnabled && !useSimpleMode;
|
|
69
|
+
if (showAdvancedMode) {
|
|
70
|
+
return (
|
|
71
|
+
<div className="container-fluid form-horizontal" style={{ padding: '0 15px' }}>
|
|
72
|
+
<div>
|
|
73
|
+
<p>
|
|
74
|
+
To configure a single instance type, use
|
|
75
|
+
<a className="clickable" onClick={() => handleModeChange(true)}>
|
|
76
|
+
<span> Simple Mode</span>
|
|
77
|
+
</a>
|
|
78
|
+
.
|
|
79
|
+
</p>
|
|
80
|
+
<i>
|
|
81
|
+
<b>Note:</b> If multiple instance types are already selected in advanced mode, the instance type with
|
|
82
|
+
highest priority will be preserved in simple mode.
|
|
83
|
+
</i>
|
|
84
|
+
</div>
|
|
85
|
+
<AdvancedModeSelector
|
|
86
|
+
formik={props.formik}
|
|
87
|
+
instanceTypeDetails={instanceTypeDetails}
|
|
88
|
+
setUnlimitedCpuCredits={setUnlimitedCpuCredits}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className="container-fluid form-horizontal" style={{ padding: '0 15px' }}>
|
|
96
|
+
<div>
|
|
97
|
+
<span>To configure mixed server groups with multiple instance types,</span>
|
|
98
|
+
{!isLaunchTemplatesEnabled && (
|
|
99
|
+
<span>
|
|
100
|
+
<a
|
|
101
|
+
href={
|
|
102
|
+
'https://spinnaker.io/docs/setup/other_config/server-group-launch-settings/aws-ec2/launch-templates-setup/'
|
|
103
|
+
}
|
|
104
|
+
>
|
|
105
|
+
<span> enable launch templates</span>
|
|
106
|
+
</a>
|
|
107
|
+
<span> and</span>
|
|
108
|
+
</span>
|
|
109
|
+
)}
|
|
110
|
+
<span>
|
|
111
|
+
<a
|
|
112
|
+
className={isLaunchTemplatesEnabled ? 'clickable' : 'disabled'}
|
|
113
|
+
onClick={isLaunchTemplatesEnabled ? () => handleModeChange(false) : () => {}}
|
|
114
|
+
>
|
|
115
|
+
<span> use Advanced Mode </span>
|
|
116
|
+
</a>
|
|
117
|
+
<HelpField id={'aws.serverGroup.advancedMode'} />.
|
|
118
|
+
</span>
|
|
119
|
+
<p></p>
|
|
120
|
+
{isLaunchTemplatesEnabled && (
|
|
121
|
+
<i>
|
|
122
|
+
<b>Note:</b> If an instance type is already selected in simple mode, it will be preserved in advanced mode.
|
|
123
|
+
</i>
|
|
124
|
+
)}
|
|
125
|
+
</div>
|
|
126
|
+
<SimpleModeSelector
|
|
127
|
+
command={command}
|
|
128
|
+
setUnlimitedCpuCredits={setUnlimitedCpuCredits}
|
|
129
|
+
setFieldValue={setFieldValue}
|
|
130
|
+
/>
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { FormikProps } from 'formik/dist/types';
|
|
2
|
+
import { keyBy } from 'lodash';
|
|
3
|
+
import React, { useEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { usePrevious } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { InstanceProfileSelector } from './InstanceProfileSelector';
|
|
8
|
+
import { InstanceTypeTable } from './InstanceTypeTable';
|
|
9
|
+
import { InstancesDistribution } from './InstancesDistribution';
|
|
10
|
+
import type { IAmazonInstanceTypeCategory } from '../../../../../instance/awsInstanceType.service';
|
|
11
|
+
import { AwsReactInjector } from '../../../../../reactShims';
|
|
12
|
+
import type { IAmazonInstanceTypeOverride, IAmazonServerGroupCommand } from '../../../serverGroupConfiguration.service';
|
|
13
|
+
|
|
14
|
+
export interface IAdvancedModeSelectorProps {
|
|
15
|
+
formik: FormikProps<IAmazonServerGroupCommand>;
|
|
16
|
+
instanceTypeDetails: IAmazonInstanceTypeCategory[];
|
|
17
|
+
setUnlimitedCpuCredits: (unlimitedCpuCredits: boolean | undefined) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Note: Launch templates support is expected to be enabled if this component is rendered.
|
|
22
|
+
*/
|
|
23
|
+
export function AdvancedModeSelector(props: IAdvancedModeSelectorProps) {
|
|
24
|
+
const { instanceTypeDetails, setUnlimitedCpuCredits } = props;
|
|
25
|
+
const { values: command, setFieldValue } = props.formik;
|
|
26
|
+
|
|
27
|
+
// for the case of MixedInstancesPolicy without overrides, copy command.instanceType to command.launchTemplateOverridesForInstanceType
|
|
28
|
+
const { instanceType, launchTemplateOverridesForInstanceType } = command;
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!launchTemplateOverridesForInstanceType && instanceType) {
|
|
31
|
+
props.formik.setFieldValue('launchTemplateOverridesForInstanceType', [
|
|
32
|
+
{ instanceType: command.instanceType, priority: 1 },
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const instanceTypesInProps: IAmazonInstanceTypeOverride[] = command.launchTemplateOverridesForInstanceType
|
|
38
|
+
? command.launchTemplateOverridesForInstanceType
|
|
39
|
+
: undefined;
|
|
40
|
+
|
|
41
|
+
const selectedInstanceTypesMap = new Map<string, IAmazonInstanceTypeOverride>(
|
|
42
|
+
Object.entries(keyBy(instanceTypesInProps, 'instanceType')),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const [instanceProfile, setInstanceProfile] = useState(command.viewState.instanceProfile || 'custom');
|
|
46
|
+
const prevInstanceProfile = usePrevious(instanceProfile);
|
|
47
|
+
|
|
48
|
+
const handleProfileChange = (newProfile: string) => {
|
|
49
|
+
setInstanceProfile(newProfile);
|
|
50
|
+
setFieldValue('viewState', {
|
|
51
|
+
...command.viewState,
|
|
52
|
+
instanceProfile: newProfile,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// update instance types on profile change
|
|
56
|
+
const hasProfileChanged = prevInstanceProfile && newProfile && prevInstanceProfile !== newProfile;
|
|
57
|
+
const isInstanceTypesUpdateNeeded = newProfile !== 'custom' && instanceTypesInProps && instanceTypesInProps.length;
|
|
58
|
+
if (hasProfileChanged && isInstanceTypesUpdateNeeded) {
|
|
59
|
+
const instanceTypesInProfile: string[] = AwsReactInjector.awsInstanceTypeService.getInstanceTypesInCategory(
|
|
60
|
+
instanceTypesInProps.map((it) => it.instanceType),
|
|
61
|
+
newProfile,
|
|
62
|
+
);
|
|
63
|
+
const newMultipleTypes = instanceTypesInProps.filter((o) => instanceTypesInProfile.includes(o.instanceType));
|
|
64
|
+
setFieldValue('launchTemplateOverridesForInstanceType', newMultipleTypes);
|
|
65
|
+
command.launchTemplateOverridesChanged(command);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handleInstanceTypesChange = (types: IAmazonInstanceTypeOverride[]): void => {
|
|
70
|
+
setFieldValue('launchTemplateOverridesForInstanceType', types);
|
|
71
|
+
command.launchTemplateOverridesChanged(command);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (!(instanceTypeDetails && instanceTypeDetails.length > 0)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div className={'advanced-mode-selector'}>
|
|
80
|
+
<InstanceProfileSelector
|
|
81
|
+
currentProfile={instanceProfile}
|
|
82
|
+
handleProfileChange={handleProfileChange}
|
|
83
|
+
instanceProfileList={instanceTypeDetails}
|
|
84
|
+
/>
|
|
85
|
+
<InstancesDistribution formik={props.formik} />
|
|
86
|
+
<InstanceTypeTable
|
|
87
|
+
currentProfile={instanceProfile}
|
|
88
|
+
selectedInstanceTypesMap={selectedInstanceTypesMap}
|
|
89
|
+
unlimitedCpuCreditsInCmd={command.unlimitedCpuCredits}
|
|
90
|
+
profileDetails={instanceTypeDetails.find((p) => p.type === instanceProfile)}
|
|
91
|
+
availableInstanceTypesList={
|
|
92
|
+
(command.backingData && command.backingData.filtered && command.backingData.filtered.instanceTypes) || []
|
|
93
|
+
}
|
|
94
|
+
handleInstanceTypesChange={handleInstanceTypesChange}
|
|
95
|
+
setUnlimitedCpuCredits={setUnlimitedCpuCredits}
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceProfileSelector.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IAmazonInstanceTypeCategory } from '../../../../../instance/awsInstanceType.service';
|
|
4
|
+
|
|
5
|
+
import './advancedMode.less';
|
|
6
|
+
|
|
7
|
+
export interface IInstanceProfileSelectorProps {
|
|
8
|
+
currentProfile: string;
|
|
9
|
+
handleProfileChange: (profile: string) => void;
|
|
10
|
+
instanceProfileList: IAmazonInstanceTypeCategory[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function InstanceProfileSelector(props: IInstanceProfileSelectorProps) {
|
|
14
|
+
return (
|
|
15
|
+
<div>
|
|
16
|
+
<h4 style={{ marginTop: '10px' }}>This application is</h4>
|
|
17
|
+
{props.instanceProfileList.map((profile) => (
|
|
18
|
+
<div key={profile.type} className={`instance-profile-header profile-button`}>
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
onClick={() => props.handleProfileChange(profile.type)}
|
|
22
|
+
className={props.currentProfile === profile.type ? 'instance-profile active' : 'instance-profile'}
|
|
23
|
+
>
|
|
24
|
+
{props.currentProfile === profile.type && <span className="far fa-check-circle selected-indicator" />}
|
|
25
|
+
<div className="panel-heading">
|
|
26
|
+
<h4>
|
|
27
|
+
<span className={`glyphicon glyphicon-${profile.icon}`} />
|
|
28
|
+
<div>{profile.label}</div>
|
|
29
|
+
</h4>
|
|
30
|
+
</div>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|