@spinnaker/appengine 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 (131) hide show
  1. package/dist/appengine.module.d.ts +7 -1
  2. package/dist/domain/index.d.ts +0 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/instance/details/AppengineInstanceDetails.d.ts +11 -0
  7. package/dist/loadBalancer/configure/AppengineCreateLoadBalancerModal.d.ts +29 -0
  8. package/dist/loadBalancer/details/AppengineLoadBalancerActions.d.ts +5 -0
  9. package/dist/loadBalancer/details/AppengineLoadBalancerDetailsSection.d.ts +3 -0
  10. package/dist/loadBalancer/details/index.d.ts +3 -0
  11. package/dist/loadBalancer/details/useAppengineLoadBalancerDetails.d.ts +3 -0
  12. package/dist/loadBalancer/transformer.d.ts +2 -6
  13. package/dist/pipeline/stages/AppengineExecutionDetails.d.ts +15 -0
  14. package/dist/pipeline/stages/AppengineServerGroupStageConfig.d.ts +12 -0
  15. package/dist/pipeline/stages/destroyAsg/appengineDestroyAsgStage.d.ts +1 -1
  16. package/dist/pipeline/stages/disableAsg/appengineDisableAsgStage.d.ts +1 -1
  17. package/dist/pipeline/stages/editLoadBalancer/AppengineEditLoadBalancerStageConfig.d.ts +3 -0
  18. package/dist/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.d.ts +1 -1
  19. package/dist/pipeline/stages/enableAsg/appengineEnableAsgStage.d.ts +1 -1
  20. package/dist/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.d.ts +1 -1
  21. package/dist/pipeline/stages/startServerGroup/appengineStartServerGroupStage.d.ts +1 -1
  22. package/dist/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.d.ts +1 -1
  23. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +5 -9
  24. package/dist/serverGroup/configure/wizard/AppengineCloneServerGroupModal.d.ts +22 -0
  25. package/dist/serverGroup/details/AppengineServerGroupActions.d.ts +12 -0
  26. package/dist/serverGroup/details/AppengineServerGroupDetailsSection.d.ts +3 -0
  27. package/dist/serverGroup/details/appengineServerGroupDetailsGetter.d.ts +4 -0
  28. package/dist/serverGroup/details/index.d.ts +3 -0
  29. package/dist/serverGroup/transformer.d.ts +1 -5
  30. package/dist/serverGroup/writer/serverGroup.write.service.d.ts +15 -4
  31. package/package.json +4 -8
  32. package/src/appengine.module.spec.ts +194 -0
  33. package/src/appengine.module.ts +47 -58
  34. package/src/domain/index.ts +0 -1
  35. package/src/index.ts +1 -1
  36. package/src/instance/details/AppengineInstanceDetails.tsx +33 -0
  37. package/src/loadBalancer/configure/AppengineCreateLoadBalancerModal.tsx +342 -0
  38. package/src/loadBalancer/details/AppengineLoadBalancerActions.tsx +66 -0
  39. package/src/loadBalancer/details/AppengineLoadBalancerDetailsSection.tsx +42 -0
  40. package/src/loadBalancer/details/index.ts +3 -0
  41. package/src/loadBalancer/details/useAppengineLoadBalancerDetails.ts +37 -0
  42. package/src/loadBalancer/transformer.ts +3 -14
  43. package/src/pipeline/stages/AppengineExecutionDetails.tsx +90 -0
  44. package/src/pipeline/stages/AppengineServerGroupStageConfig.tsx +190 -0
  45. package/src/pipeline/stages/destroyAsg/appengineDestroyAsgStage.ts +17 -43
  46. package/src/pipeline/stages/disableAsg/appengineDisableAsgStage.ts +18 -53
  47. package/src/pipeline/stages/editLoadBalancer/AppengineEditLoadBalancerStageConfig.tsx +94 -0
  48. package/src/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.ts +14 -74
  49. package/src/pipeline/stages/enableAsg/appengineEnableAsgStage.ts +13 -48
  50. package/src/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.ts +13 -61
  51. package/src/pipeline/stages/startServerGroup/appengineStartServerGroupStage.ts +17 -54
  52. package/src/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.ts +17 -54
  53. package/src/serverGroup/configure/serverGroupCommandBuilder.service.ts +20 -19
  54. package/src/serverGroup/configure/wizard/AppengineCloneServerGroupModal.tsx +119 -0
  55. package/src/serverGroup/configure/wizard/serverGroupWizard.less +0 -8
  56. package/src/serverGroup/details/AppengineServerGroupActions.tsx +245 -0
  57. package/src/serverGroup/details/AppengineServerGroupDetailsSection.tsx +27 -0
  58. package/src/serverGroup/details/appengineServerGroupDetailsGetter.ts +62 -0
  59. package/src/serverGroup/details/index.ts +3 -0
  60. package/src/serverGroup/transformer.ts +3 -15
  61. package/src/serverGroup/writer/serverGroup.write.service.ts +57 -8
  62. package/dist/common/componentUrlDetails.component.d.ts +0 -1
  63. package/dist/common/conditionalDescriptionListItem.component.d.ts +0 -1
  64. package/dist/common/loadBalancerMessage.component.d.ts +0 -1
  65. package/dist/domain/IAppengineStageScope.d.ts +0 -18
  66. package/dist/instance/details/details.controller.d.ts +0 -1
  67. package/dist/loadBalancer/configure/wizard/advancedSettings.component.d.ts +0 -1
  68. package/dist/loadBalancer/configure/wizard/allocationConfigurationRow.component.d.ts +0 -1
  69. package/dist/loadBalancer/configure/wizard/basicSettings.component.d.ts +0 -1
  70. package/dist/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.d.ts +0 -1
  71. package/dist/loadBalancer/configure/wizard/wizard.controller.d.ts +0 -2
  72. package/dist/loadBalancer/details/details.controller.d.ts +0 -1
  73. package/dist/loadBalancer/loadBalancer.module.d.ts +0 -1
  74. package/dist/pipeline/pipeline.module.d.ts +0 -1
  75. package/dist/pipeline/stages/appengineStage.controller.d.ts +0 -12
  76. package/dist/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.d.ts +0 -1
  77. package/dist/serverGroup/configure/wizard/basicSettings.controller.d.ts +0 -1
  78. package/dist/serverGroup/configure/wizard/cloneServerGroup.controller.d.ts +0 -2
  79. package/dist/serverGroup/configure/wizard/configFileArtifactList.module.d.ts +0 -1
  80. package/dist/serverGroup/configure/wizard/configFiles.component.d.ts +0 -20
  81. package/dist/serverGroup/configure/wizard/dynamicBranchLabel.component.d.ts +0 -1
  82. package/dist/serverGroup/details/details.controller.d.ts +0 -1
  83. package/src/common/componentUrlDetails.component.ts +0 -29
  84. package/src/common/conditionalDescriptionListItem.component.ts +0 -37
  85. package/src/common/loadBalancerMessage.component.html +0 -33
  86. package/src/common/loadBalancerMessage.component.ts +0 -13
  87. package/src/domain/IAppengineStageScope.ts +0 -22
  88. package/src/instance/details/details.controller.ts +0 -116
  89. package/src/instance/details/details.html +0 -99
  90. package/src/loadBalancer/configure/wizard/advancedSettings.component.ts +0 -56
  91. package/src/loadBalancer/configure/wizard/allocationConfigurationRow.component.ts +0 -70
  92. package/src/loadBalancer/configure/wizard/basicSettings.component.html +0 -65
  93. package/src/loadBalancer/configure/wizard/basicSettings.component.ts +0 -98
  94. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html +0 -117
  95. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.ts +0 -108
  96. package/src/loadBalancer/configure/wizard/wizard.controller.ts +0 -163
  97. package/src/loadBalancer/configure/wizard/wizard.html +0 -44
  98. package/src/loadBalancer/configure/wizard/wizard.less +0 -17
  99. package/src/loadBalancer/details/details.controller.ts +0 -151
  100. package/src/loadBalancer/details/details.html +0 -102
  101. package/src/loadBalancer/loadBalancer.module.ts +0 -21
  102. package/src/pipeline/pipeline.module.ts +0 -20
  103. package/src/pipeline/stages/appengineStage.controller.ts +0 -45
  104. package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -16
  105. package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
  106. package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -18
  107. package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
  108. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html +0 -33
  109. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html +0 -51
  110. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.ts +0 -65
  111. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html +0 -45
  112. package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -18
  113. package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
  114. package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -41
  115. package/src/pipeline/stages/startServerGroup/startServerGroupExecutionDetails.html +0 -26
  116. package/src/pipeline/stages/startServerGroup/startServerGroupStage.html +0 -18
  117. package/src/pipeline/stages/startServerGroup/startServerGroupStepLabel.html +0 -1
  118. package/src/pipeline/stages/stopServerGroup/stopServerGroupExecutionDetails.html +0 -26
  119. package/src/pipeline/stages/stopServerGroup/stopServerGroupStage.html +0 -18
  120. package/src/pipeline/stages/stopServerGroup/stopServerGroupStepLabel.html +0 -1
  121. package/src/serverGroup/configure/wizard/advancedSettings.html +0 -33
  122. package/src/serverGroup/configure/wizard/basicSettings.controller.ts +0 -151
  123. package/src/serverGroup/configure/wizard/basicSettings.html +0 -287
  124. package/src/serverGroup/configure/wizard/cloneServerGroup.controller.ts +0 -103
  125. package/src/serverGroup/configure/wizard/configFileArtifactList.module.ts +0 -18
  126. package/src/serverGroup/configure/wizard/configFiles.component.html +0 -81
  127. package/src/serverGroup/configure/wizard/configFiles.component.ts +0 -121
  128. package/src/serverGroup/configure/wizard/dynamicBranchLabel.component.ts +0 -19
  129. package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -39
  130. package/src/serverGroup/details/details.controller.ts +0 -463
  131. package/src/serverGroup/details/details.html +0 -229
