@spinnaker/ecs 2026.2.3 → 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,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):
|
|
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
|
|
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
|
|
12
|
-
|
|
13
|
-
beforeEach(mock.module(ECS_SERVER_GROUP_TRANSFORMER));
|
|
7
|
+
let transformer: EcsServerGroupTransformer;
|
|
14
8
|
|
|
15
|
-
beforeEach(
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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):
|
|
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():
|
|
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 +0,0 @@
|
|
|
1
|
-
export declare const ECS_SECURITY_GROUP_MODULE = "spinnaker.ecs.securityGroup";
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
export declare const SERVER_GROUP_DETAILS_MODULE = "spinnaker.ecs.serverGroup.details";
|
|
@@ -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,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);
|