@spinnaker/cloudrun 2026.2.3 → 2026.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/cloudrun.module.d.ts +1 -1
  2. package/dist/common/ComponentUrlDetails.d.ts +7 -0
  3. package/dist/common/LoadBalancerMessage.d.ts +4 -0
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/instance/details/CloudrunInstanceDetails.d.ts +23 -0
  8. package/dist/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.d.ts +32 -0
  9. package/dist/loadBalancer/details/CloudrunLoadBalancerActions.d.ts +3 -0
  10. package/dist/loadBalancer/details/sections.d.ts +7 -0
  11. package/dist/loadBalancer/details/useCloudrunLoadBalancerDetails.d.ts +4 -0
  12. package/dist/loadBalancer/index.d.ts +4 -2
  13. package/dist/loadBalancer/loadBalancerTransformer.d.ts +2 -6
  14. package/dist/manifest/manifest.service.d.ts +5 -0
  15. package/dist/manifest/manifestCommandBuilder.service.d.ts +1 -1
  16. package/dist/pipeline/stages/deployManifest/manifestStatus/DeployStatus.d.ts +1 -0
  17. package/dist/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.d.ts +6 -3
  18. package/dist/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerExecutionDetails.d.ts +7 -0
  19. package/dist/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerStageConfig.d.ts +30 -0
  20. package/dist/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.d.ts +2 -1
  21. package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +4 -6
  22. package/dist/serverGroup/configure/wizard/BasicSettings.d.ts +5 -2
  23. package/dist/serverGroup/configure/wizard/serverGroupWizard.d.ts +18 -6
  24. package/dist/serverGroup/details/CloudrunServerGroupActions.d.ts +6 -0
  25. package/dist/serverGroup/details/cloudrunServerGroupDetailsGetter.d.ts +3 -0
  26. package/dist/serverGroup/details/sections.d.ts +5 -0
  27. package/dist/serverGroup/index.d.ts +3 -1
  28. package/dist/serverGroup/serverGroupTransformer.service.d.ts +1 -5
  29. package/package.json +4 -11
  30. package/src/cloudrun.module.spec.ts +22 -0
  31. package/src/cloudrun.module.ts +54 -59
  32. package/src/common/ComponentUrlDetails.tsx +25 -0
  33. package/src/common/LoadBalancerMessage.tsx +17 -0
  34. package/src/index.ts +2 -1
  35. package/src/instance/details/CloudrunInstanceDetails.tsx +164 -0
  36. package/src/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.spec.tsx +85 -0
  37. package/src/loadBalancer/configure/wizard/CloudrunLoadBalancerModal.tsx +395 -0
  38. package/src/loadBalancer/details/CloudrunLoadBalancerActions.tsx +66 -0
  39. package/src/loadBalancer/details/sections.spec.ts +19 -0
  40. package/src/loadBalancer/details/sections.tsx +91 -0
  41. package/src/loadBalancer/details/useCloudrunLoadBalancerDetails.ts +56 -0
  42. package/src/loadBalancer/index.ts +4 -2
  43. package/src/loadBalancer/loadBalancerTransformer.ts +3 -13
  44. package/src/manifest/manifest.service.ts +18 -1
  45. package/src/manifest/manifestCommandBuilder.service.ts +46 -53
  46. package/src/pipeline/stages/deployManifest/manifestStatus/DeployStatus.tsx +33 -4
  47. package/src/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.spec.tsx +35 -0
  48. package/src/pipeline/stages/deployManifest/manifestStatus/ManifestDetailsLink.tsx +10 -5
  49. package/src/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerExecutionDetails.tsx +70 -0
  50. package/src/pipeline/stages/editLoadBalancer/CloudrunEditLoadBalancerStageConfig.tsx +245 -0
  51. package/src/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.spec.ts +205 -0
  52. package/src/pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage.ts +14 -71
  53. package/src/serverGroup/configure/serverGroupCommandBuilder.service.ts +5 -15
  54. package/src/serverGroup/configure/wizard/BasicSettings.tsx +10 -8
  55. package/src/serverGroup/configure/wizard/serverGroupWizard.tsx +59 -15
  56. package/src/serverGroup/details/CloudrunServerGroupActions.tsx +80 -0
  57. package/src/serverGroup/details/cloudrunServerGroupDetailsGetter.spec.ts +46 -0
  58. package/src/serverGroup/details/cloudrunServerGroupDetailsGetter.ts +53 -0
  59. package/src/serverGroup/details/sections.tsx +60 -0
  60. package/src/serverGroup/index.ts +3 -1
  61. package/src/serverGroup/routerConsumers.spec.tsx +152 -0
  62. package/src/serverGroup/serverGroupTransformer.service.ts +2 -12
  63. package/dist/common/componentUrlDetails.component.d.ts +0 -1
  64. package/dist/common/conditionalDescriptionListItem.component.d.ts +0 -1
  65. package/dist/common/loadBalancerMessage.component.d.ts +0 -1
  66. package/dist/instance/details/details.controller.d.ts +0 -1
  67. package/dist/loadBalancer/configure/wizard/allocationConfigurationRow.component.d.ts +0 -1
  68. package/dist/loadBalancer/configure/wizard/basicSettings.component.d.ts +0 -1
  69. package/dist/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.d.ts +0 -1
  70. package/dist/loadBalancer/configure/wizard/wizard.controller.d.ts +0 -2
  71. package/dist/loadBalancer/details/details.controller.d.ts +0 -1
  72. package/dist/pipeline/pipeline.module.d.ts +0 -1
  73. package/dist/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.d.ts +0 -1
  74. package/dist/serverGroup/details/details.controller.d.ts +0 -1
  75. package/src/common/componentUrlDetails.component.ts +0 -22
  76. package/src/common/conditionalDescriptionListItem.component.ts +0 -37
  77. package/src/common/loadBalancerMessage.component.html +0 -11
  78. package/src/common/loadBalancerMessage.component.ts +0 -13
  79. package/src/instance/details/details.controller.ts +0 -84
  80. package/src/instance/details/details.html +0 -68
  81. package/src/loadBalancer/configure/wizard/allocationConfigurationRow.component.ts +0 -70
  82. package/src/loadBalancer/configure/wizard/basicSettings.component.html +0 -44
  83. package/src/loadBalancer/configure/wizard/basicSettings.component.ts +0 -86
  84. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html +0 -45
  85. package/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.ts +0 -84
  86. package/src/loadBalancer/configure/wizard/wizard.controller.ts +0 -157
  87. package/src/loadBalancer/configure/wizard/wizard.html +0 -39
  88. package/src/loadBalancer/configure/wizard/wizard.less +0 -9
  89. package/src/loadBalancer/details/details.controller.ts +0 -140
  90. package/src/loadBalancer/details/details.html +0 -89
  91. package/src/pipeline/pipeline.module.ts +0 -6
  92. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html +0 -33
  93. package/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html +0 -51
  94. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.controller.ts +0 -65
  95. package/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html +0 -53
  96. package/src/serverGroup/details/details.controller.ts +0 -134
  97. package/src/serverGroup/details/details.html +0 -94
@@ -1,4 +1,4 @@
1
1
  import './help/cloudrun.help';
2
2
  import './pipeline/stages/deployManifest/deployStage';
3
+ import './pipeline/stages/editLoadBalancer/cloudrunEditLoadBalancerStage';
3
4
  import './logo/cloudrun.logo.less';
4
- export declare const CLOUDRUN_MODULE = "spinnaker.cloudrun";
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ export declare function ComponentUrlDetails({ component }: {
3
+ component: {
4
+ url?: string;
5
+ httpsUrl?: string;
6
+ };
7
+ }): JSX.Element;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare function LoadBalancerMessage({ showCreateMessage }: {
3
+ showCreateMessage?: boolean;
4
+ }): JSX.Element;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './cloudrun.module';
1
+ import './cloudrun.module';
2
2
  export * from './serverGroup';
