@spinnaker/cloudrun 2026.0.1 → 2026.1.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.
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,ExpectedArtifactService as L,ArtifactReferenceService 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,reduce as X,filter as Q,chain as _,cloneDeep as Z,has as J,camelCase as ee,get 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:X(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=Q(e.serverGroups,{isDisabled:!1});return e.instances=_(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=Z(n.serverGroups)),e}))}convertLoadBalancerToUpsertDescription(e){return new Ge(e)}buildInstanceCounts(e){const t=_(e).map("instances").flatten().reduce(((e,t)=>(J(t,"health.state")&&e[ee(t.health.state)]++,e)),{up:0,down:0,outOfService:0,succeeded:0,failed:0,starting:0,unknown:0}).value();return t.outOfService+=_(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=te(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=Z(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:()=>Z(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:()=>Z(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:()=>Z(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,Ve;function Ye({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"}))))}(Ve=Ue||(Ue={})).TEXT="text",Ve.ARTIFACT="artifact";se.Component;class je 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 Ke 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=te(e.formik.values,"manifests"),a=te(e.formik.values,"source")===Ue.TEXT;this.state={rawManifest:!ie(n)&&a?h(n):"",application:this.props.application.name,stack:te(t,"stack"),details:te(t,"details")}}render(){const e=this.props.formik.values;return se.createElement("div",{className:"form-horizontal"},se.createElement("h4",null,"Basic Settings"),se.createElement(Ye,{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(je,{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 qe 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=Z(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(Ke,{...e,accounts:this.state.accounts})})}}const We="redblack",He="strategy.spinnaker.io/max-version-history",Xe={available:"success",stable:"success",paused:"warn",failed:"danger"};class Qe 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=Xe[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 _e="cloudrunResource";class Ze 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(te(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!==_e||(i.region=n),i.region&&""!==i.region||(i.region="_"),i}loadUrl(){const e=te(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]||_e,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 Je 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(te(this.props.manifest,["manifest","metadata","annotations","artifact.spinnaker.io/location"],""));return e.map(((n,a)=>{const i=te(n,"firstTimestamp",""),r=te(n,"lastTimestamp","");let s=0,o=0;return i&&(s=pe.fromISO(i).toMillis()),r&&(o=pe.fromISO(r).toMillis()),se.createElement("div",{key:te(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 et({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(Qe,{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(Ze,{linkName:"Details",manifest:t,accountId:e})),se.createElement("div",{className:"manifest-events pad-left",key:"manifest-events"},se.createElement(Je,{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 tt=class{static subscribe(e,t,n){return tt.updateManifest(t,n),e.onRefresh(null,(()=>tt.updateManifest(t,n)))}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(e,t){return{account:t,name:tt.scopedKind(e)+" "+e.metadata.name,location:null==e.metadata.namespace?"_":e.metadata.namespace}}static apiGroup(e){const t=(e.apiVersion||"_").split("/");return t.length<2?"":t[0]}static isCRDGroup(e){return!tt.BUILT_IN_GROUPS.includes(tt.apiGroup(e))}static scopedKind(e){return tt.isCRDGroup(e)?e.kind+"."+tt.apiGroup(e):e.kind}};let nt=tt;nt.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"];class at 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=te(this.props.stage,["context","outputs.manifests"],[]).filter((e=>!!e)),a=n.map((e=>nt.manifestIdentifier(e))).sort();if(t.manifestIds.join("")!==a.join("")){this.unsubscribeAll();const e=n.map((e=>{const t=nt.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=nt.stageManifestToManifestParams(t,this.props.stage.context.account);return nt.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:te(e,"metadata.name",""),moniker:null,account:t,cloudProvider:"cloudrun",location:te(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||nt.manifestIdentifier(e.manifest);return se.createElement(et,{key:t,manifest:e,account:n.context.account})}))))))}}at.title="deployStatus",c.pipeline.registerStage({label:"Deploy (Cloud Run)",description:"Deploy a Cloud Run manifest yaml/json file.",key:"deployCloudrunManifest",cloudProvider:"cloudrun",component:qe,executionDetailsSections:[at,$,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=te(t,"trafficManagement.enabled",!1),a=te(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=te(t,"manifests",[]).filter((e=>"ReplicaSet"===e.kind)),n=te(t,"trafficManagement.options.strategy"),a=parseInt(te(e,[0,"metadata","annotations",He]),10);if(n===We&&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>${He}</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:L.accumulateArtifacts(["manifestArtifactId","requiredArtifactIds"]),artifactRemover:M.removeArtifactFromFields(["manifestArtifactId","requiredArtifactIds"])});const it=I.providers.cloudrun||{defaults:{}};var rt,st;it&&(it.resetToOriginal=I.resetProvider("cloudrun")),(st=rt||(rt={})).TEXT="text",st.ARTIFACT="artifact";const ot=e=>{switch(e){case"createPipeline":return"Add";case"editPipeline":return"Done";default:return"Create"}};class lt{buildNewServerGroupCommand(e){return dt.buildNewServerGroupCommand(e,"cloudrun","create")}buildNewServerGroupCommandForPipeline(e,t){return dt.buildNewServerGroupCommandForPipeline(e,t)}buildServerGroupCommandFromPipeline(e,t,n,a){return dt.buildServerGroupCommandFromPipeline(e,t,n,a)}}const ct=class{static ServerGroupCommandIsValid(e){return!!e.moniker&&!!e.moniker.app}static copyAndCleanCommand(e){return Z(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(e,t,n,a){return ct.buildNewServerGroupCommand(e,"cloudrun","editPipeline").then((e=>e={...e,...t,backingData:{...e.metadata.backingData.backingData,expectedArtifacts:ct.getExpectedArtifacts(a)},credentials:t.account||e.metadata.backingData.credentials,viewState:{...e.metadata.backingData.viewState,stage:n,pipeline:a}}))}static getCredentials(e){const t=(e||[]).map((e=>e.name)),n=it.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:ot(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}}}))}};let dt=ct;dt.$inject=["$q"];const ut="spinnaker.cloudrun.serverGroup.commandBuilder.service";function pt({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(ut,[]).service("cloudrunV2ServerGroupCommandBuilder",lt);class mt 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(pt,{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 ht({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 gt 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(ht,{configFiles:e.values.configFiles||e.values.command.configFiles,onEnterConfig:this.configUpdated})}}const ft=class 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=dt.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||dt.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(e){return z.show(ft,e,{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(mt,{ref:n,formik:e,app:t})}),se.createElement(U,{label:"Service Yaml",wizard:a,order:n(),render:({innerRef:t})=>se.createElement(gt,{ref:t,formik:e})}))})}};let vt=ft;vt.defaultProps={closeModal:V,dismissModal:V};class bt{}bt.PLATFORM="Cloud Run Service";class Bt{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:bt.PLATFORM,interestingHealthProviderNames:[]};this.app.attributes.platformHealthOnlyShowOverride&&this.app.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=[bt.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}))}}Bt.$inject=["$state","$scope","serverGroup","app","serverGroupWriter"];const kt="spinnaker.cloudrun.serverGroup.details.controller";e(kt,[Y]).controller("cloudrunV2ServerGroupDetailsCtrl",Bt);class Ct{constructor(e){this.$q=e}normalizeServerGroup(e){return this.$q.resolve(e)}convertServerGroupCommandToDeployConfiguration(e){return new wt(e)}}Ct.$inject=["$q"];class wt{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 yt="spinnaker.cloudrun.serverGroup.transformer.service";e(yt,[]).service("cloudrunV2ServerGroupTransformer",Ct);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 St="spinnaker.cloudrun";e(St,[ge,ut,kt,yt,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:vt,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,St as CLOUDRUN_MODULE,ut as CLOUDRUN_SERVER_GROUP_COMMAND_BUILDER,kt as CLOUDRUN_SERVER_GROUP_DETAILS_CTRL,yt as CLOUDRUN_SERVER_GROUP_TRANSFORMER,wt as CloudrunDeployDescription,xe as CloudrunLoadBalancerTransformer,Ge as CloudrunLoadBalancerUpsertDescription,dt as CloudrunServerGroupCommandBuilder,lt as CloudrunV2ServerGroupCommandBuilder,Ct as CloudrunV2ServerGroupTransformer,rt as ServerGroupSource};
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};
2
2
  //# sourceMappingURL=index.js.map