@@ -0,0 +1,190 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ import type { IStageConfigProps } from '@spinnaker/core';
4
+ import {
5
+ AccountRegionClusterSelector,
6
+ AccountService,
7
+ PlatformHealthOverride,
8
+ StageConfigField,
9
+ StageConstants,
10
+ TargetSelect,
11
+ } from '@spinnaker/core';
12
+
13
+ import { AppengineHealth } from '../../common/appengineHealth';
14
+ import type { IAppengineAccount } from '../../domain';
15
+
16
+ export function getAppengineAccountRegion(accounts: IAppengineAccount[], credentials: string): string {
17
+ return accounts.find((account) => account.name === credentials)?.region;
18
+ }
19
+
20
+ export function initializeAppengineServerGroupStage(stage: any, application: any): void {
21
+ stage.cloudProvider = 'appengine';
22
+ stage.cloudProviderType = 'appengine';
23
+
24
+ if (
25
+ stage.isNew &&
26
+ application?.attributes?.platformHealthOnlyShowOverride &&
27
+ application?.attributes?.platformHealthOnly
28
+ ) {
29
+ stage.interestingHealthProviderNames = [AppengineHealth.PLATFORM];
30
+ }
31
+ }
32
+
33
+ type AppengineStageConfigProps = Pick<IStageConfigProps, 'application' | 'pipeline' | 'stage' | 'updateStage'> & {
34
+ showHealthOverride?: boolean;
35
+ };
36
+
37
+ export function AppengineServerGroupStageConfig({
38
+ application,
39
+ pipeline,
40
+ stage,
41
+ updateStage,
42
+ showHealthOverride = false,
43
+ }: AppengineStageConfigProps) {
44
+ const [accounts, setAccounts] = useState<IAppengineAccount[]>([]);
45
+
46
+ useEffect(() => {
47
+ initializeAppengineServerGroupStage(stage, application);
48
+ AccountService.listAccounts('appengine').then((loadedAccounts: IAppengineAccount[]) => {
49
+ setAccounts(loadedAccounts);
50
+ const credentials = stage.credentials || application?.defaultCredentials?.appengine;
51
+ const region = getAppengineAccountRegion(loadedAccounts, credentials);
52
+ if (credentials || region) {
53
+ stage.credentials = credentials || stage.credentials;
54
+ stage.region = region || stage.region;
55
+ updateStage(stage);
56
+ }
57
+ });
58
+ }, []);
59
+
60
+ const onAccountUpdate = (credentials: string) => {
61
+ AccountService.getAccountDetails(credentials).then((accountDetails: IAppengineAccount) => {
62
+ stage.region = accountDetails?.region || stage.region;
63
+ updateStage(stage);
64
+ });
65
+ };
66
+
67
+ return (
68
+ <div className="form-horizontal">
69
+ {!pipeline?.strategy && (
70
+ <AccountRegionClusterSelector
71
+ accounts={accounts}
72
+ application={application}
73
+ component={stage}
74
+ disableRegionSelect={true}
75
+ onAccountUpdate={onAccountUpdate}
76
+ onComponentUpdate={updateStage}
77
+ singleRegion="true"
78
+ />
79
+ )}
80
+ <StageConfigField label="Target">
81
+ <TargetSelect
82
+ model={{ target: stage.target }}
83
+ onChange={(target: string) => {
84
+ stage.target = target;
85
+ updateStage(stage);
86
+ }}
87
+ options={StageConstants.TARGET_LIST}
88
+ />
89
+ </StageConfigField>
90
+ {showHealthOverride && application?.attributes?.platformHealthOnlyShowOverride && (
91
+ <PlatformHealthOverride
92
+ interestingHealthProviderNames={stage.interestingHealthProviderNames || []}
93
+ onChange={(interestingHealthProviderNames) => {
94
+ stage.interestingHealthProviderNames = interestingHealthProviderNames;
95
+ updateStage(stage);
96
+ }}
97
+ platformHealthType={AppengineHealth.PLATFORM}
98
+ />
99
+ )}
100
+ </div>
101
+ );
102
+ }
103
+
104
+ export function AppengineServerGroupStageConfigWithHealthOverride(props: AppengineStageConfigProps) {
105
+ return <AppengineServerGroupStageConfig {...props} showHealthOverride={true} />;
106
+ }
107
+
108
+ export function AppengineShrinkClusterStageConfig({
109
+ application,
110
+ pipeline,
111
+ stage,
112
+ updateStage,
113
+ }: AppengineStageConfigProps) {
114
+ useEffect(() => {
115
+ initializeAppengineServerGroupStage(stage, application);
116
+ if (stage.shrinkToSize === undefined) {
117
+ stage.shrinkToSize = 1;
118
+ }
119
+ if (stage.allowDeleteActive === undefined) {
120
+ stage.allowDeleteActive = false;
121
+ }
122
+ if (stage.retainLargerOverNewer === undefined) {
123
+ stage.retainLargerOverNewer = 'false';
124
+ }
125
+ stage.retainLargerOverNewer = stage.retainLargerOverNewer.toString();
126
+ updateStage(stage);
127
+ }, []);
128
+
129
+ const update = (field: string, value: any) => {
130
+ stage[field] = value;
131
+ updateStage(stage);
132
+ };
133
+
134
+ return (
135
+ <div className="form-horizontal">
136
+ <AppengineServerGroupStageConfig
137
+ application={application}
138
+ pipeline={pipeline}
139
+ stage={stage}
140
+ updateStage={updateStage}
141
+ />
142
+ <div className="form-group">
143
+ <label className="col-md-3 sm-label-right">Shrink Options</label>
144
+ <div className="col-md-7 form-inline">
145
+ Shrink to{' '}
146
+ <input
147
+ className="form-control input-sm"
148
+ min={0}
149
+ onChange={(event) => update('shrinkToSize', Number(event.target.value))}
150
+ style={{ width: 60 }}
151
+ type="number"
152
+ value={stage.shrinkToSize || 0}
153
+ />{' '}
154
+ server groups, keeping the{' '}
155
+ <select
156
+ className="form-control input-sm"
157
+ onChange={(event) => update('retainLargerOverNewer', event.target.value)}
158
+ style={{ width: 100 }}
159
+ value={stage.retainLargerOverNewer || 'false'}
160
+ >
161
+ <option value="true">largest</option>
162
+ <option value="false">newest</option>
163
+ </select>
164
+ </div>
165
+ </div>
166
+ <div className="form-group">
167
+ <div className="col-md-offset-3 col-md-7 checkbox">
168
+ <label>
169
+ <input
170
+ checked={!!stage.allowDeleteActive}
171
+ onChange={(event) => update('allowDeleteActive', event.target.checked)}
172
+ type="checkbox"
173
+ />{' '}
174
+ Allow deletion of active server groups
175
+ </label>
176
+ </div>
177
+ </div>
178
+ {application?.attributes?.platformHealthOnlyShowOverride && (
179
+ <PlatformHealthOverride
180
+ interestingHealthProviderNames={stage.interestingHealthProviderNames || []}
181
+ onChange={(interestingHealthProviderNames) => {
182
+ stage.interestingHealthProviderNames = interestingHealthProviderNames;
183
+ updateStage(stage);
184
+ }}
185
+ platformHealthType={AppengineHealth.PLATFORM}
186
+ />
187
+ )}
188
+ </div>
189
+ );
190
+ }
@@ -1,45 +1,19 @@
1
- import { module } from 'angular';
2
-
3
1
  import { Registry } from '@spinnaker/core';
