@spinnaker/appengine 0.0.0-main-2
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/CHANGELOG.md +981 -0
- package/LICENSE.txt +203 -0
- package/dist/appengine.logoc2c312af6aa99037.png +0 -0
- package/dist/appengine.module.d.ts +5 -0
- package/dist/appengine.settings.d.ts +7 -0
- package/dist/common/FormikAccountRegionSelector.d.ts +26 -0
- package/dist/common/appengineHealth.d.ts +3 -0
- package/dist/common/componentUrlDetails.component.d.ts +1 -0
- package/dist/common/conditionalDescriptionListItem.component.d.ts +1 -0
- package/dist/common/loadBalancerMessage.component.d.ts +1 -0
- package/dist/domain/IAppengineAccount.d.ts +6 -0
- package/dist/domain/IAppengineInstance.d.ts +20 -0
- package/dist/domain/IAppengineLoadBalancer.d.ts +19 -0
- package/dist/domain/IAppengineServerGroup.d.ts +11 -0
- package/dist/domain/IAppengineStageScope.d.ts +18 -0
- package/dist/domain/IAppengineTriggers.d.ts +11 -0
- package/dist/domain/index.d.ts +6 -0
- package/dist/helpContents/appengineHelpContents.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4084 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/details/details.controller.d.ts +1 -0
- package/dist/loadBalancer/configure/wizard/advancedSettings.component.d.ts +1 -0
- package/dist/loadBalancer/configure/wizard/allocationConfigurationRow.component.d.ts +1 -0
- package/dist/loadBalancer/configure/wizard/basicSettings.component.d.ts +1 -0
- package/dist/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.d.ts +1 -0
- package/dist/loadBalancer/configure/wizard/wizard.controller.d.ts +2 -0
- package/dist/loadBalancer/details/details.controller.d.ts +1 -0
- package/dist/loadBalancer/loadBalancer.module.d.ts +1 -0
- package/dist/loadBalancer/transformer.d.ts +40 -0
- package/dist/pipeline/pipeline.module.d.ts +1 -0
- package/dist/pipeline/stages/appengineStage.controller.d.ts +12 -0
- package/dist/pipeline/stages/deployAppengineConfig/DeployAppengineConfigForm.d.ts +16 -0
- package/dist/pipeline/stages/deployAppengineConfig/DeployAppengineConfigurationConfig.d.ts +5 -0
- package/dist/pipeline/stages/deployAppengineConfig/deployAppengineConfigStage.d.ts +1 -0
- package/dist/pipeline/stages/destroyAsg/appengineDestroyAsgStage.d.ts +1 -0
- package/dist/pipeline/stages/disableAsg/appengineDisableAsgStage.d.ts +1 -0
- package/dist/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.d.ts +1 -0
- package/dist/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.d.ts +1 -0
- package/dist/pipeline/stages/enableAsg/appengineEnableAsgStage.d.ts +1 -0
- package/dist/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.d.ts +1 -0
- package/dist/pipeline/stages/startServerGroup/appengineStartServerGroupStage.d.ts +1 -0
- package/dist/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.d.ts +1 -0
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +74 -0
- package/dist/serverGroup/configure/wizard/ConfigFileArtifactList.d.ts +10 -0
- package/dist/serverGroup/configure/wizard/basicSettings.controller.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/cloneServerGroup.controller.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/configFileArtifactList.module.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/configFiles.component.d.ts +20 -0
- package/dist/serverGroup/configure/wizard/dynamicBranchLabel.component.d.ts +1 -0
- package/dist/serverGroup/details/details.controller.d.ts +1 -0
- package/dist/serverGroup/transformer.d.ts +45 -0
- package/dist/serverGroup/writer/serverGroup.write.service.d.ts +8 -0
- package/dist/validation/ApplicationNameValidator.d.ts +1 -0
- package/package.json +46 -0
- package/src/appengine.module.ts +70 -0
- package/src/appengine.settings.ts +14 -0
- package/src/common/FormikAccountRegionSelector.tsx +107 -0
- package/src/common/appengineHealth.ts +3 -0
- package/src/common/componentUrlDetails.component.ts +29 -0
- package/src/common/conditionalDescriptionListItem.component.ts +37 -0
- package/src/common/loadBalancerMessage.component.html +33 -0
- package/src/common/loadBalancerMessage.component.ts +13 -0
- package/src/domain/IAppengineAccount.ts +8 -0
- package/src/domain/IAppengineInstance.ts +21 -0
- package/src/domain/IAppengineLoadBalancer.ts +21 -0
- package/src/domain/IAppengineServerGroup.ts +13 -0
- package/src/domain/IAppengineStageScope.ts +22 -0
- package/src/domain/IAppengineTriggers.ts +12 -0
- package/src/domain/index.ts +6 -0
- package/src/helpContents/appengineHelpContents.ts +141 -0
- package/src/index.ts +1 -0
- package/src/instance/details/details.controller.ts +116 -0
- package/src/instance/details/details.html +99 -0
- package/src/loadBalancer/configure/wizard/advancedSettings.component.ts +56 -0
- package/src/loadBalancer/configure/wizard/allocationConfigurationRow.component.ts +70 -0
- package/src/loadBalancer/configure/wizard/basicSettings.component.html +65 -0
- package/src/loadBalancer/configure/wizard/basicSettings.component.ts +98 -0
- package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html +117 -0
- package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.ts +108 -0
- package/src/loadBalancer/configure/wizard/wizard.controller.ts +163 -0
- package/src/loadBalancer/configure/wizard/wizard.html +44 -0
- package/src/loadBalancer/configure/wizard/wizard.less +17 -0
- package/src/loadBalancer/details/details.controller.ts +151 -0
- package/src/loadBalancer/details/details.html +102 -0
- package/src/loadBalancer/loadBalancer.module.ts +21 -0
- package/src/loadBalancer/transformer.ts +170 -0
- package/src/logo/appengine.icon.svg +37 -0
- package/src/logo/appengine.logo.less +6 -0
- package/src/logo/appengine.logo.png +0 -0
- package/src/pipeline/pipeline.module.ts +20 -0
- package/src/pipeline/stages/appengineStage.controller.ts +45 -0
- package/src/pipeline/stages/deployAppengineConfig/DeployAppengineConfigForm.tsx +203 -0
- package/src/pipeline/stages/deployAppengineConfig/DeployAppengineConfigurationConfig.tsx +34 -0
- package/src/pipeline/stages/deployAppengineConfig/deployAppengineConfigStage.ts +19 -0
- package/src/pipeline/stages/destroyAsg/appengineDestroyAsgStage.ts +45 -0
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +16 -0
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +1 -0
- package/src/pipeline/stages/disableAsg/appengineDisableAsgStage.ts +54 -0
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +18 -0
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +1 -0
- package/src/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.ts +74 -0
- package/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html +33 -0
- package/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html +51 -0
- package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.ts +65 -0
- package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html +45 -0
- package/src/pipeline/stages/enableAsg/appengineEnableAsgStage.ts +49 -0
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +18 -0
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +1 -0
- package/src/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.ts +62 -0
- package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +41 -0
- package/src/pipeline/stages/startServerGroup/appengineStartServerGroupStage.ts +54 -0
- package/src/pipeline/stages/startServerGroup/startServerGroupExecutionDetails.html +26 -0
- package/src/pipeline/stages/startServerGroup/startServerGroupStage.html +18 -0
- package/src/pipeline/stages/startServerGroup/startServerGroupStepLabel.html +1 -0
- package/src/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.ts +54 -0
- package/src/pipeline/stages/stopServerGroup/stopServerGroupExecutionDetails.html +26 -0
- package/src/pipeline/stages/stopServerGroup/stopServerGroupStage.html +18 -0
- package/src/pipeline/stages/stopServerGroup/stopServerGroupStepLabel.html +1 -0
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.ts +235 -0
- package/src/serverGroup/configure/wizard/ConfigFileArtifactList.tsx +81 -0
- package/src/serverGroup/configure/wizard/advancedSettings.html +33 -0
- package/src/serverGroup/configure/wizard/basicSettings.controller.ts +151 -0
- package/src/serverGroup/configure/wizard/basicSettings.html +287 -0
- package/src/serverGroup/configure/wizard/cloneServerGroup.controller.ts +103 -0
- package/src/serverGroup/configure/wizard/configFileArtifactList.module.ts +18 -0
- package/src/serverGroup/configure/wizard/configFileArtifactList.spec.tsx +78 -0
- package/src/serverGroup/configure/wizard/configFiles.component.html +81 -0
- package/src/serverGroup/configure/wizard/configFiles.component.ts +121 -0
- package/src/serverGroup/configure/wizard/dynamicBranchLabel.component.ts +19 -0
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +39 -0
- package/src/serverGroup/configure/wizard/serverGroupWizard.less +28 -0
- package/src/serverGroup/details/details.controller.ts +463 -0
- package/src/serverGroup/details/details.html +229 -0
- package/src/serverGroup/transformer.ts +92 -0
- package/src/serverGroup/transformet.spec.ts +40 -0
- package/src/serverGroup/writer/serverGroup.write.service.ts +57 -0
- package/src/validation/ApplicationNameValidator.ts +40 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { StateService } from '@uirouter/angularjs';
|
|
2
|
+
import type { IController, IScope } from 'angular';
|
|
3
|
+
import { module } from 'angular';
|
|
4
|
+
import type { IModalService } from 'angular-ui-bootstrap';
|
|
5
|
+
import { cloneDeep } from 'lodash';
|
|
6
|
+
|
|
7
|
+
import type { Application, ILoadBalancer, ILoadBalancerDeleteCommand } from '@spinnaker/core';
|
|
8
|
+
import { ConfirmationModalService, LoadBalancerWriter } from '@spinnaker/core';
|
|
9
|
+
import type { IAppengineLoadBalancer } from '../../domain';
|
|
10
|
+
|
|
11
|
+
interface ILoadBalancerFromStateParams {
|
|
12
|
+
accountId: string;
|
|
13
|
+
region: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class AppengineLoadBalancerDetailsController implements IController {
|
|
18
|
+
public state = { loading: true };
|
|
19
|
+
private loadBalancerFromParams: ILoadBalancerFromStateParams;
|
|
20
|
+
public loadBalancer: IAppengineLoadBalancer;
|
|
21
|
+
public dispatchRules: string[] = [];
|
|
22
|
+
|
|
23
|
+
public static $inject = ['$uibModal', '$state', '$scope', 'loadBalancer', 'app'];
|
|
24
|
+
constructor(
|
|
25
|
+
private $uibModal: IModalService,
|
|
26
|
+
private $state: StateService,
|
|
27
|
+
private $scope: IScope,
|
|
28
|
+
loadBalancer: ILoadBalancerFromStateParams,
|
|
29
|
+
private app: Application,
|
|
30
|
+
) {
|
|
31
|
+
this.loadBalancerFromParams = loadBalancer;
|
|
32
|
+
this.app
|
|
33
|
+
.getDataSource('loadBalancers')
|
|
34
|
+
.ready()
|
|
35
|
+
.then(() => this.extractLoadBalancer());
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public editLoadBalancer(): void {
|
|
39
|
+
this.$uibModal.open({
|
|
40
|
+
templateUrl: require('../configure/wizard/wizard.html'),
|
|
41
|
+
controller: 'appengineLoadBalancerWizardCtrl as ctrl',
|
|
42
|
+
size: 'lg',
|
|
43
|
+
resolve: {
|
|
44
|
+
application: () => this.app,
|
|
45
|
+
loadBalancer: () => cloneDeep(this.loadBalancer),
|
|
46
|
+
isNew: () => false,
|
|
47
|
+
forPipelineConfig: () => false,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public deleteLoadBalancer(): void {
|
|
53
|
+
const taskMonitor = {
|
|
54
|
+
application: this.app,
|
|
55
|
+
title: 'Deleting ' + this.loadBalancer.name,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const submitMethod = () => {
|
|
59
|
+
const loadBalancer: ILoadBalancerDeleteCommand = {
|
|
60
|
+
cloudProvider: this.loadBalancer.cloudProvider,
|
|
61
|
+
loadBalancerName: this.loadBalancer.name,
|
|
62
|
+
credentials: this.loadBalancer.account,
|
|
63
|
+
};
|
|
64
|
+
return LoadBalancerWriter.deleteLoadBalancer(loadBalancer, this.app);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
ConfirmationModalService.confirm({
|
|
68
|
+
header: 'Really delete ' + this.loadBalancer.name + '?',
|
|
69
|
+
buttonText: 'Delete ' + this.loadBalancer.name,
|
|
70
|
+
body: this.getConfirmationModalBodyHtml(),
|
|
71
|
+
account: this.loadBalancer.account,
|
|
72
|
+
taskMonitorConfig: taskMonitor,
|
|
73
|
+
submitMethod,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public canDeleteLoadBalancer(): boolean {
|
|
78
|
+
return this.loadBalancer.name !== 'default';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private extractLoadBalancer(): void {
|
|
82
|
+
this.loadBalancer = this.app.getDataSource('loadBalancers').data.find((test: ILoadBalancer) => {
|
|
83
|
+
return test.name === this.loadBalancerFromParams.name && test.account === this.loadBalancerFromParams.accountId;
|
|
84
|
+
}) as IAppengineLoadBalancer;
|
|
85
|
+
|
|
86
|
+
if (this.loadBalancer) {
|
|
87
|
+
this.state.loading = false;
|
|
88
|
+
this.buildDispatchRules();
|
|
89
|
+
this.app.getDataSource('loadBalancers').onRefresh(this.$scope, () => this.extractLoadBalancer());
|
|
90
|
+
} else {
|
|
91
|
+
this.autoClose();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private buildDispatchRules(): void {
|
|
96
|
+
this.dispatchRules = [];
|
|
97
|
+
if (this.loadBalancer && this.loadBalancer.dispatchRules) {
|
|
98
|
+
this.loadBalancer.dispatchRules.forEach((rule) => {
|
|
99
|
+
if (rule.service === this.loadBalancer.name) {
|
|
100
|
+
this.dispatchRules.push(rule.domain + rule.path);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private getConfirmationModalBodyHtml(): string {
|
|
107
|
+
const serverGroupNames = this.loadBalancer.serverGroups.map((serverGroup) => serverGroup.name);
|
|
108
|
+
const hasAny = serverGroupNames ? serverGroupNames.length > 0 : false;
|
|
109
|
+
const hasMoreThanOne = serverGroupNames ? serverGroupNames.length > 1 : false;
|
|
110
|
+
|
|
111
|
+
// HTML accepted by the confirmationModalService is static (i.e., not managed by angular).
|
|
112
|
+
if (hasAny) {
|
|
113
|
+
if (hasMoreThanOne) {
|
|
114
|
+
const listOfServerGroupNames = serverGroupNames.map((name) => `<li>${name}</li>`).join('');
|
|
115
|
+
return `<div class="alert alert-warning">
|
|
116
|
+
<p>
|
|
117
|
+
Deleting <b>${this.loadBalancer.name}</b> will destroy the following server groups:
|
|
118
|
+
<ul>
|
|
119
|
+
${listOfServerGroupNames}
|
|
120
|
+
</ul>
|
|
121
|
+
</p>
|
|
122
|
+
</div>
|
|
123
|
+
`;
|
|
124
|
+
} else {
|
|
125
|
+
return `<div class="alert alert-warning">
|
|
126
|
+
<p>
|
|
127
|
+
Deleting <b>${this.loadBalancer.name}</b> will destroy <b>${serverGroupNames[0]}</b>.
|
|
128
|
+
</p>
|
|
129
|
+
</div>
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private autoClose(): void {
|
|
138
|
+
if (this.$scope.$$destroyed) {
|
|
139
|
+
return;
|
|
140
|
+
} else {
|
|
141
|
+
this.$state.params.allowModalToStayOpen = true;
|
|
142
|
+
this.$state.go('^', null, { location: 'replace' });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export const APPENGINE_LOAD_BALANCER_DETAILS_CTRL = 'spinnaker.appengine.loadBalancerDetails.controller';
|
|
148
|
+
module(APPENGINE_LOAD_BALANCER_DETAILS_CTRL, []).controller(
|
|
149
|
+
'appengineLoadBalancerDetailsCtrl',
|
|
150
|
+
AppengineLoadBalancerDetailsController,
|
|
151
|
+
);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<div class="details-panel">
|
|
2
|
+
<div ng-if="ctrl.state.loading" class="header">
|
|
3
|
+
<div class="close-button">
|
|
4
|
+
<a class="btn btn-link" ui-sref="^">
|
|
5
|
+
<span class="glyphicon glyphicon-remove"></span>
|
|
6
|
+
</a>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="horizontal center middle">
|
|
9
|
+
<loading-spinner size="'small'"></loading-spinner>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div ng-if="!ctrl.state.loading" class="header">
|
|
14
|
+
<div class="close-button">
|
|
15
|
+
<a class="btn btn-link" ui-sref="^">
|
|
16
|
+
<span class="glyphicon glyphicon-remove"></span>
|
|
17
|
+
</a>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="header-text horizontal middle">
|
|
20
|
+
<i class="fa icon-sitemap"></i>
|
|
21
|
+
<h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{ctrl.loadBalancer.name}}</h3>
|
|
22
|
+
</div>
|
|
23
|
+
<div>
|
|
24
|
+
<div class="actions">
|
|
25
|
+
<div class="dropdown" uib-dropdown dropdown-append-to-body>
|
|
26
|
+
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>
|
|
27
|
+
Load Balancer Actions <span class="caret"></span>
|
|
28
|
+
</button>
|
|
29
|
+
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
|
|
30
|
+
<li><a href ng-click="ctrl.editLoadBalancer()">Edit Load Balancer</a></li>
|
|
31
|
+
<li ng-if="ctrl.canDeleteLoadBalancer()">
|
|
32
|
+
<a href ng-click="ctrl.deleteLoadBalancer()">Delete Load Balancer</a>
|
|
33
|
+
</li>
|
|
34
|
+
<li
|
|
35
|
+
ng-if="!ctrl.canDeleteLoadBalancer()"
|
|
36
|
+
uib-tooltip="You cannot delete a default service."
|
|
37
|
+
class="disabled"
|
|
38
|
+
>
|
|
39
|
+
<a href>Delete Load Balancer</a>
|
|
40
|
+
</li>
|
|
41
|
+
</ul>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div ng-if="!ctrl.state.loading" class="content">
|
|
48
|
+
<collapsible-section heading="Load Balancer Details" expanded="true">
|
|
49
|
+
<dl class="dl-horizontal dl-narrow">
|
|
50
|
+
<dt>In</dt>
|
|
51
|
+
<dd><account-tag account="ctrl.loadBalancer.account" pad="right"></account-tag></dd>
|
|
52
|
+
<dt>Region</dt>
|
|
53
|
+
<dd>{{ctrl.loadBalancer.region}}</dd>
|
|
54
|
+
<dt ng-if="ctrl.loadBalancer.serverGroups.length">Server Groups</dt>
|
|
55
|
+
<dd ng-if="ctrl.loadBalancer.serverGroups.length">
|
|
56
|
+
<ul>
|
|
57
|
+
<li ng-repeat="serverGroup in ctrl.loadBalancer.serverGroups | orderBy: ['isDisabled', '-name']">
|
|
58
|
+
<a
|
|
59
|
+
ui-sref="^.serverGroup({region: serverGroup.region,
|
|
60
|
+
accountId: serverGroup.account,
|
|
61
|
+
serverGroup: serverGroup.name,
|
|
62
|
+
provider: 'appengine'})"
|
|
63
|
+
>
|
|
64
|
+
{{serverGroup.name}}
|
|
65
|
+
</a>
|
|
66
|
+
</li>
|
|
67
|
+
</ul>
|
|
68
|
+
</dd>
|
|
69
|
+
</dl>
|
|
70
|
+
</collapsible-section>
|
|
71
|
+
<collapsible-section heading="Status" expanded="true">
|
|
72
|
+
<health-counts class="pull-left" container="ctrl.loadBalancer.instanceCounts"></health-counts>
|
|
73
|
+
</collapsible-section>
|
|
74
|
+
<collapsible-section heading="Traffic Split" expanded="true">
|
|
75
|
+
<dl class="dl-horizontal dl-narrow">
|
|
76
|
+
<dt ng-if="ctrl.loadBalancer.split.shardBy">Shard By</dt>
|
|
77
|
+
<dd ng-if="ctrl.loadBalancer.split.shardBy">
|
|
78
|
+
{{ctrl.loadBalancer.split.shardBy}}
|
|
79
|
+
<help-field
|
|
80
|
+
key="appengine.loadBalancer.shardBy.{{ctrl.loadBalancer.split.shardBy.toLowerCase()}}"
|
|
81
|
+
></help-field>
|
|
82
|
+
</dd>
|
|
83
|
+
<hr ng-if="ctrl.loadBalancer.split.shardBy" />
|
|
84
|
+
<ul>
|
|
85
|
+
<li ng-repeat="(serverGroup, percent) in ctrl.loadBalancer.split.allocations">
|
|
86
|
+
{{serverGroup}}:<span class="pull-right">{{percent | decimalToPercent}}</span>
|
|
87
|
+
</li>
|
|
88
|
+
</ul>
|
|
89
|
+
</dl>
|
|
90
|
+
</collapsible-section>
|
|
91
|
+
<collapsible-section heading="DNS" expanded="true">
|
|
92
|
+
<dl class="dl-narrow">
|
|
93
|
+
<appengine-component-url-details component="ctrl.loadBalancer"></appengine-component-url-details>
|
|
94
|
+
</dl>
|
|
95
|
+
</collapsible-section>
|
|
96
|
+
<collapsible-section heading="Dispatch Rules" expanded="true" ng-if="ctrl.dispatchRules.length > 0">
|
|
97
|
+
<dl class="dl-horizontal dl-narrow">
|
|
98
|
+
<span ng-repeat-start="rule in ctrl.dispatchRules">{{rule}}</span><br ng-repeat-end />
|
|
99
|
+
</dl>
|
|
100
|
+
</collapsible-section>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { module } from 'angular';
|
|
2
|
+
|
|
3
|
+
import { APPENGINE_LOAD_BALANCER_ADVANCED_SETTINGS } from './configure/wizard/advancedSettings.component';
|
|
4
|
+
import { APPENGINE_ALLOCATION_CONFIGURATION_ROW } from './configure/wizard/allocationConfigurationRow.component';
|
|
5
|
+
import { APPENGINE_LOAD_BALANCER_BASIC_SETTINGS } from './configure/wizard/basicSettings.component';
|
|
6
|
+
import { APPENGINE_STAGE_ALLOCATION_CONFIGURATION_ROW } from './configure/wizard/stageAllocationConfigurationRow.component';
|
|
7
|
+
import { APPENGINE_LOAD_BALANCER_WIZARD_CTRL } from './configure/wizard/wizard.controller';
|
|
8
|
+
import { APPENGINE_LOAD_BALANCER_DETAILS_CTRL } from './details/details.controller';
|
|
9
|
+
import { APPENGINE_LOAD_BALANCER_TRANSFORMER } from './transformer';
|
|
10
|
+
|
|
11
|
+
export const APPENGINE_LOAD_BALANCER_MODULE = 'spinnaker.appengine.loadBalancer.module';
|
|
12
|
+
|
|
13
|
+
module(APPENGINE_LOAD_BALANCER_MODULE, [
|
|
14
|
+
APPENGINE_ALLOCATION_CONFIGURATION_ROW,
|
|
15
|
+
APPENGINE_LOAD_BALANCER_DETAILS_CTRL,
|
|
16
|
+
APPENGINE_LOAD_BALANCER_ADVANCED_SETTINGS,
|
|
17
|
+
APPENGINE_LOAD_BALANCER_BASIC_SETTINGS,
|
|
18
|
+
APPENGINE_LOAD_BALANCER_TRANSFORMER,
|
|
19
|
+
APPENGINE_LOAD_BALANCER_WIZARD_CTRL,
|
|
20
|
+
APPENGINE_STAGE_ALLOCATION_CONFIGURATION_ROW,
|
|
21
|
+
]);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { module } from 'angular';
|
|
2
|
+
import { camelCase, chain, cloneDeep, filter, get, has, reduce } from 'lodash';
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Application,
|
|
6
|
+
IInstance,
|
|
7
|
+
IInstanceCounts,
|
|
8
|
+
ILoadBalancer,
|
|
9
|
+
ILoadBalancerUpsertCommand,
|
|
10
|
+
IServerGroup,
|
|
11
|
+
} from '@spinnaker/core';
|
|
12
|
+
import type { IAppengineLoadBalancer, IAppengineTrafficSplit, ShardBy } from '../domain/index';
|
|
13
|
+
|
|
14
|
+
export interface IAppengineAllocationDescription {
|
|
15
|
+
serverGroupName?: string;
|
|
16
|
+
target?: string;
|
|
17
|
+
cluster?: string;
|
|
18
|
+
allocation: number;
|
|
19
|
+
locatorType: 'fromExisting' | 'targetCoordinate' | 'text';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface IAppengineTrafficSplitDescription {
|
|
23
|
+
shardBy: ShardBy;
|
|
24
|
+
allocationDescriptions: IAppengineAllocationDescription[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class AppengineLoadBalancerUpsertDescription implements ILoadBalancerUpsertCommand, IAppengineLoadBalancer {
|
|
28
|
+
public credentials: string;
|
|
29
|
+
public account: string;
|
|
30
|
+
public loadBalancerName: string;
|
|
31
|
+
public name: string;
|
|
32
|
+
public splitDescription: IAppengineTrafficSplitDescription;
|
|
33
|
+
public split?: IAppengineTrafficSplit;
|
|
34
|
+
public migrateTraffic: boolean;
|
|
35
|
+
public region: string;
|
|
36
|
+
public cloudProvider: string;
|
|
37
|
+
public serverGroups?: any[];
|
|
38
|
+
|
|
39
|
+
public static convertTrafficSplitToTrafficSplitDescription(
|
|
40
|
+
split: IAppengineTrafficSplit,
|
|
41
|
+
): IAppengineTrafficSplitDescription {
|
|
42
|
+
const allocationDescriptions = reduce(
|
|
43
|
+
split.allocations,
|
|
44
|
+
(acc: IAppengineAllocationDescription[], allocation: number, serverGroupName: string) => {
|
|
45
|
+
return acc.concat({ serverGroupName, allocation, locatorType: 'fromExisting' });
|
|
46
|
+
},
|
|
47
|
+
[],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
return { shardBy: split.shardBy, allocationDescriptions };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
constructor(loadBalancer: IAppengineLoadBalancer) {
|
|
54
|
+
this.credentials = loadBalancer.account || loadBalancer.credentials;
|
|
55
|
+
this.account = this.credentials;
|
|
56
|
+
this.cloudProvider = loadBalancer.cloudProvider;
|
|
57
|
+
this.loadBalancerName = loadBalancer.name;
|
|
58
|
+
this.name = loadBalancer.name;
|
|
59
|
+
this.region = loadBalancer.region;
|
|
60
|
+
this.migrateTraffic = loadBalancer.migrateTraffic || false;
|
|
61
|
+
this.serverGroups = loadBalancer.serverGroups;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public mapAllocationsToDecimals() {
|
|
65
|
+
this.splitDescription.allocationDescriptions.forEach((description) => {
|
|
66
|
+
description.allocation = description.allocation / 100;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public mapAllocationsToPercentages() {
|
|
71
|
+
this.splitDescription.allocationDescriptions.forEach((description) => {
|
|
72
|
+
// An allocation percent has at most one decimal place.
|
|
73
|
+
description.allocation = Math.round(description.allocation * 1000) / 10;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class AppengineLoadBalancerTransformer {
|
|
79
|
+
public static $inject = ['$q'];
|
|
80
|
+
constructor(private $q: ng.IQService) {}
|
|
81
|
+
|
|
82
|
+
public normalizeLoadBalancer(loadBalancer: ILoadBalancer): PromiseLike<ILoadBalancer> {
|
|
83
|
+
loadBalancer.provider = loadBalancer.type;
|
|
84
|
+
loadBalancer.instanceCounts = this.buildInstanceCounts(loadBalancer.serverGroups);
|
|
85
|
+
loadBalancer.instances = [];
|
|
86
|
+
loadBalancer.serverGroups.forEach((serverGroup) => {
|
|
87
|
+
serverGroup.account = loadBalancer.account;
|
|
88
|
+
serverGroup.region = loadBalancer.region;
|
|
89
|
+
|
|
90
|
+
if (serverGroup.detachedInstances) {
|
|
91
|
+
serverGroup.detachedInstances = (serverGroup.detachedInstances as any).map((id: string) => ({ id }));
|
|
92
|
+
}
|
|
93
|
+
serverGroup.instances = serverGroup.instances
|
|
94
|
+
.concat(serverGroup.detachedInstances || [])
|
|
95
|
+
.map((instance: any) => this.transformInstance(instance, loadBalancer));
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const activeServerGroups = filter(loadBalancer.serverGroups, { isDisabled: false });
|
|
99
|
+
loadBalancer.instances = chain(activeServerGroups).map('instances').flatten().value() as IInstance[];
|
|
100
|
+
return this.$q.resolve(loadBalancer);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public convertLoadBalancerForEditing(
|
|
104
|
+
loadBalancer: IAppengineLoadBalancer,
|
|
105
|
+
application: Application,
|
|
106
|
+
): PromiseLike<IAppengineLoadBalancer> {
|
|
107
|
+
return application
|
|
108
|
+
.getDataSource('loadBalancers')
|
|
109
|
+
.ready()
|
|
110
|
+
.then(() => {
|
|
111
|
+
const upToDateLoadBalancer = application
|
|
112
|
+
.getDataSource('loadBalancers')
|
|
113
|
+
.data.find((candidate: ILoadBalancer) => {
|
|
114
|
+
return (
|
|
115
|
+
candidate.name === loadBalancer.name &&
|
|
116
|
+
(candidate.account === loadBalancer.account || candidate.account === loadBalancer.credentials)
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (upToDateLoadBalancer) {
|
|
121
|
+
loadBalancer.serverGroups = cloneDeep(upToDateLoadBalancer.serverGroups);
|
|
122
|
+
}
|
|
123
|
+
return loadBalancer;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public convertLoadBalancerToUpsertDescription(
|
|
128
|
+
loadBalancer: IAppengineLoadBalancer,
|
|
129
|
+
): AppengineLoadBalancerUpsertDescription {
|
|
130
|
+
return new AppengineLoadBalancerUpsertDescription(loadBalancer);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private buildInstanceCounts(serverGroups: IServerGroup[]): IInstanceCounts {
|
|
134
|
+
const instanceCounts: IInstanceCounts = chain(serverGroups)
|
|
135
|
+
.map('instances')
|
|
136
|
+
.flatten()
|
|
137
|
+
.reduce(
|
|
138
|
+
(acc: IInstanceCounts, instance: any) => {
|
|
139
|
+
if (has(instance, 'health.state')) {
|
|
140
|
+
acc[camelCase(instance.health.state)]++;
|
|
141
|
+
}
|
|
142
|
+
return acc;
|
|
143
|
+
},
|
|
144
|
+
{ up: 0, down: 0, outOfService: 0, succeeded: 0, failed: 0, starting: 0, unknown: 0 },
|
|
145
|
+
)
|
|
146
|
+
.value();
|
|
147
|
+
|
|
148
|
+
instanceCounts.outOfService += chain(serverGroups).map('detachedInstances').flatten().value().length;
|
|
149
|
+
return instanceCounts;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private transformInstance(instance: any, loadBalancer: ILoadBalancer) {
|
|
153
|
+
instance.provider = loadBalancer.type;
|
|
154
|
+
instance.account = loadBalancer.account;
|
|
155
|
+
instance.region = loadBalancer.region;
|
|
156
|
+
instance.loadBalancers = [loadBalancer.name];
|
|
157
|
+
const health = instance.health || {};
|
|
158
|
+
instance.healthState = get(instance, 'health.state') || 'OutOfService';
|
|
159
|
+
instance.health = [health];
|
|
160
|
+
|
|
161
|
+
return instance as IInstance;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const APPENGINE_LOAD_BALANCER_TRANSFORMER = 'spinnaker.appengine.loadBalancer.transformer.service';
|
|
166
|
+
|
|
167
|
+
module(APPENGINE_LOAD_BALANCER_TRANSFORMER, []).service(
|
|
168
|
+
'appengineLoadBalancerTransformer',
|
|
169
|
+
AppengineLoadBalancerTransformer,
|
|
170
|
+
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="128px"
|
|
4
|
+
height="128px" viewBox="15 15 90 90" xml:space="preserve">
|
|
5
|
+
<filter id="invert">
|
|
6
|
+
<feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1
|
|
7
|
+
0 -1 0 0 1
|
|
8
|
+
0 0 -1 0 1
|
|
9
|
+
0 0 0 1 0"/>
|
|
10
|
+
</filter>
|
|
11
|
+
<g id="art" filter="url(#invert)">
|
|
12
|
+
<g>
|
|
13
|
+
<path style="fill:#FFFFFF;" d="M63.9988,40.9577c-12.7278,0-23.0452,10.3167-23.0452,23.0464
|
|
14
|
+
c0,12.726,10.3174,23.0463,23.0452,23.0463c12.7273,0,23.0446-10.3203,23.0446-23.0463
|
|
15
|
+
C87.0434,51.2744,76.7261,40.9577,63.9988,40.9577 M63.9988,81.4887c-9.6584,0-17.4876-7.8286-17.4876-17.4846
|
|
16
|
+
c0-9.6584,7.8291-17.4877,17.4876-17.4877c9.6578,0,17.4858,7.8292,17.4858,17.4877
|
|
17
|
+
C81.4846,73.6601,73.6566,81.4887,63.9988,81.4887"/>
|
|
18
|
+
<path style="fill:#FFFFFF;" d="M100.1431,61.274l-9.6079-3.0195c0.3997,1.8539,0.615,3.7759,0.615,5.7478
|
|
19
|
+
c0,1.3791-0.1047,2.7337-0.3021,4.0569h9.295c0.8587-0.2515,1.4327-0.7846,1.4327-1.5765v-3.6345
|
|
20
|
+
C101.5759,62.0575,101.0018,61.5094,100.1431,61.274"/>
|
|
21
|
+
<path style="fill:#FFFFFF;" d="M63.9923,36.8497c1.9303,0,3.8119,0.2046,5.6285,0.5884l-3.4443-9.5729
|
|
22
|
+
c-0.2515-0.8606-0.7852-1.434-1.5765-1.434h-1.4392c-0.7913,0-1.3407,0.5734-1.5761,1.434l-2.9924,9.5236
|
|
23
|
+
C60.3372,37.0368,62.1425,36.8497,63.9923,36.8497"/>
|
|
24
|
+
<path style="fill:#FFFFFF;" d="M36.8468,64.0023c0-1.9719,0.2154-3.8932,0.6145-5.7478l-9.6073,3.0195
|
|
25
|
+
c-0.8587,0.2354-1.4322,0.7835-1.4322,1.5754v3.6344c0,0.7907,0.5735,1.3238,1.4322,1.5753h9.2955
|
|
26
|
+
C36.9515,66.7366,36.8468,65.3814,36.8468,64.0023"/>
|
|
27
|
+
<path style="fill:#FFFFFF;" d="M72.2276,56.4819l-2.1802,2.1794v-0.0048c-1.5651-1.5639-3.6549-2.4274-5.8687-2.4274
|
|
28
|
+
c-2.2192,0-4.303,0.8659-5.8704,2.4322c-3.2362,3.2355-3.2362,8.5037,0,11.7399l-2.1802,2.1783
|
|
29
|
+
c2.0627,2.0609,4.9096,3.3383,8.0483,3.3383c6.2803,0,11.3896-5.1081,11.3896-11.3895
|
|
30
|
+
C75.566,61.3883,74.289,58.5421,72.2276,56.4819 M67.7284,67.7342c-1.0278,1.0302-2.3799,1.5459-3.7284,1.5459
|
|
31
|
+
c-1.3526,0-2.7012-0.5156-3.7313-1.5459c-2.0616-2.0615-2.0616-5.4018,0-7.4639c1.0301-1.0314,2.3787-1.544,3.7313-1.544
|
|
32
|
+
c1.3485,0,2.7006,0.5127,3.7284,1.544C69.79,62.3312,69.79,65.6727,67.7284,67.7342"/>
|
|
33
|
+
</g>
|
|
34
|
+
</g>
|
|
35
|
+
<g id="Guides" style="display:none;">
|
|
36
|
+
</g>
|
|
37
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { module } from 'angular';
|
|
2
|
+
|
|
3
|
+
import { APPENGINE_DESTROY_ASG_STAGE } from './stages/destroyAsg/appengineDestroyAsgStage';
|
|
4
|
+
import { APPENGINE_DISABLE_ASG_STAGE } from './stages/disableAsg/appengineDisableAsgStage';
|
|
5
|
+
import { APPENGINE_EDIT_LOAD_BALANCER_STAGE } from './stages/editLoadBalancer/appengineEditLoadBalancerStage';
|
|
6
|
+
import { APPENGINE_ENABLE_ASG_STAGE } from './stages/enableAsg/appengineEnableAsgStage';
|
|
7
|
+
import { APPENGINE_SHRINK_CLUSTER_STAGE } from './stages/shrinkCluster/appengineShrinkClusterStage';
|
|
8
|
+
import { APPENGINE_START_SERVER_GROUP_STAGE } from './stages/startServerGroup/appengineStartServerGroupStage';
|
|
9
|
+
import { APPENGINE_STOP_SERVER_GROUP_STAGE } from './stages/stopServerGroup/appengineStopServerGroupStage';
|
|
10
|
+
|
|
11
|
+
export const APPENGINE_PIPELINE_MODULE = 'spinnaker.appengine.pipeline.module';
|
|
12
|
+
module(APPENGINE_PIPELINE_MODULE, [
|
|
13
|
+
APPENGINE_DESTROY_ASG_STAGE,
|
|
14
|
+
APPENGINE_DISABLE_ASG_STAGE,
|
|
15
|
+
APPENGINE_EDIT_LOAD_BALANCER_STAGE,
|
|
16
|
+
APPENGINE_ENABLE_ASG_STAGE,
|
|
17
|
+
APPENGINE_SHRINK_CLUSTER_STAGE,
|
|
18
|
+
APPENGINE_START_SERVER_GROUP_STAGE,
|
|
19
|
+
APPENGINE_STOP_SERVER_GROUP_STAGE,
|
|
20
|
+
]);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IController } from 'angular';
|
|
2
|
+
|
|
3
|
+
import { AccountService, StageConstants } from '@spinnaker/core';
|
|
4
|
+
import { AppengineHealth } from '../../common/appengineHealth';
|
|
5
|
+
import type { IAppengineAccount, IAppengineStageScope } from '../../domain';
|
|
6
|
+
|
|
7
|
+
export class AppengineStageCtrl implements IController {
|
|
8
|
+
public static $inject = ['$scope'];
|
|
9
|
+
constructor(protected $scope: IAppengineStageScope) {
|
|
10
|
+
$scope.platformHealth = AppengineHealth.PLATFORM;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public setStageRegion(): void {
|
|
14
|
+
const selected = this.$scope.accounts.find((account) => account.name === this.$scope.stage.credentials);
|
|
15
|
+
if (selected && selected.name) {
|
|
16
|
+
AccountService.getAccountDetails(selected.name).then((accountDetails: IAppengineAccount) => {
|
|
17
|
+
this.$scope.stage.region = accountDetails.region;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected setStageCloudProvider(): void {
|
|
23
|
+
this.$scope.stage.cloudProvider = 'appengine';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
protected setAccounts(): PromiseLike<void> {
|
|
27
|
+
return AccountService.listAccounts('appengine').then((accounts: IAppengineAccount[]) => {
|
|
28
|
+
this.$scope.accounts = accounts;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected setTargets(): void {
|
|
33
|
+
this.$scope.targets = StageConstants.TARGET_LIST;
|
|
34
|
+
|
|
35
|
+
if (!this.$scope.stage.target) {
|
|
36
|
+
this.$scope.stage.target = this.$scope.targets[0].val;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
protected setStageCredentials(): void {
|
|
41
|
+
if (!this.$scope.stage.credentials && this.$scope.application.defaultCredentials.appengine) {
|
|
42
|
+
this.$scope.stage.credentials = this.$scope.application.defaultCredentials.appengine;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|