@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.
Files changed (116) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/aws.settings.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 +10 -2
  6. package/dist/instance/awsInstanceTypes.d.ts +10 -0
  7. package/dist/instance/details/CostFactor.d.ts +6 -0
  8. package/dist/search/searchResultFormatter.d.ts +2 -2
  9. package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +14 -1
  10. package/dist/serverGroup/configure/wizard/instanceType/CpuCreditsToggle.d.ts +3 -4
  11. package/dist/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.d.ts +9 -0
  12. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.d.ts +13 -0
  13. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceProfileSelector.d.ts +9 -0
  14. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.d.ts +11 -0
  15. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.d.ts +14 -0
  16. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.d.ts +12 -0
  17. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.d.ts +15 -0
  18. package/dist/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.d.ts +8 -0
  19. package/dist/serverGroup/configure/wizard/instanceType/simpleMode/SimpleModeSelector.d.ts +8 -0
  20. package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +9 -6
  21. package/dist/serverGroup/details/scalingPolicy/ScalingPolicySummary.d.ts +0 -1
  22. package/dist/serverGroup/details/scalingPolicy/chart/MetricAlarmChart.d.ts +0 -4
  23. package/dist/serverGroup/details/scalingPolicy/index.d.ts +0 -1
  24. package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingChart.d.ts +1 -3
  25. package/package.json +5 -5
  26. package/src/aws.module.ts +3 -3
  27. package/src/aws.settings.ts +2 -0
  28. package/src/function/details/FunctionActions.spec.tsx +15 -12
  29. package/src/function/details/FunctionActions.tsx +2 -1
  30. package/src/help/amazon.help.ts +9 -6
  31. package/src/image/image.reader.spec.ts +75 -0
  32. package/src/instance/awsInstanceType.service.spec.js +37 -71
  33. package/src/instance/awsInstanceType.service.ts +191 -0
  34. package/src/instance/awsInstanceTypes.ts +311 -0
  35. package/src/instance/details/CostFactor.tsx +29 -0
  36. package/src/instance/details/InstanceInformation.spec.tsx +2 -1
  37. package/src/instance/details/instance.details.controller.js +472 -473
  38. package/src/loadBalancer/details/LoadBalancerActions.tsx +2 -1
  39. package/src/loadBalancer/details/loadBalancerDetails.controller.spec.ts +5 -3
  40. package/src/search/{searchResultFormatter.js → searchResultFormatter.ts} +5 -4
  41. package/src/securityGroup/details/securityGroupDetail.controller.js +2 -1
  42. package/src/serverGroup/configure/AmazonImageSelectInput.spec.tsx +10 -7
  43. package/src/serverGroup/configure/serverGroupCommandBuilder.aws.service.spec.js +302 -1
  44. package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +96 -24
  45. package/src/serverGroup/configure/serverGroupCommandBuilder.spec.js +25 -8
  46. package/src/serverGroup/configure/serverGroupConfiguration.service.spec.ts +6 -13
  47. package/src/serverGroup/configure/serverGroupConfiguration.service.ts +26 -1
  48. package/src/serverGroup/configure/wizard/AmazonCloneServerGroupModal.tsx +1 -1
  49. package/src/serverGroup/configure/wizard/instanceType/CpuCreditsToggle.tsx +31 -31
  50. package/src/serverGroup/configure/wizard/instanceType/InstanceTypeSelector.tsx +133 -0
  51. package/src/serverGroup/configure/wizard/instanceType/advancedMode/AdvancedModeSelector.tsx +99 -0
  52. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceProfileSelector.tsx +36 -0
  53. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeRow.tsx +144 -0
  54. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTable.tsx +137 -0
  55. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableBody.tsx +135 -0
  56. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstanceTypeTableParts.tsx +137 -0
  57. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.less +5 -0
  58. package/src/serverGroup/configure/wizard/instanceType/advancedMode/InstancesDistribution.tsx +108 -0
  59. package/src/serverGroup/configure/wizard/instanceType/advancedMode/advancedMode.less +110 -0
  60. package/src/serverGroup/configure/wizard/instanceType/simpleMode/SimpleModeSelector.tsx +62 -0
  61. package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +106 -62
  62. package/src/serverGroup/configure/wizard/pages/advancedSettings/ServerGroupAdvancedSettingsCommon.tsx +1 -1
  63. package/src/serverGroup/details/AmazonServerGroupActions.tsx +2 -1
  64. package/src/serverGroup/details/scalingPolicy/ScalingPolicySummary.tsx +7 -3
  65. package/src/serverGroup/details/scalingPolicy/StepPolicySummary.tsx +26 -28
  66. package/src/serverGroup/details/scalingPolicy/chart/MetricAlarmChart.tsx +1 -25
  67. package/src/serverGroup/details/scalingPolicy/index.ts +0 -1
  68. package/src/serverGroup/details/scalingPolicy/scalingPolicy.module.ts +1 -9
  69. package/src/serverGroup/details/scalingPolicy/scalingPolicySummary.component.ts +6 -2
  70. package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingChart.tsx +2 -17
  71. package/src/serverGroup/details/scalingPolicy/upsert/alarm/AlarmConfigurer.less +1 -1
  72. package/src/serverGroup/details/scalingProcesses/AutoScalingProcessService.spec.ts +1 -2
  73. package/src/serverGroup/details/sections/AdvancedSettingsDetailsSection.tsx +3 -2
  74. package/src/serverGroup/details/sections/AmazonCapacityDetailsSection.tsx +3 -8
  75. package/src/serverGroup/details/sections/InstancesDistributionDetailsSection.spec.tsx +8 -5
  76. package/src/serverGroup/details/sections/LaunchTemplateDetailsSection.spec.tsx +8 -5
  77. package/src/serverGroup/details/sections/ScalingPoliciesDetailsSection.tsx +3 -3
  78. package/src/serverGroup/details/sections/ScalingProcessesDetailsSection.tsx +3 -10
  79. package/src/serverGroup/details/sections/ScheduledActionsDetailsSection.tsx +3 -2
  80. package/src/serverGroup/details/sections/SecurityGroupsDetailsSection.tsx +3 -2
  81. package/src/serverGroup/serverGroup.transformer.spec.ts +5 -3
  82. package/src/subnet/SubnetSelectInput.spec.tsx +7 -4
  83. package/src/vpc/{VpcReader.spec.js → VpcReader.spec.ts} +2 -10
  84. package/src/vpc/VpcTag.spec.tsx +37 -0
  85. package/src/vpc/vpc.module.ts +6 -2
  86. package/dist/reactShims/aws.ngReact.d.ts +0 -11
  87. package/dist/serverGroup/details/scalingPolicy/ScalingPolicyTypeRegistry.d.ts +0 -10
  88. package/dist/serverGroup/details/scalingPolicy/alarmBasedSummary.component.d.ts +0 -2
  89. package/dist/serverGroup/details/scalingPolicy/detailsSummary.component.d.ts +0 -12
  90. package/dist/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.d.ts +0 -1
  91. package/dist/serverGroup/details/scalingPolicy/stepPolicySummary.component.d.ts +0 -1
  92. package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingPolicy.config.d.ts +0 -1
  93. package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTracking.module.d.ts +0 -2
  94. package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTrackingChart.component.d.ts +0 -1
  95. package/dist/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.d.ts +0 -1
  96. package/dist/vpc/vpcTag.directive.d.ts +0 -2
  97. package/src/image/image.reader.spec.js +0 -123
  98. package/src/instance/awsInstanceType.service.js +0 -437
  99. package/src/reactShims/aws.ngReact.ts +0 -27
  100. package/src/serverGroup/details/scalingPolicy/ScalingPolicyTypeRegistry.ts +0 -18
  101. package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html +0 -35
  102. package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.js +0 -60
  103. package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html +0 -5
  104. package/src/serverGroup/details/scalingPolicy/detailsSummary.component.ts +0 -32
  105. package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html +0 -1
  106. package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html +0 -107
  107. package/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.ts +0 -31
  108. package/src/serverGroup/details/scalingPolicy/scalingPolicySummary.component.less +0 -15
  109. package/src/serverGroup/details/scalingPolicy/stepPolicySummary.component.ts +0 -10
  110. package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingPolicy.config.ts +0 -6
  111. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTracking.module.ts +0 -8
  112. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingChart.component.ts +0 -16
  113. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.ts +0 -14
  114. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html +0 -5
  115. package/src/vpc/vpcTag.directive.js +0 -34
  116. package/src/vpc/vpcTag.directive.spec.js +0 -60
