@spinnaker/ecs 0.0.0-main-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 (173) hide show
  1. package/CHANGELOG.md +1186 -0
  2. package/LICENSE.txt +203 -0
  3. package/dist/common/common.module.d.ts +1 -0
  4. package/dist/common/footer.component.d.ts +1 -0
  5. package/dist/domain/IEcsLoadBalancer.d.ts +119 -0
  6. package/dist/ecs.help.d.ts +1 -0
  7. package/dist/ecs.module.d.ts +4 -0
  8. package/dist/ecs.settings.d.ts +9 -0
  9. package/dist/ecsCluster/IEcsCapacityProviderDetails.d.ts +10 -0
  10. package/dist/ecsCluster/IEcsCluster.d.ts +5 -0
  11. package/dist/ecsCluster/ecsCluster.read.service.d.ts +7 -0
  12. package/dist/iamRoles/IRole.d.ts +6 -0
  13. package/dist/iamRoles/iamRole.read.service.d.ts +5 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +6010 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/instance/details/instance.details.controller.d.ts +2 -0
  18. package/dist/loadBalancer/EcsLoadBalancerClusterContainer.d.ts +6 -0
  19. package/dist/loadBalancer/TargetGroup.d.ts +11 -0
  20. package/dist/loadBalancer/details/loadBalancerDetails.d.ts +27 -0
  21. package/dist/loadBalancer/details/targetGroupDetails.d.ts +30 -0
  22. package/dist/loadBalancer/listener.d.ts +10 -0
  23. package/dist/loadBalancer/loadBalancer.transformer.d.ts +8 -0
  24. package/dist/loadBalancer/targetGroup.states.d.ts +1 -0
  25. package/dist/metricAlarm/MetricAlarm.d.ts +6 -0
  26. package/dist/metricAlarm/metricAlarm.read.service.d.ts +5 -0
  27. package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +2 -0
  28. package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +2 -0
  29. package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +2 -0
  30. package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +2 -0
  31. package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +2 -0
  32. package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +2 -0
  33. package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +2 -0
  34. package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +2 -0
  35. package/dist/placementStrategy/IPlacementStrategy.d.ts +4 -0
  36. package/dist/placementStrategy/placementStrategy.service.d.ts +11 -0
  37. package/dist/secrets/ISecret.d.ts +5 -0
  38. package/dist/secrets/secret.read.service.d.ts +5 -0
  39. package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +2 -0
  40. package/dist/securityGroup/securityGroup.module.d.ts +1 -0
  41. package/dist/securityGroup/securityGroup.reader.d.ts +5 -0
  42. package/dist/securityGroup/securityGroup.transformer.d.ts +2 -0
  43. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +2 -0
  44. package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +165 -0
  45. package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +2 -0
  46. package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +2 -0
  47. package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +7 -0
  48. package/dist/serverGroup/configure/wizard/container/Container.d.ts +32 -0
  49. package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +2 -0
  50. package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +2 -0
  51. package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +1 -0
  52. package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +28 -0
  53. package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +34 -0
  54. package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +39 -0
  55. package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +1 -0
  56. package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +2 -0
  57. package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +2 -0
  58. package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +2 -0
  59. package/dist/serverGroup/details/serverGroupDetails.module.d.ts +1 -0
  60. package/dist/serverGroup/events/EventsLink.d.ts +4 -0
  61. package/dist/serverGroup/events/events.component.d.ts +3 -0
  62. package/dist/serverGroup/events/events.controller.d.ts +19 -0
  63. package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +10 -0
  64. package/dist/serverGroup/serverGroup.module.d.ts +1 -0
  65. package/dist/serverGroup/serverGroup.transformer.d.ts +11 -0
  66. package/dist/serviceDiscovery/IServiceDiscovery.d.ts +12 -0
  67. package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +4 -0
  68. package/package.json +47 -0
  69. package/src/common/common.module.ts +6 -0
  70. package/src/common/footer.component.ts +29 -0
  71. package/src/domain/IEcsLoadBalancer.ts +129 -0
  72. package/src/ecs.help.ts +91 -0
  73. package/src/ecs.module.ts +116 -0
  74. package/src/ecs.settings.ts +17 -0
  75. package/src/ecsCluster/IEcsCapacityProviderDetails.ts +11 -0
  76. package/src/ecsCluster/IEcsCluster.ts +5 -0
  77. package/src/ecsCluster/ecsCluster.read.service.ts +23 -0
  78. package/src/iamRoles/IRole.ts +6 -0
  79. package/src/iamRoles/iamRole.read.service.ts +14 -0
  80. package/src/index.ts +1 -0
  81. package/src/instance/details/instance.details.controller.js +356 -0
  82. package/src/instance/details/instanceDetails.html +204 -0
  83. package/src/loadBalancer/EcsLoadBalancerClusterContainer.tsx +48 -0
  84. package/src/loadBalancer/TargetGroup.tsx +74 -0
  85. package/src/loadBalancer/details/loadBalancerDetails.tsx +235 -0
  86. package/src/loadBalancer/details/targetGroupDetails.tsx +251 -0
  87. package/src/loadBalancer/listener.tsx +65 -0
  88. package/src/loadBalancer/loadBalancer.transformer.ts +21 -0
  89. package/src/loadBalancer/targetGroup.states.ts +59 -0
  90. package/src/logo/ecs.icon.svg +27 -0
  91. package/src/logo/ecs.logo.less +5 -0
  92. package/src/logo/ecs.logo.svg +27 -0
  93. package/src/metricAlarm/MetricAlarm.ts +6 -0
  94. package/src/metricAlarm/metricAlarm.read.service.ts +14 -0
  95. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +101 -0
  96. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +1 -0
  97. package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +94 -0
  98. package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +9 -0
  99. package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +1 -0
  100. package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +65 -0
  101. package/src/pipeline/stages/disableAsg/disableAsgStage.html +11 -0
  102. package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +1 -0
  103. package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +70 -0
  104. package/src/pipeline/stages/disableCluster/disableClusterStage.html +26 -0
  105. package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +84 -0
  106. package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +73 -0
  107. package/src/pipeline/stages/enableAsg/enableAsgStage.html +11 -0
  108. package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +1 -0
  109. package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +26 -0
  110. package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +36 -0
  111. package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +9 -0
  112. package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +128 -0
  113. package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +87 -0
  114. package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +1 -0
  115. package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +78 -0
  116. package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +35 -0
  117. package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +73 -0
  118. package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +34 -0
  119. package/src/placementStrategy/IPlacementStrategy.ts +4 -0
  120. package/src/placementStrategy/placementStrategy.service.ts +63 -0
  121. package/src/secrets/ISecret.ts +5 -0
  122. package/src/secrets/secret.read.service.ts +14 -0
  123. package/src/securityGroup/details/securityGroupDetail.controller.js +147 -0
  124. package/src/securityGroup/details/securityGroupDetail.html +104 -0
  125. package/src/securityGroup/securityGroup.module.ts +12 -0
  126. package/src/securityGroup/securityGroup.reader.ts +16 -0
  127. package/src/securityGroup/securityGroup.transformer.js +13 -0
  128. package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +281 -0
  129. package/src/serverGroup/configure/serverGroupConfiguration.service.ts +747 -0
  130. package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +259 -0
  131. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +194 -0
  132. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +17 -0
  133. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +10 -0
  134. package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +381 -0
  135. package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +11 -0
  136. package/src/serverGroup/configure/wizard/container/Container.tsx +347 -0
  137. package/src/serverGroup/configure/wizard/container/container.html +9 -0
  138. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +118 -0
  139. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +20 -0
  140. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +13 -0
  141. package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +41 -0
  142. package/src/serverGroup/configure/wizard/location/basicSettings.html +137 -0
  143. package/src/serverGroup/configure/wizard/logging/logging.component.html +29 -0
  144. package/src/serverGroup/configure/wizard/logging/logging.component.ts +12 -0
  145. package/src/serverGroup/configure/wizard/logging/logging.html +7 -0
  146. package/src/serverGroup/configure/wizard/networking/Networking.tsx +261 -0
  147. package/src/serverGroup/configure/wizard/networking/networking.html +9 -0
  148. package/src/serverGroup/configure/wizard/serverGroupWizard.html +55 -0
  149. package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +250 -0
  150. package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +11 -0
  151. package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +460 -0
  152. package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +51 -0
  153. package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +9 -0
  154. package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +10 -0
  155. package/src/serverGroup/details/resize/resizeCapacity.component.html +94 -0
  156. package/src/serverGroup/details/resize/resizeCapacity.component.ts +14 -0
  157. package/src/serverGroup/details/resize/resizeServerGroup.controller.js +85 -0
  158. package/src/serverGroup/details/resize/resizeServerGroup.html +28 -0
  159. package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +97 -0
  160. package/src/serverGroup/details/rollback/rollbackServerGroup.html +67 -0
  161. package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +366 -0
  162. package/src/serverGroup/details/serverGroupDetails.html +216 -0
  163. package/src/serverGroup/details/serverGroupDetails.module.ts +5 -0
  164. package/src/serverGroup/events/EventsLink.tsx +5 -0
  165. package/src/serverGroup/events/events.component.ts +35 -0
  166. package/src/serverGroup/events/events.controller.ts +45 -0
  167. package/src/serverGroup/events/events.html +36 -0
  168. package/src/serverGroup/events/serverGroupEventsReader.service.ts +27 -0
  169. package/src/serverGroup/serverGroup.module.ts +6 -0
  170. package/src/serverGroup/serverGroup.transformer.spec.ts +184 -0
  171. package/src/serverGroup/serverGroup.transformer.ts +117 -0
  172. package/src/serviceDiscovery/IServiceDiscovery.ts +13 -0
  173. package/src/serviceDiscovery/serviceDiscovery.read.service.ts +8 -0