3
3
  export * from './loadBalancer';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{module as e}from"angular";import{HelpContentsRegistry as t,RecentHistoryService as n,InstanceReader as a,StageConstants as i,LoadBalancerWriter as r,TaskMonitor as s,ConfirmationModalService as o,CloudProviderRegistry as l,Registry as c,StageArtifactSelector as d,ArtifactTypePatterns as u,HelpField as p,AccountSelectInput as m,yamlDocumentsToString as h,StageConfigField as g,RadioButtonInput as f,YamlEditor as v,StageArtifactSelectorDelegate as b,CheckboxInput as B,AccountService as k,FormikStageConfig as C,ReactInjector as w,relativeTime as y,JobManifestPodLogs as S,JobEventBasedPodNameProvider as E,CopyToClipboard as A,ManifestYaml as G,ManifestReader as x,ExecutionDetailsSection as D,StageFailureMessage as T,ExecutionDetailsTasks as $,ExecutionArtifactTab as N,ArtifactReferenceService as L,ExpectedArtifactService as M,SETTINGS as I,NameUtils as F,ServerGroupNamePreview as R,TextAreaInput as P,ReactModal as z,WizardModal as O,WizardPage as U,noop as V,SERVER_GROUP_WRITER as Y,ServerGroupReader as j,DeploymentStrategyRegistry as K}from"@spinnaker/core";import{flattenDeep as q,uniq as W,difference as H,filter as X,chain as Q,cloneDeep as _,has as Z,camelCase as J,get as ee,reduce as te,map as ne,capitalize as ae,isEmpty as ie,trim as re}from"lodash";import se,{useState as oe}from"react";import{Subject as le,from as ce}from"rxjs";import{takeUntil as de}from"rxjs/operators";import{dump as ue}from"js-yaml";import{DateTime as pe}from"luxon";import{$q as me}from"ngimport";const he={bindings:{component:"<"},template:'\n <dt>HTTPS</dt>\n <dl class="small">\n <a href="{{$ctrl.component.url}}" target="_blank">{{$ctrl.component.url}}</a>\n <copy-to-clipboard class="copy-to-clipboard copy-to-clipboard-sm"\n tool-tip="\'Copy URL to clipboard\'"\n text="$ctrl.component.httpsUrl"></copy-to-clipboard>\n </dl>\n '},ge="spinnaker.cloudrun.componentUrlDetails.component";e(ge,[]).component("cloudrunComponentUrlDetails",he);const fe="spinnaker.cloudrun.loadBalancer.createMessage.component";e(fe,[]).component("cloudrunLoadBalancerMessage",{bindings:{showCreateMessage:"<",columnOffset:"@",columns:"@"},templateUrl:"cloudrun/src/common/loadBalancerMessage.component.html"}),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/common/loadBalancerMessage.component.html",'<div class="row">\n <div class="col-md-offset-{{ $ctrl.columnOffset || 0 }} col-md-{{ $ctrl.columns || 12 }}">\n <div class="well">\n <p>\n <span ng-if="$ctrl.showCreateMessage">Spinnaker cannot create a load balancer for Cloud Run.</span>\n A Spinnaker load balancer maps to an Cloud Run Service, which will be created automatically alongside a\n Revision. Once created, the Service can be edited as a Load Balancer.\n </p>\n </div>\n </div>\n</div>\n')}]);[{key:"cloudrun.serverGroup.stack",value:"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing."},{key:"cloudrun.serverGroup.file",value:"<pre>\n apiVersion: serving.knative.dev/v1\n kind: Service\n metadata:\n name: spinappcloud1\n namespace: '135005621049'\n labels:\n cloud.googleapis.com/location: us-central1\n annotations:\n run.googleapis.com/client-name: cloud-console\n serving.knative.dev/creator: kiran@opsmx.io\n serving.knative.dev/lastModifier: kiran@opsmx.io\n client.knative.dev/user-image: us-docker.pkg.dev/cloudrun/container/hello\n run.googleapis.com/ingress-status: all\n spec:\n template:\n metagoogleapis.com/ingress: all\n run.data:\n name: spinappcloud1\n annotations:\n run.googleapis.com/client-name: cloud-console\n autoscaling.knative.dev/minScale: '1'\n autoscaling.knative.dev/maxScale: '3'\n spec:\n containerConcurrency: 80\n timeoutSeconds: 200\n serviceAccountName:spinnaker-cloudrun-account@my-orbit-project-71824.iam.gserviceaccount.com\n containers:\n - image:us-docker.pkg.dev/cloudrun/container/hello\n ports:\n - name: http1\n containerPort: 8080\n resources:\n limits:\n cpu: 1000m\n memory: 256Mi \n</pre>\n "},{key:"cloudrun.serverGroup.detail",value:" (Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables."},{key:"cloudrun.serverGroup.configFiles",value:"<p> The contents of a Cloud Run Service yaml </p>"},{key:"cloudrun.loadBalancer.allocations",value:"An allocation is the percent of traffic directed to a server group."},{key:"cloudrun.manifest.source",value:"\n <p>Where the manifest file content is read from.</p>\n <p>\n <b>text:</b> The manifest is supplied statically to the pipeline from the below text-box.\n </p>\n <p>\n <b>artifact:</b> The manifest is read from an artifact supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>"},{key:"cloudrun.manifest.expectedArtifact",value:"The artifact that is to be applied to the Cloud Run account for this stage. The artifact should represent a valid Cloud Run manifest."},{key:"cloudrun.manifest.skipExpressionEvaluation",value:'<p>Skip SpEL expression evaluation of the manifest artifact in this stage. Can be paired with the "Evaluate SpEL expressions in overrides at bake time" option in the Bake Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.</p>'},{key:"cloudrun.manifest.requiredArtifactsToBind",value:'These artifacts must be present in the context for this stage to successfully complete. Artifacts specified will be <a href="https://www.spinnaker.io/reference/artifacts/in-cloudrun-v2/#binding-artifacts-in-manifests" target="_blank">bound to the deployed manifest.</a>'},{key:"cloudrun.manifest.account",value:"\n <p>A Spinnaker account corresponds to a physical Cloud Run cluster. If you are unsure which account to use, talk to your Spinnaker admin.</p>\n "}].forEach(e=>t.register(e.key,e.value));class ve{constructor(e,t,n){this.$q=e,this.app=t,this.state={loading:!0},this.upToolTip="A Cloud Run instance is 'Up' if a load balancer is directing traffic to its server group.",this.outOfServiceToolTip="\n A Cloud Run instance is 'Out Of Service' if no load balancers are directing traffic to its server group.",this.app.ready().then(()=>this.retrieveInstance(n)).then(e=>{this.instance=e,this.state.loading=!1}).catch(()=>{this.instanceIdNotFound=n.instanceId,this.state.loading=!1})}retrieveInstance(e){const t=q([this.app.getDataSource("serverGroups").data,this.app.getDataSource("loadBalancers").data,this.app.getDataSource("loadBalancers").data.map(e=>e.serverGroups)]).find(t=>t.instances.some(t=>t.id===e.instanceId));if(t){const i={region:t.region,account:t.account};return"serverGroup"===t.category&&(i.serverGroup=t.name),n.addExtraDataToLatest("instances",i),a.getInstanceDetails(t.account,t.region,e.instanceId).then(e=>(e.account=t.account,e.region=t.region,e))}return this.$q.reject()}}ve.$inject=["$q","app","instance"];const be="spinnaker.cloudrun.instanceDetails.controller";e(be,[]).controller("cloudrunInstanceDetailsCtrl",ve);const Be={bindings:{allocationDescription:"<",removeAllocation:"&",serverGroupOptions:"<",onAllocationChange:"&"},template:'\n <div class="form-group">\n <div class="row">\n <div class="col-md-7">\n <ui-select ng-model="$ctrl.allocationDescription.revisionName"\n on-select="$ctrl.onAllocationChange()"\n class="form-control input-sm">\n <ui-select-match placeholder="Select...">\n {{$select.selected}}\n </ui-select-match>\n <ui-select-choices repeat="serverGroup as serverGroup in $ctrl.getServerGroupOptions() | filter: $select.search">\n <div ng-bind-html="serverGroup | highlight: $select.search"></div>\n </ui-select-choices>\n </ui-select>\n </div>\n <div class="col-md-3">\n <div class="input-group input-group-sm">\n <input type="number"\n ng-model="$ctrl.allocationDescription.percent"\n required\n class="form-control input-sm"\n min="0"\n ng-change="$ctrl.onAllocationChange()"\n max="100"/>\n <span class="input-group-addon">%</span>\n </div>\n </div>\n <div class="col-md-2">\n <a class="btn btn-link sm-label" ng-click="$ctrl.removeAllocation()">\n <span class="glyphicon glyphicon-trash"></span>\n </a>\n </div>\n </div>\n </div>\n ',controller:class{getServerGroupOptions(){return this.allocationDescription.revisionName?W(this.serverGroupOptions.concat(this.allocationDescription.revisionName)):this.serverGroupOptions}}},ke="spinnaker.cloudrun.allocationConfigurationRow.component";e(ke,[]).component("cloudrunAllocationConfigurationRow",Be);const Ce={bindings:{loadBalancer:"=",forPipelineConfig:"<",application:"<"},controller:class{$onInit(){this.updateServerGroupOptions()}addAllocation(){const e=this.serverGroupsWithoutAllocation();e.length?(this.loadBalancer.splitDescription.allocationDescriptions.push({revisionName:e[0],percent:0}),this.updateServerGroupOptions()):this.forPipelineConfig&&this.loadBalancer.splitDescription.allocationDescriptions.push({percent:0,revisionName:""})}removeAllocation(e){this.loadBalancer.splitDescription.allocationDescriptions.splice(e,1),this.updateServerGroupOptions()}allocationIsInvalid(){return 100!==this.loadBalancer.splitDescription.allocationDescriptions.reduce((e,t)=>e+t.percent,0)}updateServerGroupOptions(){this.serverGroupOptions=this.serverGroupsWithoutAllocation()}showAddButton(){return!!this.forPipelineConfig||this.serverGroupsWithoutAllocation().length>0}initializeAsTextInput(e){return!!this.forPipelineConfig&&!this.loadBalancer.serverGroups.map(e=>e.name).includes(e)}serverGroupsWithoutAllocation(){const e=this.loadBalancer.splitDescription.allocationDescriptions.map(e=>e.revisionName),t=this.loadBalancer.serverGroups.map(e=>e.name);return H(t,e)}},templateUrl:"cloudrun/src/loadBalancer/configure/wizard/basicSettings.component.html"},we="spinnaker.cloudrun.loadBalancerSettings.component";e(we,[]).component("cloudrunLoadBalancerBasicSettings",Ce),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/loadBalancer/configure/wizard/basicSettings.component.html",'<ng-form name="basicSettingsForm">\n <div class="row">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n Allocations\n <help-field key="cloudrun.loadBalancer.allocations"></help-field>\n </div>\n <div class="col-md-9">\n <div ng-if="!$ctrl.forPipelineConfig">\n <cloudrun-allocation-configuration-row\n ng-repeat="description in $ctrl.loadBalancer.splitDescription.allocationDescriptions"\n allocation-description="description"\n server-group-options="$ctrl.serverGroupOptions"\n on-allocation-change="$ctrl.updateServerGroupOptions()"\n remove-allocation="$ctrl.removeAllocation($index)"\n >\n </cloudrun-allocation-configuration-row>\n </div>\n <div ng-if="$ctrl.forPipelineConfig">\n <cloudrun-stage-allocation-configuration-row\n ng-repeat="description in $ctrl.loadBalancer.splitDescription.allocationDescriptions"\n allocation-description="description"\n application="$ctrl.application"\n region="{{ $ctrl.loadBalancer.region }}"\n account="{{ $ctrl.loadBalancer.account || $ctrl.loadBalancer.credentials }}"\n name="{{ $ctrl.loadBalancer.name }}"\n server-group-options="$ctrl.serverGroupOptions"\n on-allocation-change="$ctrl.updateServerGroupOptions()"\n remove-allocation="$ctrl.removeAllocation($index)"\n >\n </cloudrun-stage-allocation-configuration-row>\n </div>\n <button class="add-new col-md-11" ng-if="$ctrl.showAddButton()" ng-click="$ctrl.addAllocation()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add allocation\n </button>\n </div>\n </div>\n <div class="form-group" ng-if="$ctrl.allocationIsInvalid()">\n <div class="col-md-12 text-center">\n <p class="alert alert-warning">Allocations must sum to 100%.</p>\n </div>\n </div>\n </div>\n</ng-form>\n')}]);class ye{static mapTargetCoordinateToLabel(e){const t=i.TARGET_LIST.find(t=>t.val===e);return t?t.label:null}$doCheck(){this.setInputViewValue()}setInputViewValue(){if(this.allocationDescription.cluster&&this.allocationDescription.target){const e=ye.mapTargetCoordinateToLabel(this.allocationDescription.target);this.inputViewValue=`${e} (${this.allocationDescription.cluster})`}else this.inputViewValue=null}}const Se={bindings:{allocationDescription:"<"},controller:ye,template:'<input ng-model="$ctrl.inputViewValue" type="text" class="form-control input-sm" readonly/>'};const Ee={bindings:{application:"<",region:"@",account:"@",name:"@",allocationDescription:"<",removeAllocation:"&",serverGroupOptions:"<",onAllocationChange:"&"},controller:class{constructor(){this.targets=i.TARGET_LIST}$onInit(){this.allocationDescription.cluster=this.name}getServerGroupOptions(){return this.allocationDescription.revisionName?W(this.serverGroupOptions.concat(this.allocationDescription.revisionName)):this.serverGroupOptions}},templateUrl:"cloudrun/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html"},Ae="spinnaker.cloudrun.stageAllocationConfigurationRow.component";e(Ae,[]).component("cloudrunStageAllocationConfigurationRow",Ee).component("cloudrunStageAllocationLabel",Se),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/loadBalancer/configure/wizard/stageAllocationConfigurationRow.component.html",'<div class="form-group">\n <div class="row">\n <div class="col-md-7">\n <cloudrun-stage-allocation-label allocation-description="$ctrl.allocationDescription">\n </cloudrun-stage-allocation-label>\n </div>\n <div class="col-md-3">\n <div class="input-group input-group-sm">\n <input\n type="number"\n ng-model="$ctrl.allocationDescription.percent"\n required\n class="form-control input-sm"\n min="0"\n ng-change="$ctrl.onAllocationChange()"\n max="100"\n />\n <span class="input-group-addon">%</span>\n </div>\n </div>\n <div class="col-md-2">\n <a class="btn btn-link sm-label" ng-click="$ctrl.removeAllocation()">\n <span class="glyphicon glyphicon-trash"></span>\n </a>\n </div>\n </div>\n</div>\n<div class="form-group">\n <div class="well col-md-11" style="padding-top: 5px; padding-bottom: 10px">\n <div class="row">\n <div class="form-group">\n <div>\n <div class="col-md-3 sm-label-right">Cluster</div>\n <div class="col-md-7" style="margin-bottom: 10px">\n <input ng-model="$ctrl.allocationDescription.cluster" type="text" class="form-control input-sm" readonly />\n </div>\n <div class="col-md-3 sm-label-right">Target</div>\n <div class="col-md-7">\n <target-select model="$ctrl.allocationDescription" options="$ctrl.targets"></target-select>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n')}]);class Ge{static convertTrafficSplitToTrafficSplitDescription(e){return{allocationDescriptions:te(e.trafficTargets,(e,t)=>{const{revisionName:n,percent:a}=t;return e.concat({percent:a,revisionName:n})},[])}}constructor(e){this.credentials=e.account||e.credentials,this.account=this.credentials,this.cloudProvider=e.cloudProvider,this.loadBalancerName=e.name,this.name=e.name,this.region=e.region,this.migrateTraffic=e.migrateTraffic||!1,this.serverGroups=e.serverGroups}mapAllocationsToDecimals(){this.splitDescription.allocationDescriptions.forEach(e=>{e.percent=e.percent/100})}mapAllocationsToPercentages(){this.splitDescription.allocationDescriptions.forEach(e=>{e.percent=Math.round(e.percent)})}}class xe{constructor(e){this.$q=e}normalizeLoadBalancer(e){e.provider=e.type,e.instanceCounts=this.buildInstanceCounts(e.serverGroups),e.instances=[],e.serverGroups.forEach(t=>{t.account=e.account,t.region=e.region,t.detachedInstances&&(t.detachedInstances=t.detachedInstances.map(e=>({id:e}))),t.instances=t.instances.concat(t.detachedInstances||[]).map(t=>this.transformInstance(t,e))});const t=X(e.serverGroups,{isDisabled:!1});return e.instances=Q(t).map("instances").flatten().value(),this.$q.resolve(e)}convertLoadBalancerForEditing(e,t){return t.getDataSource("loadBalancers").ready().then(()=>{const n=t.getDataSource("loadBalancers").data.find(t=>t.name===e.name&&(t.account===e.account||t.account===e.credentials));return n&&(e.serverGroups=_(n.serverGroups)),e})}convertLoadBalancerToUpsertDescription(e){return new Ge(e)}buildInstanceCounts(e){const t=Q(e).map("instances").flatten().reduce((e,t)=>(Z(t,"health.state")&&e[J(t.health.state)]++,e),{up:0,down:0,outOfService:0,succeeded:0,failed:0,starting:0,unknown:0}).value();return t.outOfService+=Q(e).map("detachedInstances").flatten().value().length,t}transformInstance(e,t){e.provider=t.type,e.account=t.account,e.region=t.region,e.loadBalancers=[t.name];const n=e.health||{};return e.healthState=ee(e,"health.state")||"OutOfService",e.health=[n],e}}xe.$inject=["$q"];const De="spinnaker.cloudrun.loadBalancer.transformer.service";function Te(e,t){void 0===t&&(t={});var n=t.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css","top"===n&&a.firstChild?a.insertBefore(i,a.firstChild):a.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}e(De,[]).service("cloudrunLoadBalancerTransformer",xe);Te("cloudrun-load-balancer-basic-settings a.btn.btn-link {\n padding: 0;\n}\ncloudrun-load-balancer-basic-settings .form-group {\n margin-top: 0.4rem;\n}\n");class $e{constructor(e,t,n,a,i,r,s,o,l){this.$scope=e,this.$state=t,this.$uibModalInstance=n,this.application=a,this.isNew=r,this.forPipelineConfig=s,this.cloudrunLoadBalancerTransformer=o,this.wizardSubFormValidation=l,this.state={loading:!0},this.submitButtonLabel=this.forPipelineConfig?"Done":"Update",this.isNew?this.heading="Create New Load Balancer":(this.heading=`Edit ${[i.name,i.region,i.account||i.credentials].join(":")}`,this.cloudrunLoadBalancerTransformer.convertLoadBalancerForEditing(i,a).then(e=>{this.loadBalancer=this.cloudrunLoadBalancerTransformer.convertLoadBalancerToUpsertDescription(e),i.split&&!this.loadBalancer.splitDescription?this.loadBalancer.splitDescription=Ge.convertTrafficSplitToTrafficSplitDescription(i.split):this.loadBalancer.splitDescription=i.splitDescription,this.loadBalancer.mapAllocationsToPercentages(),this.setTaskMonitor(),this.initializeFormValidation(),this.state.loading=!1}))}submit(){const e=_(this.loadBalancer);return e.mapAllocationsToPercentages(),delete e.serverGroups,this.forPipelineConfig?this.$uibModalInstance.close(e):this.taskMonitor.submit(()=>r.upsertLoadBalancer(e,this.application,"Update"))}cancel(){this.$uibModalInstance.dismiss()}showSubmitButton(){return this.wizardSubFormValidation.subFormsAreValid()}setTaskMonitor(){this.taskMonitor=new s({application:this.application,title:"Updating your load balancer",modalInstance:this.$uibModalInstance,onTaskComplete:()=>this.onTaskComplete()})}initializeFormValidation(){this.wizardSubFormValidation.config({form:"form",scope:this.$scope}).register({page:"basic-settings",subForm:"basicSettingsForm",validators:[{watchString:"ctrl.loadBalancer.splitDescription",validator:e=>100===e.allocationDescriptions.reduce((e,t)=>e+t.percent,0),watchDeep:!0}]})}onTaskComplete(){this.application.getDataSource("loadBalancers").refresh(),this.application.getDataSource("loadBalancers").onNextRefresh(this.$scope,()=>this.onApplicationRefresh())}onApplicationRefresh(){if(this.$scope.$$destroyed)return;this.$uibModalInstance.dismiss();const e={name:this.loadBalancer.name,accountId:this.loadBalancer.credentials,region:this.loadBalancer.region,provider:"cloudrun"};this.$state.includes("**.loadBalancerDetails")?this.$state.go("^.loadBalancerDetails",e):this.$state.go(".loadBalancerDetails",e)}}$e.$inject=["$scope","$state","$uibModalInstance","application","loadBalancer","isNew","forPipelineConfig","cloudrunLoadBalancerTransformer","wizardSubFormValidation"];const Ne="spinnaker.cloudrun.loadBalancer.wizard.controller";e(Ne,[]).controller("cloudrunLoadBalancerWizardCtrl",$e);class Le{constructor(e,t,n,a,i){this.$uibModal=e,this.$state=t,this.$scope=n,this.app=i,this.state={loading:!0},this.loadBalancerFromParams=a,this.app.getDataSource("loadBalancers").ready().then(()=>this.extractLoadBalancer())}editLoadBalancer(){this.$uibModal.open({templateUrl:"cloudrun/src/loadBalancer/configure/wizard/wizard.html",controller:"cloudrunLoadBalancerWizardCtrl as ctrl",size:"lg",resolve:{application:()=>this.app,loadBalancer:()=>_(this.loadBalancer),isNew:()=>!1,forPipelineConfig:()=>!1}})}extractLoadBalancer(){this.loadBalancer=this.app.getDataSource("loadBalancers").data.find(e=>e.name===this.loadBalancerFromParams.name&&e.account===this.loadBalancerFromParams.accountId),this.loadBalancer?(this.state.loading=!1,this.app.getDataSource("loadBalancers").onRefresh(this.$scope,()=>this.extractLoadBalancer())):this.autoClose()}deleteLoadBalancer(){const e={application:this.app,title:"Deleting "+this.loadBalancer.name};o.confirm({header:"Really delete "+this.loadBalancer.name+"?",buttonText:"Delete "+this.loadBalancer.name,body:this.getConfirmationModalBodyHtml(),account:this.loadBalancer.account,taskMonitorConfig:e,submitMethod:()=>{const e={cloudProvider:this.loadBalancer.cloudProvider,loadBalancerName:this.loadBalancer.name,credentials:this.loadBalancer.account};return r.deleteLoadBalancer(e,this.app)}})}canDeleteLoadBalancer(){return"default"!==this.loadBalancer.name}getConfirmationModalBodyHtml(){const e=this.loadBalancer.serverGroups.map(e=>e.name),t=!!e&&e.length>0,n=!!e&&e.length>1;if(t){if(n){const t=e.map(e=>`<li>${e}</li>`).join("");return`<div class="alert alert-warning">\n <p>\n Deleting <b>${this.loadBalancer.name}</b> will destroy the following server groups:\n <ul>\n ${t}\n </ul>\n </p>\n </div>\n `}return`<div class="alert alert-warning">\n <p>\n Deleting <b>${this.loadBalancer.name}</b> will destroy <b>${e[0]}</b>.\n </p>\n </div>\n `}return null}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}}Le.$inject=["$uibModal","$state","$scope","loadBalancer","app"];const Me="spinnaker.cloudrun.loadBalancerDetails.controller";e(Me,[]).controller("cloudrunLoadBalancerDetailsCtrl",Le),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/loadBalancer/configure/wizard/wizard.html",'<form name="form">\n <div ng-if="ctrl.state.loading && !ctrl.isNew" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <v2-modal-wizard\n heading="{{::ctrl.heading}}"\n task-monitor="ctrl.taskMonitor"\n dismiss="$dismiss()"\n ng-if="!ctrl.state.loading || ctrl.isNew"\n >\n <div ng-if="!ctrl.isNew">\n <v2-wizard-page key="basic-settings" label="Basic Settings" mark-complete-on-view="false">\n <cloudrun-load-balancer-basic-settings\n load-balancer="ctrl.loadBalancer"\n application="ctrl.application"\n for-pipeline-config="ctrl.forPipelineConfig"\n ></cloudrun-load-balancer-basic-settings>\n </v2-wizard-page>\n </div>\n </v2-modal-wizard>\n <cloudrun-load-balancer-message\n ng-if="ctrl.isNew"\n column-offset="1"\n columns="10"\n show-create-message="true"\n ></cloudrun-load-balancer-message>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n ng-if="!ctrl.isNew && ctrl.showSubmitButton()"\n label="ctrl.submitButtonLabel"\n is-disabled="cloudrunLoadBalancerForm.$invalid || ctrl.taskMonitor.submitting || ctrl.state.loading"\n submitting="ctrl.taskMonitor.submitting"\n on-click="ctrl.submit()"\n is-new="ctrl.isNew"\n >\n </submit-button>\n </div>\n</form>\n')}]);class Ie{constructor(e,t,n){this.$uibModal=e,this.$uibModalInstance=t,this.application=n,this.state={loading:!0},this.initialize()}submit(){const e=l.getValue("cloudrun","loadBalancer"),t=this.$uibModal.open({templateUrl:e.createLoadBalancerTemplateUrl,controller:`${e.createLoadBalancerController} as ctrl`,size:"lg",resolve:{application:()=>this.application,loadBalancer:()=>_(this.selectedLoadBalancer),isNew:()=>!1,forPipelineConfig:()=>!0}}).result;this.$uibModalInstance.close(t)}cancel(){this.$uibModalInstance.dismiss()}initialize(){this.application.getDataSource("loadBalancers").ready().then(()=>{this.loadBalancers=this.application.loadBalancers.data.filter(e=>"cloudrun"===e.cloudProvider),this.loadBalancers.length&&(this.selectedLoadBalancer=this.loadBalancers[0]),this.state.loading=!1})}}Ie.$inject=["$uibModal","$uibModalInstance","application"];const Fe="spinnaker.Cloudrun.loadBalancerChoiceModal.controller";e(Fe,[]).controller("cloudrunLoadBalancerChoiceModelCtrl",Ie);class Re{constructor(e,t){this.$scope=e,this.$uibModal=t,e.stage.loadBalancers=e.stage.loadBalancers||[],e.stage.cloudProvider="cloudrun"}addLoadBalancer(){this.$uibModal.open({templateUrl:"cloudrun/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html",controller:"cloudrunLoadBalancerChoiceModelCtrl as ctrl",resolve:{application:()=>this.$scope.application}}).result.then(e=>{this.$scope.stage.loadBalancers.push(e)}).catch(()=>{})}editLoadBalancer(e){const t=l.getValue("cloudrun","loadBalancer");this.$uibModal.open({templateUrl:t.createLoadBalancerTemplateUrl,controller:`${t.createLoadBalancerController} as ctrl`,size:"lg",resolve:{application:()=>this.$scope.application,loadBalancer:()=>_(this.$scope.stage.loadBalancers[e]),isNew:()=>!1,forPipelineConfig:()=>!0}}).result.then(t=>{this.$scope.stage.loadBalancers[e]=t}).catch(()=>{})}removeLoadBalancer(e){this.$scope.stage.loadBalancers.splice(e,1)}}Re.$inject=["$scope","$uibModal"];const Pe="spinnaker.cloudrun.pipeline.stage.editLoadBalancerStage";e(Pe,[Fe]).config(()=>{c.pipeline.registerStage({label:"Edit Load Balancer (Cloud Run)",description:"Edits a load balancer",key:"upsertCloudrunLoadBalancers",cloudProvider:"cloudrun",templateUrl:"cloudrun/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html",executionDetailsUrl:"cloudrun/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html",executionConfigSections:["editLoadBalancerConfig","taskStatus"],controller:"cloudrunEditLoadBalancerStageCtrl",controllerAs:"editLoadBalancerStageCtrl",validators:[]})}).controller("cloudrunEditLoadBalancerStageCtrl",Re),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/pipeline/stages/editLoadBalancer/loadBalancerChoice.modal.html",'<div modal-page>\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Select Load Balancer</h4>\n </div>\n <div class="modal-body" ng-if="ctrl.state.loading" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div class="modal-body" ng-if="!ctrl.state.loading">\n <div class="alert alert-warning" ng-if="ctrl.loadBalancers.length === 0">\n <p>\n Spinnaker cannot create a load balancer for Cloud Run. A Spinnaker load balancer maps to a Cloud Run service\n which along with a Revision are created from Create Server Group page using a\n </p>\n <p><code>yaml file</code> <help-field key="cloudrun.serverGroup.file"></help-field></p>\n <p>\n If a service does not exist when a Revision is deployed, it will be created. It will then be editable as a load\n balancer within Spinnaker.\n </p>\n </div>\n <form\n role="form"\n name="form"\n class="form-horizontal"\n ng-submit="ctrl.submit()"\n ng-if="ctrl.loadBalancers.length > 0"\n >\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n <b>Load Balancer</b>\n </div>\n <div class="col-md-7">\n <ui-select class="form-control input-sm" ng-model="ctrl.selectedLoadBalancer">\n <ui-select-match>\n <account-tag account="$select.selected.account"></account-tag>\n <span style="margin-left: 5px">{{$select.selected.name}}</span>\n </ui-select-match>\n <ui-select-choices repeat="loadBalancer in ctrl.loadBalancers | filter: $select.search">\n <account-tag account="loadBalancer.account"></account-tag>\n <span style="margin-left: 5px" ng-bind-html="loadBalancer.name"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n </form>\n </div>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <button class="btn btn-primary" ng-if="ctrl.loadBalancers.length > 0" ng-click="ctrl.submit()">\n <span class="far fa-check-circle"></span> Edit\n </button>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/pipeline/stages/editLoadBalancer/editLoadBalancerStage.html",'<div class="well well-sm clearfix" ng-if="!pipeline.strategy">\n <div class="row">\n <div class="col-md-12">\n <h4 class="text-left">Load Balancers</h4>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <table class="table table-condensed">\n <thead>\n <tr>\n <th>Account</th>\n <th>Name</th>\n <th>Region</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="loadBalancer in stage.loadBalancers">\n <td>\n <account-tag account="loadBalancer.credentials"></account-tag>\n </td>\n <td>{{ loadBalancer.name }}</td>\n <td>{{ loadBalancer.region }}</td>\n <td class="condensed-actions">\n <a class="btn btn-sm btn-link" href ng-click="editLoadBalancerStageCtrl.editLoadBalancer($index)">\n <span class="glyphicon glyphicon-edit" uib-tooltip="Edit"></span\n ></a>\n <a\n class="btn btn-sm btn-link pad-left"\n href\n ng-click="editLoadBalancerStageCtrl.removeLoadBalancer($index)"\n >\n <span class="glyphicon glyphicon-trash" uib-tooltip="Remove"></span>\n </a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="8">\n <button class="btn btn-block btn-sm add-new" ng-click="editLoadBalancerStageCtrl.addLoadBalancer()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add load balancer\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/pipeline/stages/editLoadBalancer/editLoadBalancerExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'editLoadBalancerConfig\'">\n <div class="row">\n <div class="col-md-12">\n <table class="table table-condensed">\n <thead>\n <tr>\n <th>Account</th>\n <th>Name</th>\n <th>Region</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="loadBalancer in stage.context.loadBalancers">\n <td>\n <account-tag account="loadBalancer.credentials"></account-tag>\n </td>\n <td>{{ loadBalancer.name }}</td>\n <td>{{ loadBalancer.region }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n </div>\n <div class="step-section-details" ng-if="detailsSection === \'taskStatus\'">\n <div class="row">\n <execution-step-details item="stage"></execution-step-details>\n </div>\n </div>\n</div>\n')}]);const ze="spinnaker.cloudrun.pipeline.module";e(ze,[Pe]);class Oe extends se.Component{constructor(){super(...arguments),this.onChangeBinding=(e,t)=>{const n=(this.props.bindings||[]).slice(0);n[e]=t,this.props.onChangeBindings(n)},this.onRemoveBinding=e=>{const t=(this.props.bindings||[]).slice(0);t.splice(e,1),this.props.onChangeBindings(t)}}render(){const{stage:e,pipeline:t,bindings:n}=this.props,a=(a,i)=>{const r=(i?i.expectedArtifactId:"new")||i.artifact&&i.artifact.id;return se.createElement("div",{className:"row",key:r},se.createElement("div",{className:"col-md-10"},se.createElement(d,{pipeline:t,stage:e,expectedArtifactId:i&&i.expectedArtifactId,artifact:!!i&&i.artifact,onArtifactEdited:e=>this.onChangeBinding(a,{artifact:e}),onExpectedArtifactSelected:e=>this.onChangeBinding(a,{expectedArtifactId:e.id}),excludedArtifactIds:n.map(e=>e.expectedArtifactId),excludedArtifactTypePatterns:[u.FRONT50_PIPELINE_TEMPLATE]})),i&&se.createElement("div",{className:"col-md-2"},se.createElement("a",{className:"glyphicon glyphicon-trash",onClick:()=>this.onRemoveBinding(a)})))};return se.createElement(se.Fragment,null,n.map((e,t)=>a(t,e)),a(n.length))}}var Ue=(e=>(e.TEXT="text",e.ARTIFACT="artifact",e))(Ue||{});function Ve({accounts:e,onAccountSelect:t,selectedAccount:n}){return se.createElement("div",{className:"form-horizontal"},se.createElement("div",{className:"form-group"},se.createElement("div",{className:"col-md-3 sm-label-right"},"Account ",se.createElement(p,{id:"cloudrun.manifest.account"})),se.createElement("div",{className:"col-md-8"},se.createElement(m,{value:n,onChange:e=>t(e.target.value),readOnly:!1,accounts:e,provider:"cloudrun"}))))}se.Component;class Ye extends se.Component{render(){const e=this.props.application?this.props.application:"",t=this.props.stack?`-${this.props.stack}`:"",n=this.props.details?`-${this.props.details}`:"";return se.createElement("pre",{style:{textAlign:"center"}},se.createElement("p",null," Your server group will be in the cluster:"),se.createElement("p",null,se.createElement("b",null,e,t,n)))}}class je extends se.Component{constructor(e){super(e),this.excludedManifestArtifactTypes=[u.FRONT50_PIPELINE_TEMPLATE,u.MAVEN_FILE],this.getSourceOptions=()=>ne([Ue.TEXT,Ue.ARTIFACT],e=>({label:ae(e),value:e})),this.handleRawManifestChange=(e,t)=>{this.setState({rawManifest:e}),this.props.formik.setFieldValue("manifests",t)},this.onManifestArtifactSelected=e=>{this.props.formik.setFieldValue("manifestArtifactId",e),this.props.formik.setFieldValue("manifestArtifact",null)},this.onManifestArtifactEdited=e=>{this.props.formik.setFieldValue("manifestArtifactId",null),this.props.formik.setFieldValue("manifestArtifact",e)},this.getRequiredArtifacts=()=>{const{requiredArtifactIds:e,requiredArtifacts:t}=this.props.formik.values;return(e||[]).map(e=>({expectedArtifactId:e})).concat(t||[])},this.onRequiredArtifactsChanged=e=>{this.props.formik.setFieldValue("requiredArtifactIds",e.filter(e=>e.expectedArtifactId).map(e=>e.expectedArtifactId)),this.props.formik.setFieldValue("requiredArtifacts",e.filter(e=>e.artifact))};const t=this.props.formik.values,n=ee(e.formik.values,"manifests"),a=ee(e.formik.values,"source")===Ue.TEXT;this.state={rawManifest:!ie(n)&&a?h(n):"",application:this.props.application.name,stack:ee(t,"stack"),details:ee(t,"details")}}render(){const e=this.props.formik.values;return se.createElement("div",{className:"form-horizontal"},se.createElement("h4",null,"Basic Settings"),se.createElement(Ve,{accounts:this.props.accounts,onAccountSelect:e=>this.props.formik.setFieldValue("account",e),selectedAccount:e.account}),se.createElement(g,{label:"Application"},se.createElement("input",{className:"form-control input-sm",type:"text",value:this.props.application.name,onChange:e=>this.props.formik.setFieldValue("application",e.target.value),disabled:!0})),se.createElement(g,{label:"Stack"},se.createElement("input",{className:"form-control input-sm",type:"text",value:e.stack,onChange:e=>this.props.formik.setFieldValue("stack",e.target.value)})),se.createElement(g,{label:"Details"},se.createElement("input",{className:"form-control input-sm",type:"text",value:e.details,onChange:e=>this.props.formik.setFieldValue("details",e.target.value)})),se.createElement(Ye,{application:this.props.application.name,stack:e.stack,details:e.details}),se.createElement("hr",null),se.createElement("h4",null,"Manifest Configuration"),se.createElement(g,{label:"Manifest Source",helpKey:"cloudrun.manifest.source"},se.createElement(f,{options:this.getSourceOptions(),onChange:e=>this.props.formik.setFieldValue("source",e.target.value),value:e.source})),e.source===Ue.TEXT&&se.createElement(g,{label:"Manifest"},se.createElement(v,{onChange:this.handleRawManifestChange,value:this.state.rawManifest})),e.source===Ue.ARTIFACT&&se.createElement(se.Fragment,null,se.createElement(b,{artifact:e.manifestArtifact,excludedArtifactTypePatterns:this.excludedManifestArtifactTypes,expectedArtifactId:e.manifestArtifactId,helpKey:"cloudrun.manifest.expectedArtifact",label:"Manifest Artifact",onArtifactEdited:this.onManifestArtifactEdited,onExpectedArtifactSelected:e=>this.onManifestArtifactSelected(e.id),pipeline:this.props.pipeline,stage:e}),se.createElement(g,{label:"Expression Evaluation",helpKey:"cloudrun.manifest.skipExpressionEvaluation"},se.createElement(B,{checked:!0===e.skipExpressionEvaluation,onChange:e=>this.props.formik.setFieldValue("skipExpressionEvaluation",e.target.checked),text:"Skip SpEL expression evaluation"}))),se.createElement(g,{label:"Required Artifacts to Bind",helpKey:"cloudrun.manifest.requiredArtifactsToBind"},se.createElement(Oe,{bindings:this.getRequiredArtifacts(),onChangeBindings:this.onRequiredArtifactsChanged,pipeline:this.props.pipeline,stage:e})))}}class Ke extends se.Component{constructor(e){super(e),this.destroy$=new le,this.fetchAccounts=()=>{ce(k.getAllAccountDetailsForProvider("cloudrun")).pipe(de(this.destroy$)).subscribe(e=>{this.setState({accounts:e})})},this.state={accounts:[]};const{stage:t}=e,n=_(t);n.source||(n.source=Ue.TEXT),n.skipExpressionEvaluation||(n.skipExpressionEvaluation=!1),n.cloudProvider||(n.cloudProvider="cloudrun"),n.moniker||(n.moniker={}),n.moniker.app||(n.moniker.app=e.application.name),this.stage=n}componentDidMount(){this.fetchAccounts()}componentWillUnmount(){this.destroy$.next()}render(){return se.createElement(C,{...this.props,stage:this.stage,onChange:this.props.updateStage,render:e=>se.createElement(je,{...e,accounts:this.state.accounts})})}}const qe="redblack",We="strategy.spinnaker.io/max-version-history",He={available:"success",stable:"success",paused:"warn",failed:"danger"};class Xe extends se.Component{render(){const{manifest:e}=this.props;return null==e||null==e.status?null:Object.keys(e.status).map((t,n)=>{const a=e.status[t],i=He[t]||"",r=a.state,s=!r&&a.message;return se.createElement("span",{key:n},r&&se.createElement("span",{title:a.message,className:`pill ${i}`},t),s&&se.createElement("span",{title:a.message,className:"pill warn"},t),se.createElement("span",null," "))})}}const Qe="cloudrunResource";class _e extends se.Component{constructor(e){super(e),this.spinnakerKindStateMap={serverGroupManagers:"serverGroupManager",serverGroups:"serverGroup"},this.state={url:""},this.loadUrl()}canOpen(){return!!this.props.manifest.manifest&&!!this.state.url}spinnakerKindFromCloudrunKind(e,t){return t[Object.keys(t).find(t=>t.toLowerCase()===e.toLowerCase())]}resourceRegion(){return re(ee(this.props,["manifest","manifest","metadata","annotations","artifact.spinnaker.io/location"],""))}getStateParams(e){const t=this.props.manifest.manifest.kind.toLowerCase(),n=this.props.manifest.manifest.metadata.name,a=this.resourceRegion(),i={accountId:this.props.accountId,provider:"cloudrun",region:a,reg:a,[e]:`${t} ${n}`};return i.region||"namespace"!==t||e!==Qe||(i.region=n),i.region&&""!==i.region||(i.region="_"),i}loadUrl(){const e=ee(this.props,["manifest","manifest","kind"],""),{accountId:t}=this.props;k.getAccountDetails(t).then(t=>{const n=this.spinnakerKindFromCloudrunKind(e,t.spinnakerKindMap),a=this.spinnakerKindStateMap[n]||Qe,i=this.getStateParams(a),r=w.$state.href(`home.applications.application.insight.clusters.${a}`,i);this.setState({url:r})})}render(){return this.canOpen()?se.createElement("a",{href:this.state.url,className:"clickable"},this.props.linkName):null}}class Ze extends se.Component{pillStyle(e){return"Warning"===e.type?"alert":"Normal"===e.type?"success":""}render(){if(!this.props.manifest)return null;if(this.props.manifest&&(!this.props.manifest.events||0===this.props.manifest.events.length))return se.createElement("div",null,"No recent events found - Cloud Run does not store events for long.");const{events:e}=this.props.manifest,t=re(ee(this.props.manifest,["manifest","metadata","annotations","artifact.spinnaker.io/location"],""));return e.map((n,a)=>{const i=ee(n,"firstTimestamp",""),r=ee(n,"lastTimestamp","");let s=0,o=0;return i&&(s=pe.fromISO(i).toMillis()),r&&(o=pe.fromISO(r).toMillis()),se.createElement("div",{key:ee(n,["metadata","uid"],String(a)),className:"info"},se.createElement("div",{className:"horizontal"},n.count&&se.createElement("div",{className:`pill ${this.pillStyle(n)}`},n.count," × ",se.createElement("b",null,n.reason))),(n.firstTimestamp||n.lastTimestamp)&&se.createElement("div",null,n.firstTimestamp===n.lastTimestamp&&se.createElement("div",null,se.createElement("i",null,y(s))),n.firstTimestamp!==n.lastTimestamp&&se.createElement("div",null,se.createElement("div",null,"First Occurrence: ",se.createElement("i",null,y(s))),se.createElement("div",null,"Last Occurrence: ",se.createElement("i",null,y(o))))),se.createElement("div",null,n.message),se.createElement("div",null,se.createElement(S,{account:this.props.manifest.account,location:t,podNamesProviders:[new E(this.props.manifest,n)],linkName:"Console Output (Raw)"})),a!==e.length-1&&se.createElement("br",null))})}}function Je({account:e,manifest:t}){return se.createElement(se.Fragment,null,se.createElement("dl",{className:"manifest-status",key:"manifest-status"},se.createElement("dt",null,t.manifest.kind),se.createElement("dd",null,se.createElement(A,{displayText:!0,text:t.manifest.metadata.name,toolTip:`Copy ${t.manifest.metadata.name}`})," ",se.createElement(Xe,{manifest:t}))),se.createElement("div",{className:"manifest-support-links",key:"manifest-support-links"},se.createElement(G,{linkName:"YAML",manifestText:ue(t.manifest),modalTitle:t.manifest.metadata.name}),se.createElement(_e,{linkName:"Details",manifest:t,accountId:e})),se.createElement("div",{className:"manifest-events pad-left",key:"manifest-events"},se.createElement(Ze,{manifest:t})))}Te("dl.manifest-status {\n display: block;\n margin: 0;\n}\ndl.manifest-status dt,\ndl.manifest-status dd {\n display: inline-block;\n}\ndl.manifest-status dt {\n margin-right: 4px;\n}\n.manifest-support-links {\n margin: 0 0 1em;\n}\n.manifest-support-links a {\n margin-right: 2em;\n}\n.manifest-events {\n margin: 0 0 2em;\n}\n");const et=class e{static subscribe(t,n,a){return e.updateManifest(n,a),t.onRefresh(null,()=>e.updateManifest(n,a))}static updateManifest(e,t){x.getManifest(e.account,e.location,e.name).then(e=>t(e))}static manifestIdentifier(e){const t=e.kind.toLowerCase(),n=(e.metadata.namespace||"_").toLowerCase(),a=e.metadata.name.toLowerCase();return`${n} ${t} ${(e.apiVersion||"_").toLowerCase()} ${a}`}static stageManifestToManifestParams(t,n){return{account:n,name:e.scopedKind(t)+" "+t.metadata.name,location:null==t.metadata.namespace?"_":t.metadata.namespace}}static apiGroup(e){const t=(e.apiVersion||"_").split("/");return t.length<2?"":t[0]}static isCRDGroup(t){return!e.BUILT_IN_GROUPS.includes(e.apiGroup(t))}static scopedKind(t){return e.isCRDGroup(t)?t.kind+"."+e.apiGroup(t):t.kind}};et.BUILT_IN_GROUPS=["","core","batch","apps","extensions","storage.k8s.io","apiextensions.k8s.io","apiregistration.k8s.io","policy","scheduling.k8s.io","settings.k8s.io","authorization.k8s.io","authentication.k8s.io","rbac.authorization.k8s.io","certifcates.k8s.io","networking.k8s.io"];let tt=et;class nt extends se.Component{constructor(e){super(e),this.state={subscriptions:[],manifestIds:[]}}componentDidMount(){this.componentDidUpdate(this.props,this.state)}componentWillUnmount(){this.unsubscribeAll()}componentDidUpdate(e,t){const n=ee(this.props.stage,["context","outputs.manifests"],[]).filter(e=>!!e),a=n.map(e=>tt.manifestIdentifier(e)).sort();if(t.manifestIds.join("")!==a.join("")){this.unsubscribeAll();const e=n.map(e=>{const t=tt.manifestIdentifier(e);return{id:t,unsubscribe:this.subscribeToManifestUpdates(t,e),manifest:this.stageManifestToIManifest(e,this.props.stage.context.account)}});this.setState({subscriptions:e,manifestIds:a})}}subscribeToManifestUpdates(e,t){const n=tt.stageManifestToManifestParams(t,this.props.stage.context.account);return tt.subscribe(this.props.application,n,t=>{const n=this.state.subscriptions.findIndex(t=>t.id===e);if(-1!==n){const e={...this.state.subscriptions[n],manifest:t},a=[...this.state.subscriptions];a[n]=e,this.setState({subscriptions:a})}})}unsubscribeAll(){this.state.subscriptions.forEach(({unsubscribe:e})=>e())}stageManifestToIManifest(e,t){return{name:ee(e,"metadata.name",""),moniker:null,account:t,cloudProvider:"cloudrun",location:ee(e,"metadata.namespace",""),manifest:e,status:{},artifacts:[],events:[]}}render(){const{name:e,current:t,stage:n}=this.props,a=this.state.subscriptions.filter(e=>!!e.manifest).map(e=>e.manifest);return se.createElement(D,{name:e,current:t},se.createElement(T,{stage:n,message:n.failureMessage}),a&&se.createElement("div",{className:"row"},se.createElement("div",{className:"col-md-12"},se.createElement("div",{className:"well alert alert-info"},a.map(e=>{const t=e.manifest.metadata.uid||tt.manifestIdentifier(e.manifest);return se.createElement(Je,{key:t,manifest:e,account:n.context.account})})))))}}nt.title="deployStatus",c.pipeline.registerStage({label:"Deploy (Cloud Run)",description:"Deploy a Cloud Run manifest yaml/json file.",key:"deployCloudrunManifest",cloudProvider:"cloudrun",component:Ke,executionDetailsSections:[nt,$,N],producesArtifacts:!0,supportsCustomTimeout:!0,validators:[{type:"requiredField",fieldName:"account",fieldLabel:"Account"},{type:"requiredField",fieldName:"source",fieldLabel:"Source"},{type:"custom",validate:(e,t)=>{const n=ee(t,"trafficManagement.enabled",!1),a=ee(t,"trafficManagement.options.services",[]);if(n&&ie(a))return"Select at least one <strong>Service</strong> to enable Spinnaker-managed rollout strategy options.";if(n&&t.source===Ue.TEXT){const e=ee(t,"manifests",[]).filter(e=>"ReplicaSet"===e.kind),n=ee(t,"trafficManagement.options.strategy"),a=parseInt(ee(e,[0,"metadata","annotations",We]),10);if(n===qe&&a<2)return`The max version history specified in your manifest conflicts with the behavior of the Red/Black rollout strategy. Please update your <strong>${We}</strong> annotation to a value greater than or equal to 2.`}return null}}],accountExtractor:e=>e.account?[e.account]:[],configAccountExtractor:e=>e.account?[e.account]:[],artifactExtractor:M.accumulateArtifacts(["manifestArtifactId","requiredArtifactIds"]),artifactRemover:L.removeArtifactFromFields(["manifestArtifactId","requiredArtifactIds"])});const at=I.providers.cloudrun||{defaults:{}};at&&(at.resetToOriginal=I.resetProvider("cloudrun"));var it=(e=>(e.TEXT="text",e.ARTIFACT="artifact",e))(it||{});const rt=e=>{switch(e){case"createPipeline":return"Add";case"editPipeline":return"Done";default:return"Create"}};class st{buildNewServerGroupCommand(e){return lt.buildNewServerGroupCommand(e,"cloudrun","create")}buildNewServerGroupCommandForPipeline(e,t){return lt.buildNewServerGroupCommandForPipeline(e,t)}buildServerGroupCommandFromPipeline(e,t,n,a){return lt.buildServerGroupCommandFromPipeline(e,t,n,a)}}const ot=class e{static ServerGroupCommandIsValid(e){return!!e.moniker&&!!e.moniker.app}static copyAndCleanCommand(e){return _(e)}static buildNewServerGroupCommandForPipeline(e,t){const n=this.buildNewServerGroupCommand({name:t.application},"cloudrun","createPipeline");return n.viewState={...n.viewState,pipeline:t,requiresTemplateSelection:!0,stage:e},n}static getExpectedArtifacts(e){return e.expectedArtifacts||[]}static buildServerGroupCommandFromPipeline(t,n,a,i){return e.buildNewServerGroupCommand(t,"cloudrun","editPipeline").then(t=>t={...t,...n,backingData:{...t.metadata.backingData.backingData,expectedArtifacts:e.getExpectedArtifacts(i)},credentials:n.account||t.metadata.backingData.credentials,viewState:{...t.metadata.backingData.viewState,stage:a,pipeline:i}})}static getCredentials(e){const t=(e||[]).map(e=>e.name),n=at.defaults.account;return t.includes(n)?n:t[0]}static getRegion(e,t){const n=e.find(e=>e.name===t);return n?n.region:null}static buildNewServerGroupCommand(e,t,n){const a={accounts:k.getAllAccountDetailsForProvider("cloudrun"),artifactAccounts:k.getArtifactAccounts()};return me.all(a).then(a=>{const{accounts:i}=a,r=i.some(e=>e.name===t)?i.find(e=>e.name===t).name:i.length?i[0].name:null,s={mode:n,submitButtonLabel:rt(n),disableStrategySelection:"create"===n},o=r||this.getCredentials(i),l=this.getRegion(a.accounts,o),c="cloudrun";return{command:{application:e.name,configFiles:[""],cloudProvider:c,selectedProvider:c,provider:c,region:l,credentials:o,gitCredentialType:"NONE",manifest:null,sourceType:"git",configArtifacts:[],interestingHealthProviderNames:[],fromArtifact:!1,account:r,viewState:s},metadata:{backingData:a}}})}};ot.$inject=["$q"];let lt=ot;const ct="spinnaker.cloudrun.serverGroup.commandBuilder.service";function dt({accounts:e,onAccountSelect:t,selectedAccount:n,formik:a,onEnterStack:i,detailsChanged:r,app:s}){const{values:o}=a,{stack:l="",freeFormDetails:c}=o,d=F.getClusterName(s.name,l,c),u=!s.clusters.find(e=>e.name===d),h=s.serverGroups.data.filter(e=>e.cluster===d&&e.account===o.command.credentials&&e.region===o.command.region).sort((e,t)=>e.createdTime-t.createdTime),g=h.length?h.pop():null;return se.createElement("div",{className:"form-horizontal"},se.createElement("div",{className:"form-group"},se.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),se.createElement("div",{className:"col-md-7"},se.createElement(m,{value:n,onChange:e=>t(e.target.value),readOnly:!1,accounts:e,provider:"cloudrun"}))),se.createElement("div",{className:"form-group"},se.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",se.createElement(p,{id:"cloudrun.serverGroup.stack"})),se.createElement("div",{className:"col-md-7"},se.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:l,onChange:e=>i(e.target.value)}))),se.createElement("div",{className:"form-group"},se.createElement("div",{className:"col-md-3 sm-label-right"},"Detail ",se.createElement(p,{id:"cloudrun.serverGroup.detail"})),se.createElement("div",{className:"col-md-7"},se.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:c,onChange:e=>r(e.target.value)}))),!o.command.viewState.hideClusterNamePreview&&se.createElement(R,{createsNewCluster:u,latestServerGroupName:null==g?void 0:g.name,mode:o.command.viewState.mode,namePreview:d,navigateToLatestServerGroup:()=>{const{values:e}=a,t={provider:e.command.selectedProvider,accountId:g.account,region:g.region,serverGroup:g.name},{$state:n}=w;n.is("home.applications.application.insight.clusters")?n.go(".serverGroup",t):n.go("^.serverGroup",t)}}))}e(ct,[]).service("cloudrunV2ServerGroupCommandBuilder",st);class ut extends se.Component{constructor(){super(...arguments),this.accountUpdated=e=>{const{formik:t}=this.props;t.values.command.account=e,t.setFieldValue("account",e)},this.stackChanged=e=>{const{setFieldValue:t,values:n}=this.props.formik;n.command.stack=e,t("stack",e)},this.freeFormDetailsChanged=e=>{const{setFieldValue:t,values:n}=this.props.formik;n.command.freeFormDetails=e,t("freeFormDetails",e)}}render(){var e,t,n;const{formik:a,app:i}=this.props;return se.createElement(dt,{accounts:(null==(t=null==(e=a.values.metadata)?void 0:e.backingData)?void 0:t.accounts)||[],onAccountSelect:this.accountUpdated,selectedAccount:(null==(n=a.values.command)?void 0:n.account)||"",onEnterStack:this.stackChanged,formik:a,detailsChanged:this.freeFormDetailsChanged,app:i})}}function pt({configFiles:e,onEnterConfig:t}){const[n,a]=oe(e);return se.createElement("div",{className:"form-horizontal"},se.createElement("div",{className:"form-group"},n.map((e,i)=>se.createElement(se.Fragment,null,se.createElement("div",{className:"col-md-3 sm-label-right"},"Service Yaml",se.createElement(p,{id:"cloudrun.serverGroup.configFiles"})," "),se.createElement("div",{className:"col-md-8",key:i},se.createElement(P,{name:"text"+i,value:e,rows:10,onChange:e=>function(e,i){if(9===e.which){e.preventDefault();const t=e.target.selectionStart,n=e.target.value;e.target.value=`${n.substring(0,t)} ${n.substring(t)}`,e.target.selectionStart+=2}const r=[...n];r[i]=e.target.value,a(r),t(r)}(e,i)}))))))}class mt extends se.Component{constructor(){super(...arguments),this.configUpdated=e=>{const{formik:t}=this.props;t.values.command.configFiles=e,t.setFieldValue("configFiles",e)}}render(){const{formik:e}=this.props;return se.createElement(pt,{configFiles:e.values.configFiles||e.values.command.configFiles,onEnterConfig:this.configUpdated})}}const ht=class e extends se.Component{constructor(e){super(e),this._isUnmounted=!1,this.onTaskComplete=()=>{this.props.application.serverGroups.refresh(),this.props.application.serverGroups.onNextRefresh(null,this.onApplicationRefresh)},this.onApplicationRefresh=()=>{if(this._isUnmounted)return;const{command:e}=this.props,{taskMonitor:t}=this.state,n=t.task.execution.stages.find(e=>"cloneServerGroup"===e.type);if(n&&n.context["deploy.server.groups"]){const t=n.context["deploy.server.groups"][e.command.region];if(t){const n={serverGroup:t,accountId:e.command.credentials,region:e.command.region,provider:"cloudrun"};let a="^.^.^.clusters.serverGroup";w.$state.includes("**.clusters.serverGroup")&&(a="^.serverGroup"),w.$state.includes("**.clusters.cluster.serverGroup")&&(a="^.^.serverGroup"),w.$state.includes("**.clusters")&&(a=".serverGroup"),w.$state.go(a,n)}}},this.submit=e=>{const t=lt.copyAndCleanCommand(e.command);if(!("editPipeline"===t.viewState.mode||"createPipeline"===t.viewState.mode)){const e=()=>w.serverGroupWriter.cloneServerGroup(t,this.props.application);return this.state.taskMonitor.submit(e),null}this.props.closeModal&&this.props.closeModal(t)},e.command||lt.buildNewServerGroupCommand(e.application,"cloudrun","create").then(e=>{Object.assign(this.state.command,e),this.setState({loaded:!0})}),this.state={loaded:!!e.command,command:e.command||{},taskMonitor:new s({application:e.application,title:("Create"===e.command.command.viewState.submitButtonLabel?"Creating":"Updating")+" your Server Group",modalInstance:s.modalInstanceEmulation(()=>this.props.dismissModal()),onTaskComplete:this.onTaskComplete})}}static show(t){return z.show(e,t,{dialogClassName:"wizard-modal modal-lg"})}render(){const{dismissModal:e,application:t}=this.props,{loaded:n,taskMonitor:a,command:i}=this.state,r=this.state.command.command.viewState.submitButtonLabel;return se.createElement(O,{heading:("Add"===r||"Create"===r?"Create New":"Update")+" Server Group",initialValues:i,loading:!n,taskMonitor:a,dismissModal:e,closeModal:this.submit,submitButtonLabel:r,render:({formik:e,nextIdx:n,wizard:a})=>se.createElement(se.Fragment,null,se.createElement(U,{label:"Basic Settings",wizard:a,order:n(),render:({innerRef:n})=>se.createElement(ut,{ref:n,formik:e,app:t})}),se.createElement(U,{label:"Service Yaml",wizard:a,order:n(),render:({innerRef:t})=>se.createElement(mt,{ref:t,formik:e})}))})}};ht.defaultProps={closeModal:V,dismissModal:V};let gt=ht;class ft{}ft.PLATFORM="Cloud Run Service";class vt{constructor(e,t,n,a,i){this.$state=e,this.$scope=t,this.app=a,this.serverGroupWriter=i,this.state={loading:!0},this.extractServerGroup(n).then(()=>{this.$scope.$$destroyed||this.app.getDataSource("serverGroups").onRefresh(this.$scope,()=>this.extractServerGroup(n))}).catch(()=>this.autoClose())}canDestroyServerGroup(){if(this.serverGroup){return!this.serverGroup.tags.isLatest&&!!this.serverGroup.disabled}return!1}destroyServerGroup(){const e={name:this.serverGroup.name,accountId:this.serverGroup.account,region:this.serverGroup.region},t={application:this.app,title:"Destroying "+this.serverGroup.name,onTaskComplete:()=>{this.$state.includes("**.serverGroup",e)&&this.$state.go("^")}},n={header:"Really destroy "+this.serverGroup.name+"?",buttonText:"Destroy "+this.serverGroup.name,account:this.serverGroup.account,taskMonitorConfig:t,submitMethod:e=>this.serverGroupWriter.destroyServerGroup(this.serverGroup,this.app,e),askForReason:!0,platformHealthOnlyShowOverride:this.app.attributes.platformHealthOnlyShowOverride,platformHealthType:ft.PLATFORM,interestingHealthProviderNames:[]};this.app.attributes.platformHealthOnlyShowOverride&&this.app.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=[ft.PLATFORM]),o.confirm(n)}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}extractServerGroup({name:e,accountId:t,region:n}){return j.getServerGroup(this.app.name,t,n,e).then(a=>{let i=this.app.getDataSource("serverGroups").data.find(a=>a.name===e&&a.account===t&&a.region===n);i||this.app.getDataSource("loadBalancers").data.some(n=>n.account===t&&n.serverGroups.some(t=>{let n=!1;return t.name===e&&(i=t,n=!0),n})),this.serverGroup={...a,...i},this.state.loading=!1})}}vt.$inject=["$state","$scope","serverGroup","app","serverGroupWriter"];const bt="spinnaker.cloudrun.serverGroup.details.controller";e(bt,[Y]).controller("cloudrunV2ServerGroupDetailsCtrl",vt);class Bt{constructor(e){this.$q=e}normalizeServerGroup(e){return this.$q.resolve(e)}convertServerGroupCommandToDeployConfiguration(e){return new kt(e)}}Bt.$inject=["$q"];class kt{constructor(e){this.cloudProvider="cloudrun",this.provider="cloudrun",this.credentials=e.credentials,this.account=e.credentials,this.application=e.application,this.stack=e.stack,this.freeFormDetails=e.freeFormDetails,this.region=e.region,this.strategy=e.strategy,this.type=e.type,this.fromArtifact=e.fromArtifact,this.gitCredentialType=e.gitCredentialType,this.configFiles=e.configFiles,this.sourceType=e.sourceType,this.interestingHealthProviderNames=e.interestingHealthProviderNames||[],this.configArtifacts=[]}}const Ct="spinnaker.cloudrun.serverGroup.transformer.service";e(Ct,[]).service("cloudrunV2ServerGroupTransformer",Bt);Te('.cloud-provider-logo .icon-cloudrun {\n -webkit-mask-image: url("data:image/svg+xml,%3Csvg width%3D%2224px%22 height%3D%2224px%22 viewBox%3D%220 0 24 24%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E %3Cdefs%3E %3Cstyle%3E .cls-1 %7B fill%3A %23aecbfa%3B %7D .cls-1%2C .cls-2 %7B fill-rule%3A evenodd%3B %7D .cls-2 %7B fill%3A %234285f4%3B %7D %3C%2Fstyle%3E %3C%2Fdefs%3E %3Ctitle%3EIcon_24px_CloudRun_Color%3C%2Ftitle%3E %3Cg data-name%3D%22Product Icons%22%3E %3Cg%3E %3Cpolygon class%3D%22cls-1%22 points%3D%228.9 2.63 12.02 12 21.38 12 8.9 2.63%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%2221.38 12 12.02 12 8.9 21.38 21.38 12%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%223.44 21.38 6.57 19.81 8.9 12 5.78 12 3.44 21.38%22 %2F%3E %3Cpolygon class%3D%22cls-1%22 points%3D%223.44 2.63 5.78 12 8.9 12 6.57 4.19 3.44 2.63%22 %2F%3E %3C%2Fg%3E %3C%2Fg%3E%3C%2Fsvg%3E");\n mask-image: url("data:image/svg+xml,%3Csvg width%3D%2224px%22 height%3D%2224px%22 viewBox%3D%220 0 24 24%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E %3Cdefs%3E %3Cstyle%3E .cls-1 %7B fill%3A %23aecbfa%3B %7D .cls-1%2C .cls-2 %7B fill-rule%3A evenodd%3B %7D .cls-2 %7B fill%3A %234285f4%3B %7D %3C%2Fstyle%3E %3C%2Fdefs%3E %3Ctitle%3EIcon_24px_CloudRun_Color%3C%2Ftitle%3E %3Cg data-name%3D%22Product Icons%22%3E %3Cg%3E %3Cpolygon class%3D%22cls-1%22 points%3D%228.9 2.63 12.02 12 21.38 12 8.9 2.63%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%2221.38 12 12.02 12 8.9 21.38 21.38 12%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%223.44 21.38 6.57 19.81 8.9 12 5.78 12 3.44 21.38%22 %2F%3E %3Cpolygon class%3D%22cls-1%22 points%3D%223.44 2.63 5.78 12 8.9 12 6.57 4.19 3.44 2.63%22 %2F%3E %3C%2Fg%3E %3C%2Fg%3E%3C%2Fsvg%3E");\n background-color: #4285f4;\n}\n');const wt="spinnaker.cloudrun";e(wt,[ge,ct,bt,Ct,De,Me,Ne,fe,ke,we,Ae,ze,be]).config(()=>{l.registerProvider("cloudrun",{name:"cloudrun",logo:{path:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAFAUlEQVRYR82YfUwcRRjGn5m7veO4rZI2aKuk1kRNjQ012rRANB53YNpYtFHS1Aj9ktaPtGINpPWgKQ0sVNvUNGirgYBJSTSA1H6ltpTrVYtUS2u1aRS/LSRFEmqBPcC7vR2zixwc7N4tJ02c5P64zMwzv332fd+ZWYL/USNGWFL3MpvVJy4xMlZzTJA/7y0hw9HmR4VxlokVIGQzwOzRxCL0D4DgA4+bL4ykERHGKfiqAJb3HyAmTCXVniL7Bj09XRhXqZjBKJqnD2REicjIbNnOn9bS1YVxlvuOgrHl0w0DQo553PYswzAuQcxhwMFpB/lXkAC5LUV83UT9Sc44SpjZxPnaGLDoFsK0BwP2VG8JkcavMQnGWSYWgGD3rQIJ6TIUeor5PbowjrcGk6gktwFI0oKZk0Bw/SYLdSXNpOi6IcfK3SWbaap3a3zXqECYM85ycTcYCvTUX3JZ0NMn41D7iLt5Dgv6hhgavgrEBkSwZ3ztCcE4ynyLKGGKK2Y95ZT7TBBWxuHzH4LY2TSMBUkU+1bbcOn3IPZ95o/FJUlmJNVbbG9X0350YacgKtmTE+kRORNQs9GGO2+nyKsawrVeGe+vt+HyH0E88yiHmrP+WFyq8xTxuSEYV2n/ckbpUSNeFzxlxbKFZuxv9uPUFQkrUzgkz6U4/o2E7MUcbvgY3j01NZeILGe1bL/tmOpMernYTBgyjMBkLjBj29NWfNEhofKkH/MSKXatikPO/kEwBmQv4bA02YyD5wKGXWIEp8+4+UziFPrzAFplBEQZM4snqH8tHjcHGTZWD6nTKtfYUHvWr8aO0u6fTbHpSSt+6ZFR5THqkryBOAXfEYBplmc9wPfW2jD/Loqi+mH81C1jzeMWzEvU3lnmJFDUtfpx+GJYfdOSPkHSBbGHAIlGnRlN6efTOPU1KL+HkkzY8aw1okTLVQk1Xj+6+8bq1MQJJL1MrCYEL04FpjrPhnvvGHNm3RMWNai1mlIkFeBzHRL8QWBgSAeGkAbiKhWXMooTRmFmzSCo3xweMwfW29RYmthOfiepIP3jAAJBhP0PVV8Zy1QFpyDWAlhrBEhJ31cyLKFsevBuip3PxYVN7eyV8XFbABd+HQnoiU2Sgb7BMIc+9BTx61QYhyA+TAGl+oaragjtfSEOC+8xqXXG+72E3Mc4ZD3ChUYeuRRAw/kA/o4Sr0EZakYCGJaBVG8Rf3msApcPVoDJ26K50+K2QxF6tXYIf/mYuh0oG+hvPTLqWgO40qnthq5DQ2SXxx3/ptI/tjeViLMpp7ozTw8o7QETSrOVvUlSq2zyXBOKV1jRdCGgvpapNkrR+WcvW+wt4bvDYNTYKRNfB8E7eqJK5f365yC+vTby9EoWffmjhI7rsR0jgjLb2rSFfzsUxBMXdgnKKY+laAFZzQAfF/V2Y8ggAlysz7eHnSYnKbuEgVUM5CM9xekCCshs9adb+LBztuZjOgXfIYCt0AXiAN4au0MM9Hhjvm3SzUNT0VE64KCUnInkdxwH2GME8vtZ5uHCyXcn/XuT4DsAsJenG4gBNY35ds3tRxfGUd4/nzKqpHpCJCCbhSDeYihmAbB+2cTSPtk046rWjMh37dKBElCyI9pSRoEYUNGYb3fr6UWNQqcKRAuifYWItxDYdBwihIgyY5WRQCYVPT1io99nZvKc5jnCxKytDW+QkWNhhBbVmWgC09n/Dw0j4+SJOXQTAAAAAElFTkSuQmCC"},instance:{detailsTemplateUrl:"cloudrun/src/instance/details/details.html",detailsController:"cloudrunInstanceDetailsCtrl"},serverGroup:{CloneServerGroupModal:gt,commandBuilder:"cloudrunV2ServerGroupCommandBuilder",detailsController:"cloudrunV2ServerGroupDetailsCtrl",detailsTemplateUrl:"cloudrun/src/serverGroup/details/details.html",transformer:"cloudrunV2ServerGroupTransformer",skipUpstreamStageCheck:!0},loadBalancer:{transformer:"cloudrunLoadBalancerTransformer",createLoadBalancerTemplateUrl:"cloudrun/src/loadBalancer/configure/wizard/wizard.html",createLoadBalancerController:"cloudrunLoadBalancerWizardCtrl",detailsTemplateUrl:"cloudrun/src/loadBalancer/details/details.html",detailsController:"cloudrunLoadBalancerDetailsCtrl"}})}),K.registerProvider("cloudrun",["custom","redblack","rollingpush","rollingredblack"]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/instance/details/details.html",'<div class="details-panel">\n <div class="header">\n <instance-details-header\n health-state="ctrl.instance.healthState"\n instance-id="ctrl.instance ? ctrl.instance.name : ctrl.instanceIdNotFound"\n loading="ctrl.state.loading"\n standalone="false"\n ></instance-details-header>\n <div ng-if="!ctrl.state.loading">\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Instance Actions <span class="caret"></span>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!ctrl.state.loading && ctrl.instance">\n <collapsible-section heading="Instance Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Launched</dt>\n <dd ng-if="ctrl.instance.launchTime">{{ctrl.instance.launchTime | timestamp}}</dd>\n <dt>In</dt>\n <dd><account-tag account="ctrl.instance.account" pad="right"></account-tag>{{}}</dd>\n <dt ng-if="ctrl.instance.serverGroup">Server Group</dt>\n <dd ng-if="ctrl.instance.serverGroup">\n <a\n ui-sref="^.serverGroup({region: ctrl.instance.region,\n accountId: ctrl.instance.account,\n serverGroup: ctrl.instance.serverGroup,\n provider: \'cloudrun\'})"\n >{{ctrl.instance.serverGroup}}</a\n >\n </dd>\n <dt>Region</dt>\n <dd>{{ctrl.instance.region}}</dd>\n <cloudrun-conditional-dt-dd\n component="ctrl.instance"\n key="vmZoneName"\n label="Zone"\n ></cloudrun-conditional-dt-dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <dl>\n <dt>Load Balancer</dt>\n <dd>\n <span\n class="pull-left"\n uib-tooltip="{{ctrl.instance.healthState === \'Up\' ? ctrl.upToolTip : ctrl.outOfServiceToolTip}}"\n tooltip-placement="right"\n >\n <span class="glyphicon glyphicon-{{ctrl.instance.healthState}}-triangle"></span>\n {{ctrl.instance.loadBalancers[0]}}\n </span>\n </dd>\n </dl>\n </collapsible-section>\n </div>\n <div class="content" ng-if="!ctrl.state.loading && !ctrl.instance">\n <div class="content-section">\n <div class="content-body text-center">\n <h3>Instance not found.</h3>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/serverGroup/details/details.html",'<div class="details-panel" ng-class="{disabled: ctrl.serverGroup.isDisabled || ctrl.serverGroup.disabled}">\n <div class="header" ng-if="ctrl.state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <h4 class="text-center">\n <span us-spinner="{radius:20, width:6, length: 12}"></span>\n </h4>\n </div>\n\n <div class="header" ng-if="!ctrl.state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <cloud-provider-logo provider="ctrl.serverGroup.type" height="\'36px\'" width="\'36px\'"></cloud-provider-logo>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{ctrl.serverGroup.name}}</h3>\n </div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Server Group Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li\n ng-if="ctrl.serverGroup.tags.isLatest"\n uib-tooltip="You cannot destroy the latest server group (revision) . \n You may be able to delete this server group\'s load balancer."\n class="disabled"\n >\n <a href>Destroy</a>\n </li>\n <li ng-if="ctrl.canDestroyServerGroup() && !ctrl.serverGroup.tags.isLatest">\n <a href ng-click="ctrl.destroyServerGroup()">Destroy</a>\n </li>\n <li\n ng-if="(!ctrl.canDestroyServerGroup() && !ctrl.serverGroup.tags.isLatest)"\n uib-tooltip="You cannot destroy this server group while it is receiving traffic. \n You may be able to delete this server group\'s load balancer."\n class="disabled"\n >\n <a href>Destroy</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!ctrl.state.loading">\n <div class="band band-info" ng-if="ctrl.serverGroup.isDisabled || ctrl.serverGroup.disabled">Disabled</div>\n <server-group-running-tasks-details\n server-group="ctrl.serverGroup"\n application="ctrl.app"\n ></server-group-running-tasks-details>\n <collapsible-section heading="Server Group Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Created</dt>\n <dd>{{ctrl.serverGroup.createdTime | timestamp}}</dd>\n <dt>In</dt>\n <dd><account-tag account="ctrl.serverGroup.account"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{ctrl.serverGroup.region}}</dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="Size" expanded="true">\n <dl class="dl-horizontal dl-narrow" ng-if="ctrl.serverGroup.capacity.min === ctrl.serverGroup.capacity.max">\n <dt>Min/Max</dt>\n <dd>{{ctrl.serverGroup.capacity.min}}</dd>\n <dt>Current</dt>\n <dd>{{ctrl.serverGroup.instances.length}}</dd>\n </dl>\n <dl class="dl-horizontal dl-narrow" ng-if="ctrl.serverGroup.capacity.min !== ctrl.serverGroup.capacity.max">\n <dt>Min</dt>\n <dd>{{ctrl.serverGroup.capacity.min}}</dd>\n <dt>Max</dt>\n <dd>{{ctrl.serverGroup.capacity.max}}</dd>\n <dt>Current</dt>\n <dd>{{ctrl.serverGroup.instances.length}}</dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Health" expanded="true">\n <dl class="dl-horizontal dl-narrow" ng-if="ctrl.serverGroup">\n <dt>Instances</dt>\n <dd>\n <health-counts container="ctrl.serverGroup.instanceCounts" class="pull-left"></health-counts>\n </dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/loadBalancer/configure/wizard/wizard.html",'<form name="form">\n <div ng-if="ctrl.state.loading && !ctrl.isNew" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <v2-modal-wizard\n heading="{{::ctrl.heading}}"\n task-monitor="ctrl.taskMonitor"\n dismiss="$dismiss()"\n ng-if="!ctrl.state.loading || ctrl.isNew"\n >\n <div ng-if="!ctrl.isNew">\n <v2-wizard-page key="basic-settings" label="Basic Settings" mark-complete-on-view="false">\n <cloudrun-load-balancer-basic-settings\n load-balancer="ctrl.loadBalancer"\n application="ctrl.application"\n for-pipeline-config="ctrl.forPipelineConfig"\n ></cloudrun-load-balancer-basic-settings>\n </v2-wizard-page>\n </div>\n </v2-modal-wizard>\n <cloudrun-load-balancer-message\n ng-if="ctrl.isNew"\n column-offset="1"\n columns="10"\n show-create-message="true"\n ></cloudrun-load-balancer-message>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n ng-if="!ctrl.isNew && ctrl.showSubmitButton()"\n label="ctrl.submitButtonLabel"\n is-disabled="cloudrunLoadBalancerForm.$invalid || ctrl.taskMonitor.submitting || ctrl.state.loading"\n submitting="ctrl.taskMonitor.submitting"\n on-click="ctrl.submit()"\n is-new="ctrl.isNew"\n >\n </submit-button>\n </div>\n</form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("cloudrun/src/loadBalancer/details/details.html",'<div class="details-panel">\n <div ng-if="ctrl.state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div ng-if="!ctrl.state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <i class="fa icon-sitemap"></i>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{ctrl.loadBalancer.name}}</h3>\n </div>\n <div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Load Balancer Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li><a href ng-click="ctrl.editLoadBalancer()">Edit Load Balancer</a></li>\n <li ng-if="ctrl.canDeleteLoadBalancer()">\n <a href ng-click="ctrl.deleteLoadBalancer()">Delete Load Balancer</a>\n </li>\n <li\n ng-if="!ctrl.canDeleteLoadBalancer()"\n uib-tooltip="You cannot delete a default service."\n class="disabled"\n >\n <a href>Delete Load Balancer</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n\n <div ng-if="!ctrl.state.loading" class="content">\n <collapsible-section heading="Load Balancer Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>In</dt>\n <dd><account-tag account="ctrl.loadBalancer.account" pad="right"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{ctrl.loadBalancer.region}}</dd>\n <dt ng-if="ctrl.loadBalancer.serverGroups.length">Server Groups</dt>\n <dd ng-if="ctrl.loadBalancer.serverGroups.length">\n <ul>\n <li ng-repeat="serverGroup in ctrl.loadBalancer.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: \'cloudrun\'})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <health-counts class="pull-left" container="ctrl.loadBalancer.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Traffic Split" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <ul>\n <li ng-repeat="trafficTarget in ctrl.loadBalancer.split.trafficTargets">\n {{trafficTarget.revisionName}}:<span class="pull-right">{{trafficTarget.percent}}</span>\n </li>\n </ul>\n </dl>\n </collapsible-section>\n <collapsible-section heading="DNS" expanded="true">\n <dl class="dl-narrow">\n <cloudrun-component-url-details component="ctrl.loadBalancer"></cloudrun-component-url-details>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]);export{Me as CLOUDRUN_LOAD_BALANCER_DETAILS_CTRL,De as CLOUDRUN_LOAD_BALANCER_TRANSFORMER,Ne as CLOUDRUN_LOAD_BALANCER_WIZARD_CTRL,wt as CLOUDRUN_MODULE,ct as CLOUDRUN_SERVER_GROUP_COMMAND_BUILDER,bt as CLOUDRUN_SERVER_GROUP_DETAILS_CTRL,Ct as CLOUDRUN_SERVER_GROUP_TRANSFORMER,kt as CloudrunDeployDescription,xe as CloudrunLoadBalancerTransformer,Ge as CloudrunLoadBalancerUpsertDescription,lt as CloudrunServerGroupCommandBuilder,st as CloudrunV2ServerGroupCommandBuilder,Bt as CloudrunV2ServerGroupTransformer,it as ServerGroupSource};
1
+ import{HelpContentsRegistry as e,RecentHistoryService as t,InstanceReader as a,Spinner as n,CollapsibleSection as r,timestamp as s,AccountTag as i,LoadBalancerWriter as o,TaskMonitor as l,ReactModal as c,withRouter as m,HelpField as d,StageConstants as u,ConfirmationModalService as p,CopyToClipboard as h,HealthCounts as f,useDataSource as g,StageArtifactSelector as v,ArtifactTypePatterns as E,AccountSelectInput as b,yamlDocumentsToString as k,StageConfigField as C,RadioButtonInput as N,YamlEditor as y,StageArtifactSelectorDelegate as A,CheckboxInput as S,AccountService as w,FormikStageConfig as B,relativeTime as x,JobManifestPodLogs as T,JobEventBasedPodNameProvider as D,ManifestYaml as G,ManifestReader as M,ExecutionDetailsSection as F,StageFailureMessage as R,Registry as I,ExecutionDetailsTasks as P,ExecutionArtifactTab as L,ArtifactReferenceService as U,ExpectedArtifactService as O,SETTINGS as Y,NameUtils as z,ServerGroupNamePreview as V,TextAreaInput as j,WizardModal as K,WizardPage as H,DeckRuntimeContext as W,noop as $,useDeckRuntimeServices as q,ServerGroupReader as X,CloudProviderRegistry as Q,DeploymentStrategyRegistry as Z}from"@spinnaker/core";import{UISref as _}from"@uirouter/react";import{flattenDeep as J,filter as ee,chain as te,cloneDeep as ae,has as ne,camelCase as re,get as se,reduce as ie,difference as oe,uniq as le,map as ce,capitalize as me,isEmpty as de,trim as ue}from"lodash";import pe,{useMemo as he,useState as fe}from"react";import{Dropdown as ge,MenuItem as ve}from"react-bootstrap";import{Subject as Ee,from as be,Observable as ke}from"rxjs";import{takeUntil as Ce}from"rxjs/operators";import{dump as Ne}from"js-yaml";import{DateTime as ye}from"luxon";[{key:"cloudrun.serverGroup.stack",value:"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing."},{key:"cloudrun.serverGroup.file",value:"<pre>\n apiVersion: serving.knative.dev/v1\n kind: Service\n metadata:\n name: spinappcloud1\n namespace: '135005621049'\n labels:\n cloud.googleapis.com/location: us-central1\n annotations:\n run.googleapis.com/client-name: cloud-console\n serving.knative.dev/creator: kiran@opsmx.io\n serving.knative.dev/lastModifier: kiran@opsmx.io\n client.knative.dev/user-image: us-docker.pkg.dev/cloudrun/container/hello\n run.googleapis.com/ingress-status: all\n spec:\n template:\n metagoogleapis.com/ingress: all\n run.data:\n name: spinappcloud1\n annotations:\n run.googleapis.com/client-name: cloud-console\n autoscaling.knative.dev/minScale: '1'\n autoscaling.knative.dev/maxScale: '3'\n spec:\n containerConcurrency: 80\n timeoutSeconds: 200\n serviceAccountName:spinnaker-cloudrun-account@my-orbit-project-71824.iam.gserviceaccount.com\n containers:\n - image:us-docker.pkg.dev/cloudrun/container/hello\n ports:\n - name: http1\n containerPort: 8080\n resources:\n limits:\n cpu: 1000m\n memory: 256Mi \n</pre>\n "},{key:"cloudrun.serverGroup.detail",value:" (Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables."},{key:"cloudrun.serverGroup.configFiles",value:"<p> The contents of a Cloud Run Service yaml </p>"},{key:"cloudrun.loadBalancer.allocations",value:"An allocation is the percent of traffic directed to a server group."},{key:"cloudrun.manifest.source",value:"\n <p>Where the manifest file content is read from.</p>\n <p>\n <b>text:</b> The manifest is supplied statically to the pipeline from the below text-box.\n </p>\n <p>\n <b>artifact:</b> The manifest is read from an artifact supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>"},{key:"cloudrun.manifest.expectedArtifact",value:"The artifact that is to be applied to the Cloud Run account for this stage. The artifact should represent a valid Cloud Run manifest."},{key:"cloudrun.manifest.skipExpressionEvaluation",value:'<p>Skip SpEL expression evaluation of the manifest artifact in this stage. Can be paired with the "Evaluate SpEL expressions in overrides at bake time" option in the Bake Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.</p>'},{key:"cloudrun.manifest.requiredArtifactsToBind",value:'These artifacts must be present in the context for this stage to successfully complete. Artifacts specified will be <a href="https://www.spinnaker.io/reference/artifacts/in-cloudrun-v2/#binding-artifacts-in-manifests" target="_blank">bound to the deployed manifest.</a>'},{key:"cloudrun.manifest.account",value:"\n <p>A Spinnaker account corresponds to a physical Cloud Run cluster. If you are unsure which account to use, talk to your Spinnaker admin.</p>\n "}].forEach(t=>e.register(t.key,t.value));class Ae extends pe.Component{constructor(){super(...arguments),this.state={loading:!0},this.isUnmounted=!1}componentDidMount(){this.props.app.ready().then(()=>this.retrieveInstance()).then(e=>!this.isUnmounted&&this.setState({instance:e,loading:!1})).catch(()=>!this.isUnmounted&&this.setState({instanceIdNotFound:this.props.instance.instanceId,loading:!1}))}componentWillUnmount(){this.isUnmounted=!0}retrieveInstance(){const{app:e,instance:n}=this.props,r=J([e.getDataSource("serverGroups").data,e.getDataSource("loadBalancers").data,e.getDataSource("loadBalancers").data.map(e=>e.serverGroups)]).find(e=>e.instances.some(e=>e.id===n.instanceId));if(!r)return Promise.reject();const s={region:r.region,account:r.account};return"serverGroup"===r.category&&(s.serverGroup=r.name),t.addExtraDataToLatest("instances",s),a.getInstanceDetails(r.account,r.region,n.instanceId).then(e=>({...e,account:r.account,region:r.region}))}render(){var e;const{loading:t,instance:a,instanceIdNotFound:o}=this.state;return pe.createElement("div",{className:"details-panel"},pe.createElement("div",{className:"header"},pe.createElement("div",{className:"header-text horizontal middle"},pe.createElement("h3",{className:"horizontal middle space-between flex-1"},a?a.name:o)),t&&pe.createElement(n,{size:"small"})),!t&&a&&pe.createElement("div",{className:"content"},pe.createElement(r,{heading:"Instance Information",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},pe.createElement("dt",null,"Launched"),pe.createElement("dd",null,a.launchTime&&s(a.launchTime)),pe.createElement("dt",null,"In"),pe.createElement("dd",null,pe.createElement(i,{account:a.account})),a.serverGroup&&pe.createElement("dt",null,"Server Group"),a.serverGroup&&pe.createElement("dd",null,pe.createElement(_,{to:"^.serverGroup",params:{region:a.region,accountId:a.account,serverGroup:a.serverGroup,provider:"cloudrun"}},pe.createElement("a",null,a.serverGroup))),pe.createElement("dt",null,"Region"),pe.createElement("dd",null,a.region),a.vmZoneName&&pe.createElement("dt",null,"Zone"),a.vmZoneName&&pe.createElement("dd",null,a.vmZoneName))),pe.createElement(r,{heading:"Status",defaultExpanded:!0},pe.createElement("dl",null,pe.createElement("dt",null,"Load Balancer"),pe.createElement("dd",null,pe.createElement("span",{className:"pull-left",title:"Up"===a.healthState?"A Cloud Run instance is 'Up' if a load balancer is directing traffic to its server group.":"A Cloud Run instance is 'Out Of Service' if no load balancers are directing traffic to its server group."},pe.createElement("span",{className:`glyphicon glyphicon-${a.healthState}-triangle`})," ",null==(e=a.loadBalancers)?void 0:e[0]))))),!t&&!a&&pe.createElement("div",{className:"content"},pe.createElement("div",{className:"content-section"},pe.createElement("div",{className:"content-body text-center"},pe.createElement("h3",null,"Instance not found.")))))}}function Se({showCreateMessage:e=!1}){return pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-offset-1 col-md-10"},pe.createElement("div",{className:"well"},pe.createElement("p",null,e&&pe.createElement("span",null,"Spinnaker cannot create a load balancer for Cloud Run. "),"A Spinnaker load balancer maps to an Cloud Run Service, which will be created automatically alongside a Revision. Once created, the Service can be edited as a Load Balancer."))))}class we{static convertTrafficSplitToTrafficSplitDescription(e){return{allocationDescriptions:ie(e.trafficTargets,(e,t)=>{const{revisionName:a,percent:n}=t;return e.concat({percent:n,revisionName:a})},[])}}constructor(e){this.credentials=e.account||e.credentials,this.account=this.credentials,this.cloudProvider=e.cloudProvider,this.loadBalancerName=e.name,this.name=e.name,this.region=e.region,this.migrateTraffic=e.migrateTraffic||!1,this.serverGroups=e.serverGroups}mapAllocationsToDecimals(){this.splitDescription.allocationDescriptions.forEach(e=>{e.percent=e.percent/100})}mapAllocationsToPercentages(){this.splitDescription.allocationDescriptions.forEach(e=>{e.percent=Math.round(e.percent)})}}class Be{normalizeLoadBalancer(e){e.provider=e.type,e.instanceCounts=this.buildInstanceCounts(e.serverGroups),e.instances=[],e.serverGroups.forEach(t=>{t.account=e.account,t.region=e.region,t.detachedInstances&&(t.detachedInstances=t.detachedInstances.map(e=>({id:e}))),t.instances=t.instances.concat(t.detachedInstances||[]).map(t=>this.transformInstance(t,e))});const t=ee(e.serverGroups,{isDisabled:!1});return e.instances=te(t).map("instances").flatten().value(),Promise.resolve(e)}convertLoadBalancerForEditing(e,t){return t.getDataSource("loadBalancers").ready().then(()=>{const a=t.getDataSource("loadBalancers").data.find(t=>t.name===e.name&&(t.account===e.account||t.account===e.credentials));return a&&(e.serverGroups=ae(a.serverGroups)),e})}convertLoadBalancerToUpsertDescription(e){return new we(e)}buildInstanceCounts(e){const t=te(e).map("instances").flatten().reduce((e,t)=>(ne(t,"health.state")&&e[re(t.health.state)]++,e),{up:0,down:0,outOfService:0,succeeded:0,failed:0,starting:0,unknown:0}).value();return t.outOfService+=te(e).map("detachedInstances").flatten().value().length,t}transformInstance(e,t){e.provider=t.type,e.account=t.account,e.region=t.region,e.loadBalancers=[t.name];const a=e.health||{};return e.healthState=se(e,"health.state")||"OutOfService",e.health=[a],e}}function xe(e){return 100===e.allocationDescriptions.reduce((e,t)=>e+Number(t.percent),0)}class Te extends pe.Component{constructor(e){super(e),this.transformer=new Be,this.isUnmounted=!1,this.onTaskComplete=()=>{this.clearApplicationRefreshSubscription(),this.applicationRefreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(this.onApplicationRefresh),this.props.app.loadBalancers.refresh()},this.onApplicationRefresh=()=>{if(this.clearApplicationRefreshSubscription(),this.isUnmounted)return;const{loadBalancer:e}=this.state;this.props.dismissModal();const t={name:e.name,accountId:e.credentials,region:e.region,provider:"cloudrun"};this.props.stateService.includes("**.loadBalancerDetails")?this.props.stateService.go("^.loadBalancerDetails",t):this.props.stateService.go(".loadBalancerDetails",t)},this.clearApplicationRefreshSubscription=()=>{var e;null==(e=this.applicationRefreshUnsubscribe)||e.call(this),this.applicationRefreshUnsubscribe=void 0},this.submit=()=>{const e=ae(this.state.loadBalancer);e.mapAllocationsToPercentages(),delete e.serverGroups,this.props.forPipelineConfig?this.props.closeModal(e):this.state.taskMonitor.submit(()=>o.upsertLoadBalancer(e,this.props.app,"Update"))},this.updateLoadBalancer=e=>{this.setState({loadBalancer:e})},this.state={loading:!e.isNew,taskMonitor:new l({application:e.app,title:"Updating your load balancer",onDismiss:()=>e.dismissModal(),onTaskComplete:this.onTaskComplete})}}static show(e){return c.show(De,e,{dialogClassName:"wizard-modal modal-lg"})}componentDidMount(){const{app:e,isNew:t,loadBalancer:a}=this.props;t||this.transformer.convertLoadBalancerForEditing(a,e).then(e=>{if(this.isUnmounted)return;const t=this.transformer.convertLoadBalancerToUpsertDescription(e);a.split&&!t.splitDescription?t.splitDescription=we.convertTrafficSplitToTrafficSplitDescription(a.split):t.splitDescription=a.splitDescription,t.mapAllocationsToPercentages(),this.setState({loadBalancer:t,loading:!1})}).catch(()=>{this.isUnmounted||this.props.dismissModal()})}componentWillUnmount(){this.isUnmounted=!0,this.clearApplicationRefreshSubscription()}render(){const{dismissModal:e,forPipelineConfig:t,isNew:a,loadBalancer:n}=this.props,{loading:r,loadBalancer:s,taskMonitor:i}=this.state,o=a?"Create New Load Balancer":`Edit ${[n.name,n.region,n.account||n.credentials].join(":")}`,l=t?"Done":"Update",c=(null==s?void 0:s.splitDescription)&&xe(s.splitDescription);return pe.createElement("form",{name:"form"},pe.createElement("div",{className:"modal-header"},pe.createElement("button",{type:"button",className:"close",onClick:e},pe.createElement("span",null,"×")),pe.createElement("h4",{className:"modal-title"},o)),pe.createElement("div",{className:"modal-body"},r&&!a&&pe.createElement("div",{style:{height:200},className:"horizontal center middle"},"Loading..."),a&&pe.createElement(Se,{showCreateMessage:!0}),!r&&!a&&s&&pe.createElement(Ge,{loadBalancer:s,forPipelineConfig:t,onChange:this.updateLoadBalancer})),pe.createElement("div",{className:"modal-footer"},pe.createElement("button",{type:"button",className:"btn btn-default",onClick:e},"Cancel"),!a&&c&&pe.createElement("button",{type:"button",className:"btn btn-primary",disabled:i.submitting||r,onClick:this.submit},l)))}}const De=Object.assign(m(Te),{show:Te.show});class Ge extends pe.Component{constructor(){super(...arguments),this.addAllocation=()=>{this.changeLoadBalancer(e=>{const t=this.serverGroupsWithoutAllocation(e);e.splitDescription.allocationDescriptions.push({revisionName:t[0]||"",percent:0})})},this.removeAllocation=e=>{this.changeLoadBalancer(t=>t.splitDescription.allocationDescriptions.splice(e,1))},this.updateAllocation=(e,t)=>{this.changeLoadBalancer(a=>{a.splitDescription.allocationDescriptions[e]={...a.splitDescription.allocationDescriptions[e],...t}})}}serverGroupsWithoutAllocation(e=this.props.loadBalancer){const t=e.splitDescription.allocationDescriptions.map(e=>e.revisionName),a=e.serverGroups.map(e=>e.name);return oe(a,t)}changeLoadBalancer(e){const t=ae(this.props.loadBalancer);e(t),this.props.onChange(t)}render(){const{forPipelineConfig:e,loadBalancer:t}=this.props,a=this.serverGroupsWithoutAllocation(),n=e||a.length>0,r=!xe(t.splitDescription);return pe.createElement("div",{className:"row"},pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Allocations ",pe.createElement(d,{id:"cloudrun.loadBalancer.allocations"})),pe.createElement("div",{className:"col-md-9"},t.splitDescription.allocationDescriptions.map((n,r)=>pe.createElement(Me,{key:r,allocationDescription:n,loadBalancer:t,forPipelineConfig:e,serverGroupOptions:a,onChange:e=>this.updateAllocation(r,e),onRemove:()=>this.removeAllocation(r)})),n&&pe.createElement("button",{type:"button",className:"add-new col-md-11",onClick:this.addAllocation},pe.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add allocation"))),r&&pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-12 text-center"},pe.createElement("p",{className:"alert alert-warning"},"Allocations must sum to 100%."))))}}function Me({allocationDescription:e,forPipelineConfig:t,loadBalancer:a,onChange:n,onRemove:r,serverGroupOptions:s}){const i=e.revisionName?le(s.concat(e.revisionName)):s,o=u.TARGET_LIST.find(t=>t.val===e.target),l=o?o.label:"";return pe.createElement(pe.Fragment,null,pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-7"},t?pe.createElement("input",{value:e.cluster&&e.target?`${l} (${e.cluster})`:"",type:"text",className:"form-control input-sm",readOnly:!0}):pe.createElement("select",{value:e.revisionName||"",className:"form-control input-sm",onChange:e=>n({revisionName:e.target.value})},i.map(e=>pe.createElement("option",{key:e,value:e},e)))),pe.createElement("div",{className:"col-md-3"},pe.createElement("div",{className:"input-group input-group-sm"},pe.createElement("input",{type:"number",value:e.percent,required:!0,className:"form-control input-sm",min:0,max:100,onChange:e=>n({percent:Number(e.target.value)})}),pe.createElement("span",{className:"input-group-addon"},"%"))),pe.createElement("div",{className:"col-md-2"},pe.createElement("button",{type:"button",className:"btn btn-link sm-label",onClick:r},pe.createElement("span",{className:"glyphicon glyphicon-trash"}))))),t&&pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"well col-md-11",style:{paddingTop:5,paddingBottom:10}},pe.createElement("div",{className:"row"},pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Cluster"),pe.createElement("div",{className:"col-md-7",style:{marginBottom:10}},pe.createElement("input",{value:e.cluster||a.name,type:"text",className:"form-control input-sm",readOnly:!0})),pe.createElement("div",{className:"col-md-3 sm-label-right"},"Target"),pe.createElement("div",{className:"col-md-7"},pe.createElement("select",{value:e.target||"",className:"form-control input-sm",onChange:e=>n({target:e.target.value,cluster:a.name})},pe.createElement("option",{value:""},"Select..."),u.TARGET_LIST.map(e=>pe.createElement("option",{key:e.val,value:e.val},e.label)))))))))}function Fe({app:e,loadBalancer:t}){const a=t,n="default"!==a.name,r=()=>{const e=a.serverGroups.map(e=>e.name);if(!(null==e?void 0:e.length))return null;if(e.length>1){const t=e.map(e=>`<li>${e}</li>`).join("");return`<div class="alert alert-warning"><p>Deleting <b>${a.name}</b> will destroy the following server groups:<ul>${t}</ul></p></div>`}return`<div class="alert alert-warning"><p>Deleting <b>${a.name}</b> will destroy <b>${e[0]}</b>.</p></div>`};return pe.createElement(ge,{className:"dropdown",id:"cloudrun-load-balancer-actions-dropdown"},pe.createElement(ge.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},"Load Balancer Actions"),pe.createElement(ge.Menu,null,pe.createElement(ve,{onClick:()=>{De.show({app:e,loadBalancer:a,isNew:!1,forPipelineConfig:!1})}},"Edit Load Balancer"),n?pe.createElement(ve,{onClick:()=>{p.confirm({header:`Really delete ${a.name}?`,buttonText:`Delete ${a.name}`,body:r(),account:a.account,taskMonitorConfig:{application:e,title:`Deleting ${a.name}`},submitMethod:()=>{const t={cloudProvider:a.cloudProvider,loadBalancerName:a.name,credentials:a.account};return o.deleteLoadBalancer(t,e)}})}},"Delete Load Balancer"):pe.createElement(ve,{disabled:!0,title:"You cannot delete a default service."},"Delete Load Balancer")))}function Re({component:e}){return(null==e?void 0:e.url)?pe.createElement(pe.Fragment,null,pe.createElement("dt",null,"HTTPS"),pe.createElement("dd",{className:"small"},pe.createElement("a",{href:e.url,target:"_blank",rel:"noopener noreferrer"},e.url),pe.createElement(h,{className:"copy-to-clipboard copy-to-clipboard-sm",toolTip:"Copy URL to clipboard",text:e.httpsUrl||e.url}))):null}function Ie(e,t){return e.isDisabled!==t.isDisabled?e.isDisabled?1:-1:t.name.localeCompare(e.name)}function Pe({loadBalancer:e}){const t=e;return pe.createElement(r,{heading:"Load Balancer Details",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},pe.createElement("dt",null,"In"),pe.createElement("dd",null,pe.createElement(i,{account:t.account})),pe.createElement("dt",null,"Region"),pe.createElement("dd",null,t.region),!!t.serverGroups.length&&pe.createElement("dt",null,"Server Groups"),!!t.serverGroups.length&&pe.createElement("dd",null,pe.createElement("ul",null,t.serverGroups.slice().sort(Ie).map(e=>pe.createElement("li",{key:e.name},pe.createElement(_,{to:"^.serverGroup",params:{region:e.region,accountId:e.account,serverGroup:e.name,provider:"cloudrun"}},pe.createElement("a",null,e.name))))))))}function Le({loadBalancer:e}){return pe.createElement(r,{heading:"Status",defaultExpanded:!0},pe.createElement(f,{className:"pull-left",container:e.instanceCounts}))}function Ue({loadBalancer:e}){var t,a;const n=e;return pe.createElement(r,{heading:"Traffic Split",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},pe.createElement("ul",null,null==(a=null==(t=n.split)?void 0:t.trafficTargets)?void 0:a.map(e=>pe.createElement("li",{key:e.revisionName},e.revisionName,":",pe.createElement("span",{className:"pull-right"},e.percent))))))}function Oe({loadBalancer:e}){return pe.createElement(r,{heading:"DNS",defaultExpanded:!0},pe.createElement("dl",{className:"dl-narrow"},pe.createElement(Re,{component:e})))}const Ye=({app:e,loadBalancerParams:t,autoClose:a})=>{const n=e.getDataSource("loadBalancers"),{data:r,loaded:s,error:i,refresh:o}=g(n);return{data:he(()=>{if(!s||i)return;const e=ze(r,t);if(e)return e;a()},[s,i,r,t.name,t.accountId,t.region,a]),loading:!s,error:i||null,refetch:async()=>o()}};function ze(e,t){return e.find(e=>e.name===t.name&&e.account===t.accountId&&e.region===t.region)}class Ve extends pe.Component{constructor(){super(...arguments),this.onChangeBinding=(e,t)=>{const a=(this.props.bindings||[]).slice(0);a[e]=t,this.props.onChangeBindings(a)},this.onRemoveBinding=e=>{const t=(this.props.bindings||[]).slice(0);t.splice(e,1),this.props.onChangeBindings(t)}}render(){const{stage:e,pipeline:t,bindings:a}=this.props,n=(n,r)=>{const s=(r?r.expectedArtifactId:"new")||r.artifact&&r.artifact.id;return pe.createElement("div",{className:"row",key:s},pe.createElement("div",{className:"col-md-10"},pe.createElement(v,{pipeline:t,stage:e,expectedArtifactId:r&&r.expectedArtifactId,artifact:!!r&&r.artifact,onArtifactEdited:e=>this.onChangeBinding(n,{artifact:e}),onExpectedArtifactSelected:e=>this.onChangeBinding(n,{expectedArtifactId:e.id}),excludedArtifactIds:a.map(e=>e.expectedArtifactId),excludedArtifactTypePatterns:[E.FRONT50_PIPELINE_TEMPLATE]})),r&&pe.createElement("div",{className:"col-md-2"},pe.createElement("a",{className:"glyphicon glyphicon-trash",onClick:()=>this.onRemoveBinding(n)})))};return pe.createElement(pe.Fragment,null,a.map((e,t)=>n(t,e)),n(a.length))}}var je=(e=>(e.TEXT="text",e.ARTIFACT="artifact",e))(je||{});function Ke({accounts:e,onAccountSelect:t,selectedAccount:a}){return pe.createElement("div",{className:"form-horizontal"},pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Account ",pe.createElement(d,{id:"cloudrun.manifest.account"})),pe.createElement("div",{className:"col-md-8"},pe.createElement(b,{value:a,onChange:e=>t(e.target.value),readOnly:!1,accounts:e,provider:"cloudrun"}))))}pe.Component;class He extends pe.Component{render(){const e=this.props.application?this.props.application:"",t=this.props.stack?`-${this.props.stack}`:"",a=this.props.details?`-${this.props.details}`:"";return pe.createElement("pre",{style:{textAlign:"center"}},pe.createElement("p",null," Your server group will be in the cluster:"),pe.createElement("p",null,pe.createElement("b",null,e,t,a)))}}class We extends pe.Component{constructor(e){super(e),this.excludedManifestArtifactTypes=[E.FRONT50_PIPELINE_TEMPLATE,E.MAVEN_FILE],this.getSourceOptions=()=>ce([je.TEXT,je.ARTIFACT],e=>({label:me(e),value:e})),this.handleRawManifestChange=(e,t)=>{this.setState({rawManifest:e}),this.props.formik.setFieldValue("manifests",t)},this.onManifestArtifactSelected=e=>{this.props.formik.setFieldValue("manifestArtifactId",e),this.props.formik.setFieldValue("manifestArtifact",null)},this.onManifestArtifactEdited=e=>{this.props.formik.setFieldValue("manifestArtifactId",null),this.props.formik.setFieldValue("manifestArtifact",e)},this.getRequiredArtifacts=()=>{const{requiredArtifactIds:e,requiredArtifacts:t}=this.props.formik.values;return(e||[]).map(e=>({expectedArtifactId:e})).concat(t||[])},this.onRequiredArtifactsChanged=e=>{this.props.formik.setFieldValue("requiredArtifactIds",e.filter(e=>e.expectedArtifactId).map(e=>e.expectedArtifactId)),this.props.formik.setFieldValue("requiredArtifacts",e.filter(e=>e.artifact))};const t=this.props.formik.values,a=se(e.formik.values,"manifests"),n=se(e.formik.values,"source")===je.TEXT;this.state={rawManifest:!de(a)&&n?k(a):"",application:this.props.application.name,stack:se(t,"stack"),details:se(t,"details")}}render(){const e=this.props.formik.values;return pe.createElement("div",{className:"form-horizontal"},pe.createElement("h4",null,"Basic Settings"),pe.createElement(Ke,{accounts:this.props.accounts,onAccountSelect:e=>this.props.formik.setFieldValue("account",e),selectedAccount:e.account}),pe.createElement(C,{label:"Application"},pe.createElement("input",{className:"form-control input-sm",type:"text",value:this.props.application.name,onChange:e=>this.props.formik.setFieldValue("application",e.target.value),disabled:!0})),pe.createElement(C,{label:"Stack"},pe.createElement("input",{className:"form-control input-sm",type:"text",value:e.stack,onChange:e=>this.props.formik.setFieldValue("stack",e.target.value)})),pe.createElement(C,{label:"Details"},pe.createElement("input",{className:"form-control input-sm",type:"text",value:e.details,onChange:e=>this.props.formik.setFieldValue("details",e.target.value)})),pe.createElement(He,{application:this.props.application.name,stack:e.stack,details:e.details}),pe.createElement("hr",null),pe.createElement("h4",null,"Manifest Configuration"),pe.createElement(C,{label:"Manifest Source",helpKey:"cloudrun.manifest.source"},pe.createElement(N,{options:this.getSourceOptions(),onChange:e=>this.props.formik.setFieldValue("source",e.target.value),value:e.source})),e.source===je.TEXT&&pe.createElement(C,{label:"Manifest"},pe.createElement(y,{onChange:this.handleRawManifestChange,value:this.state.rawManifest})),e.source===je.ARTIFACT&&pe.createElement(pe.Fragment,null,pe.createElement(A,{artifact:e.manifestArtifact,excludedArtifactTypePatterns:this.excludedManifestArtifactTypes,expectedArtifactId:e.manifestArtifactId,helpKey:"cloudrun.manifest.expectedArtifact",label:"Manifest Artifact",onArtifactEdited:this.onManifestArtifactEdited,onExpectedArtifactSelected:e=>this.onManifestArtifactSelected(e.id),pipeline:this.props.pipeline,stage:e}),pe.createElement(C,{label:"Expression Evaluation",helpKey:"cloudrun.manifest.skipExpressionEvaluation"},pe.createElement(S,{checked:!0===e.skipExpressionEvaluation,onChange:e=>this.props.formik.setFieldValue("skipExpressionEvaluation",e.target.checked),text:"Skip SpEL expression evaluation"}))),pe.createElement(C,{label:"Required Artifacts to Bind",helpKey:"cloudrun.manifest.requiredArtifactsToBind"},pe.createElement(Ve,{bindings:this.getRequiredArtifacts(),onChangeBindings:this.onRequiredArtifactsChanged,pipeline:this.props.pipeline,stage:e})))}}class $e extends pe.Component{constructor(e){super(e),this.destroy$=new Ee,this.fetchAccounts=()=>{be(w.getAllAccountDetailsForProvider("cloudrun")).pipe(Ce(this.destroy$)).subscribe(e=>{this.setState({accounts:e})})},this.state={accounts:[]};const{stage:t}=e,a=ae(t);a.source||(a.source=je.TEXT),a.skipExpressionEvaluation||(a.skipExpressionEvaluation=!1),a.cloudProvider||(a.cloudProvider="cloudrun"),a.moniker||(a.moniker={}),a.moniker.app||(a.moniker.app=e.application.name),this.stage=a}componentDidMount(){this.fetchAccounts()}componentWillUnmount(){this.destroy$.next()}render(){return pe.createElement(B,{...this.props,stage:this.stage,onChange:this.props.updateStage,render:e=>pe.createElement(We,{...e,accounts:this.state.accounts})})}}const qe="redblack",Xe="strategy.spinnaker.io/max-version-history",Qe={available:"success",stable:"success",paused:"warn",failed:"danger"};class Ze extends pe.Component{render(){const{manifest:e}=this.props;return null==e||null==e.status?null:Object.keys(e.status).map((t,a)=>{const n=e.status[t],r=Qe[t]||"",s=n.state,i=!s&&n.message;return pe.createElement("span",{key:a},s&&pe.createElement("span",{title:n.message,className:`pill ${r}`},t),i&&pe.createElement("span",{title:n.message,className:"pill warn"},t),pe.createElement("span",null," "))})}}const _e="cloudrunResource";class Je extends pe.Component{constructor(e){super(e),this.spinnakerKindStateMap={serverGroupManagers:"serverGroupManager",serverGroups:"serverGroup"},this.state={url:""},this.loadUrl()}canOpen(){return!!this.props.manifest.manifest&&!!this.state.url}spinnakerKindFromCloudrunKind(e,t){return t[Object.keys(t).find(t=>t.toLowerCase()===e.toLowerCase())]}resourceRegion(){return ue(se(this.props,["manifest","manifest","metadata","annotations","artifact.spinnaker.io/location"],""))}getStateParams(e){const t=this.props.manifest.manifest.kind.toLowerCase(),a=this.props.manifest.manifest.metadata.name,n=this.resourceRegion(),r={accountId:this.props.accountId,provider:"cloudrun",region:n,reg:n,[e]:`${t} ${a}`};return r.region||"namespace"!==t||e!==_e||(r.region=a),r.region&&""!==r.region||(r.region="_"),r}loadUrl(){const e=se(this.props,["manifest","manifest","kind"],""),{accountId:t}=this.props;w.getAccountDetails(t).then(t=>{const a=this.spinnakerKindFromCloudrunKind(e,t.spinnakerKindMap),n=this.spinnakerKindStateMap[a]||_e,r=this.getStateParams(n),s=this.props.stateService.href(`home.applications.application.insight.clusters.${n}`,r);this.setState({url:s})})}render(){return this.canOpen()?pe.createElement("a",{href:this.state.url,className:"clickable"},this.props.linkName):null}}const et=m(Je);class tt extends pe.Component{pillStyle(e){return"Warning"===e.type?"alert":"Normal"===e.type?"success":""}render(){if(!this.props.manifest)return null;if(this.props.manifest&&(!this.props.manifest.events||0===this.props.manifest.events.length))return pe.createElement("div",null,"No recent events found - Cloud Run does not store events for long.");const{events:e}=this.props.manifest,t=ue(se(this.props.manifest,["manifest","metadata","annotations","artifact.spinnaker.io/location"],""));return e.map((a,n)=>{const r=se(a,"firstTimestamp",""),s=se(a,"lastTimestamp","");let i=0,o=0;return r&&(i=ye.fromISO(r).toMillis()),s&&(o=ye.fromISO(s).toMillis()),pe.createElement("div",{key:se(a,["metadata","uid"],String(n)),className:"info"},pe.createElement("div",{className:"horizontal"},a.count&&pe.createElement("div",{className:`pill ${this.pillStyle(a)}`},a.count," × ",pe.createElement("b",null,a.reason))),(a.firstTimestamp||a.lastTimestamp)&&pe.createElement("div",null,a.firstTimestamp===a.lastTimestamp&&pe.createElement("div",null,pe.createElement("i",null,x(i))),a.firstTimestamp!==a.lastTimestamp&&pe.createElement("div",null,pe.createElement("div",null,"First Occurrence: ",pe.createElement("i",null,x(i))),pe.createElement("div",null,"Last Occurrence: ",pe.createElement("i",null,x(o))))),pe.createElement("div",null,a.message),pe.createElement("div",null,pe.createElement(T,{account:this.props.manifest.account,location:t,podNamesProviders:[new D(this.props.manifest,a)],linkName:"Console Output (Raw)"})),n!==e.length-1&&pe.createElement("br",null))})}}function at(e,t){void 0===t&&(t={});var a=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===a&&n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}function nt({account:e,manifest:t}){return pe.createElement(pe.Fragment,null,pe.createElement("dl",{className:"manifest-status",key:"manifest-status"},pe.createElement("dt",null,t.manifest.kind),pe.createElement("dd",null,pe.createElement(h,{displayText:!0,text:t.manifest.metadata.name,toolTip:`Copy ${t.manifest.metadata.name}`})," ",pe.createElement(Ze,{manifest:t}))),pe.createElement("div",{className:"manifest-support-links",key:"manifest-support-links"},pe.createElement(G,{linkName:"YAML",manifestText:Ne(t.manifest),modalTitle:t.manifest.metadata.name}),pe.createElement(et,{linkName:"Details",manifest:t,accountId:e})),pe.createElement("div",{className:"manifest-events pad-left",key:"manifest-events"},pe.createElement(tt,{manifest:t})))}function rt(e){return!!e&&"object"==typeof e&&"remote/map/base64"===e.type&&"string"==typeof e.reference}at("dl.manifest-status {\n display: block;\n margin: 0;\n}\ndl.manifest-status dt,\ndl.manifest-status dd {\n display: inline-block;\n}\ndl.manifest-status dt {\n margin-right: 4px;\n}\n.manifest-support-links {\n margin: 0 0 1em;\n}\n.manifest-support-links a {\n margin-right: 2em;\n}\n.manifest-events {\n margin: 0 0 2em;\n}\n");const st=class e{static subscribe(t,a,n){return e.updateManifest(a,n),t.onRefresh(()=>e.updateManifest(a,n))}static updateManifest(e,t){M.getManifest(e.account,e.location,e.name).then(e=>t(e))}static manifestIdentifier(e){const t=e.kind.toLowerCase(),a=(e.metadata.namespace||"_").toLowerCase(),n=e.metadata.name.toLowerCase();return`${a} ${t} ${(e.apiVersion||"_").toLowerCase()} ${n}`}static stageManifestToManifestParams(t,a){return{account:a,name:e.scopedKind(t)+" "+t.metadata.name,location:null==t.metadata.namespace?"_":t.metadata.namespace}}static apiGroup(e){const t=(e.apiVersion||"_").split("/");return t.length<2?"":t[0]}static isCRDGroup(t){return!e.BUILT_IN_GROUPS.includes(e.apiGroup(t))}static scopedKind(t){return e.isCRDGroup(t)?t.kind+"."+e.apiGroup(t):t.kind}};st.BUILT_IN_GROUPS=["","core","batch","apps","extensions","storage.k8s.io","apiextensions.k8s.io","apiregistration.k8s.io","policy","scheduling.k8s.io","settings.k8s.io","authorization.k8s.io","authentication.k8s.io","rbac.authorization.k8s.io","certifcates.k8s.io","networking.k8s.io"];let it=st;class ot extends pe.Component{constructor(e){super(e),this.state={subscriptions:[],manifestIds:[]}}componentDidMount(){this.componentDidUpdate(this.props,this.state)}componentWillUnmount(){this.unsubscribeAll()}componentDidUpdate(e,t){const a=se(this.props.stage,["context","outputs.manifests"],[]).filter(e=>!!e).filter(e=>!rt(e)),n=a.map(e=>it.manifestIdentifier(e)).sort();if(t.manifestIds.join("")!==n.join("")){this.unsubscribeAll();const e=a.map(e=>{const t=it.manifestIdentifier(e);return{id:t,unsubscribe:this.subscribeToManifestUpdates(t,e),manifest:this.stageManifestToIManifest(e,this.props.stage.context.account)}});this.setState({subscriptions:e,manifestIds:n})}}subscribeToManifestUpdates(e,t){const a=it.stageManifestToManifestParams(t,this.props.stage.context.account);return it.subscribe(this.props.application,a,t=>{const a=this.state.subscriptions.findIndex(t=>t.id===e);if(-1!==a){const e={...this.state.subscriptions[a],manifest:t},n=[...this.state.subscriptions];n[a]=e,this.setState({subscriptions:n})}})}unsubscribeAll(){this.state.subscriptions.forEach(({unsubscribe:e})=>e())}get storedManifestRefs(){return se(this.props.stage,["context","outputs.manifests"],[]).filter(e=>!!e).filter(rt)}stageManifestToIManifest(e,t){return{name:se(e,"metadata.name",""),moniker:null,account:t,cloudProvider:"cloudrun",location:se(e,"metadata.namespace",""),manifest:e,status:{},artifacts:[],events:[]}}render(){const{name:e,current:t,stage:a}=this.props,n=this.state.subscriptions.filter(e=>!!e.manifest).map(e=>e.manifest);return pe.createElement(F,{name:e,current:t},pe.createElement(R,{stage:a,message:a.failureMessage}),n&&pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-12"},pe.createElement("div",{className:"well alert alert-info"},n.map(e=>{const t=e.manifest.metadata.uid||it.manifestIdentifier(e.manifest);return pe.createElement(nt,{key:t,manifest:e,account:a.context.account})})))),!!this.storedManifestRefs.length&&pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-12"},pe.createElement("div",{className:"well alert alert-info"},this.storedManifestRefs.map((e,t)=>pe.createElement("div",{key:t},pe.createElement(G,{linkName:"Load Manifest Details",modalTitle:"Manifest",manifestUri:e.reference.replace(/^ref?:\/\//,"")})))))))}}function lt(e){const{current:t,name:a,stage:n}=e,r=(n.context||{}).loadBalancers||[];return pe.createElement(F,{name:a,current:t},pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-12"},pe.createElement("table",{className:"table table-condensed"},pe.createElement("thead",null,pe.createElement("tr",null,pe.createElement("th",null,"Account"),pe.createElement("th",null,"Name"),pe.createElement("th",null,"Region"),pe.createElement("th",null,"Allocations"))),pe.createElement("tbody",null,r.map(e=>{var t;return pe.createElement("tr",{key:ct(e)},pe.createElement("td",null,pe.createElement(i,{account:e.credentials||e.account})),pe.createElement("td",null,e.name),pe.createElement("td",null,e.region),pe.createElement("td",null,function(e=[]){if(!e.length)return null;return pe.createElement("ul",{className:"list-unstyled no-margin"},e.map((e,t)=>pe.createElement("li",{key:`${e.revisionName||e.target||e.cluster||"allocation"}:${t}`},e.revisionName||e.target||e.cluster||"Allocation",":"," ",pe.createElement("span",null,e.percent,"%"))))}(null==(t=e.splitDescription)?void 0:t.allocationDescriptions)))}))))),pe.createElement(R,{stage:n,message:n.failureMessage}))}function ct(e){return[e.name||"",e.credentials||e.account||"",e.region||""].join(":")}ot.title="deployStatus",I.pipeline.registerStage({label:"Deploy (Cloud Run)",description:"Deploy a Cloud Run manifest yaml/json file.",key:"deployCloudrunManifest",cloudProvider:"cloudrun",component:$e,executionDetailsSections:[ot,P,L],producesArtifacts:!0,supportsCustomTimeout:!0,validators:[{type:"requiredField",fieldName:"account",fieldLabel:"Account"},{type:"requiredField",fieldName:"source",fieldLabel:"Source"},{type:"custom",validate:(e,t)=>{const a=se(t,"trafficManagement.enabled",!1),n=se(t,"trafficManagement.options.services",[]);if(a&&de(n))return"Select at least one <strong>Service</strong> to enable Spinnaker-managed rollout strategy options.";if(a&&t.source===je.TEXT){const e=se(t,"manifests",[]).filter(e=>"ReplicaSet"===e.kind),a=se(t,"trafficManagement.options.strategy"),n=parseInt(se(e,[0,"metadata","annotations",Xe]),10);if(a===qe&&n<2)return`The max version history specified in your manifest conflicts with the behavior of the Red/Black rollout strategy. Please update your <strong>${Xe}</strong> annotation to a value greater than or equal to 2.`}return null}}],accountExtractor:e=>e.account?[e.account]:[],configAccountExtractor:e=>e.account?[e.account]:[],artifactExtractor:O.accumulateArtifacts(["manifestArtifactId","requiredArtifactIds"]),artifactRemover:U.removeArtifactFromFields(["manifestArtifactId","requiredArtifactIds"])}),lt.title="editLoadBalancerConfig";class mt extends pe.Component{constructor(){super(...arguments),this.addLoadBalancer=()=>{dt.show({application:this.props.application}).then(e=>{this.props.updateStage({loadBalancers:[...this.props.stage.loadBalancers||[],e]})}).catch(()=>{})},this.editLoadBalancer=e=>{De.show({app:this.props.application,loadBalancer:ae(this.props.stage.loadBalancers[e]),isNew:!1,forPipelineConfig:!0}).then(t=>{const a=[...this.props.stage.loadBalancers];a[e]=t,this.props.updateStage({loadBalancers:a})}).catch(()=>{})},this.removeLoadBalancer=e=>{const t=[...this.props.stage.loadBalancers];t.splice(e,1),this.props.updateStage({loadBalancers:t})}}componentDidMount(){this.props.updateStage({loadBalancers:this.props.stage.loadBalancers||[],cloudProvider:"cloudrun"})}render(){const{pipeline:e,stage:t}=this.props;return e.strategy?null:pe.createElement("div",{className:"well well-sm clearfix"},pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-12"},pe.createElement("h4",{className:"text-left"},"Load Balancers"))),pe.createElement("div",{className:"row"},pe.createElement("div",{className:"col-md-12"},pe.createElement("table",{className:"table table-condensed"},pe.createElement("thead",null,pe.createElement("tr",null,pe.createElement("th",null,"Account"),pe.createElement("th",null,"Name"),pe.createElement("th",null,"Region"),pe.createElement("th",null,"Actions"))),pe.createElement("tbody",null,(t.loadBalancers||[]).map((e,t)=>pe.createElement("tr",{key:`${e.credentials||e.account}:${e.name}:${e.region}`},pe.createElement("td",null,pe.createElement(i,{account:e.credentials||e.account})),pe.createElement("td",null,e.name),pe.createElement("td",null,e.region),pe.createElement("td",{className:"condensed-actions"},pe.createElement("button",{type:"button",className:"btn btn-sm btn-link",onClick:()=>this.editLoadBalancer(t)},pe.createElement("span",{className:"glyphicon glyphicon-edit",title:"Edit"})),pe.createElement("button",{type:"button",className:"btn btn-sm btn-link pad-left",onClick:()=>this.removeLoadBalancer(t)},pe.createElement("span",{className:"glyphicon glyphicon-trash",title:"Remove"})))))),pe.createElement("tfoot",null,pe.createElement("tr",null,pe.createElement("td",{colSpan:8},pe.createElement("button",{type:"button",className:"btn btn-block btn-sm add-new",onClick:this.addLoadBalancer},pe.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add load balancer"))))))))}}class dt extends pe.Component{constructor(){super(...arguments),this.mounted=!1,this.state={loading:!0,loadBalancers:[]},this.submit=()=>{De.show({app:this.props.application,loadBalancer:ae(this.state.selectedLoadBalancer),isNew:!1,forPipelineConfig:!0}).then(this.props.closeModal).catch(()=>{})}}static show(e){return c.show(dt,e)}componentDidMount(){this.mounted=!0,this.props.application.loadBalancers.ready().then(()=>{if(!this.mounted)return;const e=this.props.application.loadBalancers.data.filter(e=>"cloudrun"===e.cloudProvider);this.setState({loadBalancers:e,selectedLoadBalancer:e[0],loading:!1})}).catch(()=>{this.mounted&&this.setState({loading:!1})})}componentWillUnmount(){this.mounted=!1}render(){const{dismissModal:e}=this.props,{loading:t,loadBalancers:a,selectedLoadBalancer:n}=this.state;return pe.createElement("div",null,pe.createElement("div",{className:"modal-header"},pe.createElement("button",{type:"button",className:"close",onClick:e},pe.createElement("span",null,"×")),pe.createElement("h4",{className:"modal-title"},"Select Load Balancer")),pe.createElement("div",{className:"modal-body"},t&&pe.createElement("div",{style:{height:200},className:"horizontal center middle"},"Loading..."),!t&&0===a.length&&pe.createElement(Se,{showCreateMessage:!0}),!t&&a.length>0&&pe.createElement("div",{className:"form-horizontal"},pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},pe.createElement("b",null,"Load Balancer")),pe.createElement("div",{className:"col-md-7"},pe.createElement("select",{className:"form-control input-sm",value:ct(n),onChange:e=>this.setState({selectedLoadBalancer:a.find(t=>ct(t)===e.target.value)})},a.map(e=>pe.createElement("option",{key:ct(e),value:ct(e)},function(e){return[e.account,e.name,e.region].filter(Boolean).join(" ")}(e)))))))),pe.createElement("div",{className:"modal-footer"},pe.createElement("button",{type:"button",className:"btn btn-default",onClick:e},"Cancel"),a.length>0&&pe.createElement("button",{type:"button",className:"btn btn-primary",onClick:this.submit},pe.createElement("span",{className:"far fa-check-circle"})," Edit")))}}const ut={label:"Edit Load Balancer (Cloud Run)",description:"Edits a load balancer",key:"upsertCloudrunLoadBalancers",cloudProvider:"cloudrun",component:mt,executionDetailsSections:[lt,P],validators:[]};I.pipeline.registerStage(ut);const pt=Y.providers.cloudrun||{defaults:{}};pt&&(pt.resetToOriginal=Y.resetProvider("cloudrun"));var ht=(e=>(e.TEXT="text",e.ARTIFACT="artifact",e))(ht||{});const ft=e=>{switch(e){case"createPipeline":return"Add";case"editPipeline":return"Done";default:return"Create"}};class gt{buildNewServerGroupCommand(e){return vt.buildNewServerGroupCommand(e,"cloudrun","create")}buildNewServerGroupCommandForPipeline(e,t){return vt.buildNewServerGroupCommandForPipeline(e,t)}buildServerGroupCommandFromPipeline(e,t,a,n){return vt.buildServerGroupCommandFromPipeline(e,t,a,n)}}class vt{static ServerGroupCommandIsValid(e){return!!e.moniker&&!!e.moniker.app}static copyAndCleanCommand(e){return ae(e)}static buildNewServerGroupCommandForPipeline(e,t){const a=this.buildNewServerGroupCommand({name:t.application},"cloudrun","createPipeline");return a.viewState={...a.viewState,pipeline:t,requiresTemplateSelection:!0,stage:e},a}static getExpectedArtifacts(e){return e.expectedArtifacts||[]}static buildServerGroupCommandFromPipeline(e,t,a,n){return vt.buildNewServerGroupCommand(e,"cloudrun","editPipeline").then(e=>e={...e,...t,backingData:{...e.metadata.backingData.backingData,expectedArtifacts:vt.getExpectedArtifacts(n)},credentials:t.account||e.metadata.backingData.credentials,viewState:{...e.metadata.backingData.viewState,stage:a,pipeline:n}})}static getCredentials(e){const t=(e||[]).map(e=>e.name),a=pt.defaults.account;return t.includes(a)?a:t[0]}static getRegion(e,t){const a=e.find(e=>e.name===t);return a?a.region:null}static buildNewServerGroupCommand(e,t,a){const n={accounts:w.getAllAccountDetailsForProvider("cloudrun"),artifactAccounts:w.getArtifactAccounts()};return Promise.all([n.accounts,n.artifactAccounts]).then(([n,r])=>{const s={accounts:n,artifactAccounts:r},i=n.some(e=>e.name===t)?n.find(e=>e.name===t).name:n.length?n[0].name:null,o={mode:a,submitButtonLabel:ft(a),disableStrategySelection:"create"===a},l=i||this.getCredentials(n),c=this.getRegion(s.accounts,l),m="cloudrun";return{command:{application:e.name,configFiles:[""],cloudProvider:m,selectedProvider:m,provider:m,region:c,credentials:l,gitCredentialType:"NONE",manifest:null,sourceType:"git",configArtifacts:[],interestingHealthProviderNames:[],fromArtifact:!1,account:i,viewState:o},metadata:{backingData:s}}})}}const Et=m(function({accounts:e,onAccountSelect:t,selectedAccount:a,formik:n,onEnterStack:r,detailsChanged:s,app:i,stateService:o}){const{values:l}=n,{stack:c="",freeFormDetails:m}=l,u=z.getClusterName(i.name,c,m),p=!i.clusters.find(e=>e.name===u),h=i.serverGroups.data.filter(e=>e.cluster===u&&e.account===l.command.credentials&&e.region===l.command.region).sort((e,t)=>e.createdTime-t.createdTime),f=h.length?h.pop():null;return pe.createElement("div",{className:"form-horizontal"},pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),pe.createElement("div",{className:"col-md-7"},pe.createElement(b,{value:a,onChange:e=>t(e.target.value),readOnly:!1,accounts:e,provider:"cloudrun"}))),pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",pe.createElement(d,{id:"cloudrun.serverGroup.stack"})),pe.createElement("div",{className:"col-md-7"},pe.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:c,onChange:e=>r(e.target.value)}))),pe.createElement("div",{className:"form-group"},pe.createElement("div",{className:"col-md-3 sm-label-right"},"Detail ",pe.createElement(d,{id:"cloudrun.serverGroup.detail"})),pe.createElement("div",{className:"col-md-7"},pe.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:m,onChange:e=>s(e.target.value)}))),!l.command.viewState.hideClusterNamePreview&&pe.createElement(V,{createsNewCluster:p,latestServerGroupName:null==f?void 0:f.name,mode:l.command.viewState.mode,namePreview:u,navigateToLatestServerGroup:()=>{const{values:e}=n,t={provider:e.command.selectedProvider,accountId:f.account,region:f.region,serverGroup:f.name};o.is("home.applications.application.insight.clusters")?o.go(".serverGroup",t):o.go("^.serverGroup",t)}}))});class bt extends pe.Component{constructor(){super(...arguments),this.accountUpdated=e=>{const{formik:t}=this.props;t.values.command.account=e,t.setFieldValue("account",e)},this.stackChanged=e=>{const{setFieldValue:t,values:a}=this.props.formik;a.command.stack=e,t("stack",e)},this.freeFormDetailsChanged=e=>{const{setFieldValue:t,values:a}=this.props.formik;a.command.freeFormDetails=e,t("freeFormDetails",e)}}render(){var e,t,a;const{formik:n,app:r}=this.props;return pe.createElement(Et,{accounts:(null==(t=null==(e=n.values.metadata)?void 0:e.backingData)?void 0:t.accounts)||[],onAccountSelect:this.accountUpdated,selectedAccount:(null==(a=n.values.command)?void 0:a.account)||"",onEnterStack:this.stackChanged,formik:n,detailsChanged:this.freeFormDetailsChanged,app:r})}}function kt({configFiles:e,onEnterConfig:t}){const[a,n]=fe(e);return pe.createElement("div",{className:"form-horizontal"},pe.createElement("div",{className:"form-group"},a.map((e,r)=>pe.createElement(pe.Fragment,null,pe.createElement("div",{className:"col-md-3 sm-label-right"},"Service Yaml",pe.createElement(d,{id:"cloudrun.serverGroup.configFiles"})," "),pe.createElement("div",{className:"col-md-8",key:r},pe.createElement(j,{name:"text"+r,value:e,rows:10,onChange:e=>function(e,r){if(9===e.which){e.preventDefault();const t=e.target.selectionStart,a=e.target.value;e.target.value=`${a.substring(0,t)} ${a.substring(t)}`,e.target.selectionStart+=2}const s=[...a];s[r]=e.target.value,n(s),t(s)}(e,r)}))))))}class Ct extends pe.Component{constructor(){super(...arguments),this.configUpdated=e=>{const{formik:t}=this.props;t.values.command.configFiles=e,t.setFieldValue("configFiles",e)}}render(){const{formik:e}=this.props;return pe.createElement(kt,{configFiles:e.values.configFiles||e.values.command.configFiles,onEnterConfig:this.configUpdated})}}class Nt extends pe.Component{constructor(e){super(e),this._isUnmounted=!1,this.onTaskComplete=()=>{this.clearApplicationRefreshSubscription(),this.applicationRefreshUnsubscribe=this.props.application.serverGroups.onNextRefresh(this.onApplicationRefresh),this.props.application.serverGroups.refresh()},this.onApplicationRefresh=()=>{if(this.clearApplicationRefreshSubscription(),this._isUnmounted)return;const{command:e}=this.props,{taskMonitor:t}=this.state,a=t.task.execution.stages.find(e=>"cloneServerGroup"===e.type);if(a&&a.context["deploy.server.groups"]){const t=a.context["deploy.server.groups"][e.command.region];if(t){const a={serverGroup:t,accountId:e.command.credentials,region:e.command.region,provider:"cloudrun"};let n="^.^.^.clusters.serverGroup";this.props.stateService.includes("**.clusters.serverGroup")&&(n="^.serverGroup"),this.props.stateService.includes("**.clusters.cluster.serverGroup")&&(n="^.^.serverGroup"),this.props.stateService.includes("**.clusters")&&(n=".serverGroup"),this.props.stateService.go(n,a)}}},this.clearApplicationRefreshSubscription=()=>{var e;null==(e=this.applicationRefreshUnsubscribe)||e.call(this),this.applicationRefreshUnsubscribe=void 0},this.submit=e=>{const t=vt.copyAndCleanCommand(e.command);if(!("editPipeline"===t.viewState.mode||"createPipeline"===t.viewState.mode)){const e=()=>this.context.services.serverGroupWriter.cloneServerGroup(t,this.props.application);return this.state.taskMonitor.submit(e),null}this.props.closeModal&&this.props.closeModal(t)},e.command||vt.buildNewServerGroupCommand(e.application,"cloudrun","create").then(e=>{Object.assign(this.state.command,e),this.setState({loaded:!0})}),this.state={loaded:!!e.command,command:e.command||{},taskMonitor:new l({application:e.application,title:("Create"===e.command.command.viewState.submitButtonLabel?"Creating":"Updating")+" your Server Group",onDismiss:()=>this.props.dismissModal(),onTaskComplete:this.onTaskComplete})}}static show(e,t){return c.show(yt,e,{dialogClassName:"wizard-modal modal-lg"},t)}componentWillUnmount(){this._isUnmounted=!0,this.clearApplicationRefreshSubscription()}render(){const{dismissModal:e,application:t}=this.props,{loaded:a,taskMonitor:n,command:r}=this.state,s=this.state.command.command.viewState.submitButtonLabel;return pe.createElement(K,{heading:("Add"===s||"Create"===s?"Create New":"Update")+" Server Group",initialValues:r,loading:!a,taskMonitor:n,dismissModal:e,closeModal:this.submit,submitButtonLabel:s,render:({formik:e,nextIdx:a,wizard:n})=>pe.createElement(pe.Fragment,null,pe.createElement(H,{label:"Basic Settings",wizard:n,order:a(),render:({innerRef:a})=>pe.createElement(bt,{ref:a,formik:e,app:t})}),pe.createElement(H,{label:"Service Yaml",wizard:n,order:a(),render:({innerRef:t})=>pe.createElement(Ct,{ref:t,formik:e})}))})}}Nt.contextType=W,Nt.defaultProps={closeModal:$,dismissModal:$};const yt=Object.assign(m(Nt),{show:Nt.show});class At{}function St({app:e,serverGroup:t,stateService:a}){var n,r,s;const{serverGroupWriter:i}=q(),o=t,l=Boolean(o&&!(null==(n=o.tags)?void 0:n.isLatest)&&o.disabled);return pe.createElement(ge,{className:"dropdown",id:"cloudrun-server-group-actions-dropdown"},pe.createElement(ge.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},"Server Group Actions"),pe.createElement(ge.Menu,null,(null==(r=o.tags)?void 0:r.isLatest)&&pe.createElement(ve,{disabled:!0,title:"You cannot destroy the latest server group (revision). You may be able to delete this server group's load balancer."},"Destroy"),l&&pe.createElement(ve,{onClick:()=>{const t={name:o.name,accountId:o.account,region:o.region},n={application:e,title:`Destroying ${o.name}`,onTaskComplete:()=>{a.includes("**.serverGroup",t)&&a.go("^")}},r={header:`Really destroy ${o.name}?`,buttonText:`Destroy ${o.name}`,account:o.account,taskMonitorConfig:n,submitMethod:t=>i.destroyServerGroup(o,e,t),askForReason:!0,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:At.PLATFORM,interestingHealthProviderNames:[]};e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(r.interestingHealthProviderNames=[At.PLATFORM]),p.confirm(r)}},"Destroy"),!l&&!(null==(s=o.tags)?void 0:s.isLatest)&&pe.createElement(ve,{disabled:!0,title:"You cannot destroy this server group while it is receiving traffic. You may be able to delete this server group's load balancer."},"Destroy")))}At.PLATFORM="Cloud Run Service";const wt=m(St),Bt=(e,t)=>{const{app:a,serverGroup:n}=e;return new ke(e=>{X.getServerGroup(a.name,n.accountId,n.region,n.name).then(r=>{let s=a.serverGroups.data.find(e=>e.name===n.name&&e.account===n.accountId&&e.region===n.region);s||a.loadBalancers.data.some(e=>e.account===n.accountId&&e.serverGroups.some(e=>e.name===n.name&&(s=e,!0)));const i={...r,...s};if(de(i))return t(),void e.complete();e.next(i)},()=>{t(),e.complete()})})};function xt({serverGroup:e}){return pe.createElement(r,{heading:"Server Group Information",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},pe.createElement("dt",null,"Created"),pe.createElement("dd",null,s(e.createdTime)),pe.createElement("dt",null,"In"),pe.createElement("dd",null,pe.createElement(i,{account:e.account})),pe.createElement("dt",null,"Region"),pe.createElement("dd",null,e.region)))}function Tt({serverGroup:e}){var t;const a=e.capacity||{},n=(null==(t=e.instances)?void 0:t.length)||0;return pe.createElement(r,{heading:"Size",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},a.min===a.max?pe.createElement(pe.Fragment,null,pe.createElement("dt",null,"Min/Max"),pe.createElement("dd",null,a.min)):pe.createElement(pe.Fragment,null,pe.createElement("dt",null,"Min"),pe.createElement("dd",null,a.min),pe.createElement("dt",null,"Max"),pe.createElement("dd",null,a.max)),pe.createElement("dt",null,"Current"),pe.createElement("dd",null,n)))}function Dt({serverGroup:e}){return pe.createElement(r,{heading:"Health",defaultExpanded:!0},pe.createElement("dl",{className:"dl-horizontal dl-narrow"},pe.createElement("dt",null,"Instances"),pe.createElement("dd",null,pe.createElement(f,{container:e.instanceCounts,className:"pull-left"}))))}class Gt{normalizeServerGroup(e){return Promise.resolve(e)}convertServerGroupCommandToDeployConfiguration(e){return new Mt(e)}}class Mt{constructor(e){this.cloudProvider="cloudrun",this.provider="cloudrun",this.credentials=e.credentials,this.account=e.credentials,this.application=e.application,this.stack=e.stack,this.freeFormDetails=e.freeFormDetails,this.region=e.region,this.strategy=e.strategy,this.type=e.type,this.fromArtifact=e.fromArtifact,this.gitCredentialType=e.gitCredentialType,this.configFiles=e.configFiles,this.sourceType=e.sourceType,this.interestingHealthProviderNames=e.interestingHealthProviderNames||[],this.configArtifacts=[]}}at('.cloud-provider-logo .icon-cloudrun {\n -webkit-mask-image: url("data:image/svg+xml,%3Csvg width%3D%2224px%22 height%3D%2224px%22 viewBox%3D%220 0 24 24%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E %3Cdefs%3E %3Cstyle%3E .cls-1 %7B fill%3A %23aecbfa%3B %7D .cls-1%2C .cls-2 %7B fill-rule%3A evenodd%3B %7D .cls-2 %7B fill%3A %234285f4%3B %7D %3C%2Fstyle%3E %3C%2Fdefs%3E %3Ctitle%3EIcon_24px_CloudRun_Color%3C%2Ftitle%3E %3Cg data-name%3D%22Product Icons%22%3E %3Cg%3E %3Cpolygon class%3D%22cls-1%22 points%3D%228.9 2.63 12.02 12 21.38 12 8.9 2.63%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%2221.38 12 12.02 12 8.9 21.38 21.38 12%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%223.44 21.38 6.57 19.81 8.9 12 5.78 12 3.44 21.38%22 %2F%3E %3Cpolygon class%3D%22cls-1%22 points%3D%223.44 2.63 5.78 12 8.9 12 6.57 4.19 3.44 2.63%22 %2F%3E %3C%2Fg%3E %3C%2Fg%3E%3C%2Fsvg%3E");\n mask-image: url("data:image/svg+xml,%3Csvg width%3D%2224px%22 height%3D%2224px%22 viewBox%3D%220 0 24 24%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E %3Cdefs%3E %3Cstyle%3E .cls-1 %7B fill%3A %23aecbfa%3B %7D .cls-1%2C .cls-2 %7B fill-rule%3A evenodd%3B %7D .cls-2 %7B fill%3A %234285f4%3B %7D %3C%2Fstyle%3E %3C%2Fdefs%3E %3Ctitle%3EIcon_24px_CloudRun_Color%3C%2Ftitle%3E %3Cg data-name%3D%22Product Icons%22%3E %3Cg%3E %3Cpolygon class%3D%22cls-1%22 points%3D%228.9 2.63 12.02 12 21.38 12 8.9 2.63%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%2221.38 12 12.02 12 8.9 21.38 21.38 12%22 %2F%3E %3Cpolygon class%3D%22cls-2%22 points%3D%223.44 21.38 6.57 19.81 8.9 12 5.78 12 3.44 21.38%22 %2F%3E %3Cpolygon class%3D%22cls-1%22 points%3D%223.44 2.63 5.78 12 8.9 12 6.57 4.19 3.44 2.63%22 %2F%3E %3C%2Fg%3E %3C%2Fg%3E%3C%2Fsvg%3E");\n background-color: #4285f4;\n}\n'),Q.registerProvider("cloudrun",{name:"cloudrun",logo:{path:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAFAUlEQVRYR82YfUwcRRjGn5m7veO4rZI2aKuk1kRNjQ012rRANB53YNpYtFHS1Aj9ktaPtGINpPWgKQ0sVNvUNGirgYBJSTSA1H6ltpTrVYtUS2u1aRS/LSRFEmqBPcC7vR2zixwc7N4tJ02c5P64zMwzv332fd+ZWYL/USNGWFL3MpvVJy4xMlZzTJA/7y0hw9HmR4VxlokVIGQzwOzRxCL0D4DgA4+bL4ykERHGKfiqAJb3HyAmTCXVniL7Bj09XRhXqZjBKJqnD2REicjIbNnOn9bS1YVxlvuOgrHl0w0DQo553PYswzAuQcxhwMFpB/lXkAC5LUV83UT9Sc44SpjZxPnaGLDoFsK0BwP2VG8JkcavMQnGWSYWgGD3rQIJ6TIUeor5PbowjrcGk6gktwFI0oKZk0Bw/SYLdSXNpOi6IcfK3SWbaap3a3zXqECYM85ycTcYCvTUX3JZ0NMn41D7iLt5Dgv6hhgavgrEBkSwZ3ztCcE4ynyLKGGKK2Y95ZT7TBBWxuHzH4LY2TSMBUkU+1bbcOn3IPZ95o/FJUlmJNVbbG9X0350YacgKtmTE+kRORNQs9GGO2+nyKsawrVeGe+vt+HyH0E88yiHmrP+WFyq8xTxuSEYV2n/ckbpUSNeFzxlxbKFZuxv9uPUFQkrUzgkz6U4/o2E7MUcbvgY3j01NZeILGe1bL/tmOpMernYTBgyjMBkLjBj29NWfNEhofKkH/MSKXatikPO/kEwBmQv4bA02YyD5wKGXWIEp8+4+UziFPrzAFplBEQZM4snqH8tHjcHGTZWD6nTKtfYUHvWr8aO0u6fTbHpSSt+6ZFR5THqkryBOAXfEYBplmc9wPfW2jD/Loqi+mH81C1jzeMWzEvU3lnmJFDUtfpx+GJYfdOSPkHSBbGHAIlGnRlN6efTOPU1KL+HkkzY8aw1okTLVQk1Xj+6+8bq1MQJJL1MrCYEL04FpjrPhnvvGHNm3RMWNai1mlIkFeBzHRL8QWBgSAeGkAbiKhWXMooTRmFmzSCo3xweMwfW29RYmthOfiepIP3jAAJBhP0PVV8Zy1QFpyDWAlhrBEhJ31cyLKFsevBuip3PxYVN7eyV8XFbABd+HQnoiU2Sgb7BMIc+9BTx61QYhyA+TAGl+oaragjtfSEOC+8xqXXG+72E3Mc4ZD3ChUYeuRRAw/kA/o4Sr0EZakYCGJaBVG8Rf3msApcPVoDJ26K50+K2QxF6tXYIf/mYuh0oG+hvPTLqWgO40qnthq5DQ2SXxx3/ptI/tjeViLMpp7ozTw8o7QETSrOVvUlSq2zyXBOKV1jRdCGgvpapNkrR+WcvW+wt4bvDYNTYKRNfB8E7eqJK5f365yC+vTby9EoWffmjhI7rsR0jgjLb2rSFfzsUxBMXdgnKKY+laAFZzQAfF/V2Y8ggAlysz7eHnSYnKbuEgVUM5CM9xekCCshs9adb+LBztuZjOgXfIYCt0AXiAN4au0MM9Hhjvm3SzUNT0VE64KCUnInkdxwH2GME8vtZ5uHCyXcn/XuT4DsAsJenG4gBNY35ds3tRxfGUd4/nzKqpHpCJCCbhSDeYihmAbB+2cTSPtk046rWjMh37dKBElCyI9pSRoEYUNGYb3fr6UWNQqcKRAuifYWItxDYdBwihIgyY5WRQCYVPT1io99nZvKc5jnCxKytDW+QkWNhhBbVmWgC09n/Dw0j4+SJOXQTAAAAAElFTkSuQmCC"},instance:{details:Ae},serverGroup:{CloneServerGroupModal:yt,commandBuilder:gt,detailsActions:wt,detailsGetter:Bt,detailsSections:[xt,Tt,Dt],transformer:Gt,skipUpstreamStageCheck:!0},loadBalancer:{transformer:Be,CreateLoadBalancerModal:De,useDetailsHook:Ye,detailsActions:Fe,detailsSections:[Pe,Le,Ue,Oe]}}),Z.registerProvider("cloudrun",["custom","redblack","rollingpush","rollingredblack"]);export{Mt as CloudrunDeployDescription,Fe as CloudrunLoadBalancerActions,Pe as CloudrunLoadBalancerDetailsSection,Oe as CloudrunLoadBalancerDnsSection,De as CloudrunLoadBalancerModal,Te as CloudrunLoadBalancerModalComponent,Le as CloudrunLoadBalancerStatusSection,Ue as CloudrunLoadBalancerTrafficSplitSection,Be as CloudrunLoadBalancerTransformer,we as CloudrunLoadBalancerUpsertDescription,wt as CloudrunServerGroupActions,St as CloudrunServerGroupActionsComponent,vt as CloudrunServerGroupCommandBuilder,Dt as CloudrunServerGroupHealthSection,xt as CloudrunServerGroupInformationSection,Tt as CloudrunServerGroupSizeSection,gt as CloudrunV2ServerGroupCommandBuilder,Gt as CloudrunV2ServerGroupTransformer,ht as ServerGroupSource,Bt as cloudrunServerGroupDetailsGetter,Ie as compareCloudrunLoadBalancerServerGroups,ze as findCloudrunLoadBalancer,Ye as useCloudrunLoadBalancerDetails};
2
2
  //# sourceMappingURL=index.js.map