@@ -0,0 +1,110 @@
1
+ .advanced-mode-selector {
2
+ .instance-profile-header {
3
+ display: inline-block;
4
+ button {
5
+ width: 100%;
6
+ }
7
+ h4 {
8
+ min-height: 52px;
9
+ }
10
+ .panel-heading {
11
+ padding: 0 0 0 0;
12
+ }
13
+ &.profile-button {
14
+ width: calc(~'25% - 20px');
15
+ margin: 0 10px 15px 10px;
16
+ }
17
+ }
18
+
19
+ .sub-section {
20
+ padding: 0 15px;
21
+ margin-bottom: 5px;
22
+
23
+ .description {
24
+ padding: 0 10px;
25
+ }
26
+
27
+ tr {
28
+ &.unavailable {
29
+ opacity: 0.5;
30
+ }
31
+
32
+ &.sortable {
33
+ .instance-type-drag-handle {
34
+ display: inline-block;
35
+ opacity: 0.9;
36
+ font-size: 100%;
37
+ padding-top: 8px;
38
+ }
39
+ }
40
+ }
41
+
42
+ th {
43
+ font-size: 110%;
44
+ }
45
+ }
46
+ }
47
+
48
+ .custom-profile {
49
+ .select {
50
+ width: 80%;
51
+ }
52
+ }
53
+
54
+ .instance-profile {
55
+ vertical-align: top;
56
+ text-align: left;
57
+ min-height: 100px;
58
+ font-size: 90%;
59
+ border: 1px solid var(--color-silver);
60
+ border-radius: 3px;
61
+ color: var(--color-mineshaft);
62
+ background-color: transparent;
63
+
64
+ &:hover,
65
+ &:focus {
66
+ color: var(--color-mineshaft);
67
+ text-decoration: none;
68
+ }
69
+
70
+ .selected-indicator {
71
+ display: flex;
72
+ width: 100%;
73
+ text-align: right;
74
+ padding-right: 5px;
75
+ font-size: 150%;
76
+ color: var(--color-accent);
77
+
78
+ &.custom {
79
+ margin-top: 5px;
80
+ }
81
+ }
82
+
83
+ h4 {
84
+ margin-top: 0;
85
+ text-align: center;
86
+ word-spacing: 300px;
87
+ }
88
+
89
+ ul {
90
+ font-size: 95%;
91
+ padding-left: 20px;
92
+ }
93
+ .panel-heading {
94
+ padding-top: 0;
95
+ padding-bottom: 0;
96
+ }
97
+ &:hover,
98
+ &:focus,
99
+ &.active {
100
+ outline: 0;
101
+ }
102
+ &.active {
103
+ box-shadow: inset 0 0 3px 2px var(--color-accent);
104
+ border-color: var(--color-accent);
105
+ }
106
+ &:hover,
107
+ &:focus {
108
+ box-shadow: 0 0 8px 2px var(--color-accent);
109
+ }
110
+ }
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+
3
+ import { NgReact } from '@spinnaker/core';
4
+
5
+ import { CpuCreditsToggle } from '../CpuCreditsToggle';
6
+ import { AWSProviderSettings } from '../../../../../aws.settings';
7
+ import type { IAmazonServerGroupCommand } from '../../../serverGroupConfiguration.service';
8
+
9
+ export interface ISimpleModeSelectorProps {
10
+ command: IAmazonServerGroupCommand;
11
+ setUnlimitedCpuCredits: (unlimitedCpuCredits: boolean | undefined) => void;
12
+ setFieldValue: (field: keyof IAmazonServerGroupCommand, value: any, shouldValidate?: boolean) => void;
13
+ }
14
+
15
+ export function SimpleModeSelector(props: ISimpleModeSelectorProps) {
16
+ const { command } = props;
17
+ const { InstanceArchetypeSelector, InstanceTypeSelector } = NgReact;
18
+ const isLaunchTemplatesEnabled = AWSProviderSettings.serverGroups?.enableLaunchTemplates;
19
+ const isCpuCreditsEnabled = AWSProviderSettings.serverGroups?.enableCpuCredits;
20
+
21
+ const instanceProfileChanged = (newProfile: string) => {
22
+ // Instance profile is already set on values.viewState, so just use that value.
23
+ // Once angular is gone from this component tree, we can move all the viewState stuff
24
+ // into react state
25
+ props.setFieldValue('viewState', {
26
+ ...command.viewState,
27
+ instanceProfile: newProfile,
28
+ });
29
+ };
30
+
31
+ const instanceTypeChanged = (type: string) => {
32
+ command.instanceTypeChanged(command);
33
+ props.setFieldValue('instanceType', type);
34
+ };
35
+
36
+ return (
37
+ <div className="container-fluid form-horizontal">
38
+ <div className="row">
39
+ <InstanceArchetypeSelector
40
+ command={command}
41
+ onTypeChanged={instanceTypeChanged}
42
+ onProfileChanged={instanceProfileChanged}
43
+ />
44
+ <div style={{ padding: '0 15px' }}>
45
+ {command.viewState.instanceProfile && command.viewState.instanceProfile !== 'custom' && (
46
+ <InstanceTypeSelector command={command} onTypeChanged={instanceTypeChanged} />
47
+ )}
48
+ </div>
49
+ </div>
50
+ {isLaunchTemplatesEnabled && isCpuCreditsEnabled && (
51
+ <div className="row">
52
+ <CpuCreditsToggle
53
+ unlimitedCpuCredits={command.unlimitedCpuCredits}
54
+ selectedInstanceTypes={[command.instanceType]}
55
+ currentProfile={command.viewState.instanceProfile}
56
+ setUnlimitedCpuCredits={props.setUnlimitedCpuCredits}
57
+ />
58
+ </div>
59
+ )}
60
+ </div>
61
+ );
62
+ }
@@ -1,11 +1,13 @@
1
1
  import type { FormikErrors, FormikProps } from 'formik';
