@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.
Files changed (209) hide show
  1. package/dist/ecs.module.d.ts +3 -1
  2. package/dist/ecsCluster/ecsCluster.read.service.d.ts +2 -3
  3. package/dist/iamRoles/iamRole.read.service.d.ts +1 -2
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/instance/details/EcsInstanceDetails.d.ts +50 -0
  8. package/dist/loadBalancer/loadBalancer.transformer.d.ts +1 -5
  9. package/dist/loadBalancer/targetGroup.states.d.ts +2 -1
  10. package/dist/metricAlarm/metricAlarm.read.service.d.ts +1 -2
  11. package/dist/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.d.ts +1 -0
  12. package/dist/pipeline/stages/common/EcsServerGroupStepLabel.d.ts +7 -0
  13. package/dist/pipeline/stages/common/EcsStageConfigs.d.ts +11 -0
  14. package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +1 -2
  15. package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +1 -2
  16. package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +1 -2
  17. package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +1 -2
  18. package/dist/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.d.ts +5 -0
  19. package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +1 -2
  20. package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +1 -2
  21. package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +1 -2
  22. package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +1 -2
  23. package/dist/placementStrategy/placementStrategy.service.d.ts +0 -1
  24. package/dist/secrets/secret.read.service.d.ts +1 -2
  25. package/dist/securityGroup/details/EcsSecurityGroupDetails.d.ts +45 -0
  26. package/dist/securityGroup/securityGroup.reader.d.ts +0 -1
  27. package/dist/securityGroup/securityGroup.transformer.d.ts +3 -2
  28. package/dist/serverGroup/configure/dockerImage.util.d.ts +3 -0
  29. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +111 -2
  30. package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +13 -63
  31. package/dist/serverGroup/configure/wizard/EcsCloneServerGroupModal.d.ts +64 -0
  32. package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +29 -4
  33. package/dist/serverGroup/configure/wizard/container/Container.d.ts +3 -3
  34. package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +3 -3
  35. package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
  36. package/dist/serverGroup/configure/wizard/pages/BasicSettings.d.ts +3 -0
  37. package/dist/serverGroup/configure/wizard/pages/ContainerSettings.d.ts +3 -0
  38. package/dist/serverGroup/configure/wizard/pages/HorizontalScalingSettings.d.ts +3 -0
  39. package/dist/serverGroup/configure/wizard/pages/LoggingSettings.d.ts +3 -0
  40. package/dist/serverGroup/configure/wizard/pages/NetworkingSettings.d.ts +3 -0
  41. package/dist/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.d.ts +3 -0
  42. package/dist/serverGroup/configure/wizard/pages/TaskDefinitionSettings.d.ts +3 -0
  43. package/dist/serverGroup/configure/wizard/pages/common.d.ts +8 -0
  44. package/dist/serverGroup/configure/wizard/pages/validation.d.ts +22 -0
  45. package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +5 -3
  46. package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +3 -3
  47. package/dist/serverGroup/details/EcsServerGroupActions.d.ts +6 -0
  48. package/dist/serverGroup/details/ecsServerGroupDetailsGetter.d.ts +3 -0
  49. package/dist/serverGroup/details/resize/EcsResizeServerGroupModal.d.ts +43 -0
  50. package/dist/serverGroup/details/resize/index.d.ts +1 -0
  51. package/dist/serverGroup/details/rollback/EcsRollbackServerGroupModal.d.ts +46 -0
  52. package/dist/serverGroup/details/rollback/index.d.ts +1 -0
  53. package/dist/serverGroup/details/sections/EcsServerGroupDetailsSections.d.ts +9 -0
  54. package/dist/serverGroup/details/sections/EcsServerGroupEventsSection.d.ts +3 -0
  55. package/dist/serverGroup/details/sections/EcsServerGroupInformationSection.d.ts +3 -0
  56. package/dist/serverGroup/events/EcsServerGroupEventsModal.d.ts +22 -0
  57. package/dist/serverGroup/events/EventsLink.d.ts +2 -0
  58. package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +1 -1
  59. package/dist/serverGroup/serverGroup.transformer.d.ts +1 -2
  60. package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +1 -1
  61. package/package.json +3 -9
  62. package/src/ecs.module.spec.ts +86 -0
  63. package/src/ecs.module.ts +68 -84
  64. package/src/ecsCluster/ecsCluster.read.service.ts +3 -9
  65. package/src/iamRoles/iamRole.read.service.ts +1 -7
  66. package/src/index.ts +6 -0
  67. package/src/instance/details/EcsInstanceDetails.spec.tsx +426 -0
  68. package/src/instance/details/EcsInstanceDetails.tsx +474 -0
  69. package/src/loadBalancer/details/loadBalancerDetails.tsx +1 -1
  70. package/src/loadBalancer/details/targetGroupDetails.tsx +1 -1
  71. package/src/loadBalancer/loadBalancer.transformer.ts +2 -7
  72. package/src/loadBalancer/targetGroup.states.ts +55 -53
  73. package/src/metricAlarm/metricAlarm.read.service.ts +1 -7
  74. package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +22 -94
  75. package/src/pipeline/stages/common/EcsServerGroupStepLabel.tsx +16 -0
  76. package/src/pipeline/stages/common/EcsStageConfigs.tsx +587 -0
  77. package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +29 -65
  78. package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +27 -70
  79. package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +21 -84
  80. package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +22 -73
  81. package/src/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.tsx +40 -0
  82. package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +12 -24
  83. package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +30 -128
  84. package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +24 -78
  85. package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +19 -73
  86. package/src/placementStrategy/placementStrategy.service.ts +0 -6
  87. package/src/secrets/secret.read.service.ts +1 -7
  88. package/src/securityGroup/details/EcsSecurityGroupDetails.spec.tsx +245 -0
  89. package/src/securityGroup/details/EcsSecurityGroupDetails.tsx +285 -0
  90. package/src/securityGroup/securityGroup.reader.ts +0 -5
  91. package/src/securityGroup/securityGroup.transformer.js +5 -13
  92. package/src/serverGroup/configure/dockerImage.util.ts +29 -0
  93. package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +215 -278
  94. package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.ts +83 -0
  95. package/src/serverGroup/configure/serverGroupConfiguration.service.ts +16 -633
  96. package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.spec.tsx +2078 -0
  97. package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.tsx +712 -0
  98. package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +98 -49
  99. package/src/serverGroup/configure/wizard/container/Container.spec.tsx +20 -8
  100. package/src/serverGroup/configure/wizard/container/Container.tsx +53 -24
  101. package/src/serverGroup/configure/wizard/networking/Networking.tsx +60 -38
  102. package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +290 -0
  103. package/src/serverGroup/configure/wizard/pages/BasicSettings.tsx +101 -0
  104. package/src/serverGroup/configure/wizard/pages/ContainerSettings.tsx +10 -0
  105. package/src/serverGroup/configure/wizard/pages/HorizontalScalingSettings.tsx +137 -0
  106. package/src/serverGroup/configure/wizard/pages/LoggingSettings.tsx +60 -0
  107. package/src/serverGroup/configure/wizard/pages/NetworkingSettings.tsx +10 -0
  108. package/src/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.tsx +10 -0
  109. package/src/serverGroup/configure/wizard/pages/TaskDefinitionSettings.tsx +59 -0
  110. package/src/serverGroup/configure/wizard/pages/common.ts +10 -0
  111. package/src/serverGroup/configure/wizard/pages/validation.tsx +190 -0
  112. package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +83 -34
  113. package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.spec.tsx +21 -8
  114. package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +63 -33
  115. package/src/serverGroup/details/EcsServerGroupActions.spec.tsx +244 -0
  116. package/src/serverGroup/details/EcsServerGroupActions.tsx +152 -0
  117. package/src/serverGroup/details/ecsServerGroupDetailsGetter.spec.ts +110 -0
  118. package/src/serverGroup/details/ecsServerGroupDetailsGetter.ts +73 -0
  119. package/src/serverGroup/details/resize/EcsResizeServerGroupModal.spec.tsx +130 -0
  120. package/src/serverGroup/details/resize/EcsResizeServerGroupModal.tsx +263 -0
  121. package/src/serverGroup/details/resize/index.ts +1 -0
  122. package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.spec.tsx +173 -0
  123. package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.tsx +285 -0
  124. package/src/serverGroup/details/rollback/index.ts +1 -0
  125. package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.spec.tsx +130 -0
  126. package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.tsx +172 -0
  127. package/src/serverGroup/details/sections/EcsServerGroupEventsSection.tsx +14 -0
  128. package/src/serverGroup/details/sections/EcsServerGroupInformationSection.tsx +25 -0
  129. package/src/serverGroup/events/EcsServerGroupEventsModal.spec.tsx +109 -0
  130. package/src/serverGroup/events/EcsServerGroupEventsModal.tsx +112 -0
  131. package/src/serverGroup/events/EventsLink.tsx +18 -0
  132. package/src/serverGroup/events/serverGroupEventsReader.service.spec.ts +41 -0
  133. package/src/serverGroup/events/serverGroupEventsReader.service.ts +2 -8
  134. package/src/serverGroup/serverGroup.transformer.spec.ts +10 -24
  135. package/src/serverGroup/serverGroup.transformer.ts +1 -5
  136. package/src/serviceDiscovery/serviceDiscovery.read.service.ts +1 -1
  137. package/dist/common/common.module.d.ts +0 -1
  138. package/dist/common/footer.component.d.ts +0 -1
  139. package/dist/instance/details/instance.details.controller.d.ts +0 -2
  140. package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
  141. package/dist/securityGroup/securityGroup.module.d.ts +0 -1
  142. package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +0 -2
  143. package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +0 -2
  144. package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +0 -2
  145. package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +0 -2
  146. package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +0 -1
  147. package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +0 -1
  148. package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +0 -2
  149. package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +0 -2
  150. package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +0 -2
  151. package/dist/serverGroup/details/serverGroupDetails.module.d.ts +0 -1
  152. package/dist/serverGroup/events/events.component.d.ts +0 -3
  153. package/dist/serverGroup/events/events.controller.d.ts +0 -19
  154. package/dist/serverGroup/serverGroup.module.d.ts +0 -1
  155. package/src/common/common.module.ts +0 -6
  156. package/src/common/footer.component.ts +0 -29
  157. package/src/instance/details/instance.details.controller.js +0 -356
  158. package/src/instance/details/instanceDetails.html +0 -204
  159. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +0 -101
  160. package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +0 -1
  161. package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
  162. package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
  163. package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
  164. package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
  165. package/src/pipeline/stages/disableCluster/disableClusterStage.html +0 -26
  166. package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
  167. package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
  168. package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +0 -36
  169. package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +0 -9
  170. package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +0 -87
  171. package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +0 -1
  172. package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +0 -35
  173. package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -34
  174. package/src/securityGroup/details/securityGroupDetail.controller.js +0 -147
  175. package/src/securityGroup/details/securityGroupDetail.html +0 -104
  176. package/src/securityGroup/securityGroup.module.ts +0 -12
  177. package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +0 -259
  178. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +0 -194
  179. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +0 -17
  180. package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -10
  181. package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +0 -11
  182. package/src/serverGroup/configure/wizard/container/container.html +0 -9
  183. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +0 -118
  184. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +0 -20
  185. package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +0 -13
  186. package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +0 -41
  187. package/src/serverGroup/configure/wizard/location/basicSettings.html +0 -137
  188. package/src/serverGroup/configure/wizard/logging/logging.component.html +0 -29
  189. package/src/serverGroup/configure/wizard/logging/logging.component.ts +0 -12
  190. package/src/serverGroup/configure/wizard/logging/logging.html +0 -7
  191. package/src/serverGroup/configure/wizard/networking/networking.html +0 -9
  192. package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -55
  193. package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +0 -11
  194. package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +0 -51
  195. package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +0 -9
  196. package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +0 -10
  197. package/src/serverGroup/details/resize/resizeCapacity.component.html +0 -94
  198. package/src/serverGroup/details/resize/resizeCapacity.component.ts +0 -14
  199. package/src/serverGroup/details/resize/resizeServerGroup.controller.js +0 -85
  200. package/src/serverGroup/details/resize/resizeServerGroup.html +0 -28
  201. package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +0 -97
  202. package/src/serverGroup/details/rollback/rollbackServerGroup.html +0 -67
  203. package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +0 -366
  204. package/src/serverGroup/details/serverGroupDetails.html +0 -216
  205. package/src/serverGroup/details/serverGroupDetails.module.ts +0 -5
  206. package/src/serverGroup/events/events.component.ts +0 -35
  207. package/src/serverGroup/events/events.controller.ts +0 -45
  208. package/src/serverGroup/events/events.html +0 -36
  209. package/src/serverGroup/serverGroup.module.ts +0 -6
