@spinnaker/amazon 0.13.0 → 0.13.1
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 +8 -0
- package/dist/image/image.reader.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/awsInstanceType.service.d.ts +41 -1
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +4 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/AmazonInstanceTypeInfoRenderer.d.ts +5 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeSelect.d.ts +7 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.d.ts +2 -1
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.d.ts +3 -1
- package/package.json +2 -2
- package/src/help/amazon.help.ts +19 -1
- package/src/image/image.reader.ts +1 -0
- package/src/instance/awsInstanceType.service.spec.js +225 -32
- package/src/instance/awsInstanceType.service.ts +77 -21
- package/src/serverGroup/configure/AmazonImageSelectInput.tsx +1 -1
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +21 -10
- package/src/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.tsx +2 -2
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.tsx +1 -1
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/AmazonInstanceTypeInfoRenderer.tsx +59 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.tsx +15 -2
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeSelect.tsx +78 -0
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.tsx +6 -2
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.tsx +10 -1
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.tsx +16 -24
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.tsx +4 -1
- package/src/serverGroup/configure/wizard/instanceType/advancedMode/advancedMode.less +13 -1
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +3 -0
|
@@ -54,6 +54,7 @@ import type {
|
|
|
54
54
|
IScalingProcess,
|
|
55
55
|
} from '../../domain';
|
|
56
56
|
import { AMAZON_INSTANCE_AWSINSTANCETYPE_SERVICE } from '../../instance/awsInstanceType.service';
|
|
57
|
+
import type { IAmazonInstanceType } from '../../instance/awsInstanceType.service';
|
|
57
58
|
import { KeyPairsReader } from '../../keyPairs';
|
|
58
59
|
|
|
59
60
|
export type IBlockDeviceMappingSource = 'source' | 'ami' | 'default';
|
|
@@ -69,6 +70,7 @@ export interface IAmazonServerGroupCommandResult extends IServerGroupCommandResu
|
|
|
69
70
|
export interface IAmazonServerGroupCommandBackingDataFiltered extends IServerGroupCommandBackingDataFiltered {
|
|
70
71
|
keyPairs: string[];
|
|
71
72
|
targetGroups: string[];
|
|
73
|
+
instanceTypesInfo: IAmazonInstanceType[];
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
export interface IAmazonServerGroupCommandBackingData extends IServerGroupCommandBackingData {
|
|
@@ -77,6 +79,7 @@ export interface IAmazonServerGroupCommandBackingData extends IServerGroupComman
|
|
|
77
79
|
keyPairs: IKeyPair[];
|
|
78
80
|
targetGroups: string[];
|
|
79
81
|
scalingProcesses: IScalingProcess[];
|
|
82
|
+
instanceTypesInfo: IAmazonInstanceType[];
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
export interface IAmazonServerGroupCommandViewState extends IServerGroupCommandViewState {
|
|
@@ -145,6 +148,7 @@ export interface IAmazonServerGroupCommand extends IServerGroupCommand {
|
|
|
145
148
|
spotAllocationStrategy?: string;
|
|
146
149
|
spotInstancePools?: number;
|
|
147
150
|
launchTemplateOverridesForInstanceType?: IAmazonInstanceTypeOverride[];
|
|
151
|
+
amiArchitecture: string;
|
|
148
152
|
|
|
149
153
|
getBlockDeviceMappingsSource: (command: IServerGroupCommand) => IBlockDeviceMappingSource;
|
|
150
154
|
selectBlockDeviceMappingsSource: (command: IServerGroupCommand, selection: string) => void;
|
|
@@ -274,7 +278,7 @@ export class AwsServerGroupConfigurationService {
|
|
|
274
278
|
subnets,
|
|
275
279
|
preferredZones,
|
|
276
280
|
keyPairs,
|
|
277
|
-
|
|
281
|
+
instanceTypesInfo,
|
|
278
282
|
enabledMetrics,
|
|
279
283
|
healthCheckTypes,
|
|
280
284
|
terminationPolicies,
|
|
@@ -285,7 +289,7 @@ export class AwsServerGroupConfigurationService {
|
|
|
285
289
|
subnets,
|
|
286
290
|
preferredZones,
|
|
287
291
|
keyPairs,
|
|
288
|
-
|
|
292
|
+
instanceTypesInfo,
|
|
289
293
|
enabledMetrics,
|
|
290
294
|
healthCheckTypes,
|
|
291
295
|
terminationPolicies,
|
|
@@ -373,23 +377,29 @@ export class AwsServerGroupConfigurationService {
|
|
|
373
377
|
public configureInstanceTypes(command: IAmazonServerGroupCommand): IServerGroupCommandResult {
|
|
374
378
|
const result: IAmazonServerGroupCommandResult = { dirty: {} };
|
|
375
379
|
if (command.region && (command.virtualizationType || command.viewState.disableImageSelection)) {
|
|
376
|
-
let
|
|
377
|
-
command.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
380
|
+
let filteredTypesInfo: IAmazonInstanceType[] = this.awsInstanceTypeService.getAvailableTypesForRegions(
|
|
381
|
+
command.backingData.instanceTypesInfo,
|
|
382
|
+
[command.region],
|
|
383
|
+
);
|
|
384
|
+
if (command.virtualizationType || command.amiArchitecture) {
|
|
385
|
+
filteredTypesInfo = this.awsInstanceTypeService.filterInstanceTypes(
|
|
386
|
+
filteredTypesInfo,
|
|
382
387
|
command.virtualizationType,
|
|
383
388
|
!!command.vpcId,
|
|
389
|
+
command.amiArchitecture,
|
|
384
390
|
);
|
|
385
391
|
}
|
|
386
|
-
|
|
392
|
+
|
|
393
|
+
const filteredTypes: string[] = map(filteredTypesInfo, 'name');
|
|
394
|
+
if (command.instanceType && !filteredTypes.includes(command.instanceType)) {
|
|
387
395
|
result.dirty.instanceType = command.instanceType;
|
|
388
396
|
command.instanceType = null;
|
|
389
397
|
}
|
|
390
|
-
command.backingData.filtered.instanceTypes =
|
|
398
|
+
command.backingData.filtered.instanceTypes = filteredTypes;
|
|
399
|
+
command.backingData.filtered.instanceTypesInfo = filteredTypesInfo;
|
|
391
400
|
} else {
|
|
392
401
|
command.backingData.filtered.instanceTypes = [];
|
|
402
|
+
command.backingData.filtered.instanceTypesInfo = [];
|
|
393
403
|
}
|
|
394
404
|
extend(command.viewState.dirty, result.dirty);
|
|
395
405
|
return result;
|
|
@@ -399,6 +409,7 @@ export class AwsServerGroupConfigurationService {
|
|
|
399
409
|
const result: IAmazonServerGroupCommandResult = { dirty: {} };
|
|
400
410
|
if (!command.amiName) {
|
|
401
411
|
command.virtualizationType = null;
|
|
412
|
+
command.amiArchitecture = null;
|
|
402
413
|
}
|
|
403
414
|
if (command.viewState.disableImageSelection) {
|
|
404
415
|
return result;
|
|
@@ -71,7 +71,7 @@ export function InstanceTypeSelector(props: IInstanceTypeSelectorProps) {
|
|
|
71
71
|
<div className="container-fluid form-horizontal" style={{ padding: '0 15px' }}>
|
|
72
72
|
<div>
|
|
73
73
|
<p>
|
|
74
|
-
|
|
74
|
+
Switch to
|
|
75
75
|
<a className="clickable" onClick={() => handleModeChange(true)}>
|
|
76
76
|
<span> Simple Mode</span>
|
|
77
77
|
</a>
|
|
@@ -94,7 +94,7 @@ export function InstanceTypeSelector(props: IInstanceTypeSelectorProps) {
|
|
|
94
94
|
return (
|
|
95
95
|
<div className="container-fluid form-horizontal" style={{ padding: '0 15px' }}>
|
|
96
96
|
<div>
|
|
97
|
-
<span>To configure mixed server groups
|
|
97
|
+
<span>To configure mixed server groups and/or multiple instance types,</span>
|
|
98
98
|
{!isLaunchTemplatesEnabled && (
|
|
99
99
|
<span>
|
|
100
100
|
<a
|
|
@@ -89,7 +89,7 @@ export function AdvancedModeSelector(props: IAdvancedModeSelectorProps) {
|
|
|
89
89
|
unlimitedCpuCreditsInCmd={command.unlimitedCpuCredits}
|
|
90
90
|
profileDetails={instanceTypeDetails.find((p) => p.type === instanceProfile)}
|
|
91
91
|
availableInstanceTypesList={
|
|
92
|
-
(command.backingData && command.backingData.filtered && command.backingData.filtered.
|
|
92
|
+
(command.backingData && command.backingData.filtered && command.backingData.filtered.instanceTypesInfo) || []
|
|
93
93
|
}
|
|
94
94
|
handleInstanceTypesChange={handleInstanceTypesChange}
|
|
95
95
|
setUnlimitedCpuCredits={setUnlimitedCpuCredits}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { IAmazonInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
5
|
+
|
|
6
|
+
export function AmazonInstanceTypeInfoRenderer(props: { instanceType: IAmazonInstanceType }) {
|
|
7
|
+
const spotSupport = props.instanceType.supportedUsageClasses.includes('spot') ? '| SPOT supported' : '';
|
|
8
|
+
const CpuMem = `${props.instanceType.defaultVCpus} vCPU | ${props.instanceType.memoryInGiB} Gib Memory ${spotSupport}`;
|
|
9
|
+
const instanceStorageInfo = props.instanceType.instanceStorageSupported && (
|
|
10
|
+
<span>
|
|
11
|
+
<br />
|
|
12
|
+
<span className={`select-option-label-attributes`}>
|
|
13
|
+
{`Instance Storage: ${_.toUpper(props.instanceType.instanceStorageInfo.storageTypes)} | ${
|
|
14
|
+
props.instanceType.instanceStorageInfo.totalSizeInGB
|
|
15
|
+
} Gib total size`}
|
|
16
|
+
</span>
|
|
17
|
+
</span>
|
|
18
|
+
);
|
|
19
|
+
const ebsInfo = props.instanceType.ebsInfo && (
|
|
20
|
+
<span>
|
|
21
|
+
<br />
|
|
22
|
+
<span className={`select-option-label-attributes`}>
|
|
23
|
+
{`EBS: optimization ${props.instanceType.ebsInfo.ebsOptimizedSupport} | NVMe ${props.instanceType.ebsInfo.nvmeSupport} | Encryption ${props.instanceType.ebsInfo.encryptionSupport}`}
|
|
24
|
+
</span>
|
|
25
|
+
</span>
|
|
26
|
+
);
|
|
27
|
+
const gpuInfo = props.instanceType.gpuInfo && (
|
|
28
|
+
<span>
|
|
29
|
+
<br />
|
|
30
|
+
<span className={`select-option-label-attributes`}>
|
|
31
|
+
{`GPU: ${props.instanceType.gpuInfo.totalGpuMemoryInMiB} MiB total memory`}
|
|
32
|
+
{props.instanceType.gpuInfo.gpus.map(
|
|
33
|
+
(g) => ` | ${g.count} ${g.manufacturer} ${g.name} GPUs, size: ${g.gpuSizeInMiB} MiB`,
|
|
34
|
+
)}
|
|
35
|
+
</span>
|
|
36
|
+
</span>
|
|
37
|
+
);
|
|
38
|
+
const generationInfo = typeof props.instanceType.currentGeneration !== 'undefined' &&
|
|
39
|
+
props.instanceType.currentGeneration !== null && (
|
|
40
|
+
<span>
|
|
41
|
+
<br />
|
|
42
|
+
<span className={`select-option-label-attributes`}>
|
|
43
|
+
{props.instanceType.currentGeneration ? 'Current Generation' : 'Previous Generation'}
|
|
44
|
+
</span>
|
|
45
|
+
</span>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<span>
|
|
50
|
+
<span className={`select-option-label`}>{props.instanceType.name}</span>
|
|
51
|
+
<br />
|
|
52
|
+
<span className={`select-option-label-attributes`}>{CpuMem}</span>
|
|
53
|
+
{instanceStorageInfo}
|
|
54
|
+
{ebsInfo}
|
|
55
|
+
{gpuInfo}
|
|
56
|
+
{generationInfo}
|
|
57
|
+
</span>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Checkbox } from 'react-bootstrap';
|
|
3
3
|
import { SortableHandle } from 'react-sortable-hoc';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
import { HoverablePopover, TextInput, Tooltip } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { AmazonInstanceTypeInfoRenderer } from './AmazonInstanceTypeInfoRenderer';
|
|
5
8
|
import type { IAmazonPreferredInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
9
|
+
import type { IAmazonInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
6
10
|
import { CostFactor } from '../../../../../instance/details/CostFactor';
|
|
7
11
|
import type { IAmazonInstanceTypeOverride } from '../../../serverGroupConfiguration.service';
|
|
8
12
|
|
|
9
13
|
export interface IRowProps {
|
|
10
14
|
isCustom: boolean;
|
|
11
15
|
selectedType?: IAmazonInstanceTypeOverride;
|
|
16
|
+
selectedTypeInfo?: IAmazonInstanceType;
|
|
12
17
|
instanceTypeDetails?: IAmazonPreferredInstanceType;
|
|
13
18
|
removeInstanceType?: (typeToRemove: string) => void;
|
|
14
19
|
addOrUpdateInstanceType: (instanceType: string, weight: string) => void;
|
|
@@ -38,12 +43,20 @@ export function InstanceTypeRow(props: IRowProps) {
|
|
|
38
43
|
|
|
39
44
|
let row;
|
|
40
45
|
if (props.isCustom) {
|
|
46
|
+
const instanceTypeInfo = <AmazonInstanceTypeInfoRenderer instanceType={props.selectedTypeInfo} />;
|
|
41
47
|
row = (
|
|
42
48
|
<tr key={instanceType} className={'sortable clickable'}>
|
|
43
49
|
<td>
|
|
44
50
|
<DragHandle />
|
|
45
51
|
</td>
|
|
46
|
-
<td>
|
|
52
|
+
<td>
|
|
53
|
+
{`${instanceType} `}
|
|
54
|
+
<HoverablePopover placement={'right'} template={instanceTypeInfo} className={'custom-profile'}>
|
|
55
|
+
<span className="clickable help-field">
|
|
56
|
+
<i className="small glyphicon glyphicon-info-sign" />
|
|
57
|
+
</span>
|
|
58
|
+
</HoverablePopover>
|
|
59
|
+
</td>
|
|
47
60
|
<td title={'Enter optional weight (allowed values: 1 to 999).'}>
|
|
48
61
|
<TextInput
|
|
49
62
|
className={'form-control input input-sm'}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { Option } from 'react-select';
|
|
4
|
+
import Select from 'react-select';
|
|
5
|
+
|
|
6
|
+
import { HelpField } from '@spinnaker/core';
|
|
7
|
+
|
|
8
|
+
import { AmazonInstanceTypeInfoRenderer } from './AmazonInstanceTypeInfoRenderer';
|
|
9
|
+
import type { IAmazonInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
10
|
+
|
|
11
|
+
export interface InstanceTypeSelectProps {
|
|
12
|
+
availableInstanceTypesList: IAmazonInstanceType[];
|
|
13
|
+
addOrUpdateInstanceType: (type: string, weight: string) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function InstanceTypeSelect(props: InstanceTypeSelectProps) {
|
|
17
|
+
/**
|
|
18
|
+
* Filters implemented:
|
|
19
|
+
* - instance family / size / type e.g. c3/ large/ c3.large
|
|
20
|
+
* - min vcpu e.g. 16vcpu
|
|
21
|
+
* - min memory e.g 32gib
|
|
22
|
+
* - instance storage type e.g. ssd, hdd
|
|
23
|
+
* - spot support
|
|
24
|
+
* - ebs support
|
|
25
|
+
* - gpu support
|
|
26
|
+
* - current generation v/s old generation like 'currentGen' / 'oldGen'
|
|
27
|
+
*/
|
|
28
|
+
const filterOption = (option: IAmazonInstanceType, inputValue: string) => {
|
|
29
|
+
const {
|
|
30
|
+
name,
|
|
31
|
+
defaultVCpus,
|
|
32
|
+
memoryInGiB,
|
|
33
|
+
instanceStorageInfo,
|
|
34
|
+
ebsInfo,
|
|
35
|
+
gpuInfo,
|
|
36
|
+
supportedUsageClasses,
|
|
37
|
+
currentGeneration,
|
|
38
|
+
} = option;
|
|
39
|
+
|
|
40
|
+
return inputValue.split(',').every((inputVal: string) => {
|
|
41
|
+
const searchVal = _.toLower(inputVal.trim());
|
|
42
|
+
return (
|
|
43
|
+
(searchVal.match(/\d+\s*vcpu/) && defaultVCpus >= _.toNumber(searchVal.split('vcpu')[0].trim())) ||
|
|
44
|
+
(searchVal.match(/\d+\s*gib/) && memoryInGiB >= _.toNumber(searchVal.split('gib')[0].trim())) ||
|
|
45
|
+
(searchVal.match(/\b(ssd|hdd)\b/) && instanceStorageInfo?.storageTypes.includes(searchVal)) ||
|
|
46
|
+
(searchVal === 'spot' && supportedUsageClasses?.includes(searchVal)) ||
|
|
47
|
+
(searchVal === 'ebs' && ebsInfo) ||
|
|
48
|
+
(searchVal === 'gpu' && gpuInfo) ||
|
|
49
|
+
(searchVal === 'currentgen' && currentGeneration) ||
|
|
50
|
+
(searchVal === 'oldgen' && !currentGeneration) ||
|
|
51
|
+
name.match(searchVal)
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const optionRenderer = (option: IAmazonInstanceType) => {
|
|
57
|
+
return <AmazonInstanceTypeInfoRenderer instanceType={option} />;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div className={'custom-profile'}>
|
|
62
|
+
<Select
|
|
63
|
+
className={`select`}
|
|
64
|
+
clearable={false}
|
|
65
|
+
multi={false}
|
|
66
|
+
placeholder={'Filter like 16vcpu, 32gib, spot, oldGen or Select an instance type to add'}
|
|
67
|
+
removeSelected={true}
|
|
68
|
+
searchable={true}
|
|
69
|
+
options={props.availableInstanceTypesList}
|
|
70
|
+
optionRenderer={optionRenderer}
|
|
71
|
+
filterOption={filterOption}
|
|
72
|
+
valueRenderer={(o) => <>{o.name}</>}
|
|
73
|
+
onChange={(o: Option<IAmazonInstanceType>) => props.addOrUpdateInstanceType(o.name, undefined)}
|
|
74
|
+
/>{' '}
|
|
75
|
+
<HelpField id="aws.serverGroup.instanceTypesSelect" />
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -8,6 +8,7 @@ import { Header, Heading } from './InstanceTypeTableParts';
|
|
|
8
8
|
import { Footer } from './InstanceTypeTableParts';
|
|
9
9
|
import { AWSProviderSettings } from '../../../../../aws.settings';
|
|
10
10
|
import type { IAmazonInstanceTypeCategory } from '../../../../../instance/awsInstanceType.service';
|
|
11
|
+
import type { IAmazonInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
11
12
|
import type { IAmazonInstanceTypeOverride } from '../../../serverGroupConfiguration.service';
|
|
12
13
|
|
|
13
14
|
import './advancedMode.less';
|
|
@@ -17,7 +18,7 @@ export interface IInstanceTypeTableProps {
|
|
|
17
18
|
selectedInstanceTypesMap: Map<string, IAmazonInstanceTypeOverride>;
|
|
18
19
|
unlimitedCpuCreditsInCmd: boolean;
|
|
19
20
|
profileDetails: IAmazonInstanceTypeCategory;
|
|
20
|
-
availableInstanceTypesList:
|
|
21
|
+
availableInstanceTypesList: IAmazonInstanceType[];
|
|
21
22
|
handleInstanceTypesChange: (instanceTypes: IAmazonInstanceTypeOverride[]) => void;
|
|
22
23
|
setUnlimitedCpuCredits: (unlimitedCpuCredits: boolean | undefined) => void;
|
|
23
24
|
}
|
|
@@ -120,6 +121,9 @@ export function InstanceTypeTable(props: IInstanceTypeTableProps) {
|
|
|
120
121
|
<InstanceTypeTableBody
|
|
121
122
|
isCustom={isCustom}
|
|
122
123
|
selectedInstanceTypesMap={selectedInstanceTypesMap}
|
|
124
|
+
selectedInstanceTypesInfo={props.availableInstanceTypesList.filter((it) =>
|
|
125
|
+
selectedInstanceTypeNames.includes(it.name),
|
|
126
|
+
)}
|
|
123
127
|
addOrUpdateInstanceType={addOrUpdateInstanceType}
|
|
124
128
|
removeInstanceType={removeInstanceType}
|
|
125
129
|
handleSortEnd={handleSortEnd}
|
|
@@ -127,7 +131,7 @@ export function InstanceTypeTable(props: IInstanceTypeTableProps) {
|
|
|
127
131
|
<Footer
|
|
128
132
|
isCustom={isCustom}
|
|
129
133
|
availableInstanceTypesList={props.availableInstanceTypesList.filter(
|
|
130
|
-
(it) => !selectedInstanceTypeNames.includes(it),
|
|
134
|
+
(it) => !selectedInstanceTypeNames.includes(it.name),
|
|
131
135
|
)}
|
|
132
136
|
addOrUpdateInstanceType={addOrUpdateInstanceType}
|
|
133
137
|
/>
|
package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.tsx
CHANGED
|
@@ -6,13 +6,17 @@ import { SortableContainer, SortableElement } from 'react-sortable-hoc';
|
|
|
6
6
|
import type { IInstanceTypeFamily } from '@spinnaker/core';
|
|
7
7
|
|
|
8
8
|
import { InstanceTypeRow } from './InstanceTypeRow';
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
IAmazonInstanceType,
|
|
11
|
+
IAmazonPreferredInstanceType,
|
|
12
|
+
} from '../../../../../instance/awsInstanceType.service';
|
|
10
13
|
import type { IAmazonInstanceTypeOverride } from '../../../serverGroupConfiguration.service';
|
|
11
14
|
|
|
12
15
|
export function InstanceTypeTableBody(props: {
|
|
13
16
|
isCustom: boolean;
|
|
14
17
|
profileFamiliesDetails?: IInstanceTypeFamily[];
|
|
15
18
|
selectedInstanceTypesMap: Map<string, IAmazonInstanceTypeOverride>;
|
|
19
|
+
selectedInstanceTypesInfo?: IAmazonInstanceType[];
|
|
16
20
|
addOrUpdateInstanceType: (instanceType: string, weight: string) => void;
|
|
17
21
|
removeInstanceType: (instanceType: string) => void;
|
|
18
22
|
handleSortEnd: (sortEnd: SortEnd) => void;
|
|
@@ -21,6 +25,7 @@ export function InstanceTypeTableBody(props: {
|
|
|
21
25
|
<TableRows
|
|
22
26
|
isCustom={props.isCustom}
|
|
23
27
|
selectedInstanceTypesMap={props.selectedInstanceTypesMap}
|
|
28
|
+
selectedInstanceTypesInfo={props.selectedInstanceTypesInfo}
|
|
24
29
|
removeInstanceType={props.removeInstanceType}
|
|
25
30
|
addOrUpdateInstanceType={props.addOrUpdateInstanceType}
|
|
26
31
|
instanceTypeDetails={
|
|
@@ -43,6 +48,7 @@ const TableRows = SortableContainer(
|
|
|
43
48
|
isCustom: boolean;
|
|
44
49
|
instanceTypeDetails?: Map<string, IAmazonPreferredInstanceType>;
|
|
45
50
|
selectedInstanceTypesMap: Map<string, IAmazonInstanceTypeOverride>;
|
|
51
|
+
selectedInstanceTypesInfo?: IAmazonInstanceType[];
|
|
46
52
|
removeInstanceType: (typeToRemove: string) => void;
|
|
47
53
|
addOrUpdateInstanceType: (instanceType: string, weight: string) => void;
|
|
48
54
|
}) => {
|
|
@@ -60,6 +66,7 @@ const TableRows = SortableContainer(
|
|
|
60
66
|
index={index}
|
|
61
67
|
isCustom={true}
|
|
62
68
|
selectedType={selectedType}
|
|
69
|
+
selectedTypeInfo={props.selectedInstanceTypesInfo.find((it) => it.name === selectedType.instanceType)}
|
|
63
70
|
removeInstanceType={props.removeInstanceType}
|
|
64
71
|
addOrUpdateInstanceType={props.addOrUpdateInstanceType}
|
|
65
72
|
/>
|
|
@@ -119,6 +126,7 @@ const SortableRow = SortableElement(
|
|
|
119
126
|
(props: {
|
|
120
127
|
isCustom: boolean;
|
|
121
128
|
selectedType: IAmazonInstanceTypeOverride;
|
|
129
|
+
selectedTypeInfo?: IAmazonInstanceType;
|
|
122
130
|
instanceTypeDetails?: Map<string, IAmazonPreferredInstanceType>;
|
|
123
131
|
removeInstanceType: (typeToRemove: string) => void;
|
|
124
132
|
addOrUpdateInstanceType: (instanceType: string, weight: string) => void;
|
|
@@ -127,6 +135,7 @@ const SortableRow = SortableElement(
|
|
|
127
135
|
key={props.selectedType.instanceType}
|
|
128
136
|
isCustom={props.isCustom}
|
|
129
137
|
selectedType={props.selectedType}
|
|
138
|
+
selectedTypeInfo={props.selectedTypeInfo}
|
|
130
139
|
instanceTypeDetails={!props.isCustom ? props.instanceTypeDetails.get(props.selectedType.instanceType) : null}
|
|
131
140
|
removeInstanceType={props.removeInstanceType}
|
|
132
141
|
addOrUpdateInstanceType={props.addOrUpdateInstanceType}
|
package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.tsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Option } from 'react-select';
|
|
3
|
-
import Select from 'react-select';
|
|
4
2
|
|
|
5
3
|
import { HelpField } from '@spinnaker/core';
|
|
6
4
|
|
|
5
|
+
import { InstanceTypeSelect } from './InstanceTypeSelect';
|
|
6
|
+
import type { IAmazonInstanceType } from '../../../../../instance/awsInstanceType.service';
|
|
7
|
+
|
|
8
|
+
import './advancedMode.less';
|
|
9
|
+
|
|
7
10
|
export function Heading(props: { isCustom: boolean; profileLabel?: string; profileDescriptionArr?: string[] }) {
|
|
8
11
|
let description;
|
|
9
12
|
if (props.isCustom) {
|
|
@@ -28,6 +31,16 @@ export function Heading(props: { isCustom: boolean; profileLabel?: string; profi
|
|
|
28
31
|
<h4>Instance Types</h4>
|
|
29
32
|
<div className={'description'}>
|
|
30
33
|
{description}
|
|
34
|
+
<p>
|
|
35
|
+
Learn about AWS recommended best practices in{' '}
|
|
36
|
+
<a
|
|
37
|
+
target="_blank"
|
|
38
|
+
href="https://spinnaker.io/docs/setup/other_config/server-group-launch-settings/aws-ec2/launch-templates/#create-a-server-group-with-aws-recommended-best-practices-for-ec2-spot"
|
|
39
|
+
>
|
|
40
|
+
examples and docs
|
|
41
|
+
</a>
|
|
42
|
+
.
|
|
43
|
+
</p>
|
|
31
44
|
<i>
|
|
32
45
|
<b>Note:</b>
|
|
33
46
|
<ul>
|
|
@@ -94,7 +107,7 @@ export function Header(props: { isCustom: boolean; showCpuCredits?: boolean }) {
|
|
|
94
107
|
|
|
95
108
|
export function Footer(props: {
|
|
96
109
|
isCustom: boolean;
|
|
97
|
-
availableInstanceTypesList:
|
|
110
|
+
availableInstanceTypesList: IAmazonInstanceType[];
|
|
98
111
|
addOrUpdateInstanceType: (type: string, weight: string) => void;
|
|
99
112
|
}) {
|
|
100
113
|
return props.isCustom ? (
|
|
@@ -114,24 +127,3 @@ export function Footer(props: {
|
|
|
114
127
|
</tfoot>
|
|
115
128
|
) : null;
|
|
116
129
|
}
|
|
117
|
-
|
|
118
|
-
const InstanceTypeSelect = (props: {
|
|
119
|
-
availableInstanceTypesList: string[];
|
|
120
|
-
addOrUpdateInstanceType: (type: string, weight: string) => void;
|
|
121
|
-
}): JSX.Element => {
|
|
122
|
-
const instanceTypeListOptions = props.availableInstanceTypesList.map((instanceType) => {
|
|
123
|
-
return { label: instanceType, value: instanceType };
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<Select
|
|
128
|
-
clearable={false}
|
|
129
|
-
multi={false}
|
|
130
|
-
placeholder={'Select an instance type to add...'}
|
|
131
|
-
removeSelected={true}
|
|
132
|
-
searchable={true}
|
|
133
|
-
options={instanceTypeListOptions}
|
|
134
|
-
onChange={(o: Option<string>) => props.addOrUpdateInstanceType(o.value, undefined)}
|
|
135
|
-
/>
|
|
136
|
-
);
|
|
137
|
-
};
|
package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.tsx
CHANGED
|
@@ -99,7 +99,10 @@ export function InstancesDistribution(props: IInstancesDistributionProps) {
|
|
|
99
99
|
help={<HelpField id={'aws.serverGroup.spotMaxPrice'} />}
|
|
100
100
|
input={(inputProps) => (
|
|
101
101
|
<Tooltip value={'Recommended to leave empty and use AWS default i.e. On-Demand price'}>
|
|
102
|
-
<TextInput
|
|
102
|
+
<TextInput
|
|
103
|
+
{...inputProps}
|
|
104
|
+
placeholder={'Recommended to leave empty and use AWS default i.e. On-Demand price'}
|
|
105
|
+
/>
|
|
103
106
|
</Tooltip>
|
|
104
107
|
)}
|
|
105
108
|
/>
|
|
@@ -47,7 +47,19 @@
|
|
|
47
47
|
|
|
48
48
|
.custom-profile {
|
|
49
49
|
.select {
|
|
50
|
-
width:
|
|
50
|
+
width: 97%;
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.select-option-label {
|
|
55
|
+
font-size: 100%;
|
|
56
|
+
font-weight: bold;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.select-option-label-attributes {
|
|
60
|
+
font-size: 90%;
|
|
61
|
+
font-weight: normal;
|
|
62
|
+
font-style: italic;
|
|
51
63
|
}
|
|
52
64
|
}
|
|
53
65
|
|
|
@@ -82,9 +82,12 @@ export class ServerGroupBasicSettings
|
|
|
82
82
|
this.setState({ selectedImage: image });
|
|
83
83
|
|
|
84
84
|
const virtualizationType = image && image.attributes.virtualizationType;
|
|
85
|
+
const amiArchitecture = image && image.attributes.architecture;
|
|
85
86
|
const imageName = image && image.imageName;
|
|
86
87
|
values.virtualizationType = virtualizationType;
|
|
88
|
+
values.amiArchitecture = amiArchitecture;
|
|
87
89
|
values.amiName = imageName;
|
|
90
|
+
setFieldValue('amiArchitecture', amiArchitecture);
|
|
88
91
|
setFieldValue('virtualizationType', virtualizationType);
|
|
89
92
|
setFieldValue('amiName', imageName);
|
|
90
93
|
values.imageChanged(values);
|