@spinnaker/google 2026.0.3 → 2026.1.1

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 (33) hide show
  1. package/dist/domain/loadBalancer.d.ts +4 -2
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/loadBalancer/configure/choice/gceLoadBalancerPipelineModal.d.ts +9 -0
  5. package/dist/loadBalancer/configure/http/templates.d.ts +3 -0
  6. package/package.json +3 -3
  7. package/src/domain/loadBalancer.ts +4 -2
  8. package/src/gce.module.ts +2 -0
  9. package/src/help/gce.help.ts +2 -0
  10. package/src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.spec.js +66 -0
  11. package/src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.ts +20 -5
  12. package/src/loadBalancer/configure/choice/gceLoadBalancerPipelineModal.ts +47 -0
  13. package/src/loadBalancer/configure/gceL4LoadBalancerPipeline.spec.js +143 -0
  14. package/src/loadBalancer/configure/http/createHttpLoadBalancer.controller.js +22 -0
  15. package/src/loadBalancer/configure/http/createHttpLoadBalancer.controller.spec.js +96 -0
  16. package/src/loadBalancer/configure/http/listeners/listener.component.html +79 -24
  17. package/src/loadBalancer/configure/http/listeners/listener.component.js +82 -0
  18. package/src/loadBalancer/configure/http/listeners/listener.component.spec.js +125 -0
  19. package/src/loadBalancer/configure/http/templates.ts +3 -0
  20. package/src/loadBalancer/configure/http/transformer.service.js +16 -1
  21. package/src/loadBalancer/configure/http/transformer.service.spec.js +182 -0
  22. package/src/loadBalancer/configure/internal/gceCreateInternalLoadBalancer.controller.ts +8 -0
  23. package/src/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.spec.js +89 -0
  24. package/src/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.ts +23 -0
  25. package/src/loadBalancer/configure/network/createLoadBalancer.controller.js +48 -32
  26. package/src/loadBalancer/configure/network/createLoadBalancer.controller.spec.js +36 -0
  27. package/src/loadBalancer/configure/ssl/gceCreateSslLoadBalancer.controller.ts +8 -0
  28. package/src/loadBalancer/configure/tcp/gceCreateTcpLoadBalancer.controller.ts +8 -0
  29. package/src/loadBalancer/details/loadBalancerType/loadBalancerType.component.js +3 -1
  30. package/src/loadBalancer/details/loadBalancerType/loadBalancerType.component.spec.js +85 -0
  31. package/src/loadBalancer/loadBalancer.setTransformer.ts +1 -0
  32. package/src/serverGroup/configure/serverGroupConfiguration.service.js +0 -1
  33. package/src/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component.js +1 -4
