@spinnaker/ecs 2026.2.2 → 2026.3.0
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/dist/ecs.module.d.ts +3 -1
- package/dist/ecsCluster/ecsCluster.read.service.d.ts +2 -3
- package/dist/iamRoles/iamRole.read.service.d.ts +1 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/details/EcsInstanceDetails.d.ts +50 -0
- package/dist/loadBalancer/loadBalancer.transformer.d.ts +1 -5
- package/dist/loadBalancer/targetGroup.states.d.ts +2 -1
- package/dist/metricAlarm/metricAlarm.read.service.d.ts +1 -2
- package/dist/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.d.ts +1 -0
- package/dist/pipeline/stages/common/EcsServerGroupStepLabel.d.ts +7 -0
- package/dist/pipeline/stages/common/EcsStageConfigs.d.ts +11 -0
- package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.d.ts +5 -0
- package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +1 -2
- package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +1 -2
- package/dist/placementStrategy/placementStrategy.service.d.ts +0 -1
- package/dist/secrets/secret.read.service.d.ts +1 -2
- package/dist/securityGroup/details/EcsSecurityGroupDetails.d.ts +45 -0
- package/dist/securityGroup/securityGroup.reader.d.ts +0 -1
- package/dist/securityGroup/securityGroup.transformer.d.ts +3 -2
- package/dist/serverGroup/configure/dockerImage.util.d.ts +3 -0
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +111 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +13 -63
- package/dist/serverGroup/configure/wizard/EcsCloneServerGroupModal.d.ts +64 -0
- package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +29 -4
- package/dist/serverGroup/configure/wizard/container/Container.d.ts +3 -3
- package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +3 -3
- package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/BasicSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/ContainerSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/HorizontalScalingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/LoggingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/NetworkingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/TaskDefinitionSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/common.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/pages/validation.d.ts +22 -0
- package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +5 -3
- package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +3 -3
- package/dist/serverGroup/details/EcsServerGroupActions.d.ts +6 -0
- package/dist/serverGroup/details/ecsServerGroupDetailsGetter.d.ts +3 -0
- package/dist/serverGroup/details/resize/EcsResizeServerGroupModal.d.ts +43 -0
- package/dist/serverGroup/details/resize/index.d.ts +1 -0
- package/dist/serverGroup/details/rollback/EcsRollbackServerGroupModal.d.ts +46 -0
- package/dist/serverGroup/details/rollback/index.d.ts +1 -0
- package/dist/serverGroup/details/sections/EcsServerGroupDetailsSections.d.ts +9 -0
- package/dist/serverGroup/details/sections/EcsServerGroupEventsSection.d.ts +3 -0
- package/dist/serverGroup/details/sections/EcsServerGroupInformationSection.d.ts +3 -0
- package/dist/serverGroup/events/EcsServerGroupEventsModal.d.ts +22 -0
- package/dist/serverGroup/events/EventsLink.d.ts +2 -0
- package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +1 -1
- package/dist/serverGroup/serverGroup.transformer.d.ts +1 -2
- package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +1 -1
- package/package.json +3 -9
- package/src/ecs.module.spec.ts +86 -0
- package/src/ecs.module.ts +68 -84
- package/src/ecsCluster/ecsCluster.read.service.ts +3 -9
- package/src/iamRoles/iamRole.read.service.ts +1 -7
- package/src/index.ts +6 -0
- package/src/instance/details/EcsInstanceDetails.spec.tsx +426 -0
- package/src/instance/details/EcsInstanceDetails.tsx +474 -0
- package/src/loadBalancer/details/loadBalancerDetails.tsx +1 -1
- package/src/loadBalancer/details/targetGroupDetails.tsx +1 -1
- package/src/loadBalancer/loadBalancer.transformer.ts +2 -7
- package/src/loadBalancer/targetGroup.states.ts +55 -53
- package/src/metricAlarm/metricAlarm.read.service.ts +1 -7
- package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +22 -94
- package/src/pipeline/stages/common/EcsServerGroupStepLabel.tsx +16 -0
- package/src/pipeline/stages/common/EcsStageConfigs.tsx +587 -0
- package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +29 -65
- package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +27 -70
- package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +21 -84
- package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +22 -73
- package/src/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.tsx +40 -0
- package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +12 -24
- package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +30 -128
- package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +24 -78
- package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +19 -73
- package/src/placementStrategy/placementStrategy.service.ts +0 -6
- package/src/secrets/secret.read.service.ts +1 -7
- package/src/securityGroup/details/EcsSecurityGroupDetails.spec.tsx +245 -0
- package/src/securityGroup/details/EcsSecurityGroupDetails.tsx +285 -0
- package/src/securityGroup/securityGroup.reader.ts +0 -5
- package/src/securityGroup/securityGroup.transformer.js +5 -13
- package/src/serverGroup/configure/dockerImage.util.ts +29 -0
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +215 -278
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.ts +83 -0
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +16 -633
- package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.spec.tsx +2078 -0
- package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.tsx +712 -0
- package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +98 -49
- package/src/serverGroup/configure/wizard/container/Container.spec.tsx +20 -8
- package/src/serverGroup/configure/wizard/container/Container.tsx +53 -24
- package/src/serverGroup/configure/wizard/networking/Networking.tsx +60 -38
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +290 -0
- package/src/serverGroup/configure/wizard/pages/BasicSettings.tsx +101 -0
- package/src/serverGroup/configure/wizard/pages/ContainerSettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/HorizontalScalingSettings.tsx +137 -0
- package/src/serverGroup/configure/wizard/pages/LoggingSettings.tsx +60 -0
- package/src/serverGroup/configure/wizard/pages/NetworkingSettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/TaskDefinitionSettings.tsx +59 -0
- package/src/serverGroup/configure/wizard/pages/common.ts +10 -0
- package/src/serverGroup/configure/wizard/pages/validation.tsx +190 -0
- package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +83 -34
- package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.spec.tsx +21 -8
- package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +63 -33
- package/src/serverGroup/details/EcsServerGroupActions.spec.tsx +244 -0
- package/src/serverGroup/details/EcsServerGroupActions.tsx +152 -0
- package/src/serverGroup/details/ecsServerGroupDetailsGetter.spec.ts +110 -0
- package/src/serverGroup/details/ecsServerGroupDetailsGetter.ts +73 -0
- package/src/serverGroup/details/resize/EcsResizeServerGroupModal.spec.tsx +130 -0
- package/src/serverGroup/details/resize/EcsResizeServerGroupModal.tsx +263 -0
- package/src/serverGroup/details/resize/index.ts +1 -0
- package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.spec.tsx +173 -0
- package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.tsx +285 -0
- package/src/serverGroup/details/rollback/index.ts +1 -0
- package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.spec.tsx +130 -0
- package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.tsx +172 -0
- package/src/serverGroup/details/sections/EcsServerGroupEventsSection.tsx +14 -0
- package/src/serverGroup/details/sections/EcsServerGroupInformationSection.tsx +25 -0
- package/src/serverGroup/events/EcsServerGroupEventsModal.spec.tsx +109 -0
- package/src/serverGroup/events/EcsServerGroupEventsModal.tsx +112 -0
- package/src/serverGroup/events/EventsLink.tsx +18 -0
- package/src/serverGroup/events/serverGroupEventsReader.service.spec.ts +41 -0
- package/src/serverGroup/events/serverGroupEventsReader.service.ts +2 -8
- package/src/serverGroup/serverGroup.transformer.spec.ts +10 -24
- package/src/serverGroup/serverGroup.transformer.ts +1 -5
- package/src/serviceDiscovery/serviceDiscovery.read.service.ts +1 -1
- package/dist/common/common.module.d.ts +0 -1
- package/dist/common/footer.component.d.ts +0 -1
- package/dist/instance/details/instance.details.controller.d.ts +0 -2
- package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
- package/dist/securityGroup/securityGroup.module.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +0 -1
- package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +0 -1
- package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.module.d.ts +0 -1
- package/dist/serverGroup/events/events.component.d.ts +0 -3
- package/dist/serverGroup/events/events.controller.d.ts +0 -19
- package/dist/serverGroup/serverGroup.module.d.ts +0 -1
- package/src/common/common.module.ts +0 -6
- package/src/common/footer.component.ts +0 -29
- package/src/instance/details/instance.details.controller.js +0 -356
- package/src/instance/details/instanceDetails.html +0 -204
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +0 -101
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +0 -1
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableCluster/disableClusterStage.html +0 -26
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +0 -36
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +0 -9
- package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +0 -87
- package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +0 -1
- package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +0 -35
- package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -34
- package/src/securityGroup/details/securityGroupDetail.controller.js +0 -147
- package/src/securityGroup/details/securityGroupDetail.html +0 -104
- package/src/securityGroup/securityGroup.module.ts +0 -12
- package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +0 -259
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +0 -194
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +0 -17
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -10
- package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +0 -11
- package/src/serverGroup/configure/wizard/container/container.html +0 -9
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +0 -118
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +0 -20
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +0 -13
- package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +0 -41
- package/src/serverGroup/configure/wizard/location/basicSettings.html +0 -137
- package/src/serverGroup/configure/wizard/logging/logging.component.html +0 -29
- package/src/serverGroup/configure/wizard/logging/logging.component.ts +0 -12
- package/src/serverGroup/configure/wizard/logging/logging.html +0 -7
- package/src/serverGroup/configure/wizard/networking/networking.html +0 -9
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -55
- package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +0 -11
- package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +0 -51
- package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +0 -9
- package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +0 -10
- package/src/serverGroup/details/resize/resizeCapacity.component.html +0 -94
- package/src/serverGroup/details/resize/resizeCapacity.component.ts +0 -14
- package/src/serverGroup/details/resize/resizeServerGroup.controller.js +0 -85
- package/src/serverGroup/details/resize/resizeServerGroup.html +0 -28
- package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +0 -97
- package/src/serverGroup/details/rollback/rollbackServerGroup.html +0 -67
- package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +0 -366
- package/src/serverGroup/details/serverGroupDetails.html +0 -216
- package/src/serverGroup/details/serverGroupDetails.module.ts +0 -5
- package/src/serverGroup/events/events.component.ts +0 -35
- package/src/serverGroup/events/events.controller.ts +0 -45
- package/src/serverGroup/events/events.html +0 -36
- package/src/serverGroup/serverGroup.module.ts +0 -6
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { HelpField } from '@spinnaker/core';
|
|
4
|
+
|
|
5
|
+
import { EcsCapacityProvider } from '../capacityProvider/CapacityProvider';
|
|
6
|
+
import type { IEcsWizardPageProps } from './common';
|
|
7
|
+
|
|
8
|
+
export const HorizontalScalingSettings = ({ command, configureCommand, onFieldChange }: IEcsWizardPageProps) => {
|
|
9
|
+
const useCapacityProviders =
|
|
10
|
+
command.computeOption === 'capacityProviders' ||
|
|
11
|
+
(!command.computeOption && (command.capacityProviderStrategy || []).length > 0);
|
|
12
|
+
const capacity = command.capacity || {};
|
|
13
|
+
const updateCapacity = (field: string, value: number) => onFieldChange('capacity', { ...capacity, [field]: value });
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="container-fluid form-horizontal" data-test-id="EcsServerGroupWizard.horizontalScaling">
|
|
17
|
+
<div className="form-group">
|
|
18
|
+
<div className="col-md-4 sm-label-right">
|
|
19
|
+
<b>Compute options</b> <HelpField id="ecs.computeOptions" />
|
|
20
|
+
</div>
|
|
21
|
+
<div className="col-md-2 radio">
|
|
22
|
+
<label>
|
|
23
|
+
<input
|
|
24
|
+
checked={!useCapacityProviders}
|
|
25
|
+
data-test-id="ServerGroup.computeOptionsLaunchType"
|
|
26
|
+
id="computeOptionsLaunchType"
|
|
27
|
+
onChange={() => {
|
|
28
|
+
onFieldChange('computeOption', 'launchType');
|
|
29
|
+
onFieldChange('capacityProviderStrategy', []);
|
|
30
|
+
}}
|
|
31
|
+
type="radio"
|
|
32
|
+
/>{' '}
|
|
33
|
+
Launch type
|
|
34
|
+
</label>
|
|
35
|
+
</div>
|
|
36
|
+
<div className="col-md-3 radio">
|
|
37
|
+
<label>
|
|
38
|
+
<input
|
|
39
|
+
checked={useCapacityProviders}
|
|
40
|
+
data-test-id="ServerGroup.computeOptionsCapacityProviders"
|
|
41
|
+
id="computeOptionsCapacityProviders"
|
|
42
|
+
onChange={() => {
|
|
43
|
+
onFieldChange('computeOption', 'capacityProviders');
|
|
44
|
+
onFieldChange('launchType', '');
|
|
45
|
+
}}
|
|
46
|
+
type="radio"
|
|
47
|
+
/>{' '}
|
|
48
|
+
Capacity Providers
|
|
49
|
+
</label>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
{useCapacityProviders ? (
|
|
54
|
+
<div className="form-group">
|
|
55
|
+
<EcsCapacityProvider command={command} configureCommand={configureCommand} onFieldChange={onFieldChange} />
|
|
56
|
+
</div>
|
|
57
|
+
) : (
|
|
58
|
+
<div className="form-group">
|
|
59
|
+
<div className="col-md-5 sm-label-right">
|
|
60
|
+
Launch Type <HelpField id="ecs.launchtype" />
|
|
61
|
+
</div>
|
|
62
|
+
<div className="col-md-3">
|
|
63
|
+
<select
|
|
64
|
+
aria-label="Launch type"
|
|
65
|
+
className="form-control input-sm"
|
|
66
|
+
data-test-id="ServerGroup.launchType"
|
|
67
|
+
onChange={(event) => onFieldChange('launchType', event.target.value)}
|
|
68
|
+
value={command.launchType || ''}
|
|
69
|
+
>
|
|
70
|
+
<option value="">Select...</option>
|
|
71
|
+
{(command.backingData.launchTypes || []).map((launchType) => (
|
|
72
|
+
<option key={launchType} value={launchType}>
|
|
73
|
+
{launchType}
|
|
74
|
+
</option>
|
|
75
|
+
))}
|
|
76
|
+
</select>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
|
|
81
|
+
<hr />
|
|
82
|
+
{[
|
|
83
|
+
['desired', 'Desired capacity', 'ecs.capacity.desired'],
|
|
84
|
+
['min', 'Minimum', 'ecs.capacity.minimum'],
|
|
85
|
+
['max', 'Maximum', 'ecs.capacity.maximum'],
|
|
86
|
+
].map(([field, label, help]) => (
|
|
87
|
+
<div className="form-group" key={field}>
|
|
88
|
+
<div className="col-md-5 sm-label-right">
|
|
89
|
+
{label} <HelpField id={help} />
|
|
90
|
+
</div>
|
|
91
|
+
<div className="col-md-2">
|
|
92
|
+
<input
|
|
93
|
+
aria-label={`${label === 'Minimum' || label === 'Maximum' ? `${label} capacity` : label}`}
|
|
94
|
+
className="form-control input-sm no-spel"
|
|
95
|
+
data-test-id={`ServerGroup.capacity.${field}`}
|
|
96
|
+
onChange={(event) => updateCapacity(field, event.target.valueAsNumber)}
|
|
97
|
+
type="number"
|
|
98
|
+
value={capacity[field] ?? ''}
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
))}
|
|
103
|
+
|
|
104
|
+
<div className="form-group">
|
|
105
|
+
<div className="col-md-12 checkbox">
|
|
106
|
+
<label>
|
|
107
|
+
<input
|
|
108
|
+
checked={!!command.useSourceCapacity}
|
|
109
|
+
data-test-id="ServerGroup.useSourceCapacity"
|
|
110
|
+
onChange={(event) => {
|
|
111
|
+
onFieldChange('useSourceCapacity', event.target.checked);
|
|
112
|
+
onFieldChange('preferSourceCapacity', event.target.checked);
|
|
113
|
+
}}
|
|
114
|
+
type="checkbox"
|
|
115
|
+
/>{' '}
|
|
116
|
+
<b>If available, use the previous server group's capacity</b>
|
|
117
|
+
</label>{' '}
|
|
118
|
+
<HelpField id="ecs.capacity.overwrite" />
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div className="form-group">
|
|
122
|
+
<div className="col-md-12 checkbox">
|
|
123
|
+
<label>
|
|
124
|
+
<input
|
|
125
|
+
checked={!!command.copySourceScalingPoliciesAndActions}
|
|
126
|
+
data-test-id="ServerGroup.copySourceScalingPoliciesAndActions"
|
|
127
|
+
onChange={(event) => onFieldChange('copySourceScalingPoliciesAndActions', event.target.checked)}
|
|
128
|
+
type="checkbox"
|
|
129
|
+
/>{' '}
|
|
130
|
+
<b>If available, copy the previous server group's autoscaling policies</b>
|
|
131
|
+
</label>{' '}
|
|
132
|
+
<HelpField id="ecs.capacity.copySourceScalingPoliciesAndActions" />
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { HelpField, MapEditor } from '@spinnaker/core';
|
|
4
|
+
|
|
5
|
+
import type { IEcsWizardPageProps } from './common';
|
|
6
|
+
|
|
7
|
+
const logDrivers = [
|
|
8
|
+
'None',
|
|
9
|
+
'awslogs',
|
|
10
|
+
'fluentd',
|
|
11
|
+
'gelf',
|
|
12
|
+
'journald',
|
|
13
|
+
'json-file',
|
|
14
|
+
'logentries',
|
|
15
|
+
'splunk',
|
|
16
|
+
'sumologic',
|
|
17
|
+
'syslog',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
export const LoggingSettings = ({ command, onFieldChange }: IEcsWizardPageProps) => (
|
|
21
|
+
<div className="container-fluid form-horizontal" data-test-id="EcsServerGroupWizard.logging">
|
|
22
|
+
<div className="form-group">
|
|
23
|
+
<div className="col-md-5 sm-label-right">
|
|
24
|
+
<b>Log driver (Optional)</b> <HelpField id="ecs.logDriver" />
|
|
25
|
+
</div>
|
|
26
|
+
<div className="col-md-7">
|
|
27
|
+
<select
|
|
28
|
+
aria-label="Log driver"
|
|
29
|
+
className="form-control input-sm"
|
|
30
|
+
data-test-id="Logging.logDriver"
|
|
31
|
+
onChange={(event) => onFieldChange('logDriver', event.target.value)}
|
|
32
|
+
value={command.logDriver || ''}
|
|
33
|
+
>
|
|
34
|
+
<option value="">Select...</option>
|
|
35
|
+
{logDrivers.map((driver) => (
|
|
36
|
+
<option key={driver} value={driver}>
|
|
37
|
+
{driver}
|
|
38
|
+
</option>
|
|
39
|
+
))}
|
|
40
|
+
</select>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
{command.logDriver && command.logDriver !== 'None' ? (
|
|
44
|
+
<div className="form-group">
|
|
45
|
+
<div className="sm-label-left">
|
|
46
|
+
<b>Logging options (optional)</b> <HelpField id="ecs.logOptions" />
|
|
47
|
+
</div>
|
|
48
|
+
<MapEditor
|
|
49
|
+
allowEmpty={true}
|
|
50
|
+
keyLabel="Logging option"
|
|
51
|
+
model={command.logOptions || {}}
|
|
52
|
+
onChange={(logOptions) => onFieldChange('logOptions', logOptions)}
|
|
53
|
+
valueLabel="Logging option value"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
) : (
|
|
57
|
+
<div className="form-group">Logging options are not available for your log driver selection.</div>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IEcsWizardPageProps } from './common';
|
|
4
|
+
import { EcsNetworking } from '../networking/Networking';
|
|
5
|
+
|
|
6
|
+
export const NetworkingSettings = ({ command, configureCommand, onFieldChange }: IEcsWizardPageProps) => (
|
|
7
|
+
<div data-test-id="EcsServerGroupWizard.networking">
|
|
8
|
+
<EcsNetworking command={command} configureCommand={configureCommand} onFieldChange={onFieldChange} />
|
|
9
|
+
</div>
|
|
10
|
+
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IEcsWizardPageProps } from './common';
|
|
4
|
+
import { ServiceDiscovery } from '../serviceDiscovery/ServiceDiscovery';
|
|
5
|
+
|
|
6
|
+
export const ServiceDiscoverySettings = ({ command, configureCommand, onFieldChange }: IEcsWizardPageProps) => (
|
|
7
|
+
<div data-test-id="EcsServerGroupWizard.serviceDiscovery">
|
|
8
|
+
<ServiceDiscovery command={command} configureCommand={configureCommand} onFieldChange={onFieldChange} />
|
|
9
|
+
</div>
|
|
10
|
+
);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { HelpField } from '@spinnaker/core';
|
|
4
|
+
|
|
5
|
+
import type { IEcsWizardPageProps } from './common';
|
|
6
|
+
import { TaskDefinition } from '../taskDefinition/TaskDefinition';
|
|
7
|
+
|
|
8
|
+
export const TaskDefinitionSettings = ({ command, configureCommand, onFieldChange }: IEcsWizardPageProps) => (
|
|
9
|
+
<div className="clearfix" data-test-id="EcsServerGroupWizard.taskDefinition">
|
|
10
|
+
<div className="row">
|
|
11
|
+
<div className="col-md-12">
|
|
12
|
+
<div className="container-fluid form-horizontal">
|
|
13
|
+
<div className="form-group">
|
|
14
|
+
<div className="col-md-4 sm-label-right">
|
|
15
|
+
<b>Task Definition source</b> <HelpField id="ecs.taskDefinition" />
|
|
16
|
+
</div>
|
|
17
|
+
<div className="col-md-2 radio">
|
|
18
|
+
<label>
|
|
19
|
+
<input
|
|
20
|
+
checked={!command.useTaskDefinitionArtifact}
|
|
21
|
+
data-test-id="ServerGroup.useInputs"
|
|
22
|
+
id="taskDefinitionSourceInputs"
|
|
23
|
+
onChange={() => onFieldChange('useTaskDefinitionArtifact', false)}
|
|
24
|
+
type="radio"
|
|
25
|
+
/>{' '}
|
|
26
|
+
Inputs
|
|
27
|
+
</label>
|
|
28
|
+
</div>
|
|
29
|
+
<div className="col-md-2 radio">
|
|
30
|
+
<label>
|
|
31
|
+
<input
|
|
32
|
+
checked={command.useTaskDefinitionArtifact}
|
|
33
|
+
data-test-id="ServerGroup.useArtifacts"
|
|
34
|
+
disabled={command.viewState.mode === 'create'}
|
|
35
|
+
id="taskDefinitionSourceArtifact"
|
|
36
|
+
onChange={() => onFieldChange('useTaskDefinitionArtifact', true)}
|
|
37
|
+
type="radio"
|
|
38
|
+
/>{' '}
|
|
39
|
+
Artifact
|
|
40
|
+
</label>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
{command.viewState.mode === 'create' && (
|
|
44
|
+
<div className="color-text-caption">
|
|
45
|
+
<hr />
|
|
46
|
+
<em>Artifacts not supported outside of pipelines.</em>
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
{command.useTaskDefinitionArtifact && (
|
|
52
|
+
<div className="col-md-12">
|
|
53
|
+
<hr />
|
|
54
|
+
<TaskDefinition command={command} configureCommand={configureCommand} onFieldChange={onFieldChange} />
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Application } from '@spinnaker/core';
|
|
2
|
+
|
|
3
|
+
import type { IEcsServerGroupCommand } from '../../serverGroupConfiguration.service';
|
|
4
|
+
|
|
5
|
+
export interface IEcsWizardPageProps {
|
|
6
|
+
application: Application;
|
|
7
|
+
command: IEcsServerGroupCommand;
|
|
8
|
+
configureCommand: (query?: string) => Promise<void>;
|
|
9
|
+
onFieldChange: (field: string, value: any) => void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IWizardPageComponent } from '@spinnaker/core';
|
|
4
|
+
|
|
5
|
+
import type { IEcsServerGroupCommand } from '../../serverGroupConfiguration.service';
|
|
6
|
+
|
|
7
|
+
type ValidationErrors = { [key: string]: any };
|
|
8
|
+
type Validator = (values: IEcsServerGroupCommand) => ValidationErrors;
|
|
9
|
+
|
|
10
|
+
const required = (value: any): boolean => value !== undefined && value !== null && value !== '';
|
|
11
|
+
const validInteger = (value: any): boolean => Number.isFinite(value) && Number.isInteger(value) && value >= 0;
|
|
12
|
+
const usableCapacityProviderStrategyItem = (item: any): boolean =>
|
|
13
|
+
required(item?.capacityProvider) && validInteger(item?.base) && validInteger(item?.weight);
|
|
14
|
+
const hasRowErrors = (errors: ValidationErrors[]): boolean => errors.some((error) => Object.keys(error).length > 0);
|
|
15
|
+
const isExpressionLanguage = (value: string): boolean => value?.includes('${');
|
|
16
|
+
const isStackPattern = (value = ''): boolean =>
|
|
17
|
+
isExpressionLanguage(value) || /^([a-zA-Z_0-9._${}]*(\${.+})*)*$/.test(value);
|
|
18
|
+
const isDetailPattern = (value = ''): boolean =>
|
|
19
|
+
isExpressionLanguage(value) || /^([a-zA-Z_0-9._${}-]*(\${.+})*)*$/.test(value);
|
|
20
|
+
|
|
21
|
+
const validateTargetGroupMappings = (values: IEcsServerGroupCommand): ValidationErrors => {
|
|
22
|
+
const targetGroupMappings = (values.targetGroupMappings || []).map((mapping) => {
|
|
23
|
+
const errors: ValidationErrors = {};
|
|
24
|
+
if (values.useTaskDefinitionArtifact && !required(mapping.containerName)) {
|
|
25
|
+
errors.containerName = 'Container name is required.';
|
|
26
|
+
}
|
|
27
|
+
if (!required(mapping.targetGroup)) {
|
|
28
|
+
errors.targetGroup = 'Target group is required.';
|
|
29
|
+
}
|
|
30
|
+
if (!validInteger(mapping.containerPort)) {
|
|
31
|
+
errors.containerPort = 'Container port must be a non-negative integer.';
|
|
32
|
+
}
|
|
33
|
+
return errors;
|
|
34
|
+
});
|
|
35
|
+
return hasRowErrors(targetGroupMappings) ? { targetGroupMappings } : {};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const validateEcsBasicSettings: Validator = (values) => {
|
|
39
|
+
const errors: ValidationErrors = {};
|
|
40
|
+
if (!required(values.credentials)) {
|
|
41
|
+
errors.credentials = 'Account is required.';
|
|
42
|
+
}
|
|
43
|
+
if (!required(values.region)) {
|
|
44
|
+
errors.region = 'Region is required.';
|
|
45
|
+
}
|
|
46
|
+
if (!required(values.ecsClusterName)) {
|
|
47
|
+
errors.ecsClusterName = 'ECS cluster is required.';
|
|
48
|
+
}
|
|
49
|
+
if (!isStackPattern(values.stack)) {
|
|
50
|
+
errors.stack = 'Only dot(.) and underscore(_) special characters are allowed in the Stack field.';
|
|
51
|
+
}
|
|
52
|
+
if (!isDetailPattern(values.freeFormDetails)) {
|
|
53
|
+
errors.freeFormDetails =
|
|
54
|
+
'Only dot(.), underscore(_), and dash(-) special characters are allowed in the Detail field.';
|
|
55
|
+
}
|
|
56
|
+
return errors;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const validateEcsTaskDefinition: Validator = (values) => {
|
|
60
|
+
if (!values.useTaskDefinitionArtifact) {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
const errors: ValidationErrors = validateTargetGroupMappings(values);
|
|
64
|
+
if (!values.taskDefinitionArtifact?.artifact && !values.taskDefinitionArtifact?.artifactId) {
|
|
65
|
+
errors.taskDefinitionArtifact = 'Task definition artifact is required.';
|
|
66
|
+
}
|
|
67
|
+
const containerMappings = (values.containerMappings || []).map((mapping) => {
|
|
68
|
+
const mappingErrors: ValidationErrors = {};
|
|
69
|
+
if (!required(mapping.containerName)) {
|
|
70
|
+
mappingErrors.containerName = 'Container name is required.';
|
|
71
|
+
}
|
|
72
|
+
if (!required(mapping.imageDescription?.imageId)) {
|
|
73
|
+
mappingErrors.imageDescription = 'Container image is required.';
|
|
74
|
+
}
|
|
75
|
+
return mappingErrors;
|
|
76
|
+
});
|
|
77
|
+
if (hasRowErrors(containerMappings)) {
|
|
78
|
+
errors.containerMappings = containerMappings;
|
|
79
|
+
}
|
|
80
|
+
return errors;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const validateEcsContainer: Validator = (values) => {
|
|
84
|
+
if (values.useTaskDefinitionArtifact) {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
const errors: ValidationErrors = validateTargetGroupMappings(values);
|
|
88
|
+
if (!required(values.imageDescription?.imageId)) {
|
|
89
|
+
errors.imageDescription = { imageId: 'Container image is required.' };
|
|
90
|
+
}
|
|
91
|
+
return errors;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const validateEcsServiceDiscovery: Validator = (values) => {
|
|
95
|
+
const serviceDiscoveryAssociations = (values.serviceDiscoveryAssociations || []).map((association) => {
|
|
96
|
+
const errors: ValidationErrors = {};
|
|
97
|
+
if (values.useTaskDefinitionArtifact && !required(association.containerName)) {
|
|
98
|
+
errors.containerName = 'Container name is required.';
|
|
99
|
+
}
|
|
100
|
+
if (!required(association.registry?.id) && !required(association.registry?.displayName)) {
|
|
101
|
+
errors.registry = 'Service registry is required.';
|
|
102
|
+
}
|
|
103
|
+
if (!validInteger(association.containerPort)) {
|
|
104
|
+
errors.containerPort = 'Container port must be a non-negative integer.';
|
|
105
|
+
}
|
|
106
|
+
return errors;
|
|
107
|
+
});
|
|
108
|
+
return hasRowErrors(serviceDiscoveryAssociations) ? { serviceDiscoveryAssociations } : {};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const validateEcsCapacity: Validator = (values) => {
|
|
112
|
+
const capacity = values.capacity || {};
|
|
113
|
+
const useCapacityProviders =
|
|
114
|
+
values.computeOption === 'capacityProviders' ||
|
|
115
|
+
(!values.computeOption && (values.capacityProviderStrategy || []).length > 0);
|
|
116
|
+
const validationErrors: ValidationErrors = {};
|
|
117
|
+
const errors: ValidationErrors = {};
|
|
118
|
+
['min', 'desired', 'max'].forEach((field) => {
|
|
119
|
+
if (!validInteger(capacity[field])) {
|
|
120
|
+
errors[field] = 'Capacity must be a non-negative integer.';
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
if (Object.keys(errors).length === 0) {
|
|
124
|
+
if (capacity.min > capacity.max) {
|
|
125
|
+
errors.min = 'Minimum capacity cannot exceed maximum capacity.';
|
|
126
|
+
}
|
|
127
|
+
if (capacity.desired < capacity.min || capacity.desired > capacity.max) {
|
|
128
|
+
errors.desired = 'Desired capacity must be between minimum and maximum capacity.';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!useCapacityProviders && !required(values.launchType)) {
|
|
132
|
+
validationErrors.launchType = 'Launch type is required.';
|
|
133
|
+
}
|
|
134
|
+
if (useCapacityProviders && values.useDefaultCapacityProviders !== false) {
|
|
135
|
+
const defaultStrategy = values.backingData?.filtered?.defaultCapacityProviderStrategy || [];
|
|
136
|
+
if (!defaultStrategy.length || !defaultStrategy.every(usableCapacityProviderStrategyItem)) {
|
|
137
|
+
validationErrors.capacityProviderStrategy = 'A usable default capacity provider strategy is required.';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (useCapacityProviders && values.useDefaultCapacityProviders === false) {
|
|
141
|
+
const strategy = values.capacityProviderStrategy || [];
|
|
142
|
+
if (!strategy.length) {
|
|
143
|
+
validationErrors.capacityProviderStrategy = 'At least one capacity provider is required.';
|
|
144
|
+
} else {
|
|
145
|
+
const strategyErrors = strategy.map((item) => {
|
|
146
|
+
const itemErrors: ValidationErrors = {};
|
|
147
|
+
if (!required(item.capacityProvider)) {
|
|
148
|
+
itemErrors.capacityProvider = 'Capacity provider is required.';
|
|
149
|
+
}
|
|
150
|
+
if (!validInteger(item.base)) {
|
|
151
|
+
itemErrors.base = 'Base must be a non-negative integer.';
|
|
152
|
+
}
|
|
153
|
+
if (!validInteger(item.weight)) {
|
|
154
|
+
itemErrors.weight = 'Weight must be a non-negative integer.';
|
|
155
|
+
}
|
|
156
|
+
return itemErrors;
|
|
157
|
+
});
|
|
158
|
+
if (hasRowErrors(strategyErrors)) {
|
|
159
|
+
validationErrors.capacityProviderStrategy = strategyErrors;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (Object.keys(errors).length) {
|
|
164
|
+
validationErrors.capacity = errors;
|
|
165
|
+
}
|
|
166
|
+
return validationErrors;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const validateEcsServerGroup: Validator = (values) => ({
|
|
170
|
+
...validateEcsBasicSettings(values),
|
|
171
|
+
...validateEcsTaskDefinition(values),
|
|
172
|
+
...validateEcsContainer(values),
|
|
173
|
+
...validateEcsServiceDiscovery(values),
|
|
174
|
+
...validateEcsCapacity(values),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
interface IEcsWizardPageValidationProps {
|
|
178
|
+
children: React.ReactElement;
|
|
179
|
+
validator: Validator;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export class EcsWizardPageValidation
|
|
183
|
+
extends React.Component<IEcsWizardPageValidationProps>
|
|
184
|
+
implements IWizardPageComponent<IEcsServerGroupCommand> {
|
|
185
|
+
public validate = (values: IEcsServerGroupCommand) => this.props.validator(values);
|
|
186
|
+
|
|
187
|
+
public render() {
|
|
188
|
+
return React.Children.only(this.props.children);
|
|
189
|
+
}
|
|
190
|
+
}
|