2
+ import { AppengineServerGroupStageConfig } from '../AppengineServerGroupStageConfig';
4
3
 
5
- import { AppengineStageCtrl } from '../appengineStage.controller';
6
- import type { IAppengineStageScope } from '../../../domain';
7
-
8
- class AppengineDestroyAsgStageCtrl extends AppengineStageCtrl {
9
- public static $inject = ['$scope'];
10
- constructor(protected $scope: IAppengineStageScope) {
11
- super($scope);
12
-
13
- super.setAccounts().then(() => {
14
- super.setStageRegion();
15
- });
16
-
17
- super.setStageCloudProvider();
18
- super.setTargets();
19
- super.setStageCredentials();
20
- }
21
- }
22
-
23
- export const APPENGINE_DESTROY_ASG_STAGE = 'spinnaker.appengine.pipeline.stage.destroyAsgStage';
24
-
25
- module(APPENGINE_DESTROY_ASG_STAGE, [])
26
- .config(() => {
27
- Registry.pipeline.registerStage({
28
- provides: 'destroyServerGroup',
29
- key: 'destroyServerGroup',
30
- cloudProvider: 'appengine',
31
- templateUrl: require('./destroyAsgStage.html'),
32
- executionStepLabelUrl: require('./destroyAsgStepLabel.html'),
33
- validators: [
34
- {
35
- type: 'targetImpedance',
36
- message:
37
- 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',
38
- },
39
- { type: 'requiredField', fieldName: 'cluster' },
40
- { type: 'requiredField', fieldName: 'target' },
41
- { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
42
- ],
43
- });
44
- })
45
- .controller('appengineDestroyAsgStageCtrl', AppengineDestroyAsgStageCtrl);
4
+ Registry.pipeline.registerStage({
5
+ provides: 'destroyServerGroup',
6
+ key: 'destroyServerGroup',
7
+ cloudProvider: 'appengine',
8
+ component: AppengineServerGroupStageConfig,
9
+ validators: [
10
+ {
11
+ type: 'targetImpedance',
12
+ message:
13
+ 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',
14
+ },
15
+ { type: 'requiredField', fieldName: 'cluster' },
16
+ { type: 'requiredField', fieldName: 'target' },
17
+ { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
18
+ ],
19
+ });
@@ -1,54 +1,19 @@
1
- import { module } from 'angular';
2
-
3
1
  import { Registry } from '@spinnaker/core';
4
-
5
- import { AppengineStageCtrl } from '../appengineStage.controller';
6
- import { AppengineHealth } from '../../../common/appengineHealth';
7
- import type { IAppengineStageScope } from '../../../domain';
8
-
9
- class AppengineDisableAsgStageCtrl extends AppengineStageCtrl {
10
- public static $inject = ['$scope'];
11
- constructor(protected $scope: IAppengineStageScope) {
12
- super($scope);
13
-
14
- super.setAccounts().then(() => {
15
- super.setStageRegion();
16
- });
17
-
18
- super.setStageCloudProvider();
19
- super.setTargets();
20
- super.setStageCredentials();
21
-
22
- if (
23
- $scope.stage.isNew &&
24
- $scope.application.attributes.platformHealthOnlyShowOverride &&
25
- $scope.application.attributes.platformHealthOnly
26
- ) {
27
- $scope.stage.interestingHealthProviderNames = [AppengineHealth.PLATFORM];
28
- }
29
- }
30
- }
31
-
32
- export const APPENGINE_DISABLE_ASG_STAGE = 'spinnaker.appengine.pipeline.stage.disableAsgStage';
33
-
34
- module(APPENGINE_DISABLE_ASG_STAGE, [])
35
- .config(() => {
36
- Registry.pipeline.registerStage({
37
- provides: 'disableServerGroup',
38
- key: 'disableServerGroup',
39
- cloudProvider: 'appengine',
40
- templateUrl: require('./disableAsgStage.html'),
41
- executionStepLabelUrl: require('./disableAsgStepLabel.html'),
42
- validators: [
43
- {
44
- type: 'targetImpedance',
45
- message:
46
- 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',
47
- },
48
- { type: 'requiredField', fieldName: 'cluster' },
49
- { type: 'requiredField', fieldName: 'target' },
50
- { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
51
- ],
52
- });
53
- })
54
- .controller('appengineDisableAsgStageCtrl', AppengineDisableAsgStageCtrl);
2
+ import { AppengineServerGroupStageConfigWithHealthOverride } from '../AppengineServerGroupStageConfig';
3
+
4
+ Registry.pipeline.registerStage({
5
+ provides: 'disableServerGroup',
6
+ key: 'disableServerGroup',
7
+ cloudProvider: 'appengine',
8
+ component: AppengineServerGroupStageConfigWithHealthOverride,
9
+ validators: [
10
+ {
11
+ type: 'targetImpedance',
12
+ message:
13
+ 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',
14
+ },
15
+ { type: 'requiredField', fieldName: 'cluster' },
16
+ { type: 'requiredField', fieldName: 'target' },
17
+ { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
18
+ ],
19
+ });
@@ -0,0 +1,94 @@
1
+ import React, { useEffect } from 'react';
2
+
3
+ import type { ILoadBalancer, IStageConfigProps } from '@spinnaker/core';
4
+
5
+ import { AppengineCreateLoadBalancerModal } from '../../../loadBalancer/configure/AppengineCreateLoadBalancerModal';
6
+
7
+ export function AppengineEditLoadBalancerStageConfig({ application, stage, updateStage }: IStageConfigProps) {
8
+ useEffect(() => {
9
+ stage.loadBalancers = stage.loadBalancers || [];
10
+ stage.cloudProvider = 'appengine';
11
+ updateStage(stage);
12
+ }, []);
13
+
14
+ const setLoadBalancers = (loadBalancers: ILoadBalancer[]) => {
15
+ stage.loadBalancers = loadBalancers;
16
+ updateStage(stage);
17
+ };
18
+
19
+ const addLoadBalancer = () => {
20
+ AppengineCreateLoadBalancerModal.show({
21
+ app: application,
22
+ loadBalancer: null,
23
+ forPipelineConfig: true,
24
+ isNew: true,
25
+ } as any)
26
+ .then((loadBalancer) => setLoadBalancers([...(stage.loadBalancers || []), loadBalancer]))
27
+ .catch(() => {});
28
+ };
29
+
30
+ const editLoadBalancer = (index: number) => {
31
+ AppengineCreateLoadBalancerModal.show({
32
+ app: application,
33
+ loadBalancer: stage.loadBalancers[index],
34
+ forPipelineConfig: true,
35
+ isNew: false,
36
+ } as any)
37
+ .then((loadBalancer) => {
38
+ const loadBalancers = [...stage.loadBalancers];
39
+ loadBalancers[index] = loadBalancer;
40
+ setLoadBalancers(loadBalancers);
41
+ })
42
+ .catch(() => {});
43
+ };
44
+
45
+ const removeLoadBalancer = (index: number) => {
46
+ setLoadBalancers(stage.loadBalancers.filter((_loadBalancer: ILoadBalancer, i: number) => i !== index));
47
+ };
48
+
49
+ return (
50
+ <div className="well well-sm clearfix">
51
+ <h4>Load Balancers</h4>
52
+ <table className="table table-condensed">
53
+ <thead>
54
+ <tr>
55
+ <th>Account</th>
56
+ <th>Name</th>
57
+ <th>Region</th>
58
+ <th>Actions</th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ {(stage.loadBalancers || []).map((loadBalancer: any, index: number) => (
63
+ <tr key={`${loadBalancer.name}-${index}`}>
64
+ <td>{loadBalancer.credentials || loadBalancer.account}</td>
65
+ <td>{loadBalancer.name}</td>
66
+ <td>{loadBalancer.region}</td>
67
+ <td className="condensed-actions">
68
+ <button className="btn btn-sm btn-link" onClick={() => editLoadBalancer(index)} type="button">
69
+ <span className="glyphicon glyphicon-edit" />
70
+ </button>
71
+ <button
72
+ className="btn btn-sm btn-link pad-left"
73
+ onClick={() => removeLoadBalancer(index)}
74
+ type="button"
75
+ >
76
+ <span className="glyphicon glyphicon-trash" />
77
+ </button>
78
+ </td>
79
+ </tr>
80
+ ))}
81
+ </tbody>
82
+ <tfoot>
83
+ <tr>
84
+ <td colSpan={4}>
85
+ <button className="btn btn-block btn-sm add-new" onClick={addLoadBalancer} type="button">
86
+ <span className="glyphicon glyphicon-plus-sign" /> Add load balancer
87
+ </button>
88
+ </td>
89
+ </tr>
90
+ </tfoot>
91
+ </table>
92
+ </div>
93
+ );
94
+ }
@@ -1,74 +1,14 @@
1
- import type { IController } from 'angular';
2
- import { module } from 'angular';
3
- import type { IModalService } from 'angular-ui-bootstrap';
4
- import { cloneDeep } from 'lodash';
5
-
6
- import type { ILoadBalancer } from '@spinnaker/core';
7
- import { CloudProviderRegistry, Registry } from '@spinnaker/core';
8
-
9
- import { APPENGINE_LOAD_BALANCER_CHOICE_MODAL_CTRL } from './loadBalancerChoice.modal.controller';
10
-
11
- class AppengineEditLoadBalancerStageCtrl implements IController {
12
- public static $inject = ['$scope', '$uibModal'];
13
- constructor(public $scope: any, private $uibModal: IModalService) {
14
- $scope.stage.loadBalancers = $scope.stage.loadBalancers || [];
15
- $scope.stage.cloudProvider = 'appengine';
16
- }
17
-
18
- public addLoadBalancer(): void {
19
- this.$uibModal
20
- .open({
21
- templateUrl: require('./loadBalancerChoice.modal.html'),
22
- controller: `appengineLoadBalancerChoiceModelCtrl as ctrl`,
23
- resolve: {
24
- application: () => this.$scope.application,
25
- },
26
- })
27
- .result.then((newLoadBalancer: ILoadBalancer) => {
28
- this.$scope.stage.loadBalancers.push(newLoadBalancer);
29
- })
30
- .catch(() => {});
31
- }
32
-
33
- public editLoadBalancer(index: number) {
34
- const config = CloudProviderRegistry.getValue('appengine', 'loadBalancer');
35
- this.$uibModal
36
- .open({
37
- templateUrl: config.createLoadBalancerTemplateUrl,
38
- controller: `${config.createLoadBalancerController} as ctrl`,
39
- size: 'lg',
40
- resolve: {
41
- application: () => this.$scope.application,
42
- loadBalancer: () => cloneDeep(this.$scope.stage.loadBalancers[index]),
43
- isNew: () => false,
44
- forPipelineConfig: () => true,
45
- },
46
- })
47
- .result.then((updatedLoadBalancer: ILoadBalancer) => {
48
- this.$scope.stage.loadBalancers[index] = updatedLoadBalancer;
49
- })
50
- .catch(() => {});
51
- }
52
-
53
- public removeLoadBalancer(index: number): void {
54
- this.$scope.stage.loadBalancers.splice(index, 1);
55
- }
56
- }
57
-
58
- export const APPENGINE_EDIT_LOAD_BALANCER_STAGE = 'spinnaker.appengine.pipeline.stage.editLoadBalancerStage';
59
- module(APPENGINE_EDIT_LOAD_BALANCER_STAGE, [APPENGINE_LOAD_BALANCER_CHOICE_MODAL_CTRL])
60
- .config(() => {
61
- Registry.pipeline.registerStage({
62
- label: 'Edit Load Balancer',
63
- description: 'Edits a load balancer',
64
- key: 'upsertAppEngineLoadBalancers',
65
- cloudProvider: 'appengine',
66
- templateUrl: require('./editLoadBalancerStage.html'),
67
- executionDetailsUrl: require('./editLoadBalancerExecutionDetails.html'),
68
- executionConfigSections: ['editLoadBalancerConfig', 'taskStatus'],
69
- controller: 'appengineEditLoadBalancerStageCtrl',
70
- controllerAs: 'editLoadBalancerStageCtrl',
71
- validators: [],
72
- });
73
- })
74
- .controller('appengineEditLoadBalancerStageCtrl', AppengineEditLoadBalancerStageCtrl);
1
+ import { ExecutionDetailsTasks, Registry } from '@spinnaker/core';
2
+
3
+ import { AppengineEditLoadBalancerStageConfig } from './AppengineEditLoadBalancerStageConfig';
4
+ import { AppengineEditLoadBalancerExecutionDetails } from '../AppengineExecutionDetails';
5
+
6
+ Registry.pipeline.registerStage({
7
+ label: 'Edit Load Balancer',
8
+ description: 'Edits a load balancer',
9
+ key: 'upsertAppEngineLoadBalancers',
10
+ cloudProvider: 'appengine',
11
+ component: AppengineEditLoadBalancerStageConfig,
12
+ executionDetailsSections: [AppengineEditLoadBalancerExecutionDetails, ExecutionDetailsTasks],
13
+ validators: [],
14
+ });
@@ -1,49 +1,14 @@
1
- import { module } from 'angular';
2
-
3
1
  import { Registry } from '@spinnaker/core';
4
-
5
- import { AppengineStageCtrl } from '../appengineStage.controller';
6
- import { AppengineHealth } from '../../../common/appengineHealth';
7
- import type { IAppengineStageScope } from '../../../domain';
8
-
9
- class AppengineEnableAsgStageCtrl extends AppengineStageCtrl {
10
- public static $inject = ['$scope'];
11
- constructor(protected $scope: IAppengineStageScope) {
12
- super($scope);
13
-
14
- super.setAccounts().then(() => {
15
- super.setStageRegion();
16
- });
17
-
18
- super.setStageCloudProvider();
19
- super.setTargets();
20
- super.setStageCredentials();
21
-
22
- if (
23
- $scope.stage.isNew &&
24
- $scope.application.attributes.platformHealthOnlyShowOverride &&
25
- $scope.application.attributes.platformHealthOnly
26
- ) {
27
- $scope.stage.interestingHealthProviderNames = [AppengineHealth.PLATFORM];
28
- }
29
- }
30
- }
31
-
32
- export const APPENGINE_ENABLE_ASG_STAGE = 'spinnaker.appengine.pipeline.stage.enableAsgStage';
33
-
34
- module(APPENGINE_ENABLE_ASG_STAGE, [])
35
- .config(() => {
36
- Registry.pipeline.registerStage({
37
- provides: 'enableServerGroup',
38
- key: 'enableServerGroup',
39
- cloudProvider: 'appengine',
40
- templateUrl: require('./enableAsgStage.html'),
41
- executionStepLabelUrl: require('./enableAsgStepLabel.html'),
42
- validators: [
43
- { type: 'requiredField', fieldName: 'cluster' },
44
- { type: 'requiredField', fieldName: 'target' },
45
- { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
46
- ],
47
- });
48
- })
49
- .controller('appengineEnableAsgStageCtrl', AppengineEnableAsgStageCtrl);
2
+ import { AppengineServerGroupStageConfigWithHealthOverride } from '../AppengineServerGroupStageConfig';
3
+
4
+ Registry.pipeline.registerStage({
5
+ provides: 'enableServerGroup',
6
+ key: 'enableServerGroup',
7
+ cloudProvider: 'appengine',
8
+ component: AppengineServerGroupStageConfigWithHealthOverride,
9
+ validators: [
10
+ { type: 'requiredField', fieldName: 'cluster' },
11
+ { type: 'requiredField', fieldName: 'target' },
12
+ { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
13
+ ],
14
+ });
@@ -1,62 +1,14 @@
1
- import { module } from 'angular';
2
-
3
1
  import { Registry } from '@spinnaker/core';
4
-
5
- import { AppengineStageCtrl } from '../appengineStage.controller';
6
- import type { IAppengineStage, IAppengineStageScope } from '../../../domain/index';
7
-
8
- interface IAppengineShrinkClusterStage extends IAppengineStage {
9
- shrinkToSize: number;
10
- allowDeleteActive: boolean;
11
- retainLargerOverNewer: string | boolean;
12
- }
13
-
14
- class AppengineShrinkClusterStageCtrl extends AppengineStageCtrl {
15
- public static $inject = ['$scope'];
16
- constructor(public $scope: IAppengineStageScope) {
17
- super($scope);
18
-
19
- super.setAccounts().then(() => {
20
- super.setStageRegion();
21
- });
22
- super.setStageCloudProvider();
23
- super.setStageCredentials();
24
-
25
- const stage = $scope.stage as IAppengineShrinkClusterStage;
26
- if (stage.shrinkToSize === undefined) {
27
- stage.shrinkToSize = 1;
28
- }
29
-
30
- if (stage.allowDeleteActive === undefined) {
31
- stage.allowDeleteActive = false;
32
- }
33
-
34
- if (stage.retainLargerOverNewer === undefined) {
35
- stage.retainLargerOverNewer = 'false';
36
- }
37
-
38
- stage.retainLargerOverNewer = stage.retainLargerOverNewer.toString();
39
- }
40
-
41
- public pluralize(str: string, val: number): string {
42
- return val === 1 ? str : str + 's';
43
- }
44
- }
45
-
46
- export const APPENGINE_SHRINK_CLUSTER_STAGE = 'spinnaker.appengine.pipeline.stage.shrinkClusterStage';
47
-
48
- module(APPENGINE_SHRINK_CLUSTER_STAGE, [])
49
- .config(function () {
50
- Registry.pipeline.registerStage({
51
- provides: 'shrinkCluster',
52
- key: 'shrinkCluster',
53
- cloudProvider: 'appengine',
54
- templateUrl: require('./shrinkClusterStage.html'),
55
- validators: [
56
- { type: 'requiredField', fieldName: 'cluster' },
57
- { type: 'requiredField', fieldName: 'shrinkToSize', fieldLabel: 'shrink to [X] Server Groups' },
58
- { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
59
- ],
60
- });
61
- })
62
- .controller('appengineShrinkClusterStageCtrl', AppengineShrinkClusterStageCtrl);
2
+ import { AppengineShrinkClusterStageConfig } from '../AppengineServerGroupStageConfig';
3
+
4
+ Registry.pipeline.registerStage({
5
+ provides: 'shrinkCluster',
6
+ key: 'shrinkCluster',
7
+ cloudProvider: 'appengine',
8
+ component: AppengineShrinkClusterStageConfig,
9
+ validators: [
10
+ { type: 'requiredField', fieldName: 'cluster' },
11
+ { type: 'requiredField', fieldName: 'shrinkToSize', fieldLabel: 'shrink to [X] Server Groups' },
12
+ { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },
13
+ ],
14
+ });