@@ -0,0 +1,109 @@
1
+ import React from 'react';
2
+ import { shallow } from 'enzyme';
3
+
4
+ import { ModalBody, ReactModal, Spinner } from '@spinnaker/core';
5
+
6
+ import { EcsServerGroupEventsModal } from './EcsServerGroupEventsModal';
7
+ import { EventsLink } from './EventsLink';
8
+ import { ServerGroupEventsReader } from './serverGroupEventsReader.service';
9
+
10
+ function deferred<T>() {
11
+ let resolve: (value: T) => void;
12
+ const promise = new Promise<T>((res) => (resolve = res));
13
+ return { promise, resolve: resolve! };
14
+ }
15
+
16
+ describe('ECS server group events', () => {
17
+ const serverGroup = { name: 'fnord-main-v001' } as any;
18
+ const modalProps = {
19
+ serverGroup,
20
+ dismissModal: jasmine.createSpy('dismissModal'),
21
+ resolveModal: jasmine.createSpy('resolveModal'),
22
+ };
23
+
24
+ const modalBody = (wrapper: any) => shallow(<div>{wrapper.find(ModalBody).prop('children')}</div>);
25
+
26
+ it('opens the React events modal from the events link', () => {
27
+ const show = spyOn(ReactModal, 'show');
28
+ const wrapper = shallow(<EventsLink serverGroup={serverGroup} />);
29
+
30
+ wrapper.find('a').simulate('click', { preventDefault: jasmine.createSpy('preventDefault') });
31
+
32
+ expect(show).toHaveBeenCalledOnceWith(EcsServerGroupEventsModal, { serverGroup });
33
+ });
34
+
35
+ it('renders loading while events are pending', () => {
36
+ spyOn(ServerGroupEventsReader, 'getEvents').and.returnValue(new Promise(() => undefined));
37
+
38
+ const wrapper = shallow(<EcsServerGroupEventsModal {...modalProps} />);
39
+
40
+ expect(wrapper.find(Spinner).exists()).toBe(true);
41
+ });
42
+
43
+ it('renders an error when the reader rejects', async () => {
44
+ spyOn(ServerGroupEventsReader, 'getEvents').and.returnValue(Promise.reject(new Error('failed')));
45
+ const wrapper = shallow(<EcsServerGroupEventsModal {...modalProps} />);
46
+
47
+ await Promise.resolve();
48
+ wrapper.update();
49
+
50
+ expect(modalBody(wrapper).text()).toContain('There was an error loading events for fnord-main-v001');
51
+ });
52
+
53
+ it('renders an empty state when no events are returned', async () => {
54
+ spyOn(ServerGroupEventsReader, 'getEvents').and.returnValue(Promise.resolve([]));
55
+ const wrapper = shallow(<EcsServerGroupEventsModal {...modalProps} />);
56
+
57
+ await Promise.resolve();
58
+ wrapper.update();
59
+
60
+ expect(modalBody(wrapper).text()).toContain('No ECS events found for fnord-main-v001');
61
+ });
62
+
63
+ it('renders ECS events and status labels', async () => {
64
+ spyOn(ServerGroupEventsReader, 'getEvents').and.returnValue(
65
+ Promise.resolve([
66
+ { id: 'one', createdAt: 1710000000000, message: 'service reached steady state', status: 'Success' },
67
+ { id: 'two', createdAt: 1710000001000, message: 'deployment transitioning', status: 'Transition' },
68
+ ]),
69
+ );
70
+ const wrapper = shallow(<EcsServerGroupEventsModal {...modalProps} />);
71
+
72
+ await Promise.resolve();
73
+ wrapper.update();
74
+
75
+ const body = modalBody(wrapper);
76
+ expect(body.text()).toContain('service reached steady state');
77
+ expect(body.text()).toContain('deployment transitioning');
78
+ expect(body.find('.label-success').text()).toBe('Success');
79
+ expect(body.find('.label-info').text()).toBe('Transition');
80
+ });
81
+
82
+ it('ignores stale responses and responses received after unmount', async () => {
83
+ const first = deferred<any[]>();
84
+ const second = deferred<any[]>();
85
+ const getEvents = spyOn(ServerGroupEventsReader, 'getEvents').and.callFake((group: any) =>
86
+ group.name === 'first' ? first.promise : second.promise,
87
+ );
88
+ const wrapper = shallow(
89
+ <EcsServerGroupEventsModal {...modalProps} serverGroup={{ ...serverGroup, name: 'first' }} />,
90
+ );
91
+ wrapper.setProps({ serverGroup: { ...serverGroup, name: 'second' } });
92
+
93
+ first.resolve([{ id: 'old', message: 'stale event', status: 'Success', createdAt: 1 }]);
94
+ await first.promise;
95
+ await Promise.resolve();
96
+ wrapper.update();
97
+ expect(modalBody(wrapper).text()).not.toContain('stale event');
98
+
99
+ const instance = wrapper.instance() as EcsServerGroupEventsModal;
100
+ const setState = spyOn(instance, 'setState').and.callThrough();
101
+ wrapper.unmount();
102
+ second.resolve([{ id: 'new', message: 'late event', status: 'Success', createdAt: 2 }]);
103
+ await second.promise;
104
+ await Promise.resolve();
105
+
106
+ expect(getEvents).toHaveBeenCalledTimes(2);
107
+ expect(setState).not.toHaveBeenCalled();
108
+ });
109
+ });
@@ -0,0 +1,112 @@
1
+ import React from 'react';
2
+
3
+ import type { IModalComponentProps, IServerGroup } from '@spinnaker/core';
4
+ import { ModalBody, ModalFooter, ModalHeader, Spinner, timestamp } from '@spinnaker/core';
5
+
6
+ import type { IEventDescription } from './serverGroupEventsReader.service';
7
+ import { ServerGroupEventsReader } from './serverGroupEventsReader.service';
8
+
9
+ export interface IEcsServerGroupEventsModalProps extends IModalComponentProps {
10
+ serverGroup: IServerGroup;
11
+ }
12
+
13
+ interface IEcsServerGroupEventsModalState {
14
+ loading: boolean;
15
+ error: boolean;
16
+ events: IEventDescription[];
17
+ }
18
+
19
+ export class EcsServerGroupEventsModal extends React.Component<
20
+ IEcsServerGroupEventsModalProps,
21
+ IEcsServerGroupEventsModalState
22
+ > {
23
+ public state: IEcsServerGroupEventsModalState = { loading: true, error: false, events: [] };
24
+
25
+ private mounted = false;
26
+ private requestId = 0;
27
+
28
+ public componentDidMount(): void {
29
+ this.mounted = true;
30
+ this.loadEvents();
31
+ }
32
+
33
+ public componentDidUpdate(previousProps: IEcsServerGroupEventsModalProps): void {
34
+ if (previousProps.serverGroup !== this.props.serverGroup) {
35
+ this.loadEvents();
36
+ }
37
+ }
38
+
39
+ public componentWillUnmount(): void {
40
+ this.mounted = false;
41
+ this.requestId++;
42
+ }
43
+
44
+ private loadEvents(): void {
45
+ const requestId = ++this.requestId;
46
+ this.setState({ loading: true, error: false, events: [] });
47
+ ServerGroupEventsReader.getEvents(this.props.serverGroup).then(
48
+ (events) => {
49
+ if (this.mounted && requestId === this.requestId) {
50
+ this.setState({ loading: false, error: false, events });
51
+ }
52
+ },
53
+ () => {
54
+ if (this.mounted && requestId === this.requestId) {
55
+ this.setState({ loading: false, error: true, events: [] });
56
+ }
57
+ },
58
+ );
59
+ }
60
+
61
+ public render() {
62
+ const { dismissModal, serverGroup } = this.props;
63
+ const { loading, error, events } = this.state;
64
+ return (
65
+ <>
66
+ <ModalHeader>{`Server Group Events for ${serverGroup.name}`}</ModalHeader>
67
+ <ModalBody>
68
+ {loading && (
69
+ <div className="horizontal center middle sp-margin-xl-yaxis">
70
+ <Spinner size="small" />
71
+ </div>
72
+ )}
73
+ {!loading && error && (
74
+ <div className="text-center">
75
+ <p>{`There was an error loading events for ${serverGroup.name}. Please try again later.`}</p>
76
+ </div>
77
+ )}
78
+ {!loading && !error && events.length === 0 && (
79
+ <div className="text-center">
80
+ <p>{`No ECS events found for ${serverGroup.name}.`}</p>
81
+ </div>
82
+ )}
83
+ {!loading &&
84
+ !error &&
85
+ events.map((event, index) => (
86
+ <div key={event.id || index}>
87
+ <p className="clearfix">
88
+ <span
89
+ className={`label label-${
90
+ event.status === 'Success' ? 'success' : event.status === 'Transition' ? 'info' : 'danger'
91
+ } pull-left`}
92
+ >
93
+ {event.status}
94
+ </span>
95
+ <span className="label label-default pull-right">{timestamp(event.createdAt)}</span>
96
+ </p>
97
+ <div>{event.message}</div>
98
+ {index < events.length - 1 && <hr />}
99
+ </div>
100
+ ))}
101
+ </ModalBody>
102
+ <ModalFooter
103
+ primaryActions={
104
+ <button className="btn btn-primary" onClick={dismissModal}>
105
+ Close
106
+ </button>
107
+ }
108
+ />
109
+ </>
110
+ );
111
+ }
112
+ }
@@ -1,5 +1,23 @@
1
+ import React from 'react';
2
+
1
3
  import type { IServerGroup } from '@spinnaker/core';
