@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.
Files changed (138) hide show
  1. package/CHANGELOG.md +981 -0
  2. package/LICENSE.txt +203 -0
  3. package/dist/appengine.logoc2c312af6aa99037.png +0 -0
  4. package/dist/appengine.module.d.ts +5 -0
  5. package/dist/appengine.settings.d.ts +7 -0
  6. package/dist/common/FormikAccountRegionSelector.d.ts +26 -0
  7. package/dist/common/appengineHealth.d.ts +3 -0
  8. package/dist/common/componentUrlDetails.component.d.ts +1 -0
  9. package/dist/common/conditionalDescriptionListItem.component.d.ts +1 -0
  10. package/dist/common/loadBalancerMessage.component.d.ts +1 -0
  11. package/dist/domain/IAppengineAccount.d.ts +6 -0
  12. package/dist/domain/IAppengineInstance.d.ts +20 -0
  13. package/dist/domain/IAppengineLoadBalancer.d.ts +19 -0
  14. package/dist/domain/IAppengineServerGroup.d.ts +11 -0
  15. package/dist/domain/IAppengineStageScope.d.ts +18 -0
  16. package/dist/domain/IAppengineTriggers.d.ts +11 -0
  17. package/dist/domain/index.d.ts +6 -0
  18. package/dist/helpContents/appengineHelpContents.d.ts +1 -0
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.js +4084 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/instance/details/details.controller.d.ts +1 -0
  23. package/dist/loadBalancer/configure/wizard/advancedSettings.component.d.ts +1 -0
  24. package/dist/loadBalancer/configure/wizard/allocationConfigurationRow.component.d.ts +1 -0
  25. package/dist/loadBalancer/configure/wizard/basicSettings.component.d.ts +1 -0
  26. package/dist/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.d.ts +1 -0
  27. package/dist/loadBalancer/configure/wizard/wizard.controller.d.ts +2 -0
  28. package/dist/loadBalancer/details/details.controller.d.ts +1 -0
  29. package/dist/loadBalancer/loadBalancer.module.d.ts +1 -0
  30. package/dist/loadBalancer/transformer.d.ts +40 -0
  31. package/dist/pipeline/pipeline.module.d.ts +1 -0
  32. package/dist/pipeline/stages/appengineStage.controller.d.ts +12 -0
  33. package/dist/pipeline/stages/deployAppengineConfig/DeployAppengineConfigForm.d.ts +16 -0
  34. package/dist/pipeline/stages/deployAppengineConfig/DeployAppengineConfigurationConfig.d.ts +5 -0
  35. package/dist/pipeline/stages/deployAppengineConfig/deployAppengineConfigStage.d.ts +1 -0
  36. package/dist/pipeline/stages/destroyAsg/appengineDestroyAsgStage.d.ts +1 -0
  37. package/dist/pipeline/stages/disableAsg/appengineDisableAsgStage.d.ts +1 -0
  38. package/dist/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.d.ts +1 -0
  39. package/dist/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.d.ts +1 -0
  40. package/dist/pipeline/stages/enableAsg/appengineEnableAsgStage.d.ts +1 -0
  41. package/dist/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.d.ts +1 -0
  42. package/dist/pipeline/stages/startServerGroup/appengineStartServerGroupStage.d.ts +1 -0
  43. package/dist/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.d.ts +1 -0
  44. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +74 -0
  45. package/dist/serverGroup/configure/wizard/ConfigFileArtifactList.d.ts +10 -0
  46. package/dist/serverGroup/configure/wizard/basicSettings.controller.d.ts +1 -0
  47. package/dist/serverGroup/configure/wizard/cloneServerGroup.controller.d.ts +2 -0
  48. package/dist/serverGroup/configure/wizard/configFileArtifactList.module.d.ts +1 -0
  49. package/dist/serverGroup/configure/wizard/configFiles.component.d.ts +20 -0
  50. package/dist/serverGroup/configure/wizard/dynamicBranchLabel.component.d.ts +1 -0
  51. package/dist/serverGroup/details/details.controller.d.ts +1 -0
  52. package/dist/serverGroup/transformer.d.ts +45 -0
  53. package/dist/serverGroup/writer/serverGroup.write.service.d.ts +8 -0
  54. package/dist/validation/ApplicationNameValidator.d.ts +1 -0
  55. package/package.json +46 -0
  56. package/src/appengine.module.ts +70 -0
  57. package/src/appengine.settings.ts +14 -0
  58. package/src/common/FormikAccountRegionSelector.tsx +107 -0
  59. package/src/common/appengineHealth.ts +3 -0
  60. package/src/common/componentUrlDetails.component.ts +29 -0
  61. package/src/common/conditionalDescriptionListItem.component.ts +37 -0
  62. package/src/common/loadBalancerMessage.component.html +33 -0
  63. package/src/common/loadBalancerMessage.component.ts +13 -0
  64. package/src/domain/IAppengineAccount.ts +8 -0
  65. package/src/domain/IAppengineInstance.ts +21 -0
  66. package/src/domain/IAppengineLoadBalancer.ts +21 -0
  67. package/src/domain/IAppengineServerGroup.ts +13 -0
  68. package/src/domain/IAppengineStageScope.ts +22 -0
  69. package/src/domain/IAppengineTriggers.ts +12 -0
  70. package/src/domain/index.ts +6 -0
  71. package/src/helpContents/appengineHelpContents.ts +141 -0
  72. package/src/index.ts +1 -0
  73. package/src/instance/details/details.controller.ts +116 -0
  74. package/src/instance/details/details.html +99 -0
  75. package/src/loadBalancer/configure/wizard/advancedSettings.component.ts +56 -0
  76. package/src/loadBalancer/configure/wizard/allocationConfigurationRow.component.ts +70 -0
  77. package/src/loadBalancer/configure/wizard/basicSettings.component.html +65 -0
  78. package/src/loadBalancer/configure/wizard/basicSettings.component.ts +98 -0
  79. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html +117 -0
  80. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.ts +108 -0
  81. package/src/loadBalancer/configure/wizard/wizard.controller.ts +163 -0
  82. package/src/loadBalancer/configure/wizard/wizard.html +44 -0
  83. package/src/loadBalancer/configure/wizard/wizard.less +17 -0
  84. package/src/loadBalancer/details/details.controller.ts +151 -0
  85. package/src/loadBalancer/details/details.html +102 -0
  86. package/src/loadBalancer/loadBalancer.module.ts +21 -0
  87. package/src/loadBalancer/transformer.ts +170 -0
  88. package/src/logo/appengine.icon.svg +37 -0
  89. package/src/logo/appengine.logo.less +6 -0
  90. package/src/logo/appengine.logo.png +0 -0
  91. package/src/pipeline/pipeline.module.ts +20 -0
  92. package/src/pipeline/stages/appengineStage.controller.ts +45 -0
  93. package/src/pipeline/stages/deployAppengineConfig/DeployAppengineConfigForm.tsx +203 -0
  94. package/src/pipeline/stages/deployAppengineConfig/DeployAppengineConfigurationConfig.tsx +34 -0
  95. package/src/pipeline/stages/deployAppengineConfig/deployAppengineConfigStage.ts +19 -0
  96. package/src/pipeline/stages/destroyAsg/appengineDestroyAsgStage.ts +45 -0
  97. package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +16 -0
  98. package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +1 -0
  99. package/src/pipeline/stages/disableAsg/appengineDisableAsgStage.ts +54 -0
  100. package/src/pipeline/stages/disableAsg/disableAsgStage.html +18 -0
  101. package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +1 -0
  102. package/src/pipeline/stages/editLoadBalancer/appengineEditLoadBalancerStage.ts +74 -0
  103. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html +33 -0
  104. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html +51 -0
  105. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.ts +65 -0
  106. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html +45 -0
  107. package/src/pipeline/stages/enableAsg/appengineEnableAsgStage.ts +49 -0
  108. package/src/pipeline/stages/enableAsg/enableAsgStage.html +18 -0
  109. package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +1 -0
  110. package/src/pipeline/stages/shrinkCluster/appengineShrinkClusterStage.ts +62 -0
  111. package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +41 -0
  112. package/src/pipeline/stages/startServerGroup/appengineStartServerGroupStage.ts +54 -0
  113. package/src/pipeline/stages/startServerGroup/startServerGroupExecutionDetails.html +26 -0
  114. package/src/pipeline/stages/startServerGroup/startServerGroupStage.html +18 -0
  115. package/src/pipeline/stages/startServerGroup/startServerGroupStepLabel.html +1 -0
  116. package/src/pipeline/stages/stopServerGroup/appengineStopServerGroupStage.ts +54 -0
  117. package/src/pipeline/stages/stopServerGroup/stopServerGroupExecutionDetails.html +26 -0
  118. package/src/pipeline/stages/stopServerGroup/stopServerGroupStage.html +18 -0
  119. package/src/pipeline/stages/stopServerGroup/stopServerGroupStepLabel.html +1 -0
  120. package/src/serverGroup/configure/serverGroupCommandBuilder.service.ts +235 -0
  121. package/src/serverGroup/configure/wizard/ConfigFileArtifactList.tsx +81 -0
  122. package/src/serverGroup/configure/wizard/advancedSettings.html +33 -0
  123. package/src/serverGroup/configure/wizard/basicSettings.controller.ts +151 -0
  124. package/src/serverGroup/configure/wizard/basicSettings.html +287 -0
  125. package/src/serverGroup/configure/wizard/cloneServerGroup.controller.ts +103 -0
  126. package/src/serverGroup/configure/wizard/configFileArtifactList.module.ts +18 -0
  127. package/src/serverGroup/configure/wizard/configFileArtifactList.spec.tsx +78 -0
  128. package/src/serverGroup/configure/wizard/configFiles.component.html +81 -0
  129. package/src/serverGroup/configure/wizard/configFiles.component.ts +121 -0
  130. package/src/serverGroup/configure/wizard/dynamicBranchLabel.component.ts +19 -0
  131. package/src/serverGroup/configure/wizard/serverGroupWizard.html +39 -0
  132. package/src/serverGroup/configure/wizard/serverGroupWizard.less +28 -0
  133. package/src/serverGroup/details/details.controller.ts +463 -0
  134. package/src/serverGroup/details/details.html +229 -0
  135. package/src/serverGroup/transformer.ts +92 -0
  136. package/src/serverGroup/transformet.spec.ts +40 -0
  137. package/src/serverGroup/writer/serverGroup.write.service.ts +57 -0
  138. package/src/validation/ApplicationNameValidator.ts +40 -0