2
+ import { some } from 'lodash';
2
3
  import React from 'react';
4
+ import { Subject } from 'rxjs';
3
5
 
4
6
  import type { IWizardPageComponent } from '@spinnaker/core';
5
- import { NgReact } from '@spinnaker/core';
6
- import { AWSProviderSettings } from '../../../../aws.settings';
7
7
 
8
- import { CpuCreditsToggle } from '../instanceType/CpuCreditsToggle';
8
+ import type { IAmazonInstanceTypeCategory } from '../../../../instance/awsInstanceType.service';
9
+ import { InstanceTypeSelector } from '../instanceType/InstanceTypeSelector';
10
+ import { AwsReactInjector } from '../../../../reactShims';
9
11
  import type { IAmazonServerGroupCommand } from '../../serverGroupConfiguration.service';
10
12
 
11
13
  export interface IServerGroupInstanceTypeProps {
@@ -13,88 +15,130 @@ export interface IServerGroupInstanceTypeProps {
13
15
  }
14
16
 
15
17
  export interface IServerGroupInstanceTypeState {
16
- newInstanceType?: string;
17
- newProfileType?: string;
18
+ instanceTypeDetails: IAmazonInstanceTypeCategory[];
18
19
  }
19
20
 
20
21
  export class ServerGroupInstanceType
21
22
  extends React.Component<IServerGroupInstanceTypeProps, IServerGroupInstanceTypeState>
22
23
  implements IWizardPageComponent<IAmazonServerGroupCommand> {
23
- constructor(props: IServerGroupInstanceTypeProps) {
24
- super(props);
25
- this.state = {
26
- newInstanceType: undefined,
27
- newProfileType: undefined,
28
- };
29
- }
24
+ public state: IServerGroupInstanceTypeState = {
25
+ instanceTypeDetails: [],
26
+ };
27
+ private props$ = new Subject<IServerGroupInstanceTypeProps>();
28
+ private destroy$ = new Subject<void>();
30
29
 
31
- public validate(values: IAmazonServerGroupCommand) {
30
+ public validate(values: IAmazonServerGroupCommand): FormikErrors<IAmazonServerGroupCommand> {
32
31
  const errors: FormikErrors<IAmazonServerGroupCommand> = {};
33
32
 
34
- if (!values.instanceType) {
35
- errors.instanceType = 'Instance Type required.';
33
+ if (values.viewState.useSimpleInstanceTypeSelector) {
34
+ if (!values.instanceType) {
35
+ errors.instanceType = 'Instance Type required.';
36
+ }
37
+ } else {
38
+ const advancedModeErrors = this.validateAdvancedModeFields(values, errors);
39
+ Object.assign(errors, { ...advancedModeErrors });
36
40
  }
37
41
 
38
42
  return errors;
39
43
  }
40
44
 
41
- private instanceProfileChanged = (_profile: string) => {
42
- // Instance profile is already set on values.viewState, so just use that value.
43
- // Once angular is gone from this component tree, we can move all the viewState stuff
44
- // into react state
45
- this.setState({ newProfileType: _profile, newInstanceType: undefined });
46
- };
45
+ private validateAdvancedModeFields(
46
+ values: IAmazonServerGroupCommand,
47
+ errors: FormikErrors<IAmazonServerGroupCommand>,
48
+ ): FormikErrors<IAmazonServerGroupCommand> {
49
+ if (!values.launchTemplateOverridesForInstanceType.length) {
50
+ errors.instanceType = 'At least one instance type required.';
51
+ }
52
+ if (values.launchTemplateOverridesForInstanceType.length > 40) {
53
+ errors.instanceType = 'Maximum of 40 instance types are allowed.';
54
+ }
55
+ const weightsSpecified = values.launchTemplateOverridesForInstanceType.filter(
56
+ (it) => it.weightedCapacity !== undefined,
57
+ );
58
+ if (
59
+ !(
60
+ weightsSpecified.length === values.launchTemplateOverridesForInstanceType.length ||
61
+ weightsSpecified.length === 0
62
+ )
63
+ ) {
64
+ errors.instanceType = 'Weighted capacity must be specified for all instance types selected or none.';
65
+ }
66
+ if (
67
+ some(weightsSpecified, function (instanceType) {
68
+ return instanceType.weightedCapacity < 1 || instanceType.weightedCapacity > 999;
69
+ })
70
+ ) {
71
+ errors.instanceType = 'Weighted capacity must be a number between 1 and 999.';
72
+ }
47
73
 
48
- private instanceTypeChanged = (type: string) => {
49
- const { values } = this.props.formik;
50
- values.instanceTypeChanged(values);
51
- this.props.formik.setFieldValue('instanceType', type);
52
- this.setState({ newInstanceType: type, newProfileType: undefined });
53
- };
74
+ if (values.onDemandBaseCapacity < 0) {
75
+ errors.onDemandBaseCapacity = 'On-Demand base capacity must be non-negative.';
76
+ }
54
77
 
55
- private setUnlimitedCpuCredits = (unlimitedCpuCredits: boolean | undefined) => {
56
- if (this.props.formik.values.unlimitedCpuCredits !== unlimitedCpuCredits) {
57
- this.props.formik.setFieldValue('unlimitedCpuCredits', unlimitedCpuCredits);
58
- this.setState({});
78
+ if (values.onDemandBaseCapacity > values.capacity.max) {
79
+ errors.onDemandBaseCapacity = 'On-Demand base capacity must be less than or equal to max capacity.';
80
+ }
81
+
82
+ if (values.onDemandPercentageAboveBaseCapacity < 0 || values.onDemandPercentageAboveBaseCapacity > 100) {
83
+ errors.onDemandPercentageAboveBaseCapacity =
84
+ 'On-Demand percentage above base capacity must be a number between 0 and 100.';
85
+ }
86
+
87
+ if (values.spotPrice) {
88
+ const spotPriceNum = Number(values.spotPrice);
89
+ if (Number.isNaN(spotPriceNum)) {
90
+ errors.spotPrice = 'Spot Max Price must be a number or empty string, used to unset previous max price.';
91
+ }
92
+ if (spotPriceNum <= 0) {
93
+ errors.spotPrice = 'Spot Max Price must be greater than 0, if specified.';
94
+ }
59
95
  }
60
- };
96
+
97
+ if (values.spotInstancePools && values.spotAllocationStrategy !== 'lowest-price') {
98
+ errors.spotInstancePools = "Spot Instance Pools is only supported for 'lowest-price' Spot Allocation Strategy.";
99
+ }
100
+ if (values.spotInstancePools <= 0 || values.spotInstancePools > 20) {
101
+ errors.spotInstancePools = 'Spot Instance Pools count must be a number between 1 and 20, when applicable.';
102
+ }
103
+
104
+ return errors;
105
+ }
106
+
107
+ public componentDidMount(): void {
108
+ Promise.resolve(AwsReactInjector.awsInstanceTypeService.getCategories()).then(
109
+ (categories: IAmazonInstanceTypeCategory[]) => {
110
+ this.setState({ instanceTypeDetails: categories });
111
+ },
112
+ );
113
+ }
114
+
115
+ public componentDidUpdate() {
116
+ this.props$.next(this.props);
117
+ }
118
+
119
+ public componentWillUnmount() {
120
+ this.destroy$.next();
121
+ }
61
122
 
62
123
  public render() {
63
124
  const { values } = this.props.formik;
64
-
65
- const { InstanceArchetypeSelector, InstanceTypeSelector } = NgReact;
66
125
  const showTypeSelector = !!(values.viewState.disableImageSelection || values.amiName);
67
126
 
68
- const isLaunchTemplatesEnabled = AWSProviderSettings.serverGroups?.enableLaunchTemplates;
69
- const isCpuCreditsEnabled = AWSProviderSettings.serverGroups?.enableCpuCredits;
127
+ // mark unavailable instance types for all profiles
128
+ const availableInstanceTypesForConfig: string[] = values.backingData?.filtered?.instanceTypes ?? [];
129
+ const markedInstanceTypeDetails: IAmazonInstanceTypeCategory[] = Array.from(this.state.instanceTypeDetails);
130
+ if (!values.viewState.disableImageSelection && availableInstanceTypesForConfig.length) {
131
+ markedInstanceTypeDetails.forEach((profile) => {
132
+ profile.families.forEach((family) => {
133
+ family.instanceTypes.forEach((instanceType) => {
134
+ instanceType.unavailable = !availableInstanceTypesForConfig.includes(instanceType.name);
135
+ });
136
+ });
137
+ });
138
+ }
70
139
 
71
140
  if (showTypeSelector && values) {
72
- return (
73
- <div className="container-fluid form-horizontal">
74
- <div className="row">
75
- <InstanceArchetypeSelector
76
- command={values}
77
- onTypeChanged={this.instanceTypeChanged}
78
- onProfileChanged={this.instanceProfileChanged}
79
- />
80
- <div style={{ padding: '0 15px' }}>
81
- {values.viewState.instanceProfile && values.viewState.instanceProfile !== 'custom' && (
82
- <InstanceTypeSelector command={values} onTypeChanged={this.instanceTypeChanged} />
83
- )}
84
- </div>
85
- </div>
86
- {isLaunchTemplatesEnabled && isCpuCreditsEnabled && (
87
- <div className="row">
88
- <CpuCreditsToggle
89
- command={values}
90
- newInstanceType={this.state.newInstanceType}
91
- newProfileType={this.state.newProfileType}
92
- setUnlimitedCpuCredits={this.setUnlimitedCpuCredits}
93
- />
94
- </div>
95
- )}
96
- </div>
97
- );
141
+ return <InstanceTypeSelector formik={this.props.formik} instanceTypeDetails={markedInstanceTypeDetails} />;
98
142
  }
99
143
 
100
144
  return <h5 className="text-center">Please select an image.</h5>;
@@ -222,7 +222,7 @@ export class ServerGroupAdvancedSettingsCommon extends React.Component<IServerGr
222
222
  </div>
223
223
  </div>
224
224
  )}
225
- {!AWSProviderSettings.disableSpotPricing && (
225
+ {!AWSProviderSettings.disableSpotPricing && values.viewState.useSimpleInstanceTypeSelector && (
226
226
  <div className="form-group">
227
227
  <div className="col-md-5 sm-label-right">
228
228
  <b>Spot Instances Price (optional)</b> <HelpField id="aws.serverGroup.spotMaxPrice" />
@@ -15,6 +15,7 @@ import {
15
15
  SETTINGS,
16
16
  } from '@spinnaker/core';
17
17
 
18
+ import { AWSProviderSettings } from '../../aws.settings';
18
19
  import type { IAmazonServerGroupCommand } from '../configure';
19
20
  import { AmazonCloneServerGroupModal } from '../configure/wizard/AmazonCloneServerGroupModal';
20
21
  import type { IAmazonServerGroup, IAmazonServerGroupView } from '../../domain';
@@ -286,7 +287,7 @@ export class AmazonServerGroupActions extends React.Component<IAmazonServerGroup
286
287
 
287
288
  return (
288
289
  <>
289
- {SETTINGS.awsAdHocInfraWritesEnabled && (
290
+ {AWSProviderSettings.adHocInfraWritesEnabled && (
290
291
  <Dropdown className="dropdown" id="server-group-actions-dropdown">
291
292
  <Dropdown.Toggle className="btn btn-sm btn-primary dropdown-toggle">Server Group Actions</Dropdown.Toggle>
292
293
  <Dropdown.Menu className="dropdown-menu">
@@ -6,8 +6,6 @@ import { StepPolicySummary } from './StepPolicySummary';
6
6
  import type { IScalingPolicyView, ITargetTrackingPolicy } from '../../../domain';
7
7
  import { TargetTrackingSummary } from './targetTracking/TargetTrackingSummary';
8
8
 
9
- import './scalingPolicySummary.component.less';
10
-
11
9
  export interface IScalingPolicySummaryProps {
12
10
  application: Application;
13
11
  policy: IScalingPolicyView;
@@ -15,7 +13,13 @@ export interface IScalingPolicySummaryProps {
15
13
  }
16
14
 
17
15
  export const ScalingPolicySummary = ({ application, policy, serverGroup }: IScalingPolicySummaryProps) => {
18
- if (policy.policyType === 'TargetTrackingScaling') {
16
+ const scalingPolicyType = policy.policyType
17
+ ? policy.policyType
18
+ : policy.targetTrackingConfiguration
19
+ ? 'TargetTrackingScaling'
20
+ : 'StepScaling';
21
+
22
+ if (scalingPolicyType === 'TargetTrackingScaling') {
19
23
  return (
20
24
  <TargetTrackingSummary
21
25
  application={application}
@@ -83,39 +83,37 @@ export const StepPolicySummary = ({ application, policy, serverGroup }: IStepPol
83
83
  });
84
84
  };
85
85
 
86
- if (!policy.alarms?.length) {
87
- return <div>No alarms configured for this policy - it's safe to delete.</div>;
88
- }
89
-
90
86
  return (
91
87
  <div className="StepPolicySummary">
92
88
  <div>
93
- {policy.alarms.map((a) => (
94
- <div key={`step-summary-${policy.policyName}`}>
95
- <HoverablePopover
96
- Component={() => (
97
- <StepPolicyPopoverContent policy={policy} serverGroup={serverGroup as IAmazonServerGroup} />
98
- )}
99
- placement="left"
100
- title={policy.policyName}
101
- >
102
- <div>
103
- <div className="label label-default">{robotToHuman(policy.policyType).toUpperCase()}</div>
104
- <AlarmSummary alarm={a} />
89
+ {!Boolean(policy.alarms?.length) && <div>No alarms configured for this policy - it's safe to delete.</div>}
90
+ {Boolean(policy.alarms?.length) &&
91
+ policy.alarms.map((a) => (
92
+ <div key={`step-summary-${policy.policyName}`}>
93
+ <HoverablePopover
94
+ Component={() => (
95
+ <StepPolicyPopoverContent policy={policy} serverGroup={serverGroup as IAmazonServerGroup} />
96
+ )}
97
+ placement="left"
98
+ title={policy.policyName}
99
+ >
100
+ <div>
101
+ <div className="label label-default">{robotToHuman(policy.policyType).toUpperCase()}</div>
102
+ <AlarmSummary alarm={a} />
103
+ </div>
104
+ </HoverablePopover>
105
+ <div className="actions">
106
+ <button className="btn btn-xs btn-link" onClick={editPolicy}>
107
+ <span className="glyphicon glyphicon-cog"></span>
108
+ <span className="sr-only">Edit policy</span>
109
+ </button>
110
+ <button className="btn btn-xs btn-link" onClick={deletePolicy}>
111
+ <span className="glyphicon glyphicon-trash"></span>
112
+ <span className="sr-only">Delete policy</span>
113
+ </button>
105
114
  </div>
106
- </HoverablePopover>
107
- <div className="actions">
108
- <button className="btn btn-xs btn-link" onClick={editPolicy}>
109
- <span className="glyphicon glyphicon-cog"></span>
110
- <span className="sr-only">Edit policy</span>
111
- </button>
112
- <button className="btn btn-xs btn-link" onClick={deletePolicy}>
113
- <span className="glyphicon glyphicon-trash"></span>
114
- <span className="sr-only">Delete policy</span>
115
- </button>
116
115
  </div>
117
- </div>
118
- ))}
116
+ ))}
119
117
  </div>
120
118
  </div>
121
119
  );
@@ -1,11 +1,7 @@
1
- import { module } from 'angular';
2
1
  import * as React from 'react';
3
- import { react2angular } from 'react2angular';
4
- import type { Observable } from 'rxjs';
5
2
 
6
3
  import type { ICloudMetricStatistics } from '@spinnaker/core';
7
- import { CloudMetricsReader, Spinner, useData, useForceUpdate, useObservable } from '@spinnaker/core';
8
- import { withErrorBoundary } from '@spinnaker/core';
4
+ import { CloudMetricsReader, Spinner, useData } from '@spinnaker/core';
9
5
 
10
6
  import type { IDateLine } from './DateLineChart';
11
7
  import { DateLineChart } from './DateLineChart';
@@ -14,9 +10,6 @@ import type { IAmazonServerGroup, IScalingPolicyAlarm } from '../../../../domain
14
10
  interface IMetricAlarmChartProps {
15
11
  serverGroup: IAmazonServerGroup;
16
12
  alarm: IScalingPolicyAlarm;
17
- // Allows AngularJS to tell the chart to update
18
- alarmUpdated?: Observable<any>;
19
- // Allows the chart data to inform the parent component of the fetched metric units
20
13
  onChartLoaded?: (stats: ICloudMetricStatistics) => void;
21
14
  }
22
15
 
@@ -46,10 +39,6 @@ export function MetricAlarmChartImpl(props: IMetricAlarmChartProps) {
46
39
  [namespace, statistic, period, type, account, region, metricName],
47
40
  );
48
41
 
49
- // Used by AngularJS to tell the chart to refresh, delete when all callers are reactified
50
- const forceUpdate = useForceUpdate();
51
- useObservable(props.alarmUpdated, () => forceUpdate());
52
-
53
42
  if (status === 'PENDING') {
54
43
  return (
55
44
  <div className="flex-container-v middle center sp-margin-xl">
@@ -91,16 +80,3 @@ export function MetricAlarmChartImpl(props: IMetricAlarmChartProps) {
91
80
  };
92
81
  return <DateLineChart lines={[line, setline]} />;
93
82
  }
94
-
95
- export const AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_CHART_METRICALARMCHART_COMPONENT =
96
- 'spinnaker.amazon.serverGroup.details.scalingPolicy.metricAlarmChart.component';
97
- export const name = AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_CHART_METRICALARMCHART_COMPONENT; // for backwards compatibility
98
- module(AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_CHART_METRICALARMCHART_COMPONENT, []).component(
99
- 'metricAlarmChart',
100
- react2angular(withErrorBoundary(MetricAlarmChart, 'metricAlarmChart'), [
101
- 'alarm',
102
- 'serverGroup',
103
- 'alarmUpdated',
104
- 'onChartLoaded',
105
- ]),
106
- );
@@ -1,6 +1,5 @@
1
1
  export { DateLineChart } from './chart/DateLineChart';
2
2
  export { MetricAlarmChart } from './chart/MetricAlarmChart';
3
- export * from './ScalingPolicyTypeRegistry';
4
3
  export * from './CreateScalingPolicyButton';
5
4
  export * from './ScalingPolicyWriter';
6
5
  export * from './StepPolicySummary';
@@ -1,14 +1,6 @@
1
1
  import { module } from 'angular';
2
2
 
3
- import { AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_ALARMBASEDSUMMARY_COMPONENT } from './alarmBasedSummary.component';
4
3
  import { SCALING_POLICY_SUMMARY_COMPONENT } from './scalingPolicySummary.component';
5
- import { STEP_POLICY_SUMMARY_COMPONENT } from './stepPolicySummary.component';
6
- import { TARGET_TRACKING_MODULE } from './targetTracking/targetTracking.module';
7
4
 
8
5
  export const SCALING_POLICY_MODULE = 'spinnaker.amazon.scalingPolicy.module';
9
- module(SCALING_POLICY_MODULE, [
10
- TARGET_TRACKING_MODULE,
11
- AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_ALARMBASEDSUMMARY_COMPONENT,
12
- STEP_POLICY_SUMMARY_COMPONENT,
13
- SCALING_POLICY_SUMMARY_COMPONENT,
14
- ]);
6
+ module(SCALING_POLICY_MODULE, [SCALING_POLICY_SUMMARY_COMPONENT]);
@@ -1,10 +1,14 @@
1
1
  import { module } from 'angular';
2
2
  import { react2angular } from 'react2angular';
3
3
  import { withErrorBoundary } from '@spinnaker/core';
4
- import { StepPolicySummary } from './StepPolicySummary';
4
+ import { ScalingPolicySummary } from './ScalingPolicySummary';
5
5
 
6
6
  export const SCALING_POLICY_SUMMARY_COMPONENT = 'spinnaker.amazon.scalingPolicy.scalingPolicySummary.component';
7
7
  module(SCALING_POLICY_SUMMARY_COMPONENT, []).component(
8
8
  'scalingPolicySummary',
9
- react2angular(withErrorBoundary(StepPolicySummary, 'scalingPolicySummary'), ['application', 'policy', 'serverGroup']),
9
+ react2angular(withErrorBoundary(ScalingPolicySummary, 'scalingPolicySummary'), [
10
+ 'application',
11
+ 'policy',
12
+ 'serverGroup',
13
+ ]),
10
14
  );
@@ -1,6 +1,5 @@
1
1
  import type { Dictionary } from 'lodash';
2
2
  import * as React from 'react';
3
- import { Subject } from 'rxjs';
4
3
 
5
4
  import type { ICloudMetricStatistics } from '@spinnaker/core';
6
5
 
@@ -8,7 +7,6 @@ import { MetricAlarmChart } from '../chart/MetricAlarmChart';
8
7
  import type { IAmazonServerGroup, IScalingPolicyAlarm, ITargetTrackingConfiguration } from '../../../../domain';
9
8
 
10
9
  export interface ITargetTrackingChartProps {
11
- alarmUpdated?: Subject<void>;
12
10
  config: ITargetTrackingConfiguration;
13
11
  serverGroup: IAmazonServerGroup;
14
12
  unit?: string;
@@ -21,12 +19,7 @@ const predefinedMetricTypeMapping: Dictionary<string> = {
21
19
  ASGAverageNetworkOut: 'NetworkOut',
22
20
  };
23
21
 
24
- export const TargetTrackingChart = ({
25
- alarmUpdated = new Subject<void>(),
26
- config,
27
- serverGroup,
28
- updateUnit,
29
- }: ITargetTrackingChartProps) => {
22
+ export const TargetTrackingChart = ({ config, serverGroup, updateUnit }: ITargetTrackingChartProps) => {
30
23
  const [alarm, setAlarm] = React.useState<IScalingPolicyAlarm>({
31
24
  alarmName: null,
32
25
  alarmArn: null,
@@ -72,15 +65,7 @@ export const TargetTrackingChart = ({
72
65
  if (updateUnit) {
73
66
  updateUnit(stats.unit);
74
67
  }
75
- alarmUpdated?.next();
76
68
  };
77
69
 
78
- return (
79
- <MetricAlarmChart
80
- alarm={alarm}
81
- alarmUpdated={alarmUpdated}
82
- onChartLoaded={onChartLoaded}
83
- serverGroup={serverGroup}
84
- />
85
- );
70
+ return <MetricAlarmChart alarm={alarm} onChartLoaded={onChartLoaded} serverGroup={serverGroup} />;
86
71
  };
@@ -10,7 +10,7 @@
10
10
  }
11
11
 
12
12
  .configurer-field-med {
13
- width: 48px;
13
+ width: 60px;
14
14
  }
15
15
 
16
16
  .number-input-field {
@@ -1,6 +1,5 @@
1
- import { IAmazonAsg, IAmazonServerGroup } from '../../../domain';
2
-
3
1
  import { AutoScalingProcessService } from './AutoScalingProcessService';
2
+ import type { IAmazonAsg, IAmazonServerGroup } from '../../../domain';
4
3
 
5
4
  describe('AutoScalingProcessService', () => {
6
5
  describe('normalizeScalingProcesses', () => {