4
+ import { ReactModal } from '@spinnaker/core';
5
+
6
+ import { EcsServerGroupEventsModal } from './EcsServerGroupEventsModal';
2
7
 
3
8
  export interface IViewScalingActivitiesLinkProps {
4
9
  serverGroup: IServerGroup;
5
10
  }
11
+
12
+ export function EventsLink({ serverGroup }: IViewScalingActivitiesLinkProps) {
13
+ const showEvents = (event: React.MouseEvent<HTMLAnchorElement>) => {
14
+ event.preventDefault();
15
+ ReactModal.show(EcsServerGroupEventsModal, { serverGroup });
16
+ };
17
+
18
+ return (
19
+ <a href="#" onClick={showEvents}>
20
+ View Events
21
+ </a>
22
+ );
23
+ }
@@ -0,0 +1,41 @@
1
+ import { mockHttpClient } from '../../../../core/src/api/mock/jasmine';
2
+
3
+ import { ServerGroupEventsReader } from './serverGroupEventsReader.service';
4
+
5
+ describe('ServerGroupEventsReader', () => {
6
+ const serverGroup = {
7
+ app: 'fnord',
8
+ account: 'test',
9
+ name: 'fnord-main-v001',
10
+ region: 'us-east-1',
11
+ cloudProvider: 'ecs',
12
+ } as any;
13
+
14
+ it('reads ECS server group events', async () => {
15
+ const http = mockHttpClient();
16
+ const events = [{ id: 'one', createdAt: 1, message: 'steady state', status: 'Success' }];
17
+ http
18
+ .expectGET('/applications/fnord/serverGroups/test/fnord-main-v001/events')
19
+ .withParams({ region: 'us-east-1', provider: 'ecs' })
20
+ .respond(200, events);
21
+
22
+ const result = ServerGroupEventsReader.getEvents(serverGroup);
23
+ await http.flush();
24
+
25
+ await expectAsync(Promise.resolve(result)).toBeResolvedTo(events);
26
+ });
27
+
28
+ it('rejects when the events request fails', async () => {
29
+ const http = mockHttpClient();
30
+ http
31
+ .expectGET('/applications/fnord/serverGroups/test/fnord-main-v001/events')
32
+ .withParams({ region: 'us-east-1', provider: 'ecs' })
33
+ .respond(500, { message: 'failed' });
34
+
35
+ const result = Promise.resolve(ServerGroupEventsReader.getEvents(serverGroup));
36
+ const expectation = expectAsync(result).toBeRejected();
37
+ await http.flush();
38
+
39
+ await expectation;
40
+ });
41
+ });
@@ -1,5 +1,3 @@
1
- import { $log } from 'ngimport';
2
-
3
1
  import type { IServerGroup } from '@spinnaker/core';
