@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
@@ -134,80 +134,46 @@ describe('Service: InstanceType', function () {
134
134
  });
135
135
  });
136
136
 
137
- describe('isBurstingSupported', function () {
138
- it('identifies burstable performance instance types correctly', function () {
139
- const types = ['t2.small', 't3.nano', 't3a.medium', 't4g.large', 'm5.small', 'r5.4xlarge'];
140
- const service = this.awsInstanceTypeService;
141
-
142
- let supportedInstanceTypes = [];
143
- for (it of types) {
144
- const actualResult = service.isBurstingSupported(it);
145
- if (actualResult) {
146
- supportedInstanceTypes.push(it);
147
- }
148
- }
149
-
150
- expect(supportedInstanceTypes).toEqual(['t2.small', 't3.nano', 't3a.medium', 't4g.large']);
137
+ describe('isBurstingSupportedForAllTypes', function () {
138
+ const testInputs = [
139
+ { types: ['t2.small', 't3.nano', 't3a.medium', 't4g.large'], result: true },
140
+ { types: ['m5.large'], result: false },
141
+ { types: ['t2.small', 't3.nano', 't3a.medium', 't4g.large', 'm5.small'], result: false },
142
+ { types: ['t2.small', 'r5.large'], result: false },
143
+ { types: ['invalid'], result: false },
144
+ { types: [], result: false },
145
+ { types: null, result: false },
146
+ ];
147
+
148
+ testInputs.forEach((testInput) => {
149
+ it(`identifies if bursting is supported for all instance types passed correctly for ${testInput.types}`, function () {
150
+ const actualResult = this.awsInstanceTypeService.isBurstingSupportedForAllTypes(testInput.types);
151
+ expect(actualResult).toEqual(testInput.result);
152
+ });
151
153
  });
152
154
  });
153
155
 
154
- describe('isInstanceTypeInCategory', function () {
155
- it('identifies instance types in category correctly', function () {
156
- const input = [
157
- { type: 'm5.large', cat: 'general' },
158
- { type: 't2.small', cat: 'general' },
159
- { type: 't2.medium', cat: 'general' },
160
- { type: 'r5.large', cat: 'memory' },
161
- { type: 'r5.xlarge', cat: 'memory' },
162
- { type: 't2.nano', cat: 'micro' },
163
- { type: 't2.micro', cat: 'micro' },
164
- { type: 't2.small', cat: 'micro' },
165
- { type: 't3.nano', cat: 'micro' },
166
- { type: 't3.micro', cat: 'micro' },
167
- { type: 't3.small', cat: 'micro' },
168
- { type: 'm3.small', cat: 'custom' },
169
- { type: 'a1.medium', cat: 'custom' },
170
- ];
171
- let service = this.awsInstanceTypeService;
172
-
173
- for (let test of input) {
174
- expect(service.isInstanceTypeInCategory(test.type, test.cat)).toBeTrue();
175
- }
176
- });
177
-
178
- it('returns false for instance types NOT in category', function () {
179
- const input = [
180
- { type: 't2.nano', cat: 'general' },
181
- { type: 't3.nano', cat: 'general' },
182
- { type: 't2.micro', cat: 'general' },
183
- { type: 't3.micro', cat: 'general' },
184
- { type: 't2.medium', cat: 'micro' },
185
- { type: 't3.medium', cat: 'micro' },
186
- ];
187
- let service = this.awsInstanceTypeService;
188
-
189
- for (let test of input) {
190
- expect(service.isInstanceTypeInCategory(test.type, test.cat)).toBeFalse();
191
- }
192
- });
193
-
194
- it('returns undefined for instance families NOT in category or invalid input', function () {
195
- const input = [
196
- { type: 'm5.large', cat: 'memory' },
197
- { type: 't2.small', cat: 'memory' },
198
- { type: 't3.something', cat: 'memory' },
199
- { type: 'r5.xlarge', cat: 'micro' },
200
- { type: 'm5.large', cat: 'invalid' },
201
- { type: 't2.invalid', cat: 'memory' },
202
- { type: 't3.invalid', cat: 'memory' },
203
- { type: 'invalid', cat: 'micro' },
204
- { type: 'invalid', cat: 'invalid' },
205
- ];
206
- let service = this.awsInstanceTypeService;
207
-
208
- for (let test of input) {
209
- expect(service.isInstanceTypeInCategory(test.type, test.cat)).toBeFalsy();
210
- }
156
+ describe('getInstanceTypesInCategory', function () {
157
+ const testInputs = [
158
+ { types: ['m5.large'], cat: 'general', result: ['m5.large'] },
159
+ { types: ['t2.small', 't2.medium'], cat: 'general', result: ['t2.small', 't2.medium'] },
160
+ { types: ['r5.large', 'r5.xlarge'], cat: 'memory', result: ['r5.large', 'r5.xlarge'] },
161
+ { types: ['t2.nano', 't2.micro', 't2.small'], cat: 'micro', result: ['t2.nano', 't2.micro', 't2.small'] },
162
+ { types: ['t3.nano', 't3.micro', 't3.small'], cat: 'micro', result: ['t3.nano', 't3.micro', 't3.small'] },
163
+ { types: ['m3.small', 'a1.medium'], cat: 'custom', result: ['m3.small', 'a1.medium'] },
164
+ { types: ['t3.nano', 'm3.large', 'r5.large'], cat: 'micro', result: ['t3.nano'] },
165
+ { types: ['m5.small', 'r5.large'], cat: 'memory', result: ['r5.large'] },
166
+ { types: ['invalid'], cat: 'micro', result: [] },
167
+ { types: ['invalid'], cat: 'invalid', result: [] },
168
+ { types: ['t2.invalid'], cat: 'micro', result: [] },
169
+ { types: ['m5.small', 'a1.medium'], cat: 'general', result: [] },
170
+ ];
171
+
172
+ testInputs.forEach((testInput) => {
173
+ it(`identifies instance types in category correctly for ${testInput.types}`, function () {
174
+ const actual = this.awsInstanceTypeService.getInstanceTypesInCategory(testInput.types, testInput.cat);
175
+ expect(actual).toEqual(testInput.result);
176
+ });
211
177
  });
212
178
  });
213
179
  });
@@ -0,0 +1,191 @@
1
+ import type { IQService } from 'angular';
2
+ import { module } from 'angular';
3
+ import _ from 'lodash';
4
+
5
+ import type {
6
+ IInstanceType,
7
+ IInstanceTypeCategory,
8
+ IInstanceTypesByRegion,
9
+ IPreferredInstanceType,
10
+ } from '@spinnaker/core';
11
+ import { REST } from '@spinnaker/core';
12
+
13
+ import { categories, defaultCategories } from './awsInstanceTypes';
14
+
15
+ export interface IAmazonPreferredInstanceType extends IPreferredInstanceType {
16
+ cpuCreditsPerHour?: number;
17
+ }
18
+
19
+ export interface IAmazonInstanceTypeCategory extends IInstanceTypeCategory {
20
+ showCpuCredits?: boolean;
21
+ descriptionListOverride?: string[];
22
+ }
23
+
24
+ export const AMAZON_INSTANCE_AWSINSTANCETYPE_SERVICE = 'spinnaker.amazon.instanceType.service';
25
+ export const name = AMAZON_INSTANCE_AWSINSTANCETYPE_SERVICE; // for backwards compatibility
26
+
27
+ module(AMAZON_INSTANCE_AWSINSTANCETYPE_SERVICE, []).factory('awsInstanceTypeService', [
28
+ '$q',
29
+ function ($q: IQService) {
30
+ function getCategories() {
31
+ return $q.when(categories);
32
+ }
33
+
34
+ const getAllTypesByRegion = function getAllTypesByRegion(): PromiseLike<IInstanceTypesByRegion> {
35
+ return REST('/instanceTypes')
36
+ .get()
37
+ .then(function (types) {
38
+ return _.chain(types)
39
+ .map(function (type: IInstanceType) {
40
+ return {
41
+ region: type.region,
42
+ account: type.account,
43
+ name: type.name,
44
+ key: [type.region, type.account, type.name].join(':'),
45
+ };
46
+ })
47
+ .uniqBy('key')
48
+ .groupBy('region')
49
+ .value();
50
+ });
51
+ };
52
+
53
+ const instanceClassOrder = ['xlarge', 'large', 'medium', 'small', 'micro', 'nano'];
54
+
55
+ function sortTypesByFamilyAndSize(o1: string, o2: string) {
56
+ const type1 = o1.split('.');
57
+ const type2 = o2.split('.');
58
+
59
+ const [family1, class1 = ''] = type1;
60
+ const [family2, class2 = ''] = type2;
61
+
62
+ if (family1 !== family2) {
63
+ if (family1 > family2) {
64
+ return 1;
65
+ } else if (family1 < family2) {
66
+ return -1;
67
+ }
68
+ return 0;
69
+ }
70
+
71
+ const t1Idx = instanceClassOrder.findIndex((el) => class1.endsWith(el));
72
+ const t2Idx = instanceClassOrder.findIndex((el) => class2.endsWith(el));
73
+
74
+ if (t1Idx === -1 || t2Idx === -1) {
75
+ return 0;
76
+ }
77
+
78
+ if (t1Idx === 0 && t2Idx === 0) {
79
+ const size1 = parseInt(class1.replace('xlarge', '')) || 0;
80
+ const size2 = parseInt(class2.replace('xlarge', '')) || 0;
81
+
82
+ if (size2 < size1) {
83
+ return 1;
84
+ } else if (size2 > size1) {
85
+ return -1;
86
+ }
87
+ return 0;
88
+ }
89
+
90
+ if (t1Idx > t2Idx) {
91
+ return -1;
92
+ } else if (t1Idx < t2Idx) {
93
+ return 1;
94
+ }
95
+ return 0;
96
+ }
97
+
98
+ function getAvailableTypesForRegions(availableInstanceTypes: IInstanceTypesByRegion, selectedRegions: string[]) {
99
+ selectedRegions = selectedRegions || [];
100
+ let availableTypes: string[] = [];
101
+
102
+ // prime the list of available types
103
+ if (selectedRegions && selectedRegions.length) {
104
+ availableTypes = _.map(availableInstanceTypes[selectedRegions[0]], 'name');
105
+ }
106
+
107
+ // this will perform an unnecessary intersection with the first region, which is fine
108
+ selectedRegions.forEach(function (selectedRegion) {
109
+ if (availableInstanceTypes[selectedRegion]) {
110
+ availableTypes = _.intersection(availableTypes, _.map(availableInstanceTypes[selectedRegion], 'name'));
111
+ }
112
+ });
113
+
114
+ return availableTypes.sort(sortTypesByFamilyAndSize);
115
+ }
116
+
117
+ const families: { [key: string]: string[] } = {
118
+ paravirtual: ['c1', 'c3', 'hi1', 'hs1', 'm1', 'm2', 'm3', 't1'],
119
+ hvm: ['c3', 'c4', 'd2', 'i2', 'g2', 'm3', 'm4', 'm5', 'p2', 'r3', 'r4', 'r5', 't2', 'x1'],
120
+ vpcOnly: ['c4', 'm4', 'm5', 'r4', 'r5', 't2', 'x1'],
121
+ ebsOptimized: ['c4', 'd2', 'f1', 'g3', 'i3', 'm4', 'm5', 'p2', 'r4', 'r5', 'x1'],
122
+ burstablePerf: ['t2', 't3', 't3a', 't4g'],
123
+ };
124
+
125
+ function filterInstanceTypes(instanceTypes: string[], virtualizationType: string, vpcOnly: boolean): string[] {
126
+ return instanceTypes.filter((instanceType: string) => {
127
+ if (virtualizationType === '*') {
128
+ // show all instance types
129
+ return true;
130
+ }
131
+ const [family] = instanceType.split('.');
132
+ if (!vpcOnly && families.vpcOnly.includes(family)) {
133
+ return false;
134
+ }
135
+ if (!families.paravirtual.includes(family) && virtualizationType === 'hvm') {
136
+ return true;
137
+ }
138
+ return families[virtualizationType].includes(family);
139
+ });
140
+ }
141
+
142
+ function isEbsOptimized(instanceType: string) {
143
+ if (!instanceType) {
144
+ return false;
145
+ }
146
+ const family = _.split(instanceType, '.', 1)[0];
147
+ return families.ebsOptimized.includes(family);
148
+ }
149
+
150
+ function isBurstingSupportedForAllTypes(instanceTypes: string[]): boolean {
151
+ if (!instanceTypes || !instanceTypes.length) {
152
+ return false;
153
+ }
154
+ // for multiple instance types case, all instance types must support bursting in order to prevent incompatible configuration.
155
+ return instanceTypes.every((instanceType) => isBurstingSupported(instanceType));
156
+ }
157
+
158
+ function isBurstingSupported(instanceType: string): boolean {
159
+ if (!instanceType) {
160
+ return false;
161
+ }
162
+ const family = _.split(instanceType, '.', 1)[0];
163
+ return families.burstablePerf.includes(family);
164
+ }
165
+
166
+ function getInstanceTypesInCategory(instanceTypesToFilter: string[], category: string): string[] {
167
+ if (!instanceTypesToFilter || !instanceTypesToFilter.length || !category) {
168
+ return [];
169
+ }
170
+
171
+ if (category === 'custom') {
172
+ return instanceTypesToFilter;
173
+ }
174
+
175
+ const instanceTypesInCategory: string[] = _.flatten(
176
+ _.find(defaultCategories, { type: category })?.families.map((f) => f.instanceTypes.map((it) => it.name)),
177
+ );
178
+ return _.intersection(instanceTypesToFilter, instanceTypesInCategory);
179
+ }
180
+
181
+ return {
182
+ getCategories,
183
+ getAvailableTypesForRegions,
184
+ getAllTypesByRegion,
185
+ filterInstanceTypes,
186
+ isEbsOptimized,
187
+ isBurstingSupportedForAllTypes,
188
+ getInstanceTypesInCategory,
189
+ };
190
+ },
191
+ ]);
@@ -0,0 +1,311 @@
1
+ import type { IInstanceTypeCategory, IInstanceTypeFamily, IPreferredInstanceType } from '@spinnaker/core';
2
+
3
+ import { AWSProviderSettings } from '../aws.settings';
4
+
5
+ interface IAwsInstanceTypeFamily extends IInstanceTypeFamily {
6
+ instanceTypes: IAwsPreferredInstanceType[];
7
+ }
8
+
9
+ interface IAwsPreferredInstanceType extends IPreferredInstanceType {
10
+ cpuCreditsPerHour?: number;
11
+ }
12
+
13
+ interface IAwsInstanceTypeCategory extends IInstanceTypeCategory {
14
+ showCpuCredits?: boolean;
15
+ descriptionListOverride?: string[];
16
+ }
17
+
18
+ const m5: IAwsInstanceTypeFamily = {
19
+ type: 'm5',
20
+ description:
21
+ 'm5 instances provide a balance of compute, memory, and network resources. They are a good choice for most applications.',
22
+ instanceTypes: [
23
+ {
24
+ name: 'm5.large',
25
+ label: 'Large',
26
+ cpu: 2,
27
+ memory: 8,
28
+ storage: { type: 'EBS' },
29
+ costFactor: 2,
30
+ },
31
+ {
32
+ name: 'm5.xlarge',
33
+ label: 'XLarge',
34
+ cpu: 4,
35
+ memory: 16,
36
+ storage: { type: 'EBS' },
37
+ costFactor: 3,
38
+ },
39
+ {
40
+ name: 'm5.2xlarge',
41
+ label: '2XLarge',
42
+ cpu: 8,
43
+ memory: 32,
44
+ storage: { type: 'EBS' },
45
+ costFactor: 4,
46
+ },
47
+ ],
48
+ };
49
+
50
+ const t2gp: IAwsInstanceTypeFamily = {
51
+ type: 't2',
52
+ description:
53
+ 't2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
54
+ instanceTypes: [
55
+ {
56
+ name: 't2.small',
57
+ label: 'Small',
58
+ cpu: 1,
59
+ memory: 2,
60
+ storage: { type: 'EBS' },
61
+ costFactor: 1,
62
+ cpuCreditsPerHour: 12,
63
+ },
64
+ {
65
+ name: 't2.medium',
66
+ label: 'Medium',
67
+ cpu: 2,
68
+ memory: 4,
69
+ storage: { type: 'EBS' },
70
+ costFactor: 1,
71
+ cpuCreditsPerHour: 24,
72
+ },
73
+ {
74
+ name: 't2.large',
75
+ label: 'Large',
76
+ cpu: 2,
77
+ memory: 8,
78
+ storage: { type: 'EBS' },
79
+ costFactor: 2,
80
+ cpuCreditsPerHour: 36,
81
+ },
82
+ {
83
+ name: 't2.xlarge',
84
+ label: 'XLarge',
85
+ cpu: 4,
86
+ memory: 16,
87
+ storage: { type: 'EBS' },
88
+ costFactor: 3,
89
+ cpuCreditsPerHour: 54,
90
+ },
91
+ {
92
+ name: 't2.2xlarge',
93
+ label: '2XLarge',
94
+ cpu: 8,
95
+ memory: 32,
96
+ storage: { type: 'EBS' },
97
+ costFactor: 4,
98
+ cpuCreditsPerHour: 81,
99
+ },
100
+ ],
101
+ };
102
+
103
+ const t3gp: IAwsInstanceTypeFamily = {
104
+ type: 't3',
105
+ description:
106
+ 't3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
107
+ instanceTypes: [
108
+ {
109
+ name: 't3.small',
110
+ label: 'Small',
111
+ cpu: 2,
112
+ memory: 2,
113
+ storage: { type: 'EBS' },
114
+ costFactor: 1,
115
+ cpuCreditsPerHour: 24,
116
+ },
117
+ {
118
+ name: 't3.medium',
119
+ label: 'Medium',
120
+ cpu: 2,
121
+ memory: 4,
122
+ storage: { type: 'EBS' },
123
+ costFactor: 1,
124
+ cpuCreditsPerHour: 24,
125
+ },
126
+ {
127
+ name: 't3.large',
128
+ label: 'Large',
129
+ cpu: 2,
130
+ memory: 8,
131
+ storage: { type: 'EBS' },
132
+ costFactor: 2,
133
+ cpuCreditsPerHour: 36,
134
+ },
135
+ {
136
+ name: 't3.xlarge',
137
+ label: 'XLarge',
138
+ cpu: 4,
139
+ memory: 16,
140
+ storage: { type: 'EBS' },
141
+ costFactor: 3,
142
+ cpuCreditsPerHour: 96,
143
+ },
144
+ {
145
+ name: 't3.2xlarge',
146
+ label: '2XLarge',
147
+ cpu: 8,
148
+ memory: 32,
149
+ storage: { type: 'EBS' },
150
+ costFactor: 4,
151
+ cpuCreditsPerHour: 192,
152
+ },
153
+ ],
154
+ };
155
+
156
+ const t2: IAwsInstanceTypeFamily = {
157
+ type: 't2',
158
+ description:
159
+ 't2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
160
+ instanceTypes: [
161
+ {
162
+ name: 't2.nano',
163
+ label: 'Nano',
164
+ cpu: 1,
165
+ memory: 0.5,
166
+ storage: { type: 'EBS' },
167
+ costFactor: 1,
168
+ cpuCreditsPerHour: 3,
169
+ },
170
+ {
171
+ name: 't2.micro',
172
+ label: 'Micro',
173
+ cpu: 1,
174
+ memory: 1,
175
+ storage: { type: 'EBS' },
176
+ costFactor: 1,
177
+ cpuCreditsPerHour: 6,
178
+ },
179
+ {
180
+ name: 't2.small',
181
+ label: 'Small',
182
+ cpu: 1,
183
+ memory: 2,
184
+ storage: { type: 'EBS' },
185
+ costFactor: 1,
186
+ cpuCreditsPerHour: 12,
187
+ },
188
+ ],
189
+ };
190
+
191
+ const t3: IAwsInstanceTypeFamily = {
192
+ type: 't3',
193
+ description:
194
+ 't3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
195
+ instanceTypes: [
196
+ {
197
+ name: 't3.nano',
198
+ label: 'Nano',
199
+ cpu: 2,
200
+ memory: 0.5,
201
+ storage: { type: 'EBS' },
202
+ costFactor: 1,
203
+ cpuCreditsPerHour: 6,
204
+ },
205
+ {
206
+ name: 't3.micro',
207
+ label: 'Micro',
208
+ cpu: 2,
209
+ memory: 1,
210
+ storage: { type: 'EBS' },
211
+ costFactor: 1,
212
+ cpuCreditsPerHour: 12,
213
+ },
214
+ {
215
+ name: 't3.small',
216
+ label: 'Small',
217
+ cpu: 2,
218
+ memory: 2,
219
+ storage: { type: 'EBS' },
220
+ costFactor: 1,
221
+ cpuCreditsPerHour: 24,
222
+ },
223
+ ],
224
+ };
225
+
226
+ const r5: IAwsInstanceTypeFamily = {
227
+ type: 'r5',
228
+ description:
229
+ 'r5 instances are optimized for memory-intensive applications and have the lowest cost per GiB of RAM among Amazon EC2 instance types.',
230
+ instanceTypes: [
231
+ {
232
+ name: 'r5.large',
233
+ label: 'Large',
234
+ cpu: 2,
235
+ memory: 16,
236
+ storage: { type: 'EBS' },
237
+ costFactor: 1,
238
+ },
239
+ {
240
+ name: 'r5.xlarge',
241
+ label: 'XLarge',
242
+ cpu: 4,
243
+ memory: 32,
244
+ storage: { type: 'EBS' },
245
+ costFactor: 2,
246
+ },
247
+ {
248
+ name: 'r5.2xlarge',
249
+ label: '2XLarge',
250
+ cpu: 8,
251
+ memory: 64,
252
+ storage: { type: 'EBS' },
253
+ costFactor: 2,
254
+ },
255
+ {
256
+ name: 'r5.4xlarge',
257
+ label: '4XLarge',
258
+ cpu: 16,
259
+ memory: 128,
260
+ storage: { type: 'EBS' },
261
+ costFactor: 3,
262
+ },
263
+ ],
264
+ };
265
+
266
+ export const defaultCategories: IAwsInstanceTypeCategory[] = [
267
+ {
268
+ type: 'general',
269
+ label: 'General Purpose',
270
+ families: [m5, t2gp, t3gp],
271
+ icon: 'hdd',
272
+ showCpuCredits: true,
273
+ descriptionListOverride: [
274
+ m5.description,
275
+ 't2/t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
276
+ ],
277
+ },
278
+ {
279
+ type: 'memory',
280
+ label: 'High Memory',
281
+ families: [r5],
282
+ icon: 'hdd',
283
+ },
284
+ {
285
+ type: 'micro',
286
+ label: 'Micro Utility',
287
+ families: [t2, t3],
288
+ icon: 'hdd',
289
+ showCpuCredits: true,
290
+ descriptionListOverride: [
291
+ 't2/t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).',
292
+ ],
293
+ },
294
+ {
295
+ type: 'custom',
296
+ label: 'Custom Type',
297
+ families: [],
298
+ icon: 'asterisk',
299
+ },
300
+ ];
301
+
302
+ const excludeCategories = AWSProviderSettings.instanceTypes?.exclude?.categories ?? [];
303
+ const excludeFamilies = AWSProviderSettings.instanceTypes?.exclude?.families ?? [];
304
+
305
+ export const categories = defaultCategories
306
+ .filter(({ type }) => !excludeCategories.includes(type))
307
+ .map((category) =>
308
+ Object.assign({}, category, {
309
+ families: category.families.filter(({ type }) => !excludeFamilies.includes(type)),
310
+ }),
311
+ );
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+
3
+ export interface ICostFactorProps {
4
+ min: number;
5
+ max?: number;
6
+ }
7
+
8
+ export const CostFactor = ({ min, max }: ICostFactorProps) => {
9
+ const MAX_DOLLARS = 4;
10
+ const minDollars = (
11
+ <>
12
+ <span className="cost">{'$'.repeat(min)}</span>
13
+ {'$'.repeat(MAX_DOLLARS - min)}
14
+ </>
15
+ );
16
+ const maxDollars = (
17
+ <>
18
+ <span className="cost">{'$'.repeat(Math.min(MAX_DOLLARS, max))}</span>
19
+ {'$'.repeat(MAX_DOLLARS - Math.min(MAX_DOLLARS, max))}
20
+ </>
21
+ );
22
+
23
+ return (
24
+ <span className={'cost-factor'}>
25
+ {minDollars}
26
+ {max ? ` - ${maxDollars}` : ''}
27
+ </span>
28
+ );
29
+ };
@@ -1,5 +1,6 @@
1
- import React from 'react';
2
1
  import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+
3
4
  import { mockInstance } from '@spinnaker/mocks';
4
5
 
5
6
  import { InstanceInformation } from './InstanceInformation';