@@ -23,7 +23,17 @@ module(GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER, [
23
23
  'application',
24
24
  'loadBalancer',
25
25
  'isNew',
26
- function ($scope, $uibModalInstance, $state, gceLoadBalancerTransformer, application, loadBalancer, isNew) {
26
+ 'forPipelineConfig',
27
+ function (
28
+ $scope,
29
+ $uibModalInstance,
30
+ $state,
31
+ gceLoadBalancerTransformer,
32
+ application,
33
+ loadBalancer,
34
+ isNew,
35
+ forPipelineConfig,
36
+ ) {
27
37
  const ctrl = this;
28
38
 
29
39
  $scope.isNew = isNew;
@@ -180,39 +190,45 @@ module(GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER, [
180
190
  this.submit = function () {
181
191
  const descriptor = isNew ? 'Create' : 'Update';
182
192
 
183
- $scope.taskMonitor.submit(function () {
184
- const params = {
185
- cloudProvider: 'gce',
186
- loadBalancerName: $scope.loadBalancer.name,
187
- };
188
-
189
- if ($scope.loadBalancer.listeners && $scope.loadBalancer.listeners.length > 0) {
190
- const listener = $scope.loadBalancer.listeners[0];
191
-
192
- if (listener.protocol) {
193
- params.ipProtocol = listener.protocol;
194
- }
195
-
196
- if (listener.portRange) {
197
- params.portRange = listener.portRange;
198
- }
199
-
200
- if (listener.healthCheck) {
201
- params.healthCheck = {
202
- port: $scope.loadBalancer.healthCheckPort,
203
- requestPath: $scope.loadBalancer.healthCheckPath,
204
- timeoutSec: $scope.loadBalancer.healthTimeout,
205
- checkIntervalSec: $scope.loadBalancer.healthInterval,
206
- healthyThreshold: $scope.loadBalancer.healthyThreshold,
207
- unhealthyThreshold: $scope.loadBalancer.unhealthyThreshold,
208
- };
209
- } else {
210
- params.healthCheck = null;
211
- }
212
-
213
- params.sessionAffinity = $scope.loadBalancer.sessionAffinity;
193
+ const params = {
194
+ cloudProvider: 'gce',
195
+ loadBalancerName: $scope.loadBalancer.name,
196
+ };
197
+
198
+ if ($scope.loadBalancer.listeners && $scope.loadBalancer.listeners.length > 0) {
199
+ const listener = $scope.loadBalancer.listeners[0];
200
+
201
+ if (listener.protocol) {
202
+ params.ipProtocol = listener.protocol;
214
203
  }
215
204
 
205
+ if (listener.portRange) {
206
+ params.portRange = listener.portRange;
207
+ }
208
+
209
+ if (listener.healthCheck) {
210
+ params.healthCheck = {
211
+ port: $scope.loadBalancer.healthCheckPort,
212
+ requestPath: $scope.loadBalancer.healthCheckPath,
213
+ timeoutSec: $scope.loadBalancer.healthTimeout,
214
+ checkIntervalSec: $scope.loadBalancer.healthInterval,
215
+ healthyThreshold: $scope.loadBalancer.healthyThreshold,
216
+ unhealthyThreshold: $scope.loadBalancer.unhealthyThreshold,
217
+ };
218
+ } else {
219
+ params.healthCheck = null;
220
+ }
221
+
222
+ params.sessionAffinity = $scope.loadBalancer.sessionAffinity;
223
+ }
224
+
225
+ if (forPipelineConfig) {
226
+ const command = Object.assign({}, $scope.loadBalancer, params);
227
+ $uibModalInstance.close(command);
228
+ return;
229
+ }
230
+
231
+ $scope.taskMonitor.submit(function () {
216
232
  return LoadBalancerWriter.upsertLoadBalancer($scope.loadBalancer, application, descriptor, params);
217
233
  });
218
234
  };
@@ -24,6 +24,7 @@ describe('Controller: gceCreateLoadBalancerCtrl', function () {
24
24
  application: app,
25
25
  loadBalancer: null,
26
26
  isNew: true,
27
+ forPipelineConfig: false,
27
28
  });
28
29
  }),
29
30
  );
@@ -79,4 +80,39 @@ describe('Controller: gceCreateLoadBalancerCtrl', function () {
79
80
  this.ctrl.setVisibilityHealthCheckTab();
80
81
  expect(ModalWizard.includePage.calls.count()).toEqual(2);
81
82
  });
83
+
84
+ it('closes with a pipeline command instead of submitting', function () {
85
+ let modalInstance;
86
+ window.inject(function ($controller, $rootScope) {
87
+ const $scope = $rootScope.$new();
88
+ const app = ApplicationModelBuilder.createApplicationForTests('app', {
89
+ key: 'loadBalancers',
90
+ lazy: true,
91
+ defaultData: [],
92
+ });
93
+ modalInstance = {
94
+ close: jasmine.createSpy('close'),
95
+ dismiss: angular.noop,
96
+ result: { then: angular.noop },
97
+ };
98
+ const ctrl = $controller('gceCreateLoadBalancerCtrl', {
99
+ $scope,
100
+ $uibModalInstance: modalInstance,
101
+ application: app,
102
+ loadBalancer: null,
103
+ isNew: true,
104
+ forPipelineConfig: true,
105
+ });
106
+ $scope.taskMonitor = { submit: jasmine.createSpy('submit') };
107
+ ctrl.updateName();
108
+ ctrl.submit();
109
+ });
110
+
111
+ expect(modalInstance.close).toHaveBeenCalledWith(
112
+ jasmine.objectContaining({
113
+ cloudProvider: 'gce',
114
+ loadBalancerName: 'app',
115
+ }),
116
+ );
117
+ });
82
118
  });
@@ -91,6 +91,7 @@ class SslLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements IControll
91
91
  'loadBalancer',
92
92
  'gceCommonLoadBalancerCommandBuilder',
93
93
  'isNew',
94
+ 'forPipelineConfig',
94
95
  'wizardSubFormValidation',
95
96
  '$state',
96
97
  ];
@@ -101,6 +102,7 @@ class SslLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements IControll
101
102
  private loadBalancer: SslLoadBalancer,
102
103
  private gceCommonLoadBalancerCommandBuilder: GceCommonLoadBalancerCommandBuilder,
103
104
  private isNew: boolean,
105
+ private forPipelineConfig: boolean,
104
106
  private wizardSubFormValidation: any,
105
107
  $state: StateService,
106
108
  ) {
@@ -212,6 +214,12 @@ class SslLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements IControll
212
214
  toSubmitLoadBalancer.cloudProvider = 'gce';
213
215
  delete toSubmitLoadBalancer.instances;
214
216
 
217
+ if (this.forPipelineConfig) {
218
+ Object.assign(toSubmitLoadBalancer, { healthCheck: {} });
219
+ this.$uibModalInstance.close(toSubmitLoadBalancer);
220
+ return;
221
+ }
222
+
215
223
  this.taskMonitor.submit(() =>
216
224
  LoadBalancerWriter.upsertLoadBalancer(toSubmitLoadBalancer, this.application, descriptor, {
217
225
  healthCheck: {},
@@ -89,6 +89,7 @@ class TcpLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements ng.ICompo
89
89
  'loadBalancer',
90
90
  'gceCommonLoadBalancerCommandBuilder',
91
91
  'isNew',
92
+ 'forPipelineConfig',
92
93
  'wizardSubFormValidation',
93
94
  '$state',
94
95
  ];
@@ -99,6 +100,7 @@ class TcpLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements ng.ICompo
99
100
  private loadBalancer: TcpLoadBalancer,
100
101
  private gceCommonLoadBalancerCommandBuilder: GceCommonLoadBalancerCommandBuilder,
101
102
  private isNew: boolean,
103
+ private forPipelineConfig: boolean,
102
104
  private wizardSubFormValidation: any,
103
105
  $state: StateService,
104
106
  ) {
@@ -203,6 +205,12 @@ class TcpLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements ng.ICompo
203
205
  toSubmitLoadBalancer.cloudProvider = 'gce';
204
206
  delete toSubmitLoadBalancer.instances;
205
207
 
208
+ if (this.forPipelineConfig) {
209
+ Object.assign(toSubmitLoadBalancer, { healthCheck: {} });
210
+ this.$uibModalInstance.close(toSubmitLoadBalancer);
211
+ return;
212
+ }
213
+
206
214
  this.taskMonitor.submit(() =>
207
215
  LoadBalancerWriter.upsertLoadBalancer(toSubmitLoadBalancer, this.application, descriptor, {
208
216
  healthCheck: {},
@@ -15,7 +15,9 @@ module(GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT,
15
15
  this.$onInit = () => {
16
16
  this.type = (function (lb) {
17
17
  if (lb.loadBalancerType === 'HTTP') {
18
- if (_.isString(lb.certificate)) {
18
+ const hasCertificate = _.isString(lb.certificate) && !_.isEmpty(lb.certificate);
19
+ const hasCertificateMap = _.isString(lb.certificateMap) && !_.isEmpty(lb.certificateMap);
20
+ if (hasCertificate || hasCertificateMap) {
19
21
  return 'HTTPS';
20
22
  } else {
21
23
  return 'HTTP';
@@ -0,0 +1,85 @@
1
+ import { mock } from 'angular';
2
+
3
+ describe('Component: gceLoadBalancerType', () => {
4
+ let $componentController;
5
+
6
+ beforeEach(mock.module(require('./loadBalancerType.component').name));
7
+
8
+ beforeEach(
9
+ mock.inject((_$componentController_) => {
10
+ $componentController = _$componentController_;
11
+ }),
12
+ );
13
+
14
+ function buildController(loadBalancer) {
15
+ return $componentController(
16
+ 'gceLoadBalancerType',
17
+ {},
18
+ {
19
+ loadBalancer,
20
+ },
21
+ );
22
+ }
23
+
24
+ it('detects HTTPS when certificate is present', () => {
25
+ const ctrl = buildController({
26
+ loadBalancerType: 'HTTP',
27
+ certificate: 'legacy-cert',
28
+ certificateMap: null,
29
+ });
30
+
31
+ ctrl.$onInit();
32
+
33
+ expect(ctrl.type).toBe('HTTPS');
34
+ });
35
+
36
+ it('detects HTTPS when certificateMap is present', () => {
37
+ const ctrl = buildController({
38
+ loadBalancerType: 'HTTP',
39
+ certificate: null,
40
+ certificateMap: 'cm',
41
+ });
42
+
43
+ ctrl.$onInit();
44
+
45
+ expect(ctrl.type).toBe('HTTPS');
46
+ });
47
+
48
+ it('detects HTTP when neither certificate field is present', () => {
49
+ const ctrl = buildController({
50
+ loadBalancerType: 'HTTP',
51
+ certificate: null,
52
+ certificateMap: null,
53
+ });
54
+
55
+ ctrl.$onInit();
56
+
57
+ expect(ctrl.type).toBe('HTTP');
58
+ });
59
+
60
+ // Both fields populated simultaneously — the || means either triggers HTTPS.
61
+ it('detects HTTPS when both certificate and certificateMap are present', () => {
62
+ const ctrl = buildController({
63
+ loadBalancerType: 'HTTP',
64
+ certificate: 'legacy-cert',
65
+ certificateMap: 'cm',
66
+ });
67
+
68
+ ctrl.$onInit();
69
+
70
+ expect(ctrl.type).toBe('HTTPS');
71
+ });
72
+
73
+ // Non-HTTP types pass through the else branch and return verbatim.
74
+ it('returns loadBalancerType verbatim for non-HTTP types', () => {
75
+ const ctrl = buildController({
76
+ loadBalancerType: 'SSL',
77
+ certificate: null,
78
+ certificateMap: null,
79
+ });
80
+
81
+ ctrl.$onInit();
82
+
83
+ expect(ctrl.type).toBe('SSL');
84
+ });
85
+ });
@@ -16,6 +16,7 @@ export class GceLoadBalancerSetTransformer {
16
16
  port,
17
17
  name: loadBalancer.name,
18
18
  certificate: loadBalancer.certificate,
19
+ certificateMap: loadBalancer.certificateMap,
19
20
  ipAddress: loadBalancer.ipAddress,
20
21
  subnet: loadBalancer.subnet,
21
22
  };
@@ -152,7 +152,6 @@ angular
152
152
  }
153
153
  }
154
154
 
155
- // eslint-disable-next-line no-console
156
155
  if (command.autoScalingPolicy) {
157
156
  command.enableAutoScaling = true;
158
157
  }
@@ -1,9 +1,6 @@
1
- /* eslint-disable no-debugger */
2
- import { IComponentOptions, module } from 'angular';
1
+ import { module } from 'angular';
3
2
  import { cloneDeep } from 'lodash';
4
3
 
5
- import { TaskMonitor } from '@spinnaker/core';
6
-
7
4
  import { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/basicSettings/basicSettings.component';
8
5
  import { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/metricSettings/metricSettings.component';
9
6
  import { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT } from '../../../../autoscalingPolicy/components/scalingSchedules/scalingSchedules.component';