4
2
  import { REST } from '@spinnaker/core';
5
3
 
@@ -11,17 +9,13 @@ export interface IEventDescription {
11
9
  }
12
10
 
13
11
  export class ServerGroupEventsReader {
14
- public static getEvents(serverGroup: IServerGroup): PromiseLike<IEventDescription[]> {
12
+ public static getEvents(serverGroup: IServerGroup): Promise<IEventDescription[]> {
15
13
  return REST('/applications')
16
14
  .path(serverGroup.app, 'serverGroups', serverGroup.account, serverGroup.name, 'events')
17
15
  .query({
18
16
  region: serverGroup.region,
19
17
  provider: serverGroup.cloudProvider,
20
18
  })
21
- .get()
22
- .catch((error: any): any[] => {
23
- $log.error(error, 'error retrieving events');
24
- return [];
25
- });
19
+ .get();
26
20
  }
27
21
  }
@@ -1,54 +1,40 @@
1
- import type { IQService, IRootScopeService, IScope } from 'angular';
2
- import { mock } from 'angular';
3
-
4
1
  import type { IAmazonServerGroup, IScalingPolicyAlarmView, IStepAdjustment } from '@spinnaker/amazon';
5
2
  import { VpcReader } from '@spinnaker/amazon';
6
3
 
7
- import type { EcsServerGroupTransformer } from './serverGroup.transformer';
8
- import { ECS_SERVER_GROUP_TRANSFORMER } from './serverGroup.transformer';
4
+ import { EcsServerGroupTransformer } from './serverGroup.transformer';
9
5
 
10
6
  describe('ecsServerGroupTransformer', () => {
11
- let transformer: EcsServerGroupTransformer, $q: IQService, $scope: IScope;
12
-
13
- beforeEach(mock.module(ECS_SERVER_GROUP_TRANSFORMER));
7
+ let transformer: EcsServerGroupTransformer;
14
8
 
15
- beforeEach(
16
- mock.inject(
17
- (_ecsServerGroupTransformer_: EcsServerGroupTransformer, _$q_: IQService, $rootScope: IRootScopeService) => {
18
- transformer = _ecsServerGroupTransformer_;
19
- $q = _$q_;
20
- $scope = $rootScope.$new();
21
- },
22
- ),
23
- );
9
+ beforeEach(() => {
10
+ transformer = new EcsServerGroupTransformer();
11
+ });
24
12
 
25
13
  describe('normalize server group', () => {
26
14
  beforeEach(() => {
27
15
  spyOn(VpcReader, 'listVpcs').and.returnValue(
28
- $q.when([{ account: 'test', region: 'us-east-1', id: 'vpc-1', name: 'main' } as any]),
16
+ Promise.resolve([{ account: 'test', region: 'us-east-1', id: 'vpc-1', name: 'main' } as any]),
29
17
  );
30
18
  });
31
19
 
32
- it('adds vpc name to server group', () => {
20
+ it('adds vpc name to server group', async () => {
33
21
  const serverGroup = {
34
22
  account: 'test',
35
23
  region: 'us-east-1',
36
24
  vpcId: 'vpc-1',
37
25
  instances: [],
38
26
  } as IAmazonServerGroup;
39
- transformer.normalizeServerGroup(serverGroup);
40
- $scope.$digest();
27
+ await transformer.normalizeServerGroup(serverGroup);
41
28
  expect(serverGroup.vpcName).toBe('main');
42
29
  });
43
30
 
44
- it('adds empty vpc name when no vpcId found on server group', () => {
31
+ it('adds empty vpc name when no vpcId found on server group', async () => {
45
32
  const serverGroup = {
46
33
  account: 'test',
47
34
  region: 'us-east-1',
48
35
  instances: [],
49
36
  } as IAmazonServerGroup;
50
- transformer.normalizeServerGroup(serverGroup);
51
- $scope.$digest();
37
+ await transformer.normalizeServerGroup(serverGroup);
52
38
  expect(serverGroup.vpcName).toBe('');
53
39
  });
54
40
  });
@@ -1,4 +1,3 @@
1
- import { module } from 'angular';
2
1
  import { defaults } from 'lodash';
3
2
 
4
3
  import type {
@@ -70,7 +69,7 @@ export class EcsServerGroupTransformer {
70
69
  return view;
71
70
  }
72
71
 
73
- public normalizeServerGroup(serverGroup: IAmazonServerGroup): PromiseLike<IAmazonServerGroup> {
72
+ public normalizeServerGroup(serverGroup: IAmazonServerGroup): Promise<IAmazonServerGroup> {
74
73
  serverGroup.instances.forEach((instance: IInstance) => {
75
74
  instance.vpcId = serverGroup.vpcId;
76
75
  });
@@ -112,6 +111,3 @@ export class EcsServerGroupTransformer {
112
111
  return command;
113
112
  }
114
113
  }
115
-
116
- export const ECS_SERVER_GROUP_TRANSFORMER = 'spinnaker.ecs.serverGroup.transformer';
117
- module(ECS_SERVER_GROUP_TRANSFORMER, []).service('ecsServerGroupTransformer', EcsServerGroupTransformer);
@@ -2,7 +2,7 @@ import { REST } from '@spinnaker/core';
2
2
  import type { IServiceDiscoveryRegistryDescriptor } from './IServiceDiscovery';
3
3
 
4
4
  export class ServiceDiscoveryReader {
5
- public static listServiceDiscoveryRegistries(): PromiseLike<IServiceDiscoveryRegistryDescriptor[]> {
5
+ public static listServiceDiscoveryRegistries(): Promise<IServiceDiscoveryRegistryDescriptor[]> {
6
6
  return REST('/ecs/serviceDiscoveryRegistries').get();
7
7
  }
8
8
  }
@@ -1 +0,0 @@
1
- export declare const COMMON_MODULE = "spinnaker.ecs.common";
@@ -1 +0,0 @@
1
- export declare const ECS_FOOTER_COMPONENT = "spinnaker.ecs.footer";
@@ -1,2 +0,0 @@
1
- export const ECS_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER: "spinnaker.ecs.instance.details.controller";
2
- export const name: "spinnaker.ecs.instance.details.controller";
@@ -1,2 +0,0 @@
1
- export const ECS_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER: "spinnaker.ecs.securityGroup.details.controller";
2
- export const name: "spinnaker.ecs.securityGroup.details.controller";
@@ -1 +0,0 @@
1
- export declare const ECS_SECURITY_GROUP_MODULE = "spinnaker.ecs.securityGroup";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_ECS_CONTROLLER: "spinnaker.ecs.cloneServerGroup.controller";
2
- export const name: "spinnaker.ecs.cloneServerGroup.controller";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGS_COMPONENT: "spinnaker.ecs.serverGroup.configure.wizard.advancedSettings.component";
2
- export const name: "spinnaker.ecs.serverGroup.configure.wizard.advancedSettings.component";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_CONFIGURE_WIZARD_HORIZONTALSCALING_HORIZONTALSCALING_COMPONENT: "spinnaker.ecs.serverGroup.configure.wizard.horizontalScaling.component";
2
- export const name: "spinnaker.ecs.serverGroup.configure.wizard.horizontalScaling.component";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_SERVERGROUPBASICSETTINGS_CONTROLLER: "spinnaker.ecs.serverGroup.configure.basicSettings";
2
- export const name: "spinnaker.ecs.serverGroup.configure.basicSettings";
@@ -1 +0,0 @@
1
- export declare const ECS_SERVER_GROUP_LOGGING = "spinnaker.ecs.serverGroup.configure.wizard.logging.component";
@@ -1 +0,0 @@
1
- export declare const ECS_RESIZE_CAPACITY_COMPONENT = "spinnaker.ecs.serverGroup.resize";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER: "spinnaker.ecs.serverGroup.details.resize.controller";
2
- export const name: "spinnaker.ecs.serverGroup.details.resize.controller";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER: "spinnaker.ecs.serverGroup.details.rollback.controller";
2
- export const name: "spinnaker.ecs.serverGroup.details.rollback.controller";
@@ -1,2 +0,0 @@
1
- export const ECS_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_ECS_CONTROLLER: "spinnaker.ecs.serverGroup.details.controller";
2
- export const name: "spinnaker.ecs.serverGroup.details.controller";
@@ -1 +0,0 @@
1
- export declare const SERVER_GROUP_DETAILS_MODULE = "spinnaker.ecs.serverGroup.details";
@@ -1,3 +0,0 @@
1
- import type { IComponentOptions } from 'angular';
2
- export declare const viewEventsLink: IComponentOptions;
3
- export declare const VIEW_EVENTS_LINK_COMPONENT = "spinnaker.ecs.serverGroup.details.viewEvents.link";
@@ -1,19 +0,0 @@
1
- import type { IController } from 'angular';
2
- import type { IModalServiceInstance } from 'angular-ui-bootstrap';
3
- import type { IServerGroup } from '@spinnaker/core';
4
- import type { IEventDescription } from './serverGroupEventsReader.service';
5
- export interface IScalingActivitiesViewState {
6
- loading: boolean;
7
- error: boolean;
8
- }
9
- export declare class EventsController implements IController {
10
- private $uibModalInstance;
11
- serverGroup: IServerGroup;
12
- viewState: IScalingActivitiesViewState;
13
- events: IEventDescription[];
14
- static $inject: string[];
15
- constructor($uibModalInstance: IModalServiceInstance, serverGroup: IServerGroup);
16
- $onInit(): void;
17
- close(): void;
18
- }
19
- export declare const EVENTS_CTRL = "spinnaker.ecs.serverGroup.events.controller";
@@ -1 +0,0 @@
1
- export declare const ECS_SERVERGROUP_MODULE = "spinnaker.ecs.serverGroup";
@@ -1,6 +0,0 @@
1
- import { module } from 'angular';
2
-
3
- import { ECS_FOOTER_COMPONENT } from './footer.component';
4
-
5
- export const COMMON_MODULE = 'spinnaker.ecs.common';
6
- module(COMMON_MODULE, [ECS_FOOTER_COMPONENT]);
@@ -1,29 +0,0 @@
1
- import type { IComponentOptions } from 'angular';
2
- import { module } from 'angular';
3
-
4
- const footerComponent: IComponentOptions = {
5
- bindings: {
6
- action: '&',
7
- isValid: '&',
8
- cancel: '&',
9
- account: '=?',
10
- verification: '=?',
11
- },
12
- template: `
13
- <div class="modal-footer">
14
- <user-verification account="$ctrl.account" verification="$ctrl.verification"></user-verification>
15
- <button type="submit" ng-click="$ctrl.action()" style="display:none"></button> <!-- Allows form submission via enter keypress-->
16
- <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
17
- <button type="submit"
18
- class="btn btn-primary"
19
- ng-click="$ctrl.action()"
20
- ng-disabled="!$ctrl.isValid()">
21
- Submit
22
- </button>
23
- </div>
24
- `,
25
- controller: () => {},
26
- };
27
-
28
- export const ECS_FOOTER_COMPONENT = 'spinnaker.ecs.footer';
29
- module(ECS_FOOTER_COMPONENT, []).component('ecsFooter', footerComponent);