@spinnaker/cloudrun 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/cloudrun.module.d.ts +1 -1
- package/dist/common/ComponentUrlDetails.d.ts +7 -0
- package/dist/common/LoadBalancerMessage.d.ts +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/details/CloudrunInstanceDetails.d.ts +23 -0
- package/dist/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.d.ts +32 -0
- package/dist/loadBalancer/details/CloudrunLoadBalancerActions.d.ts +3 -0
- package/dist/loadBalancer/details/sections.d.ts +7 -0
- package/dist/loadBalancer/details/useCloudrunLoadBalancerDetails.d.ts +4 -0
- package/dist/loadBalancer/index.d.ts +4 -2
- package/dist/loadBalancer/loadBalancerTransformer.d.ts +2 -6
- package/dist/manifest/manifest.service.d.ts +5 -0
- package/dist/manifest/manifestCommandBuilder.service.d.ts +1 -1
- package/dist/pipeline/stages/deployManifest/manifestStatus/DeployStatus.d.ts +1 -0
- package/dist/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.d.ts +6 -3
- package/dist/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerExecutionDetails.d.ts +7 -0
- package/dist/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerStageConfig.d.ts +30 -0
- package/dist/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.d.ts +2 -1
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +4 -6
- package/dist/serverGroup/configure/wizard/BasicSettings.d.ts +5 -2
- package/dist/serverGroup/configure/wizard/serverGroupWizard.d.ts +18 -6
- package/dist/serverGroup/details/CloudrunServerGroupActions.d.ts +6 -0
- package/dist/serverGroup/details/cloudrunServerGroupDetailsGetter.d.ts +3 -0
- package/dist/serverGroup/details/sections.d.ts +5 -0
- package/dist/serverGroup/index.d.ts +3 -1
- package/dist/serverGroup/serverGroupTransformer.service.d.ts +1 -5
- package/package.json +4 -11
- package/src/cloudrun.module.spec.ts +22 -0
- package/src/cloudrun.module.ts +54 -59
- package/src/common/ComponentUrlDetails.tsx +25 -0
- package/src/common/LoadBalancerMessage.tsx +17 -0
- package/src/index.ts +2 -1
- package/src/instance/details/CloudrunInstanceDetails.tsx +164 -0
- package/src/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.spec.tsx +85 -0
- package/src/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.tsx +395 -0
- package/src/loadBalancer/details/CloudrunLoadBalancerActions.tsx +66 -0
- package/src/loadBalancer/details/sections.spec.ts +19 -0
- package/src/loadBalancer/details/sections.tsx +91 -0
- package/src/loadBalancer/details/useCloudrunLoadBalancerDetails.ts +56 -0
- package/src/loadBalancer/index.ts +4 -2
- package/src/loadBalancer/loadBalancerTransformer.ts +3 -13
- package/src/manifest/manifest.service.ts +18 -1
- package/src/manifest/manifestCommandBuilder.service.ts +46 -53
- package/src/pipeline/stages/deployManifest/manifestStatus/DeployStatus.tsx +33 -4
- package/src/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.spec.tsx +35 -0
- package/src/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.tsx +10 -5
- package/src/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerExecutionDetails.tsx +70 -0
- package/src/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerStageConfig.tsx +245 -0
- package/src/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.spec.ts +205 -0
- package/src/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.ts +14 -71
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.ts +5 -15
- package/src/serverGroup/configure/wizard/BasicSettings.tsx +10 -8
- package/src/serverGroup/configure/wizard/serverGroupWizard.tsx +59 -15
- package/src/serverGroup/details/CloudrunServerGroupActions.tsx +80 -0
- package/src/serverGroup/details/cloudrunServerGroupDetailsGetter.spec.ts +46 -0
- package/src/serverGroup/details/cloudrunServerGroupDetailsGetter.ts +53 -0
- package/src/serverGroup/details/sections.tsx +60 -0
- package/src/serverGroup/index.ts +3 -1
- package/src/serverGroup/routerConsumers.spec.tsx +152 -0
- package/src/serverGroup/serverGroupTransformer.service.ts +2 -12
- package/dist/common/componentUrlDetails.component.d.ts +0 -1
- package/dist/common/conditionalDescriptionListItem.component.d.ts +0 -1
- package/dist/common/loadBalancerMessage.component.d.ts +0 -1
- package/dist/instance/details/details.controller.d.ts +0 -1
- package/dist/loadBalancer/configure/wizard/allocationConfigurationRow.component.d.ts +0 -1
- package/dist/loadBalancer/configure/wizard/basicSettings.component.d.ts +0 -1
- package/dist/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.d.ts +0 -1
- package/dist/loadBalancer/configure/wizard/wizard.controller.d.ts +0 -2
- package/dist/loadBalancer/details/details.controller.d.ts +0 -1
- package/dist/pipeline/pipeline.module.d.ts +0 -1
- package/dist/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.d.ts +0 -1
- package/dist/serverGroup/details/details.controller.d.ts +0 -1
- package/src/common/componentUrlDetails.component.ts +0 -22
- package/src/common/conditionalDescriptionListItem.component.ts +0 -37
- package/src/common/loadBalancerMessage.component.html +0 -11
- package/src/common/loadBalancerMessage.component.ts +0 -13
- package/src/instance/details/details.controller.ts +0 -84
- package/src/instance/details/details.html +0 -68
- package/src/loadBalancer/configure/wizard/allocationConfigurationRow.component.ts +0 -70
- package/src/loadBalancer/configure/wizard/basicSettings.component.html +0 -44
- package/src/loadBalancer/configure/wizard/basicSettings.component.ts +0 -86
- package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html +0 -45
- package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.ts +0 -84
- package/src/loadBalancer/configure/wizard/wizard.controller.ts +0 -157
- package/src/loadBalancer/configure/wizard/wizard.html +0 -39
- package/src/loadBalancer/configure/wizard/wizard.less +0 -9
- package/src/loadBalancer/details/details.controller.ts +0 -140
- package/src/loadBalancer/details/details.html +0 -89
- package/src/pipeline/pipeline.module.ts +0 -6
- package/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html +0 -33
- package/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html +0 -51
- package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.ts +0 -65
- package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html +0 -53
- package/src/serverGroup/details/details.controller.ts +0 -134
- package/src/serverGroup/details/details.html +0 -94
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
Application,
|
|
5
|
+
DeckRuntimeServices,
|
|
6
|
+
IModalComponentProps,
|
|
7
|
+
IRouterInjectedProps,
|
|
8
|
+
IStage,
|
|
9
|
+
} from '@spinnaker/core';
|
|
10
|
+
import {
|
|
11
|
+
DeckRuntimeContext,
|
|
12
|
+
noop,
|
|
13
|
+
ReactModal,
|
|
14
|
+
TaskMonitor,
|
|
15
|
+
withRouter,
|
|
16
|
+
WizardModal,
|
|
17
|
+
WizardPage,
|
|
18
|
+
} from '@spinnaker/core';
|
|
19
|
+
|
|
5
20
|
import { WizardServerGroupBasicSettings } from './BasicSettings';
|
|
6
21
|
import { WizardServerGroupConfigFilesSettings } from './ConfigFiles';
|
|
7
22
|
import type { ICloudrunServerGroupCommandData } from '../serverGroupCommandBuilder.service';
|
|
@@ -12,6 +27,8 @@ export interface ICloudrunServerGroupModalProps extends IModalComponentProps {
|
|
|
12
27
|
application: Application;
|
|
13
28
|
command: ICloudrunServerGroupCommandData;
|
|
14
29
|
isNew?: boolean;
|
|
30
|
+
closeModal?: (command: any) => void;
|
|
31
|
+
dismissModal?: () => void;
|
|
15
32
|
}
|
|
16
33
|
|
|
17
34
|
export interface ICloudrunServerGroupModalState {
|
|
@@ -20,21 +37,31 @@ export interface ICloudrunServerGroupModalState {
|
|
|
20
37
|
taskMonitor: TaskMonitor;
|
|
21
38
|
}
|
|
22
39
|
|
|
23
|
-
export class
|
|
24
|
-
|
|
40
|
+
export class ServerGroupWizardComponent extends React.Component<
|
|
41
|
+
ICloudrunServerGroupModalProps & IRouterInjectedProps,
|
|
42
|
+
ICloudrunServerGroupModalState
|
|
43
|
+
> {
|
|
44
|
+
public static contextType = DeckRuntimeContext;
|
|
45
|
+
public declare context: React.ContextType<typeof DeckRuntimeContext>;
|
|
46
|
+
|
|
47
|
+
public static defaultProps: Partial<ICloudrunServerGroupModalProps & IRouterInjectedProps> = {
|
|
25
48
|
closeModal: noop,
|
|
26
49
|
dismissModal: noop,
|
|
27
50
|
};
|
|
28
51
|
|
|
29
52
|
private _isUnmounted = false;
|
|
53
|
+
private applicationRefreshUnsubscribe?: () => void;
|
|
30
54
|
|
|
31
55
|
/* private serverGroupWriter: ServerGroupWriter; */
|
|
32
|
-
public static show(
|
|
56
|
+
public static show(
|
|
57
|
+
props: ICloudrunServerGroupModalProps,
|
|
58
|
+
runtimeServices: DeckRuntimeServices,
|
|
59
|
+
): Promise<ICloudrunServerGroupCommandData> {
|
|
33
60
|
const modalProps = { dialogClassName: 'wizard-modal modal-lg' };
|
|
34
|
-
return ReactModal.show(ServerGroupWizard, props, modalProps);
|
|
61
|
+
return ReactModal.show(ServerGroupWizard, props, modalProps, runtimeServices);
|
|
35
62
|
}
|
|
36
63
|
|
|
37
|
-
constructor(props: ICloudrunServerGroupModalProps) {
|
|
64
|
+
constructor(props: ICloudrunServerGroupModalProps & IRouterInjectedProps) {
|
|
38
65
|
super(props);
|
|
39
66
|
if (!props.command) {
|
|
40
67
|
CloudrunServerGroupCommandBuilder.buildNewServerGroupCommand(props.application, 'cloudrun', 'create').then(
|
|
@@ -53,18 +80,20 @@ export class ServerGroupWizard extends React.Component<ICloudrunServerGroupModal
|
|
|
53
80
|
title: `${
|
|
54
81
|
props.command.command.viewState.submitButtonLabel === 'Create' ? 'Creating' : 'Updating'
|
|
55
82
|
} your Server Group`,
|
|
56
|
-
|
|
83
|
+
onDismiss: () => this.props.dismissModal(),
|
|
57
84
|
onTaskComplete: this.onTaskComplete,
|
|
58
85
|
}),
|
|
59
86
|
};
|
|
60
87
|
}
|
|
61
88
|
|
|
62
89
|
private onTaskComplete = () => {
|
|
90
|
+
this.clearApplicationRefreshSubscription();
|
|
91
|
+
this.applicationRefreshUnsubscribe = this.props.application.serverGroups.onNextRefresh(this.onApplicationRefresh);
|
|
63
92
|
this.props.application.serverGroups.refresh();
|
|
64
|
-
this.props.application.serverGroups.onNextRefresh(null, this.onApplicationRefresh);
|
|
65
93
|
};
|
|
66
94
|
|
|
67
95
|
protected onApplicationRefresh = (): void => {
|
|
96
|
+
this.clearApplicationRefreshSubscription();
|
|
68
97
|
if (this._isUnmounted) {
|
|
69
98
|
return;
|
|
70
99
|
}
|
|
@@ -82,23 +111,33 @@ export class ServerGroupWizard extends React.Component<ICloudrunServerGroupModal
|
|
|
82
111
|
provider: 'cloudrun',
|
|
83
112
|
};
|
|
84
113
|
let transitionTo = '^.^.^.clusters.serverGroup';
|
|
85
|
-
if (
|
|
114
|
+
if (this.props.stateService.includes('**.clusters.serverGroup')) {
|
|
86
115
|
// clone via details, all view
|
|
87
116
|
transitionTo = '^.serverGroup';
|
|
88
117
|
}
|
|
89
|
-
if (
|
|
118
|
+
if (this.props.stateService.includes('**.clusters.cluster.serverGroup')) {
|
|
90
119
|
// clone or create with details open
|
|
91
120
|
transitionTo = '^.^.serverGroup';
|
|
92
121
|
}
|
|
93
|
-
if (
|
|
122
|
+
if (this.props.stateService.includes('**.clusters')) {
|
|
94
123
|
// create new, no details open
|
|
95
124
|
transitionTo = '.serverGroup';
|
|
96
125
|
}
|
|
97
|
-
|
|
126
|
+
this.props.stateService.go(transitionTo, newStateParams);
|
|
98
127
|
}
|
|
99
128
|
}
|
|
100
129
|
};
|
|
101
130
|
|
|
131
|
+
public componentWillUnmount(): void {
|
|
132
|
+
this._isUnmounted = true;
|
|
133
|
+
this.clearApplicationRefreshSubscription();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private clearApplicationRefreshSubscription = (): void => {
|
|
137
|
+
this.applicationRefreshUnsubscribe?.();
|
|
138
|
+
this.applicationRefreshUnsubscribe = undefined;
|
|
139
|
+
};
|
|
140
|
+
|
|
102
141
|
private submit = (c: ICloudrunServerGroupCommandData): void => {
|
|
103
142
|
const command: any = CloudrunServerGroupCommandBuilder.copyAndCleanCommand(c.command);
|
|
104
143
|
const forPipelineConfig = command.viewState.mode === 'editPipeline' || command.viewState.mode === 'createPipeline';
|
|
@@ -106,7 +145,8 @@ export class ServerGroupWizard extends React.Component<ICloudrunServerGroupModal
|
|
|
106
145
|
this.props.closeModal && this.props.closeModal(command);
|
|
107
146
|
} else {
|
|
108
147
|
//command.viewState.mode = 'create';
|
|
109
|
-
const submitMethod = () =>
|
|
148
|
+
const submitMethod = () =>
|
|
149
|
+
this.context.services.serverGroupWriter.cloneServerGroup(command, this.props.application);
|
|
110
150
|
this.state.taskMonitor.submit(submitMethod);
|
|
111
151
|
return null;
|
|
112
152
|
}
|
|
@@ -148,3 +188,7 @@ export class ServerGroupWizard extends React.Component<ICloudrunServerGroupModal
|
|
|
148
188
|
);
|
|
149
189
|
}
|
|
150
190
|
}
|
|
191
|
+
|
|
192
|
+
export const ServerGroupWizard = Object.assign(withRouter(ServerGroupWizardComponent), {
|
|
193
|
+
show: ServerGroupWizardComponent.show,
|
|
194
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Dropdown, MenuItem } from 'react-bootstrap';
|
|
3
|
+
|
|
4
|
+
import type { IRouterInjectedProps, IServerGroupActionsProps } from '@spinnaker/core';
|
|
5
|
+
import { ConfirmationModalService, useDeckRuntimeServices, withRouter } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { CloudrunHealth } from '../../common/cloudrunHealth';
|
|
8
|
+
import type { ICloudrunServerGroup } from '../../interfaces';
|
|
9
|
+
|
|
10
|
+
export function CloudrunServerGroupActionsComponent({
|
|
11
|
+
app,
|
|
12
|
+
serverGroup,
|
|
13
|
+
stateService,
|
|
14
|
+
}: IServerGroupActionsProps & IRouterInjectedProps) {
|
|
15
|
+
const { serverGroupWriter } = useDeckRuntimeServices();
|
|
16
|
+
const cloudrunServerGroup = serverGroup as ICloudrunServerGroup;
|
|
17
|
+
const canDestroyServerGroup = Boolean(
|
|
18
|
+
cloudrunServerGroup && !cloudrunServerGroup.tags?.isLatest && cloudrunServerGroup.disabled,
|
|
19
|
+
);
|
|
20
|
+
const destroyServerGroup = () => {
|
|
21
|
+
const stateParams = {
|
|
22
|
+
name: cloudrunServerGroup.name,
|
|
23
|
+
accountId: cloudrunServerGroup.account,
|
|
24
|
+
region: cloudrunServerGroup.region,
|
|
25
|
+
};
|
|
26
|
+
const taskMonitor = {
|
|
27
|
+
application: app,
|
|
28
|
+
title: `Destroying ${cloudrunServerGroup.name}`,
|
|
29
|
+
onTaskComplete: () => {
|
|
30
|
+
if (stateService.includes('**.serverGroup', stateParams)) {
|
|
31
|
+
stateService.go('^');
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const confirmationModalParams = {
|
|
36
|
+
header: `Really destroy ${cloudrunServerGroup.name}?`,
|
|
37
|
+
buttonText: `Destroy ${cloudrunServerGroup.name}`,
|
|
38
|
+
account: cloudrunServerGroup.account,
|
|
39
|
+
taskMonitorConfig: taskMonitor,
|
|
40
|
+
submitMethod: (params: any) => serverGroupWriter.destroyServerGroup(cloudrunServerGroup, app, params),
|
|
41
|
+
askForReason: true,
|
|
42
|
+
platformHealthOnlyShowOverride: app.attributes.platformHealthOnlyShowOverride,
|
|
43
|
+
platformHealthType: CloudrunHealth.PLATFORM,
|
|
44
|
+
interestingHealthProviderNames: [] as string[],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (app.attributes.platformHealthOnlyShowOverride && app.attributes.platformHealthOnly) {
|
|
48
|
+
confirmationModalParams.interestingHealthProviderNames = [CloudrunHealth.PLATFORM];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ConfirmationModalService.confirm(confirmationModalParams);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Dropdown className="dropdown" id="cloudrun-server-group-actions-dropdown">
|
|
56
|
+
<Dropdown.Toggle className="btn btn-sm btn-primary dropdown-toggle">Server Group Actions</Dropdown.Toggle>
|
|
57
|
+
<Dropdown.Menu>
|
|
58
|
+
{cloudrunServerGroup.tags?.isLatest && (
|
|
59
|
+
<MenuItem
|
|
60
|
+
disabled={true}
|
|
61
|
+
title="You cannot destroy the latest server group (revision). You may be able to delete this server group's load balancer."
|
|
62
|
+
>
|
|
63
|
+
Destroy
|
|
64
|
+
</MenuItem>
|
|
65
|
+
)}
|
|
66
|
+
{canDestroyServerGroup && <MenuItem onClick={destroyServerGroup}>Destroy</MenuItem>}
|
|
67
|
+
{!canDestroyServerGroup && !cloudrunServerGroup.tags?.isLatest && (
|
|
68
|
+
<MenuItem
|
|
69
|
+
disabled={true}
|
|
70
|
+
title="You cannot destroy this server group while it is receiving traffic. You may be able to delete this server group's load balancer."
|
|
71
|
+
>
|
|
72
|
+
Destroy
|
|
73
|
+
</MenuItem>
|
|
74
|
+
)}
|
|
75
|
+
</Dropdown.Menu>
|
|
76
|
+
</Dropdown>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const CloudrunServerGroupActions = withRouter(CloudrunServerGroupActionsComponent);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ServerGroupReader } from '@spinnaker/core';
|
|
2
|
+
|
|
3
|
+
import { cloudrunServerGroupDetailsGetter } from './cloudrunServerGroupDetailsGetter';
|
|
4
|
+
|
|
5
|
+
describe('cloudrunServerGroupDetailsGetter', () => {
|
|
6
|
+
const props: any = {
|
|
7
|
+
app: {
|
|
8
|
+
name: 'fnord',
|
|
9
|
+
serverGroups: { data: [] },
|
|
10
|
+
loadBalancers: { data: [] },
|
|
11
|
+
},
|
|
12
|
+
serverGroup: {
|
|
13
|
+
name: 'service-v000',
|
|
14
|
+
accountId: 'test',
|
|
15
|
+
region: 'us-central1',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
it('auto-closes and completes when server group lookup fails', (done) => {
|
|
20
|
+
const autoClose = jasmine.createSpy('autoClose');
|
|
21
|
+
spyOn(ServerGroupReader, 'getServerGroup').and.returnValue(Promise.reject(new Error('not found')) as any);
|
|
22
|
+
|
|
23
|
+
cloudrunServerGroupDetailsGetter(props, autoClose).subscribe({
|
|
24
|
+
next: () => fail('should not emit a server group'),
|
|
25
|
+
error: () => fail('should not emit an error'),
|
|
26
|
+
complete: () => {
|
|
27
|
+
expect(autoClose).toHaveBeenCalled();
|
|
28
|
+
done();
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('auto-closes and completes when lookup returns no server group', (done) => {
|
|
34
|
+
const autoClose = jasmine.createSpy('autoClose');
|
|
35
|
+
spyOn(ServerGroupReader, 'getServerGroup').and.returnValue(Promise.resolve(null) as any);
|
|
36
|
+
|
|
37
|
+
cloudrunServerGroupDetailsGetter(props, autoClose).subscribe({
|
|
38
|
+
next: () => fail('should not emit a server group'),
|
|
39
|
+
error: () => fail('should not emit an error'),
|
|
40
|
+
complete: () => {
|
|
41
|
+
expect(autoClose).toHaveBeenCalled();
|
|
42
|
+
done();
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { isEmpty } from 'lodash';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
import type { IServerGroup, IServerGroupDetailsProps } from '@spinnaker/core';
|
|
5
|
+
import { ServerGroupReader } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
export const cloudrunServerGroupDetailsGetter = (
|
|
8
|
+
props: IServerGroupDetailsProps,
|
|
9
|
+
autoClose: () => void,
|
|
10
|
+
): Observable<IServerGroup> => {
|
|
11
|
+
const { app, serverGroup } = props;
|
|
12
|
+
return new Observable<IServerGroup>((observer) => {
|
|
13
|
+
ServerGroupReader.getServerGroup(app.name, serverGroup.accountId, serverGroup.region, serverGroup.name).then(
|
|
14
|
+
(serverGroupDetails: IServerGroup) => {
|
|
15
|
+
let fromApp = app.serverGroups.data.find((toCheck: IServerGroup) => {
|
|
16
|
+
return (
|
|
17
|
+
toCheck.name === serverGroup.name &&
|
|
18
|
+
toCheck.account === serverGroup.accountId &&
|
|
19
|
+
toCheck.region === serverGroup.region
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (!fromApp) {
|
|
24
|
+
app.loadBalancers.data.some((loadBalancer: any) => {
|
|
25
|
+
if (loadBalancer.account !== serverGroup.accountId) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return loadBalancer.serverGroups.some((toCheck: IServerGroup) => {
|
|
29
|
+
if (toCheck.name === serverGroup.name) {
|
|
30
|
+
fromApp = toCheck;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mergedServerGroup = { ...serverGroupDetails, ...fromApp };
|
|
39
|
+
if (isEmpty(mergedServerGroup)) {
|
|
40
|
+
autoClose();
|
|
41
|
+
observer.complete();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
observer.next(mergedServerGroup);
|
|
46
|
+
},
|
|
47
|
+
() => {
|
|
48
|
+
autoClose();
|
|
49
|
+
observer.complete();
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IServerGroupDetailsSectionProps } from '@spinnaker/core';
|
|
4
|
+
import { AccountTag, CollapsibleSection, HealthCounts, timestamp } from '@spinnaker/core';
|
|
5
|
+
|
|
6
|
+
export function CloudrunServerGroupInformationSection({ serverGroup }: IServerGroupDetailsSectionProps) {
|
|
7
|
+
return (
|
|
8
|
+
<CollapsibleSection heading="Server Group Information" defaultExpanded={true}>
|
|
9
|
+
<dl className="dl-horizontal dl-narrow">
|
|
10
|
+
<dt>Created</dt>
|
|
11
|
+
<dd>{timestamp(serverGroup.createdTime)}</dd>
|
|
12
|
+
<dt>In</dt>
|
|
13
|
+
<dd>
|
|
14
|
+
<AccountTag account={serverGroup.account} />
|
|
15
|
+
</dd>
|
|
16
|
+
<dt>Region</dt>
|
|
17
|
+
<dd>{serverGroup.region}</dd>
|
|
18
|
+
</dl>
|
|
19
|
+
</CollapsibleSection>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function CloudrunServerGroupSizeSection({ serverGroup }: IServerGroupDetailsSectionProps) {
|
|
24
|
+
const capacity = serverGroup.capacity || ({} as any);
|
|
25
|
+
const current = serverGroup.instances?.length || 0;
|
|
26
|
+
return (
|
|
27
|
+
<CollapsibleSection heading="Size" defaultExpanded={true}>
|
|
28
|
+
<dl className="dl-horizontal dl-narrow">
|
|
29
|
+
{capacity.min === capacity.max ? (
|
|
30
|
+
<>
|
|
31
|
+
<dt>Min/Max</dt>
|
|
32
|
+
<dd>{capacity.min}</dd>
|
|
33
|
+
</>
|
|
34
|
+
) : (
|
|
35
|
+
<>
|
|
36
|
+
<dt>Min</dt>
|
|
37
|
+
<dd>{capacity.min}</dd>
|
|
38
|
+
<dt>Max</dt>
|
|
39
|
+
<dd>{capacity.max}</dd>
|
|
40
|
+
</>
|
|
41
|
+
)}
|
|
42
|
+
<dt>Current</dt>
|
|
43
|
+
<dd>{current}</dd>
|
|
44
|
+
</dl>
|
|
45
|
+
</CollapsibleSection>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function CloudrunServerGroupHealthSection({ serverGroup }: IServerGroupDetailsSectionProps) {
|
|
50
|
+
return (
|
|
51
|
+
<CollapsibleSection heading="Health" defaultExpanded={true}>
|
|
52
|
+
<dl className="dl-horizontal dl-narrow">
|
|
53
|
+
<dt>Instances</dt>
|
|
54
|
+
<dd>
|
|
55
|
+
<HealthCounts container={serverGroup.instanceCounts} className="pull-left" />
|
|
56
|
+
</dd>
|
|
57
|
+
</dl>
|
|
58
|
+
</CollapsibleSection>
|
|
59
|
+
);
|
|
60
|
+
}
|
package/src/serverGroup/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from './configure/serverGroupCommandBuilder.service';
|
|
2
2
|
export * from './serverGroupTransformer.service';
|
|
3
|
-
export * from './details/
|
|
3
|
+
export * from './details/CloudrunServerGroupActions';
|
|
4
|
+
export * from './details/cloudrunServerGroupDetailsGetter';
|
|
5
|
+
export * from './details/sections';
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { mount, shallow } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { MenuItem } from 'react-bootstrap';
|
|
4
|
+
|
|
5
|
+
import { ConfirmationModalService, DeckRuntimeContext, ServerGroupNamePreview } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { ServerGroupBasicSettingsComponent } from './configure/wizard/BasicSettings';
|
|
8
|
+
import { ServerGroupWizardComponent } from './configure/wizard/serverGroupWizard';
|
|
9
|
+
import { CloudrunServerGroupActionsComponent } from './details/CloudrunServerGroupActions';
|
|
10
|
+
|
|
11
|
+
describe('Cloud Run server group router consumers', () => {
|
|
12
|
+
it('opens the latest server group through the injected state service', () => {
|
|
13
|
+
const go = jasmine.createSpy('go');
|
|
14
|
+
const component = shallow(
|
|
15
|
+
<ServerGroupBasicSettingsComponent
|
|
16
|
+
{...({ router: {}, stateParams: {}, stateService: { go, is: () => true } } as any)}
|
|
17
|
+
accounts={[]}
|
|
18
|
+
app={
|
|
19
|
+
{
|
|
20
|
+
clusters: [],
|
|
21
|
+
name: 'app',
|
|
22
|
+
serverGroups: {
|
|
23
|
+
data: [{ account: 'test', cluster: 'app-main', createdTime: 1, name: 'app-main-v001', region: 'us' }],
|
|
24
|
+
},
|
|
25
|
+
} as any
|
|
26
|
+
}
|
|
27
|
+
detailsChanged={() => undefined}
|
|
28
|
+
formik={
|
|
29
|
+
{
|
|
30
|
+
values: {
|
|
31
|
+
command: {
|
|
32
|
+
credentials: 'test',
|
|
33
|
+
region: 'us',
|
|
34
|
+
selectedProvider: 'cloudrun',
|
|
35
|
+
viewState: { mode: 'create' },
|
|
36
|
+
},
|
|
37
|
+
stack: 'main',
|
|
38
|
+
},
|
|
39
|
+
} as any
|
|
40
|
+
}
|
|
41
|
+
onAccountSelect={() => undefined}
|
|
42
|
+
onEnterStack={() => undefined}
|
|
43
|
+
selectedAccount="test"
|
|
44
|
+
/>,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
component.find(ServerGroupNamePreview).prop('navigateToLatestServerGroup')();
|
|
48
|
+
|
|
49
|
+
expect(go).toHaveBeenCalledWith('.serverGroup', {
|
|
50
|
+
accountId: 'test',
|
|
51
|
+
provider: 'cloudrun',
|
|
52
|
+
region: 'us',
|
|
53
|
+
serverGroup: 'app-main-v001',
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('closes destroyed server group details through the injected state service', () => {
|
|
58
|
+
const go = jasmine.createSpy('go');
|
|
59
|
+
const confirm = spyOn(ConfirmationModalService, 'confirm');
|
|
60
|
+
const component = mount(
|
|
61
|
+
<DeckRuntimeContext.Provider value={{ services: { serverGroupWriter: {} } } as any}>
|
|
62
|
+
<CloudrunServerGroupActionsComponent
|
|
63
|
+
{...({ router: {}, stateParams: {}, stateService: { go, includes: () => true } } as any)}
|
|
64
|
+
app={{ attributes: {} } as any}
|
|
65
|
+
serverGroup={
|
|
66
|
+
{
|
|
67
|
+
account: 'test',
|
|
68
|
+
disabled: true,
|
|
69
|
+
name: 'app-v001',
|
|
70
|
+
region: 'us',
|
|
71
|
+
tags: { isLatest: false },
|
|
72
|
+
} as any
|
|
73
|
+
}
|
|
74
|
+
/>
|
|
75
|
+
</DeckRuntimeContext.Provider>,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
component.find(MenuItem).first().prop('onClick')();
|
|
79
|
+
confirm.calls.mostRecent().args[0].taskMonitorConfig.onTaskComplete();
|
|
80
|
+
|
|
81
|
+
expect(go).toHaveBeenCalledWith('^');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('opens a newly created server group through the injected state service', () => {
|
|
85
|
+
const go = jasmine.createSpy('go');
|
|
86
|
+
const component = new ServerGroupWizardComponent({
|
|
87
|
+
application: { serverGroups: {} },
|
|
88
|
+
closeModal: () => undefined,
|
|
89
|
+
command: {
|
|
90
|
+
command: { credentials: 'test', region: 'us', viewState: { submitButtonLabel: 'Create' } },
|
|
91
|
+
},
|
|
92
|
+
dismissModal: () => undefined,
|
|
93
|
+
router: {},
|
|
94
|
+
stateParams: {},
|
|
95
|
+
stateService: { go, includes: (state: string) => state === '**.clusters' },
|
|
96
|
+
title: 'Create server group',
|
|
97
|
+
} as any);
|
|
98
|
+
component.state.taskMonitor = {
|
|
99
|
+
task: {
|
|
100
|
+
execution: {
|
|
101
|
+
stages: [{ context: { 'deploy.server.groups': { us: 'app-v001' } }, type: 'cloneServerGroup' }],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
} as any;
|
|
105
|
+
|
|
106
|
+
(component as any).onApplicationRefresh();
|
|
107
|
+
|
|
108
|
+
expect(go).toHaveBeenCalledWith('.serverGroup', {
|
|
109
|
+
accountId: 'test',
|
|
110
|
+
provider: 'cloudrun',
|
|
111
|
+
region: 'us',
|
|
112
|
+
serverGroup: 'app-v001',
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('owns the server group refresh subscription across replacement and unmount', () => {
|
|
117
|
+
const firstUnsubscribe = jasmine.createSpy('firstUnsubscribe');
|
|
118
|
+
const secondUnsubscribe = jasmine.createSpy('secondUnsubscribe');
|
|
119
|
+
const callbacks: Array<() => void> = [];
|
|
120
|
+
const onNextRefresh = jasmine.createSpy('onNextRefresh').and.callFake((callback: () => void) => {
|
|
121
|
+
callbacks.push(callback);
|
|
122
|
+
return callbacks.length === 1 ? firstUnsubscribe : secondUnsubscribe;
|
|
123
|
+
});
|
|
124
|
+
const refresh = jasmine.createSpy('refresh');
|
|
125
|
+
const go = jasmine.createSpy('go');
|
|
126
|
+
const component = new ServerGroupWizardComponent({
|
|
127
|
+
application: { serverGroups: { onNextRefresh, refresh } },
|
|
128
|
+
closeModal: jasmine.createSpy('closeModal'),
|
|
129
|
+
command: { command: { credentials: 'test', region: 'us', viewState: { submitButtonLabel: 'Create' } } },
|
|
130
|
+
dismissModal: jasmine.createSpy('dismissModal'),
|
|
131
|
+
router: {},
|
|
132
|
+
stateParams: {},
|
|
133
|
+
stateService: { go, includes: () => false },
|
|
134
|
+
title: 'Create server group',
|
|
135
|
+
} as any) as any;
|
|
136
|
+
|
|
137
|
+
component.onTaskComplete();
|
|
138
|
+
|
|
139
|
+
expect(onNextRefresh.calls.first().invocationOrder).toBeLessThan(refresh.calls.first().invocationOrder);
|
|
140
|
+
|
|
141
|
+
component.onTaskComplete();
|
|
142
|
+
|
|
143
|
+
expect(firstUnsubscribe).toHaveBeenCalledTimes(1);
|
|
144
|
+
|
|
145
|
+
component.componentWillUnmount();
|
|
146
|
+
callbacks[1]();
|
|
147
|
+
|
|
148
|
+
expect(secondUnsubscribe).toHaveBeenCalledTimes(1);
|
|
149
|
+
expect(component.applicationRefreshUnsubscribe).toBeUndefined();
|
|
150
|
+
expect(go).not.toHaveBeenCalled();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { module } from 'angular';
|
|
2
1
|
import type { IServerGroup } from '@spinnaker/core';
|
|
3
2
|
|
|
4
3
|
import type { ICloudrunServerGroupCommand } from '../serverGroup/configure/serverGroupCommandBuilder.service';
|
|
5
4
|
|
|
6
5
|
export class CloudrunV2ServerGroupTransformer {
|
|
7
|
-
public
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
public normalizeServerGroup(serverGroup: IServerGroup): PromiseLike<IServerGroup> {
|
|
11
|
-
return this.$q.resolve(serverGroup);
|
|
6
|
+
public normalizeServerGroup(serverGroup: IServerGroup): Promise<IServerGroup> {
|
|
7
|
+
return Promise.resolve(serverGroup);
|
|
12
8
|
}
|
|
13
9
|
|
|
14
10
|
public convertServerGroupCommandToDeployConfiguration(command: ICloudrunServerGroupCommand): any {
|
|
@@ -53,9 +49,3 @@ export class CloudrunDeployDescription {
|
|
|
53
49
|
this.configArtifacts = [];
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
|
-
|
|
57
|
-
export const CLOUDRUN_SERVER_GROUP_TRANSFORMER = 'spinnaker.cloudrun.serverGroup.transformer.service';
|
|
58
|
-
module(CLOUDRUN_SERVER_GROUP_TRANSFORMER, []).service(
|
|
59
|
-
'cloudrunV2ServerGroupTransformer',
|
|
60
|
-
CloudrunV2ServerGroupTransformer,
|
|
61
|
-
);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_COMPONENT_URL_DETAILS = "spinnaker.cloudrun.componentUrlDetails.component";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_CONDITIONAL_DESCRIPTION_LIST_ITEM = "spinnaker.cloudrun.conditionalDescriptionListItem";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_LOAD_BALANCER_CREATE_MESSAGE = "spinnaker.cloudrun.loadBalancer.createMessage.component";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_INSTANCE_DETAILS_CTRL = "spinnaker.cloudrun.instanceDetails.controller";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_ALLOCATION_CONFIGURATION_ROW = "spinnaker.cloudrun.allocationConfigurationRow.component";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_LOAD_BALANCER_BASIC_SETTINGS = "spinnaker.cloudrun.loadBalancerSettings.component";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_STAGE_ALLOCATION_CONFIGURATION_ROW = "spinnaker.cloudrun.stageAllocationConfigurationRow.component";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_LOAD_BALANCER_DETAILS_CTRL = "spinnaker.cloudrun.loadBalancerDetails.controller";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_PIPELINE_MODULE = "spinnaker.cloudrun.pipeline.module";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_LOAD_BALANCER_CHOICE_MODAL_CTRL = "spinnaker.Cloudrun.loadBalancerChoiceModal.controller";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CLOUDRUN_SERVER_GROUP_DETAILS_CTRL = "spinnaker.cloudrun.serverGroup.details.controller";
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { IComponentOptions } from 'angular';
|
|
2
|
-
import { module } from 'angular';
|
|
3
|
-
|
|
4
|
-
const cloudrunComponentUrlDetailsComponent: IComponentOptions = {
|
|
5
|
-
bindings: { component: '<' },
|
|
6
|
-
template: `
|
|
7
|
-
<dt>HTTPS</dt>
|
|
8
|
-
<dl class="small">
|
|
9
|
-
<a href="{{$ctrl.component.url}}" target="_blank">{{$ctrl.component.url}}</a>
|
|
10
|
-
<copy-to-clipboard class="copy-to-clipboard copy-to-clipboard-sm"
|
|
11
|
-
tool-tip="'Copy URL to clipboard'"
|
|
12
|
-
text="$ctrl.component.httpsUrl"></copy-to-clipboard>
|
|
13
|
-
</dl>
|
|
14
|
-
`,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const CLOUDRUN_COMPONENT_URL_DETAILS = 'spinnaker.cloudrun.componentUrlDetails.component';
|
|
18
|
-
|
|
19
|
-
module(CLOUDRUN_COMPONENT_URL_DETAILS, []).component(
|
|
20
|
-
'cloudrunComponentUrlDetails',
|
|
21
|
-
cloudrunComponentUrlDetailsComponent,
|
|
22
|
-
);
|