@@ -0,0 +1,81 @@
1
+ import classNames from 'classnames';
2
+ import React from 'react';
3
+
4
+ import type { IArtifact, IArtifactAccountPair, IExpectedArtifact, IPipeline, IStage } from '@spinnaker/core';
5
+ import { StageArtifactSelector } from '@spinnaker/core';
6
+
7
+ interface IConfigFileArtifactListProps {
8
+ configArtifacts: IArtifactAccountPair[];
9
+ pipeline: IPipeline;
10
+ stage: IStage;
11
+ updateConfigArtifacts: (configArtifacts: any[]) => void;
12
+ }
13
+
14
+ export const ConfigFileArtifactList = (props: IConfigFileArtifactListProps) => {
15
+ const addConfigArtifact = () => {
16
+ props.updateConfigArtifacts(props.configArtifacts.concat([{ id: '', account: '' }]));
17
+ };
18
+
19
+ const deleteConfigArtifact = (index: number) => {
20
+ const newConfigArtifacts = [...props.configArtifacts];
21
+ newConfigArtifacts.splice(index, 1);
22
+ props.updateConfigArtifacts(newConfigArtifacts);
23
+ };
24
+
25
+ const onExpectedArtifactEdited = (artifact: IArtifact, index: number): void => {
26
+ const newConfigArtifacts = [...props.configArtifacts];
27
+ newConfigArtifacts.splice(index, 1, { ...newConfigArtifacts[index], id: null, artifact });
28
+ props.updateConfigArtifacts(newConfigArtifacts);
29
+ };
30
+
31
+ const onExpectedArtifactSelected = (expectedArtifact: IExpectedArtifact, index: number): void => {
32
+ onChangeExpectedArtifactId(expectedArtifact.id, index);
33
+ };
34
+
35
+ const onChangeExpectedArtifactId = (id: string, index: number): void => {
36
+ const newConfigArtifacts = [...props.configArtifacts];
37
+ newConfigArtifacts.splice(index, 1, { ...newConfigArtifacts[index], id, artifact: null });
38
+ props.updateConfigArtifacts(newConfigArtifacts);
39
+ };
40
+
41
+ return (
42
+ <>
43
+ {props.configArtifacts.map((a, i) => {
44
+ return (
45
+ <div
46
+ key={a.id}
47
+ className={classNames('artifact-configuration-section col-md-12', {
48
+ 'last-entry': props.configArtifacts.length - 1 === i,
49
+ })}
50
+ >
51
+ <div className="col-md-9">
52
+ <StageArtifactSelector
53
+ artifact={a.artifact}
54
+ excludedArtifactTypePatterns={[]}
55
+ expectedArtifactId={a.artifact == null ? a.id : null}
56
+ onArtifactEdited={(artifact: IArtifact) => {
57
+ onExpectedArtifactEdited(artifact, i);
58
+ }}
59
+ onExpectedArtifactSelected={(expectedArtifact: IExpectedArtifact) => {
60
+ onExpectedArtifactSelected(expectedArtifact, i);
61
+ }}
62
+ pipeline={props.pipeline}
63
+ stage={props.stage}
64
+ />
65
+ </div>
66
+ <div className="col-md-1">
67
+ <button type="button" className="btn btn-sm btn-default" onClick={() => deleteConfigArtifact(i)}>
68
+ <span className="glyphicon glyphicon-trash" /> Delete
69
+ </button>
70
+ </div>
71
+ </div>
72
+ );
73
+ })}
74
+ <div className="col-md-7 col-md-offset-3">
75
+ <button className="btn btn-block btn-add-trigger add-new" onClick={() => addConfigArtifact()}>
76
+ <span className="glyphicon glyphicon-plus-sign" /> Add Config Artifact
77
+ </button>
78
+ </div>
79
+ </>
80
+ );
81
+ };
@@ -0,0 +1,33 @@
1
+ <div class="form-horizontal container-fluid">
2
+ <div class="form-group">
3
+ <div class="col-md-4 sm-label-right">Promote <help-field key="appengine.serverGroup.promote"></help-field></div>
4
+ <div class="col-md-7">
5
+ <input type="checkbox" ng-model="command.promote" />
6
+ </div>
7
+ </div>
8
+
9
+ <div class="form-group">
10
+ <div class="col-md-4 sm-label-right">
11
+ Stop Previous Version <help-field key="appengine.serverGroup.stopPreviousVersion"></help-field>
12
+ </div>
13
+ <div class="col-md-7">
14
+ <input type="checkbox" ng-model="command.stopPreviousVersion" />
15
+ </div>
16
+ </div>
17
+ <div class="form-group" ng-if="showPlatformHealthOnlyOverride">
18
+ <div class="col-md-4 sm-label-right">Task Completion</div>
19
+ <div class="col-md-7">
20
+ <platform-health-override command="command" platform-health-type="platformHealth"> </platform-health-override>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="form-group">
25
+ <div class="col-md-4 sm-label-right">
26
+ Suppress Version String
27
+ <help-field key="appengine.serverGroup.suppress-version-string"></help-field>
28
+ </div>
29
+ <div class="col-md-7">
30
+ <input type="checkbox" ng-model="command.suppressVersionString" />
31
+ </div>
32
+ </div>
33
+ </div>
@@ -0,0 +1,151 @@
1
+ import type { StateService } from '@uirouter/angularjs';
2
+ import type { IController, IControllerService, IScope } from 'angular';
3
+ import { extend, module } from 'angular';
4
+ import { set } from 'lodash';
5
+
6
+ import type { IArtifact, IExpectedArtifact } from '@spinnaker/core';
7
+ import {
8
+ ArtifactTypePatterns,
9
+ excludeAllTypesExcept,
10
+ ExpectedArtifactSelectorViewController,
11
+ NgAppEngineDeployArtifactDelegate,
12
+ } from '@spinnaker/core';
13
+ import type { GitCredentialType, IAppengineAccount } from '../../../domain/index';
14
+
15
+ import type { IAppengineServerGroupCommand } from '../serverGroupCommandBuilder.service';
16
+ import { AppengineSourceType } from '../serverGroupCommandBuilder.service';
17
+
18
+ interface IAppengineBasicSettingsScope extends IScope {
19
+ command: IAppengineServerGroupCommand;
20
+ }
21
+
22
+ class AppengineServerGroupBasicSettingsCtrl implements IController {
23
+ public static $inject = ['$scope', '$state', '$controller', '$uibModalStack'];
24
+
25
+ constructor(
26
+ public $scope: IAppengineBasicSettingsScope,
27
+ $state: StateService,
28
+ $controller: IControllerService,
29
+ $uibModalStack: any,
30
+ ) {
31
+ extend(
32
+ this,
33
+ $controller('BasicSettingsMixin', {
34
+ $scope,
35
+ imageReader: null,
36
+ $uibModalStack,
37
+ $state,
38
+ }),
39
+ );
40
+
41
+ if (!this.$scope.command.gitCredentialType) {
42
+ this.onAccountChange();
43
+ }
44
+
45
+ this.$scope.containerArtifactDelegate = new NgAppEngineDeployArtifactDelegate($scope, [
46
+ ArtifactTypePatterns.DOCKER_IMAGE,
47
+ ]);
48
+ this.$scope.containerArtifactController = new ExpectedArtifactSelectorViewController(
49
+ this.$scope.containerArtifactDelegate,
50
+ );
51
+ this.$scope.gcsArtifactDelegate = new NgAppEngineDeployArtifactDelegate($scope, [ArtifactTypePatterns.GCS_OBJECT]);
52
+ this.$scope.gcsArtifactController = new ExpectedArtifactSelectorViewController(this.$scope.gcsArtifactDelegate);
53
+ }
54
+
55
+ public isGitSource(): boolean {
56
+ return this.$scope.command.sourceType === AppengineSourceType.GIT;
57
+ }
58
+
59
+ public isGcsSource(): boolean {
60
+ return this.$scope.command.sourceType === AppengineSourceType.GCS;
61
+ }
62
+
63
+ public isContainerImageSource(): boolean {
64
+ return this.$scope.command.sourceType === AppengineSourceType.CONTAINER_IMAGE;
65
+ }
66
+
67
+ public toggleResolveViaTrigger(): void {
68
+ this.$scope.command.fromTrigger = !this.$scope.command.fromTrigger;
69
+ delete this.$scope.command.trigger;
70
+ delete this.$scope.command.branch;
71
+ }
72
+
73
+ public onTriggerChange(): void {
74
+ set(this, '$scope.command.trigger.matchBranchOnRegex', undefined);
75
+ }
76
+
77
+ public onAccountChange(): void {
78
+ const account = this.findAccountInBackingData();
79
+ if (account) {
80
+ this.$scope.command.gitCredentialType = this.getSupportedGitCredentialTypes()[0];
81
+ this.$scope.command.region = account.region;
82
+ } else {
83
+ this.$scope.command.gitCredentialType = 'NONE';
84
+ delete this.$scope.command.region;
85
+ }
86
+ }
87
+
88
+ public getSupportedGitCredentialTypes(): GitCredentialType[] {
89
+ const account = this.findAccountInBackingData();
90
+ if (account && account.supportedGitCredentialTypes) {
91
+ return account.supportedGitCredentialTypes;
92
+ } else {
93
+ return ['NONE'];
94
+ }
95
+ }
96
+
97
+ public humanReadableGitCredentialType(type: GitCredentialType): string {
98
+ switch (type) {
99
+ case 'HTTPS_USERNAME_PASSWORD':
100
+ return 'HTTPS with username and password';
101
+ case 'HTTPS_GITHUB_OAUTH_TOKEN':
102
+ return 'HTTPS with Github OAuth token';
103
+ case 'SSH':
104
+ return 'SSH';
105
+ case 'NONE':
106
+ return 'No credentials';
107
+ default:
108
+ return 'No credentials';
109
+ }
110
+ }
111
+
112
+ public readonly excludedGcsArtifactTypes = excludeAllTypesExcept(ArtifactTypePatterns.GCS_OBJECT);
113
+ public readonly excludedContainerArtifactTypes = excludeAllTypesExcept(ArtifactTypePatterns.DOCKER_IMAGE);
114
+
115
+ public onExpectedArtifactEdited = (artifact: IArtifact): void => {
116
+ this.$scope.$applyAsync(() => {
117
+ this.$scope.command.expectedArtifactId = null;
118
+ this.$scope.command.expectedArtifact = artifact;
119
+ });
120
+ };
121
+
122
+ public onExpectedArtifactSelected = (expectedArtifact: IExpectedArtifact): void => {
123
+ this.onChangeExpectedArtifactId(expectedArtifact.id);
124
+ };
125
+
126
+ public onChangeExpectedArtifactId = (artifactId: string): void => {
127
+ this.$scope.$applyAsync(() => {
128
+ this.$scope.command.expectedArtifactId = artifactId;
129
+ this.$scope.command.expectedArtifact = null;
130
+ });
131
+ };
132
+
133
+ public onExpectedArtifactAccountSelected = (accountName: string): void => {
134
+ this.$scope.$applyAsync(() => {
135
+ this.$scope.command.storageAccountName = accountName;
136
+ });
137
+ };
138
+
139
+ private findAccountInBackingData(): IAppengineAccount {
140
+ return this.$scope.command.backingData.accounts.find((account: IAppengineAccount) => {
141
+ return this.$scope.command.credentials === account.name;
142
+ });
143
+ }
144
+ }
145
+
146
+ export const APPENGINE_SERVER_GROUP_BASIC_SETTINGS_CTRL = 'spinnaker.appengine.basicSettings.controller';
147
+
148
+ module(APPENGINE_SERVER_GROUP_BASIC_SETTINGS_CTRL, []).controller(
149
+ 'appengineServerGroupBasicSettingsCtrl',
150
+ AppengineServerGroupBasicSettingsCtrl,
151
+ );
@@ -0,0 +1,287 @@
1
+ <div class="container-fluid form-horizontal" ng-controller="appengineServerGroupBasicSettingsCtrl as basicSettingsCtrl">
2
+ <ng-form name="basicSettings">
3
+ <div class="form-group">
4
+ <div class="col-md-3 sm-label-right">Account</div>
5
+ <div class="col-md-7">
6
+ <account-select-field
7
+ read-only="command.viewState.readOnlyFields.credentials"
8
+ component="command"
9
+ field="credentials"
10
+ on-change="basicSettingsCtrl.onAccountChange()"
11
+ accounts="command.backingData.accounts"
12
+ provider="'appengine'"
13
+ ></account-select-field>
14
+ </div>
15
+ </div>
16
+
17
+ <div class="form-group">
18
+ <div class="col-md-3 sm-label-right">Region</div>
19
+ <div class="col-md-7">
20
+ <input type="text" readonly class="form-control input-sm" name="region" ng-model="command.region" />
21
+ </div>
22
+ </div>
23
+
24
+ <div class="form-group">
25
+ <div class="col-md-3 sm-label-right">
26
+ Stack
27
+ <help-field key="aws.serverGroup.stack"></help-field>
28
+ </div>
29
+ <div class="col-md-7">
30
+ <input
31
+ type="text"
32
+ class="form-control input-sm no-spel"
33
+ ng-pattern="basicSettingsCtrl.stackPattern"
34
+ name="stack"
35
+ ng-model="command.stack"
36
+ />
37
+ </div>
38
+ </div>
39
+ <div class="form-group row slide-in" ng-if="basicSettings.stack.$error.pattern">
40
+ <div class="col-sm-9 col-sm-offset-2 error-message">
41
+ <span>Only dot(.) and underscore(_) special characters are allowed in the Stack field.</span>
42
+ </div>
43
+ </div>
44
+ <div class="form-group">
45
+ <div class="col-md-3 sm-label-right">
46
+ Detail
47
+ <help-field key="aws.serverGroup.detail"></help-field>
48
+ </div>
49
+ <div class="col-md-7">
50
+ <input
51
+ type="text"
52
+ class="form-control input-sm no-spel"
53
+ ng-pattern="basicSettingsCtrl.detailPattern"
54
+ name="details"
55
+ ng-model="command.freeFormDetails"
56
+ />
57
+ </div>
58
+ </div>
59
+
60
+ <div class="form-group row slide-in" ng-if="basicSettings.details.$error.pattern">
61
+ <div class="col-sm-9 col-sm-offset-2 error-message">
62
+ <span>Only dot(.), underscore(_), and dash(-) special characters are allowed in the Detail field.</span>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="form-group row">
67
+ <label class="col-md-3 sm-label-right">Source Type</label>
68
+ <div class="col-md-7">
69
+ <div class="radio radio-inline">
70
+ <label> <input type="radio" ng-model="command.sourceType" value="git" /> Git </label>
71
+ </div>
72
+ <div class="radio radio-inline">
73
+ <label> <input type="radio" ng-model="command.sourceType" value="gcs" /> GCS </label>
74
+ </div>
75
+ <div class="radio radio-inline">
76
+ <label> <input type="radio" ng-model="command.sourceType" value="containerImage" /> Container Image </label>
77
+ </div>
78
+ </div>
79
+ </div>
80
+
81
+ <div ng-if="basicSettingsCtrl.isGcsSource()">
82
+ <div class="form-group row">
83
+ <label class="col-md-3 sm-label-right">Resolve URL</label>
84
+ <div class="col-md-7">
85
+ <div class="radio radio-inline">
86
+ <label> <input type="radio" ng-model="command.fromArtifact" ng-value="false" /> via text input </label>
87
+ </div>
88
+ <div class="radio radio-inline" ng-if="command.viewState.pipeline">
89
+ <label>
90
+ <input type="radio" ng-model="command.fromArtifact" ng-value="true" /> via pipeline artifact
91
+ </label>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ <stage-artifact-selector-delegate
96
+ ng-if="command.fromArtifact"
97
+ artifact="command.expectedArtifact"
98
+ excluded-artifact-type-patterns="basicSettingsCtrl.excludedGcsArtifactTypes"
99
+ expected-artifact-id="command.expectedArtifactId"
100
+ field-columns="7"
101
+ label="'Expected Artifact'"
102
+ on-artifact-edited="basicSettingsCtrl.onExpectedArtifactEdited"
103
+ on-expected-artifact-selected="basicSettingsCtrl.onExpectedArtifactSelected"
104
+ pipeline="command.viewState.pipeline"
105
+ stage="command.viewState.stage"
106
+ >
107
+ </stage-artifact-selector-delegate>
108
+ <div class="form-group" ng-if="!command.fromArtifact">
109
+ <div class="col-md-3 sm-label-right">
110
+ GCS URL
111
+ <help-field class="help-field-absolute" key="appengine.serverGroup.gcs.repositoryUrl"></help-field>
112
+ </div>
113
+ <div class="col-md-7">
114
+ <input type="text" required class="form-control input-sm" name="gcsUrl" ng-model="command.repositoryUrl" />
115
+ </div>
116
+ </div>
117
+ </div>
118
+
119
+ <div ng-if="basicSettingsCtrl.isGitSource()">
120
+ <div class="form-group">
121
+ <div class="col-md-3 sm-label-right">
122
+ Git Repository URL
123
+ <help-field class="help-field-absolute" key="appengine.serverGroup.git.repositoryUrl"></help-field>
124
+ </div>
125
+ <div class="col-md-7">
126
+ <input type="text" required class="form-control input-sm" name="gitRepo" ng-model="command.repositoryUrl" />
127
+ </div>
128
+ </div>
129
+
130
+ <div class="form-group">
131
+ <div class="col-md-3 sm-label-right">
132
+ Git Credential Type
133
+ <help-field class="help-field-absolute" key="appengine.serverGroup.gitCredentialType"></help-field>
134
+ </div>
135
+ <div class="col-md-7">
136
+ <select
137
+ class="form-control input-sm"
138
+ ng-options="basicSettingsCtrl.humanReadableGitCredentialType(type) for type in basicSettingsCtrl.getSupportedGitCredentialTypes()"
139
+ ng-model="command.gitCredentialType"
140
+ ></select>
141
+ </div>
142
+ </div>
143
+
144
+ <div class="form-group">
145
+ <div class="col-md-3 sm-label-right">Branch <help-field key="appengine.serverGroup.branch"></help-field></div>
146
+ <div class="col-md-7">
147
+ <input
148
+ ng-if="!command.fromTrigger"
149
+ type="text"
150
+ required
151
+ class="form-control input-sm"
152
+ name="branch"
153
+ ng-model="command.branch"
154
+ />
155
+
156
+ <ui-select
157
+ ng-if="command.fromTrigger"
158
+ ng-model="command.trigger"
159
+ class="form-control input-sm"
160
+ on-select="basicSettingsCtrl.onTriggerChange()"
161
+ required
162
+ >
163
+ <ui-select-match allow-clear>
164
+ <appengine-dynamic-branch-label trigger="command.trigger"></appengine-dynamic-branch-label>
165
+ </ui-select-match>
166
+ <ui-select-choices repeat="trigger in command.backingData.triggerOptions">
167
+ <appengine-dynamic-branch-label trigger="trigger"></appengine-dynamic-branch-label>
168
+ </ui-select-choices>
169
+ </ui-select>
170
+ </div>
171
+
172
+ <div
173
+ class="col-md-7 col-md-offset-3"
174
+ ng-if="command.viewState.mode === 'createPipeline' || command.viewState.mode === 'editPipeline'"
175
+ >
176
+ <span class="pull-right small" ng-if="!command.fromTrigger">
177
+ <a href ng-click="basicSettingsCtrl.toggleResolveViaTrigger()">Resolve via trigger</a>
178
+ </span>
179
+ <span class="pull-right small" ng-if="command.fromTrigger">
180
+ <a href ng-click="basicSettingsCtrl.toggleResolveViaTrigger()">Click for text input</a>
181
+ </span>
182
+ </div>
183
+ </div>
184
+ </div>
185
+
186
+ <div ng-if="basicSettingsCtrl.isContainerImageSource()">
187
+ <div class="form-group">
188
+ <label class="col-md-3 sm-label-right">Resolve URL</label>
189
+ <div class="col-md-7">
190
+ <div class="radio radio-inline">
191
+ <label> <input type="radio" ng-model="command.fromArtifact" ng-value="false" /> via text input </label>
192
+ </div>
193
+ <div class="radio radio-inline" ng-if="command.viewState.pipeline">
194
+ <label>
195
+ <input type="radio" ng-model="command.fromArtifact" ng-value="true" /> via pipeline artifact
196
+ </label>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ <stage-artifact-selector-delegate
201
+ ng-if="command.fromArtifact"
202
+ artifact="command.expectedArtifact"
203
+ excluded-artifact-type-patterns="basicSettingsCtrl.excludedContainerArtifactTypes"
204
+ expected-artifact-id="command.expectedArtifactId"
205
+ field-columns="7"
206
+ label="'Expected Artifact'"
207
+ on-artifact-edited="basicSettingsCtrl.onExpectedArtifactEdited"
208
+ on-expected-artifact-selected="basicSettingsCtrl.onExpectedArtifactSelected"
209
+ pipeline="command.viewState.pipeline"
210
+ stage="command.viewState.stage"
211
+ >
212
+ </stage-artifact-selector-delegate>
213
+ <div class="form-group" ng-if="!command.fromArtifact">
214
+ <div class="col-md-3 sm-label-right">
215
+ Image URL
216
+ <help-field key="appengine.serverGroup.containerImageUrl"></help-field>
217
+ </div>
218
+ <div class="col-md-7">
219
+ <input
220
+ type="text"
221
+ required
222
+ class="form-control input-sm"
223
+ name="containerImageUrl"
224
+ ng-model="command.containerImageUrl"
225
+ />
226
+ </div>
227
+ </div>
228
+ </div>
229
+
230
+ <div ng-if="command.trigger.type === 'jenkins'" class="form-group">
231
+ <div class="col-md-7 col-md-offset-3">
232
+ <div class="form-inline">
233
+ <small>Match branch from trigger on regex</small>
234
+ <help-field key="appengine.serverGroup.matchBranchOnRegex"></help-field>
235
+ <input
236
+ type="text"
237
+ style="width: 140px"
238
+ class="form-control input-sm pull-right"
239
+ name="matchOnRegex"
240
+ ng-model="command.trigger.matchBranchOnRegex"
241
+ />
242
+ </div>
243
+ </div>
244
+ </div>
245
+
246
+ <deployment-strategy-selector
247
+ field-columns="7"
248
+ ng-if="!command.viewState.disableStrategySelection"
249
+ command="command"
250
+ ></deployment-strategy-selector>
251
+
252
+ <div class="form-group" ng-if="!command.viewState.hideClusterNamePreview">
253
+ <div class="col-md-12">
254
+ <div class="well-compact" ng-class="basicSettingsCtrl.showPreviewAsWarning() ? 'alert alert-warning' : 'well'">
255
+ <h5 class="text-center">
256
+ <p>Your server group will be in the cluster:</p>
257
+ <p>
258
+ <strong>
259
+ {{basicSettingsCtrl.getNamePreview()}}
260
+ <span ng-if="basicSettingsCtrl.createsNewCluster()"> (new cluster)</span>
261
+ </strong>
262
+ </p>
263
+ <div
264
+ class="text-left"
265
+ ng-if="!basicSettingsCtrl.createsNewCluster() && command.viewState.mode === 'create' && latestServerGroup"
266
+ >
267
+ <p>There is already a server group in this cluster. Do you want to clone it?</p>
268
+ <p>
269
+ Cloning copies the entire configuration from the selected server group, allowing you to modify whichever
270
+ fields (e.g. image) you need to change in the new server group.
271
+ </p>
272
+ <p>
273
+ To clone a server group, select "Clone" from the "Server Group Actions" menu in the details view of the
274
+ server group.
275
+ </p>
276
+ <p>
277
+ <a href ng-click="basicSettingsCtrl.navigateToLatestServerGroup()">
278
+ Go to details for {{latestServerGroup.name}}
279
+ </a>
280
+ </p>
281
+ </div>
282
+ </h5>
283
+ </div>
284
+ </div>
285
+ </div>
286
+ </ng-form>
287
+ </div>
@@ -0,0 +1,103 @@
1
+ import type { IController, IScope } from 'angular';
2
+ import { copy, module } from 'angular';
3
+ import type { IModalInstanceService } from 'angular-ui-bootstrap';
4
+ import { get, merge } from 'lodash';
5
+
6
+ import type { Application, ServerGroupWriter } from '@spinnaker/core';
7
+ import { SERVER_GROUP_WRITER, TaskMonitor } from '@spinnaker/core';
8
+ import { AppengineHealth } from '../../../common/appengineHealth';
9
+
10
+ import { APPENGINE_CONFIG_FILE_CONFIGURER } from './configFiles.component';
11
+ import { APPENGINE_DYNAMIC_BRANCH_LABEL } from './dynamicBranchLabel.component';
12
+ import type {
13
+ AppengineServerGroupCommandBuilder,
14
+ IAppengineServerGroupCommand,
15
+ } from '../serverGroupCommandBuilder.service';
16
+
17
+ import './serverGroupWizard.less';
18
+
19
+ class AppengineCloneServerGroupCtrl implements IController {
20
+ public pages: { [pageKey: string]: string } = {
21
+ basicSettings: require('./basicSettings.html'),
22
+ advancedSettings: require('./advancedSettings.html'),
23
+ };
24
+ public state = {
25
+ loading: true,
26
+ };
27
+ public taskMonitor: TaskMonitor;
28
+
29
+ public static $inject = [
30
+ '$scope',
31
+ '$uibModalInstance',
32
+ 'serverGroupCommand',
33
+ 'application',
34
+ 'serverGroupWriter',
35
+ 'appengineServerGroupCommandBuilder',
36
+ ];
37
+ constructor(
38
+ public $scope: IScope,
39
+ private $uibModalInstance: IModalInstanceService,
40
+ public serverGroupCommand: IAppengineServerGroupCommand,
41
+ private application: Application,
42
+ private serverGroupWriter: ServerGroupWriter,
43
+ appengineServerGroupCommandBuilder: AppengineServerGroupCommandBuilder,
44
+ ) {
45
+ if (['create', 'clone', 'editPipeline'].includes(get<string>(serverGroupCommand, 'viewState.mode'))) {
46
+ this.$scope.command = serverGroupCommand;
47
+ this.state.loading = false;
48
+ this.initialize();
49
+ } else {
50
+ appengineServerGroupCommandBuilder
51
+ .buildNewServerGroupCommand(application, 'appengine', 'createPipeline')
52
+ .then((constructedCommand) => {
53
+ this.$scope.command = merge(constructedCommand, serverGroupCommand);
54
+ // Re-establish references to the original pipeline and stage objects so that
55
+ // we don't mutate copies of them when assigning expected artifacts.
56
+ this.$scope.command.viewState.pipeline = serverGroupCommand.viewState.pipeline;
57
+ this.$scope.command.viewState.stage = serverGroupCommand.viewState.stage;
58
+ this.state.loading = false;
59
+ this.initialize();
60
+ });
61
+ }
62
+ }
63
+
64
+ public cancel(): void {
65
+ this.$uibModalInstance.dismiss();
66
+ }
67
+
68
+ public submit(): void {
69
+ const mode = this.$scope.command.viewState.mode;
70
+ if (['editPipeline', 'createPipeline'].includes(mode)) {
71
+ return this.$uibModalInstance.close(this.$scope.command);
72
+ } else {
73
+ const command = copy(this.$scope.command);
74
+ // Make sure we're sending off a create operation, because there's no such thing as clone for App Engine.
75
+ command.viewState.mode = 'create';
76
+ const submitMethod = () => this.serverGroupWriter.cloneServerGroup(command, this.$scope.application);
77
+ this.taskMonitor.submit(submitMethod);
78
+
79
+ return null;
80
+ }
81
+ }
82
+
83
+ private initialize(): void {
84
+ this.$scope.application = this.application;
85
+ this.taskMonitor = new TaskMonitor({
86
+ application: this.application,
87
+ title: 'Creating your server group',
88
+ modalInstance: this.$uibModalInstance,
89
+ });
90
+ this.$scope.showPlatformHealthOnlyOverride = this.application.attributes.platformHealthOnlyShowOverride;
91
+ this.$scope.platformHealth = AppengineHealth.PLATFORM;
92
+ if (this.application.attributes.platformHealthOnly) {
93
+ this.$scope.command.interestingHealthProviderNames = [AppengineHealth.PLATFORM];
94
+ }
95
+ }
96
+ }
97
+
98
+ export const APPENGINE_CLONE_SERVER_GROUP_CTRL = 'spinnaker.appengine.cloneServerGroup.controller';
99
+ module(APPENGINE_CLONE_SERVER_GROUP_CTRL, [
100
+ SERVER_GROUP_WRITER,
101
+ APPENGINE_DYNAMIC_BRANCH_LABEL,
102
+ APPENGINE_CONFIG_FILE_CONFIGURER,
103
+ ]).controller('appengineCloneServerGroupCtrl', AppengineCloneServerGroupCtrl);
@@ -0,0 +1,18 @@
1
+ import { module } from 'angular';
2
+ import { react2angular } from 'react2angular';
3
+
4
+ import { withErrorBoundary } from '@spinnaker/core';
5
+
6
+ import { ConfigFileArtifactList } from './ConfigFileArtifactList';
7
+
8
+ export const CONFIG_FILE_ARTIFACT_LIST = 'spinnaker.appengine.configFileArtifactList.component';
9
+
10
+ module(CONFIG_FILE_ARTIFACT_LIST, []).component(
11
+ 'configFileArtifactList',
12
+ react2angular(withErrorBoundary(ConfigFileArtifactList, 'configFileArtifactList'), [
13
+ 'configArtifacts',
14
+ 'pipeline',
15
+ 'stage',
16
+ 'updateConfigArtifacts',
17
+ ]),
18
+ );