@spinnaker/amazon 0.13.0 → 0.13.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.
Files changed (30) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/image/image.reader.d.ts +1 -0
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/instance/awsInstanceType.service.d.ts +41 -1
  6. package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +4 -0
  7. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/AmazonInstanceTypeInfoRenderer.d.ts +5 -0
  8. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.d.ts +2 -0
  9. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeSelect.d.ts +7 -0
  10. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.d.ts +2 -1
  11. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.d.ts +2 -0
  12. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.d.ts +3 -1
  13. package/package.json +3 -3
  14. package/src/help/amazon.help.ts +19 -1
  15. package/src/image/image.reader.ts +1 -0
  16. package/src/instance/awsInstanceType.service.spec.js +225 -32
  17. package/src/instance/awsInstanceType.service.ts +77 -21
  18. package/src/serverGroup/configure/AmazonImageSelectInput.tsx +1 -1
  19. package/src/serverGroup/configure/serverGroupConfiguration.service.ts +21 -10
  20. package/src/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.tsx +2 -2
  21. package/src/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.tsx +1 -1
  22. package/src/serverGroup/configure/wizard/instanceType/advancedMode/AmazonInstanceTypeInfoRenderer.tsx +59 -0
  23. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.tsx +15 -2
  24. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeSelect.tsx +78 -0
  25. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.tsx +6 -2
  26. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.tsx +10 -1
  27. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.tsx +16 -24
  28. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.tsx +4 -1
  29. package/src/serverGroup/configure/wizard/instanceType/advancedMode/advancedMode.less +13 -1
  30. package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +3 -0
@@ -59,7 +59,7 @@ export class AmazonImageSelectInput extends React.Component<IAmazonImageSelector
59
59
 
60
60
  // assume that the specific image exists in the selected region
61
61
  const amis = { [region]: [imageId] };
62
- const attributes = { virtualizationType: '*', creationDate: new Date().toISOString() };
62
+ const attributes = { virtualizationType: '*', architecture: '*', creationDate: new Date().toISOString() };
63
63
 
64
64
  return { imageName, amis, attributes } as IAmazonImage;
65
65
  }
@@ -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
- instanceTypes,
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
- instanceTypes,
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 filtered = this.awsInstanceTypeService.getAvailableTypesForRegions(command.backingData.instanceTypes, [
377
- command.region,
378
- ]);
379
- if (command.virtualizationType) {
380
- filtered = this.awsInstanceTypeService.filterInstanceTypes(
381
- filtered,
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
- if (command.instanceType && !filtered.includes(command.instanceType)) {
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 = filtered;
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
- To configure a single instance type, use
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 with multiple instance types,</span>
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.instanceTypes) || []
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
- import { TextInput, Tooltip } from '@spinnaker/core';
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>{instanceType}</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: string[];
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
  />
@@ -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 { IAmazonPreferredInstanceType } from '../../../../../instance/awsInstanceType.service';
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}
@@ -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: string[];
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
- };
@@ -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 {...inputProps} />
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: 80%;
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);