@@ -0,0 +1,747 @@
1
+ import type { IQService } from 'angular';
2
+ import { module } from 'angular';
3
+ import { chain, clone, extend, find, flatten, has, intersection, keys, some, xor } from 'lodash';
4
+
5
+ import type { IAmazonLoadBalancer } from '@spinnaker/amazon';
6
+ import type {
7
+ IAccountDetails,
8
+ IArtifact,
9
+ IDeploymentStrategy,
10
+ IPipeline,
11
+ IRegion,
12
+ IServerGroupCommand,
13
+ IServerGroupCommandBackingData,
14
+ IServerGroupCommandBackingDataFiltered,
15
+ IServerGroupCommandDirty,
16
+ IServerGroupCommandResult,
17
+ IServerGroupCommandViewState,
18
+ IStage,
19
+ ISubnet,
20
+ LoadBalancerReader,
21
+ SecurityGroupReader,
22
+ ServerGroupCommandRegistry,
23
+ } from '@spinnaker/core';
24
+ import {
25
+ AccountService,
26
+ CACHE_INITIALIZER_SERVICE,
27
+ LOAD_BALANCER_READ_SERVICE,
28
+ NameUtils,
29
+ SECURITY_GROUP_READER,
30
+ SERVER_GROUP_COMMAND_REGISTRY_PROVIDER,
31
+ SubnetReader,
32
+ } from '@spinnaker/core';
33
+ import type { IDockerImage } from '@spinnaker/docker';
34
+ import { DockerImageReader } from '@spinnaker/docker';
35
+
36
+ import type { IEcsCapacityProviderDetails } from '../../ecsCluster/IEcsCapacityProviderDetails';
37
+ import type { IEcsClusterDescriptor } from '../../ecsCluster/IEcsCluster';
38
+ import type { EcsClusterReader } from '../../ecsCluster/ecsCluster.read.service';
39
+ import type { IRoleDescriptor } from '../../iamRoles/IRole';
40
+ import type { IamRoleReader } from '../../iamRoles/iamRole.read.service';
41
+ import type { IMetricAlarmDescriptor } from '../../metricAlarm/MetricAlarm';
42
+ import type { MetricAlarmReader } from '../../metricAlarm/metricAlarm.read.service';
43
+ import type { IPlacementStrategy } from '../../placementStrategy/IPlacementStrategy';
44
+ import type { PlacementStrategyService } from '../../placementStrategy/placementStrategy.service';
45
+ import type { ISecretDescriptor } from '../../secrets/ISecret';
46
+ import type { SecretReader } from '../../secrets/secret.read.service';
47
+ import type { IServiceDiscoveryRegistryDescriptor } from '../../serviceDiscovery/IServiceDiscovery';
48
+ import { ServiceDiscoveryReader } from '../../serviceDiscovery/serviceDiscovery.read.service';
49
+
50
+ export interface IEcsServerGroupCommandDirty extends IServerGroupCommandDirty {
51
+ targetGroups?: string[];
52
+ defaulCapacityProviders?: string[];
53
+ customCapacityProviders?: string[];
54
+ }
55
+
56
+ export interface IEcsServerGroupCommandResult extends IServerGroupCommandResult {
57
+ dirty: IEcsServerGroupCommandDirty;
58
+ }
59
+
60
+ export interface IEcsDockerImage extends IDockerImage {
61
+ imageId: string;
62
+ message: string;
63
+ fromTrigger: boolean;
64
+ fromContext: boolean;
65
+ stageId: string;
66
+ imageLabelOrSha: string;
67
+ }
68
+
69
+ export interface IEcsServerGroupCommandViewState extends IServerGroupCommandViewState {
70
+ contextImages: IEcsDockerImage[];
71
+ pipeline: IPipeline;
72
+ currentStage: IStage;
73
+ dirty: IEcsServerGroupCommandDirty;
74
+ }
75
+
76
+ export interface IEcsServerGroupCommandBackingDataFiltered extends IServerGroupCommandBackingDataFiltered {
77
+ targetGroups: string[];
78
+ iamRoles: string[];
79
+ ecsClusters: string[];
80
+ availableCapacityProviders: string[];
81
+ defaultCapacityProviderStrategy: IEcsCapacityProviderStrategyItem[];
82
+ metricAlarms: IMetricAlarmDescriptor[];
83
+ subnetTypes: ISubnet[];
84
+ securityGroupNames: string[];
85
+ secrets: string[];
86
+ serviceDiscoveryRegistries: IServiceDiscoveryRegistryDescriptor[];
87
+ images: IEcsDockerImage[];
88
+ }
89
+
90
+ export interface IEcsServerGroupCommandBackingData extends IServerGroupCommandBackingData {
91
+ filtered: IEcsServerGroupCommandBackingDataFiltered;
92
+ targetGroups: string[];
93
+ ecsClusters: IEcsClusterDescriptor[];
94
+ capacityProviderDetails: IEcsCapacityProviderDetails[];
95
+ iamRoles: IRoleDescriptor[];
96
+ metricAlarms: IMetricAlarmDescriptor[];
97
+ launchTypes: string[];
98
+ networkModes: string[];
99
+ secrets: ISecretDescriptor[];
100
+ serviceDiscoveryRegistries: IServiceDiscoveryRegistryDescriptor[];
101
+ images: IEcsDockerImage[];
102
+ }
103
+
104
+ export interface IEcsTaskDefinitionArtifact {
105
+ artifact?: IArtifact;
106
+ artifactId?: string;
107
+ }
108
+
109
+ export interface IEcsContainerMapping {
110
+ containerName: string;
111
+ imageDescription: IEcsDockerImage;
112
+ }
113
+
114
+ export interface IEcsTargetGroupMapping {
115
+ containerName: string;
116
+ containerPort: number;
117
+ targetGroup: string;
118
+ }
119
+
120
+ export interface IEcsServiceDiscoveryRegistryAssociation {
121
+ registry: IServiceDiscoveryRegistryDescriptor;
122
+ containerPort: number;
123
+ containerName: string;
124
+ }
125
+
126
+ export interface IEcsCapacityProviderStrategyItem {
127
+ capacityProvider: string;
128
+ base: number;
129
+ weight: number;
130
+ }
131
+
132
+ export interface IEcsServerGroupCommand extends IServerGroupCommand {
133
+ associatePublicIpAddress: boolean;
134
+ backingData: IEcsServerGroupCommandBackingData;
135
+ computeUnits: number;
136
+ reservedMemory: number;
137
+ targetHealthyDeployPercentage: number;
138
+ targetGroup: string;
139
+ containerPort: number;
140
+ placementStrategyName: string;
141
+ placementStrategySequence: IPlacementStrategy[];
142
+ imageDescription: IEcsDockerImage;
143
+ networkMode: string;
144
+ subnetType: string;
145
+ subnetTypes: string[];
146
+ securityGroups: string[];
147
+ securityGroupNames: string[];
148
+ viewState: IEcsServerGroupCommandViewState;
149
+ taskDefinitionArtifact: IEcsTaskDefinitionArtifact;
150
+ taskDefinitionArtifactAccount: string;
151
+ containerMappings: IEcsContainerMapping[];
152
+ loadBalancedContainer: string;
153
+ targetGroupMappings: IEcsTargetGroupMapping[];
154
+ serviceDiscoveryAssociations: IEcsServiceDiscoveryRegistryAssociation[];
155
+ useTaskDefinitionArtifact: boolean;
156
+ evaluateTaskDefinitionArtifactExpressions: boolean;
157
+
158
+ capacityProviderStrategy: IEcsCapacityProviderStrategyItem[];
159
+ useDefaultCapacityProviders: boolean;
160
+ ecsClusterName: string;
161
+ subnetTypeChanged: (command: IEcsServerGroupCommand) => IServerGroupCommandResult;
162
+ placementStrategyNameChanged: (command: IEcsServerGroupCommand) => IServerGroupCommandResult;
163
+ regionIsDeprecated: (command: IEcsServerGroupCommand) => boolean;
164
+
165
+ clusterChanged: (command: IServerGroupCommand) => void;
166
+ }
167
+
168
+ export class EcsServerGroupConfigurationService {
169
+ // private enabledMetrics = ['GroupMinSize', 'GroupMaxSize', 'GroupDesiredCapacity', 'GroupInServiceInstances', 'GroupPendingInstances', 'GroupStandbyInstances', 'GroupTerminatingInstances', 'GroupTotalInstances'];
170
+ // private healthCheckTypes = ['EC2', 'ELB'];
171
+ // private terminationPolicies = ['OldestInstance', 'NewestInstance', 'OldestLaunchConfiguration', 'ClosestToNextInstanceHour', 'Default'];
172
+ private launchTypes = ['EC2', 'FARGATE'];
173
+ private networkModes = ['bridge', 'host', 'awsvpc', 'none', 'default'];
174
+
175
+ public static $inject = [
176
+ '$q',
177
+ 'loadBalancerReader',
178
+ 'serverGroupCommandRegistry',
179
+ 'iamRoleReader',
180
+ 'ecsClusterReader',
181
+ 'metricAlarmReader',
182
+ 'placementStrategyService',
183
+ 'securityGroupReader',
184
+ 'secretReader',
185
+ ];
186
+ constructor(
187
+ private $q: IQService,
188
+ private loadBalancerReader: LoadBalancerReader,
189
+ private serverGroupCommandRegistry: ServerGroupCommandRegistry,
190
+ private iamRoleReader: IamRoleReader,
191
+ private ecsClusterReader: EcsClusterReader,
192
+ private metricAlarmReader: MetricAlarmReader,
193
+ private placementStrategyService: PlacementStrategyService,
194
+ private securityGroupReader: SecurityGroupReader,
195
+ private secretReader: SecretReader,
196
+ ) {}
197
+
198
+ public configureUpdateCommand(command: IEcsServerGroupCommand): void {
199
+ command.backingData = {
200
+ // terminationPolicies: clone(this.terminationPolicies)
201
+ launchTypes: clone(this.launchTypes),
202
+ networkModes: clone(this.networkModes),
203
+ } as IEcsServerGroupCommandBackingData;
204
+ }
205
+
206
+ // TODO (Bruno Carrier): Why do we need to inject an Application into this constructor so that the app works? This is strange, and needs investigating
207
+ public configureCommand(cmd: IEcsServerGroupCommand, imageQuery = ''): PromiseLike<void> {
208
+ this.applyOverrides('beforeConfiguration', cmd);
209
+ cmd.toggleSuspendedProcess = (command: IEcsServerGroupCommand, process: string): void => {
210
+ command.suspendedProcesses = command.suspendedProcesses || [];
211
+ const processIndex = command.suspendedProcesses.indexOf(process);
212
+ if (processIndex === -1) {
213
+ command.suspendedProcesses.push(process);
214
+ } else {
215
+ command.suspendedProcesses.splice(processIndex, 1);
216
+ }
217
+ };
218
+
219
+ cmd.processIsSuspended = (command: IEcsServerGroupCommand, process: string): boolean =>
220
+ command.suspendedProcesses.includes(process);
221
+
222
+ cmd.onStrategyChange = (command: IEcsServerGroupCommand, strategy: IDeploymentStrategy): void => {
223
+ // Any strategy other than None or Custom should force traffic to be enabled
224
+ if (strategy.key !== '' && strategy.key !== 'custom') {
225
+ command.suspendedProcesses = (command.suspendedProcesses || []).filter((p) => p !== 'AddToLoadBalancer');
226
+ }
227
+ };
228
+
229
+ cmd.regionIsDeprecated = (command: IEcsServerGroupCommand): boolean => {
230
+ return (
231
+ has(command, 'backingData.filtered.regions') &&
232
+ command.backingData.filtered.regions.some((region) => region.name === command.region && region.deprecated)
233
+ );
234
+ };
235
+
236
+ const imageQueries = cmd.imageDescription ? [this.grabImageAndTag(cmd.imageDescription.imageId)] : [];
237
+
238
+ if (imageQuery) {
239
+ imageQueries.push(imageQuery);
240
+ }
241
+
242
+ let imagesPromise;
243
+ if (imageQueries.length) {
244
+ imagesPromise = this.$q
245
+ .all(
246
+ imageQueries.map((q) =>
247
+ DockerImageReader.findImages({
248
+ provider: 'dockerRegistry',
249
+ count: 50,
250
+ q: q,
251
+ }),
252
+ ),
253
+ )
254
+ .then((promises) => flatten(promises));
255
+ } else {
256
+ imagesPromise = this.$q.when([]);
257
+ }
258
+
259
+ return this.$q
260
+ .all({
261
+ credentialsKeyedByAccount: AccountService.getCredentialsKeyedByAccount('ecs'),
262
+ loadBalancers: this.loadBalancerReader.listLoadBalancers('ecs'),
263
+ subnets: SubnetReader.listSubnetsByProvider('ecs'),
264
+ iamRoles: this.iamRoleReader.listRoles('ecs'),
265
+ ecsClusters: this.ecsClusterReader.listClusters(),
266
+ capacityProviderDetails: this.ecsClusterReader.describeClusters(cmd.credentials, cmd.region),
267
+ metricAlarms: this.metricAlarmReader.listMetricAlarms(),
268
+ securityGroups: this.securityGroupReader.getAllSecurityGroups(),
269
+ launchTypes: this.$q.when(clone(this.launchTypes)),
270
+ networkModes: this.$q.when(clone(this.networkModes)),
271
+ secrets: this.secretReader.listSecrets(),
272
+ serviceDiscoveryRegistries: ServiceDiscoveryReader.listServiceDiscoveryRegistries(),
273
+ images: imagesPromise,
274
+ })
275
+ .then((backingData: Partial<IEcsServerGroupCommandBackingData>) => {
276
+ backingData.accounts = keys(backingData.credentialsKeyedByAccount);
277
+ backingData.filtered = {} as IEcsServerGroupCommandBackingDataFiltered;
278
+
279
+ if (cmd.viewState.contextImages) {
280
+ backingData.images = backingData.images.concat(cmd.viewState.contextImages);
281
+ }
282
+ cmd.backingData = backingData as IEcsServerGroupCommandBackingData;
283
+ this.configureVpcId(cmd);
284
+ this.configureAvailableIamRoles(cmd);
285
+ this.configureAvailableSubnetTypes(cmd);
286
+ this.configureAvailableSecurityGroups(cmd);
287
+ this.configureAvailableEcsClusters(cmd);
288
+ this.setCapacityProviderDetails(cmd);
289
+ this.configureAvailableSecrets(cmd);
290
+ this.configureAvailableServiceDiscoveryRegistries(cmd);
291
+ this.configureAvailableImages(cmd);
292
+ this.configureAvailableRegions(cmd);
293
+ this.configureLoadBalancerOptions(cmd);
294
+ this.applyOverrides('afterConfiguration', cmd);
295
+ this.attachEventHandlers(cmd);
296
+ });
297
+ }
298
+
299
+ public setCapacityProviderDetails(command: IEcsServerGroupCommand): void {
300
+ this.$q
301
+ .all({
302
+ capacityProviderDetails: this.ecsClusterReader.describeClusters(command.credentials, command.region),
303
+ })
304
+ .then((result: Partial<IEcsServerGroupCommandBackingData>) => {
305
+ command.backingData.capacityProviderDetails = chain(result.capacityProviderDetails)
306
+ .map((cluster) => this.mapCapacityProviderDetails(cluster))
307
+ .value();
308
+ });
309
+
310
+ if (command.ecsClusterName != null && command.ecsClusterName.length > 0) {
311
+ this.configureAvailableCapacityProviders(command);
312
+ } else {
313
+ command.backingData.filtered.availableCapacityProviders = [];
314
+ command.backingData.filtered.defaultCapacityProviderStrategy = [];
315
+ }
316
+ this.checkDirtyCapacityProviders(command);
317
+ }
318
+
319
+ public configureAvailableCapacityProviders(command: IEcsServerGroupCommand): void {
320
+ command.backingData.filtered.availableCapacityProviders = chain(command.backingData.capacityProviderDetails)
321
+ .filter({
322
+ clusterName: command.ecsClusterName,
323
+ })
324
+ .map((availableCPs) => availableCPs.capacityProviders)
325
+ .flattenDeep<string>()
326
+ .value();
327
+
328
+ command.backingData.filtered.defaultCapacityProviderStrategy = chain(command.backingData.capacityProviderDetails)
329
+ .filter({
330
+ clusterName: command.ecsClusterName,
331
+ })
332
+ .map((availableCPs) => availableCPs.defaultCapacityProviderStrategy)
333
+ .flattenDeep<IEcsCapacityProviderStrategyItem>()
334
+ .value();
335
+ }
336
+
337
+ public mapCapacityProviderDetails(describeClusters: IEcsCapacityProviderDetails): IEcsCapacityProviderDetails {
338
+ return {
339
+ capacityProviders: describeClusters.capacityProviders,
340
+ clusterName: describeClusters.clusterName,
341
+ defaultCapacityProviderStrategy: describeClusters.defaultCapacityProviderStrategy,
342
+ };
343
+ }
344
+
345
+ public applyOverrides(phase: string, command: IEcsServerGroupCommand): void {
346
+ this.serverGroupCommandRegistry.getCommandOverrides('ecs').forEach((override: any) => {
347
+ if (override[phase]) {
348
+ override[phase](command);
349
+ }
350
+ });
351
+ }
352
+
353
+ public grabImageAndTag(imageId: string): string {
354
+ return imageId.split('/').pop();
355
+ }
356
+
357
+ public buildImageId(image: IEcsDockerImage): string {
358
+ if (image.fromContext) {
359
+ return `${image.imageLabelOrSha}`;
360
+ } else if (image.fromTrigger && !image.tag) {
361
+ return `${image.registry}/${image.repository} (Tag resolved at runtime)`;
362
+ } else {
363
+ return `${image.registry}/${image.repository}:${image.tag}`;
364
+ }
365
+ }
366
+
367
+ public mapImage(image: IEcsDockerImage): IEcsDockerImage {
368
+ if (image.message !== undefined) {
369
+ return image;
370
+ }
371
+
372
+ return {
373
+ repository: image.repository,
374
+ tag: image.tag,
375
+ imageId: this.buildImageId(image),
376
+ registry: image.registry,
377
+ fromContext: image.fromContext,
378
+ fromTrigger: image.fromTrigger,
379
+ account: image.account,
380
+ imageLabelOrSha: image.imageLabelOrSha,
381
+ stageId: image.stageId,
382
+ message: image.message,
383
+ };
384
+ }
385
+
386
+ public configureAvailableImages(command: IEcsServerGroupCommand): void {
387
+ // No filtering required, but need to decorate with the displayable image ID
388
+ command.backingData.filtered.images = command.backingData.images.map((image) => this.mapImage(image));
389
+ }
390
+
391
+ public configureAvailabilityZones(command: IEcsServerGroupCommand): void {
392
+ command.backingData.filtered.availabilityZones = find<IRegion>(
393
+ command.backingData.credentialsKeyedByAccount[command.credentials].regions,
394
+ { name: command.region },
395
+ ).availabilityZones;
396
+ command.availabilityZones = command.backingData.filtered.availabilityZones;
397
+ }
398
+
399
+ public configureAvailableSecurityGroups(command: IEcsServerGroupCommand): void {
400
+ if (command.subnetType == null && (command.subnetTypes == null || command.subnetTypes.length == 0)) {
401
+ command.backingData.filtered.securityGroups = [];
402
+ return;
403
+ }
404
+
405
+ const vpcId = chain(command.backingData.subnets)
406
+ .filter({
407
+ account: command.credentials,
408
+ region: command.region,
409
+ purpose: command.subnetTypes ? command.subnetTypes[0] : command.subnetType,
410
+ })
411
+ .compact()
412
+ .uniqBy('purpose')
413
+ .map('vpcId')
414
+ .value()[0];
415
+
416
+ if (
417
+ command.backingData.securityGroups[command.credentials] &&
418
+ command.backingData.securityGroups[command.credentials]['ecs'] &&
419
+ command.backingData.securityGroups[command.credentials]['ecs'][command.region]
420
+ ) {
421
+ const allSecurityGroups = command.backingData.securityGroups[command.credentials]['ecs'][command.region];
422
+ command.backingData.filtered.securityGroupNames = chain(allSecurityGroups)
423
+ .filter({ vpcId: vpcId })
424
+ .map('name')
425
+ .value() as string[];
426
+ }
427
+ }
428
+
429
+ public configureAvailableSubnetTypes(command: IEcsServerGroupCommand): void {
430
+ command.backingData.filtered.subnetTypes = chain(command.backingData.subnets)
431
+ .filter({
432
+ account: command.credentials,
433
+ region: command.region,
434
+ })
435
+ .compact()
436
+ .uniqBy('purpose')
437
+ .value()
438
+ .filter(function (e: ISubnet) {
439
+ return e.purpose && e.purpose.length > 0;
440
+ });
441
+ }
442
+
443
+ public configureAvailableEcsClusters(command: IEcsServerGroupCommand): void {
444
+ command.backingData.filtered.ecsClusters = chain(command.backingData.ecsClusters)
445
+ .filter({
446
+ account: command.credentials,
447
+ region: command.region,
448
+ })
449
+ .map('name')
450
+ .value();
451
+ }
452
+
453
+ public configureAvailableSecrets(command: IEcsServerGroupCommand): void {
454
+ command.backingData.filtered.secrets = chain(command.backingData.secrets)
455
+ .filter({
456
+ account: command.credentials,
457
+ region: command.region,
458
+ })
459
+ .map('name')
460
+ .value();
461
+ }
462
+
463
+ public buildServiceRegistryDisplayName(registry: IServiceDiscoveryRegistryDescriptor): string {
464
+ return `${registry.name} (${registry.id})`;
465
+ }
466
+
467
+ public mapServiceRegistry(registry: IServiceDiscoveryRegistryDescriptor): IServiceDiscoveryRegistryDescriptor {
468
+ return {
469
+ account: registry.account,
470
+ region: registry.region,
471
+ name: registry.name,
472
+ id: registry.id,
473
+ arn: registry.arn,
474
+ displayName: this.buildServiceRegistryDisplayName(registry),
475
+ };
476
+ }
477
+
478
+ public configureAvailableServiceDiscoveryRegistries(command: IEcsServerGroupCommand): void {
479
+ command.backingData.filtered.serviceDiscoveryRegistries = chain(command.backingData.serviceDiscoveryRegistries)
480
+ .filter({
481
+ account: command.credentials,
482
+ region: command.region,
483
+ })
484
+ .map((registry) => this.mapServiceRegistry(registry))
485
+ .value();
486
+ }
487
+
488
+ public configureAvailableRegions(command: IEcsServerGroupCommand): void {
489
+ const regionsForAccount: IAccountDetails =
490
+ command.backingData.credentialsKeyedByAccount[command.credentials] || ({ regions: [] } as IAccountDetails);
491
+ command.backingData.filtered.regions = regionsForAccount.regions;
492
+ }
493
+
494
+ public configureAvailableIamRoles(command: IEcsServerGroupCommand): void {
495
+ command.backingData.filtered.iamRoles = chain(command.backingData.iamRoles)
496
+ .filter({ accountName: command.credentials })
497
+ .map('name')
498
+ .value();
499
+ if (command.backingData.filtered.iamRoles.length > 0) {
500
+ command.backingData.filtered.iamRoles.splice(0, 0, 'None (No IAM role)');
501
+ }
502
+ }
503
+
504
+ public configureSubnetPurposes(command: IEcsServerGroupCommand): IServerGroupCommandResult {
505
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
506
+ const filteredData = command.backingData.filtered;
507
+ if (command.region === null) {
508
+ return result;
509
+ }
510
+ filteredData.subnetPurposes = chain(command.backingData.subnets)
511
+ .filter({ account: command.credentials, region: command.region })
512
+ .reject({ target: 'elb' })
513
+ .reject({ purpose: null })
514
+ .uniqBy('purpose')
515
+ .value();
516
+
517
+ if (command.subnetTypes) {
518
+ result.dirty.subnetType = !command.subnetTypes.every((subnetType) =>
519
+ chain(filteredData.subnetPurposes).some({ purpose: subnetType }).value(),
520
+ );
521
+ } else if (!chain(filteredData.subnetPurposes).some({ purpose: command.subnetType }).value()) {
522
+ result.dirty.subnetType = true;
523
+ }
524
+
525
+ if (result.dirty.subnetType) {
526
+ command.subnetTypes = null;
527
+ command.subnetType = null;
528
+ }
529
+
530
+ return result;
531
+ }
532
+
533
+ private getLoadBalancerMap(command: IEcsServerGroupCommand): IAmazonLoadBalancer[] {
534
+ return chain(command.backingData.loadBalancers)
535
+ .map('accounts')
536
+ .flattenDeep()
537
+ .filter({ name: command.credentials })
538
+ .map('regions')
539
+ .flattenDeep()
540
+ .filter({ name: command.region })
541
+ .map<IAmazonLoadBalancer>('loadBalancers')
542
+ .flattenDeep<IAmazonLoadBalancer>()
543
+ .value();
544
+ }
545
+
546
+ public getLoadBalancerNames(command: IEcsServerGroupCommand): string[] {
547
+ const loadBalancers = this.getLoadBalancerMap(command).filter(
548
+ (lb) => (!lb.loadBalancerType || lb.loadBalancerType === 'classic') && lb.vpcId === command.vpcId,
549
+ );
550
+ return loadBalancers.map((lb) => lb.name).sort();
551
+ }
552
+
553
+ public getVpcLoadBalancerNames(command: IEcsServerGroupCommand): string[] {
554
+ const loadBalancersForVpc = this.getLoadBalancerMap(command).filter(
555
+ (lb) => (!lb.loadBalancerType || lb.loadBalancerType === 'classic') && lb.vpcId,
556
+ );
557
+ return loadBalancersForVpc.map((lb) => lb.name).sort();
558
+ }
559
+
560
+ public getTargetGroupNames(command: IEcsServerGroupCommand): string[] {
561
+ const loadBalancersV2 = this.getLoadBalancerMap(command).filter((lb) => lb.loadBalancerType !== 'classic') as any[];
562
+ const allTargetGroups = flatten(loadBalancersV2.map<string[]>((lb) => lb.targetGroups));
563
+ return allTargetGroups.sort();
564
+ }
565
+
566
+ public configureLoadBalancerOptions(command: IEcsServerGroupCommand): IServerGroupCommandResult {
567
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
568
+ const currentLoadBalancers = (command.loadBalancers || []).concat(command.vpcLoadBalancers || []);
569
+ const newLoadBalancers = this.getLoadBalancerNames(command);
570
+ const vpcLoadBalancers = this.getVpcLoadBalancerNames(command);
571
+ const allTargetGroups = this.getTargetGroupNames(command);
572
+ const currentTargetGroups = command.targetGroupMappings.map((tg) => tg.targetGroup);
573
+ if (currentLoadBalancers && command.loadBalancers) {
574
+ const valid = command.vpcId ? newLoadBalancers : newLoadBalancers.concat(vpcLoadBalancers);
575
+ const matched = intersection(valid, currentLoadBalancers);
576
+ const removedLoadBalancers = xor(matched, currentLoadBalancers);
577
+ command.loadBalancers = intersection(newLoadBalancers, matched);
578
+ if (!command.vpcId) {
579
+ command.vpcLoadBalancers = intersection(vpcLoadBalancers, matched);
580
+ } else {
581
+ delete command.vpcLoadBalancers;
582
+ }
583
+ if (removedLoadBalancers.length) {
584
+ result.dirty.loadBalancers = removedLoadBalancers;
585
+ }
586
+ }
587
+
588
+ if (currentTargetGroups) {
589
+ const matched = intersection(allTargetGroups, currentTargetGroups);
590
+ const removedTargetGroups = xor(matched, currentTargetGroups);
591
+ if (removedTargetGroups && removedTargetGroups.length > 0) {
592
+ command.viewState.dirty.targetGroups = removedTargetGroups;
593
+ } else if (command.viewState.dirty && command.viewState.dirty.targetGroups) {
594
+ command.viewState.dirty.targetGroups = [];
595
+ }
596
+ }
597
+
598
+ command.backingData.filtered.loadBalancers = newLoadBalancers;
599
+ command.backingData.filtered.vpcLoadBalancers = vpcLoadBalancers;
600
+ command.backingData.filtered.targetGroups = allTargetGroups;
601
+ return result;
602
+ }
603
+
604
+ public refreshLoadBalancers(command: IEcsServerGroupCommand, skipCommandReconfiguration?: boolean) {
605
+ return this.loadBalancerReader.listLoadBalancers('ecs').then((loadBalancers) => {
606
+ command.backingData.loadBalancers = loadBalancers;
607
+ if (!skipCommandReconfiguration) {
608
+ this.configureLoadBalancerOptions(command);
609
+ }
610
+ });
611
+ }
612
+
613
+ public configureVpcId(command: IEcsServerGroupCommand): IEcsServerGroupCommandResult {
614
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
615
+ if (command.subnetType == null && (command.subnetTypes == null || command.subnetTypes.length == 0)) {
616
+ command.vpcId = null;
617
+ result.dirty.vpcId = true;
618
+ } else if (command.subnetTypes != null && command.subnetTypes.length > 0) {
619
+ command.subnetTypes.forEach(function (subnetType) {
620
+ const subnet = find<ISubnet>(command.backingData.subnets, {
621
+ purpose: subnetType,
622
+ account: command.credentials,
623
+ region: command.region,
624
+ });
625
+ command.vpcId = subnet ? subnet.vpcId : null;
626
+ });
627
+ } else {
628
+ const subnet = find<ISubnet>(command.backingData.subnets, {
629
+ purpose: command.subnetType,
630
+ account: command.credentials,
631
+ region: command.region,
632
+ });
633
+ command.vpcId = subnet ? subnet.vpcId : null;
634
+ }
635
+ return result;
636
+ }
637
+
638
+ public checkDirtyCapacityProviders(command: IEcsServerGroupCommand): void {
639
+ if (command.capacityProviderStrategy) {
640
+ const availableCustomCapacityProviders = command.backingData.filtered.availableCapacityProviders;
641
+ const currentCapacityProviders = command.capacityProviderStrategy.map((cp) => cp.capacityProvider);
642
+ const matchedCustomCapacityProviders = intersection(availableCustomCapacityProviders, currentCapacityProviders);
643
+ const removedCustomCapacityProviders = xor(matchedCustomCapacityProviders, currentCapacityProviders);
644
+
645
+ if (removedCustomCapacityProviders && removedCustomCapacityProviders.length > 0) {
646
+ command.viewState.dirty.customCapacityProviders = removedCustomCapacityProviders;
647
+ } else if (command.viewState.dirty && command.viewState.dirty.customCapacityProviders) {
648
+ command.viewState.dirty.customCapacityProviders = [];
649
+ }
650
+
651
+ if (command.useDefaultCapacityProviders) {
652
+ const availableDefaultCapacityProvider = command.backingData.filtered.defaultCapacityProviderStrategy.map(
653
+ (cp) => cp.capacityProvider,
654
+ );
655
+ const matchedDefaultCapacityProviders = intersection(
656
+ availableDefaultCapacityProvider,
657
+ currentCapacityProviders,
658
+ );
659
+ const removedDefaultCapacityProviders = xor(matchedDefaultCapacityProviders, currentCapacityProviders);
660
+
661
+ if (removedDefaultCapacityProviders && removedDefaultCapacityProviders.length > 0) {
662
+ command.viewState.dirty.defaulCapacityProviders = removedDefaultCapacityProviders;
663
+ }
664
+ }
665
+ }
666
+ }
667
+
668
+ public attachEventHandlers(cmd: IEcsServerGroupCommand): void {
669
+ cmd.subnetChanged = (command: IEcsServerGroupCommand): IServerGroupCommandResult => {
670
+ const result = this.configureVpcId(command);
671
+ extend(result.dirty, this.configureLoadBalancerOptions(command).dirty);
672
+ command.viewState.dirty = command.viewState.dirty || {};
673
+ extend(command.viewState.dirty, result.dirty);
674
+ return result;
675
+ };
676
+
677
+ cmd.regionChanged = (command: IEcsServerGroupCommand): IServerGroupCommandResult => {
678
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
679
+ extend(result.dirty, this.configureSubnetPurposes(command).dirty);
680
+ if (command.region) {
681
+ extend(result.dirty, command.subnetChanged(command).dirty);
682
+ this.configureAvailabilityZones(command);
683
+ this.configureAvailableEcsClusters(command);
684
+ this.configureAvailableSubnetTypes(command);
685
+ this.configureAvailableSecurityGroups(command);
686
+ this.configureAvailableSecrets(command);
687
+ this.configureAvailableServiceDiscoveryRegistries(command);
688
+ this.setCapacityProviderDetails(command);
689
+ }
690
+
691
+ return result;
692
+ };
693
+
694
+ cmd.subnetTypeChanged = (command: IEcsServerGroupCommand): IServerGroupCommandResult => {
695
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
696
+ this.configureAvailableSecurityGroups(command);
697
+ return result;
698
+ };
699
+
700
+ cmd.clusterChanged = (command: IEcsServerGroupCommand): void => {
701
+ command.moniker = NameUtils.getMoniker(command.application, command.stack, command.freeFormDetails);
702
+ };
703
+
704
+ cmd.credentialsChanged = (command: IEcsServerGroupCommand): IServerGroupCommandResult => {
705
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
706
+ const backingData = command.backingData;
707
+ if (command.credentials) {
708
+ this.configureAvailableIamRoles(command);
709
+ this.configureAvailableEcsClusters(command);
710
+ this.configureAvailableSubnetTypes(command);
711
+ this.configureAvailableSecurityGroups(command);
712
+ this.configureAvailableSecrets(command);
713
+ this.configureAvailableServiceDiscoveryRegistries(command);
714
+ this.configureAvailableRegions(command);
715
+ this.setCapacityProviderDetails(command);
716
+
717
+ if (!some(backingData.filtered.regions, { name: command.region })) {
718
+ command.region = null;
719
+ result.dirty.region = true;
720
+ } else {
721
+ extend(result.dirty, command.regionChanged(command).dirty);
722
+ }
723
+ } else {
724
+ command.region = null;
725
+ }
726
+ return result;
727
+ };
728
+
729
+ cmd.placementStrategyNameChanged = (command: IEcsServerGroupCommand): IServerGroupCommandResult => {
730
+ const result: IEcsServerGroupCommandResult = { dirty: {} };
731
+ command.placementStrategySequence = this.placementStrategyService.getPredefinedStrategy(
732
+ command.placementStrategyName,
733
+ );
734
+ return result;
735
+ };
736
+
737
+ this.applyOverrides('attachEventHandlers', cmd);
738
+ }
739
+ }
740
+
741
+ export const ECS_SERVER_GROUP_CONFIGURATION_SERVICE = 'spinnaker.ecs.serverGroup.configure.service';
742
+ module(ECS_SERVER_GROUP_CONFIGURATION_SERVICE, [
743
+ LOAD_BALANCER_READ_SERVICE,
744
+ SECURITY_GROUP_READER,
745
+ CACHE_INITIALIZER_SERVICE,
746
+ SERVER_GROUP_COMMAND_REGISTRY_PROVIDER,
747
+ ]).service('ecsServerGroupConfigurationService', EcsServerGroupConfigurationService);