@spinnaker/tencentcloud 2026.2.3 → 2026.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/image/image.reader.d.ts +2 -2
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/keyPairs/KeyPairsReader.d.ts +1 -1
  6. package/dist/pipeline/stages/TencentcloudAccountRegionClusterSelector.d.ts +15 -0
  7. package/dist/tencentcloud.module.d.ts +0 -1
  8. package/package.json +2 -5
  9. package/src/image/image.reader.ts +4 -5
  10. package/src/index.ts +2 -1
  11. package/src/keyPairs/KeyPairsReader.ts +1 -1
  12. package/src/pipeline/stages/TencentcloudAccountRegionClusterSelector.spec.ts +114 -0
  13. package/src/pipeline/stages/TencentcloudAccountRegionClusterSelector.tsx +218 -0
  14. package/src/pipeline/stages/disableCluster/DisableClusterStageForm.tsx +8 -6
  15. package/src/pipeline/stages/rollbackCluster/RollbackClusterStageForm.tsx +8 -6
  16. package/src/pipeline/stages/scaleDownCluster/ScaleDownClusterStageForm.tsx +7 -6
  17. package/src/pipeline/stages/shrinkCluster/ShrinkClusterStageForm.tsx +7 -6
  18. package/src/tencentcloud.module.ts +8 -17
  19. package/src/tencentcloud.spec.ts +20 -0
  20. package/dist/reactShims/index.d.ts +0 -2
  21. package/dist/reactShims/tencentcloud.ngReact.d.ts +0 -8
  22. package/dist/reactShims/tencentcloud.react.injector.d.ts +0 -7
  23. package/dist/reactShims/tencentcloud.react.module.d.ts +0 -1
  24. package/dist/search/searchResultFormatter.d.ts +0 -1
  25. package/src/reactShims/index.ts +0 -2
  26. package/src/reactShims/tencentcloud.ngReact.ts +0 -21
  27. package/src/reactShims/tencentcloud.react.injector.ts +0 -14
  28. package/src/reactShims/tencentcloud.react.module.ts +0 -14
  29. package/src/search/searchResultFormatter.js +0 -10
@@ -30,6 +30,6 @@ export declare class TencentcloudImageReader {
30
30
  findImages(params: {
31
31
  q: string;
32
32
  region?: string;
33
- }): PromiseLike<ITencentcloudImage[]>;
34
- getImage(name: string, region: string, credentials: string): PromiseLike<ITencentcloudImage>;
33
+ }): Promise<ITencentcloudImage[]>;
34
+ getImage(name: string, region: string, credentials: string): Promise<ITencentcloudImage>;
35
35
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { TENCENTCLOUD_MODULE } from './tencentcloud.module';
1
+ import './tencentcloud.module';
2
2
  export * from './tencentcloud.settings';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{module as e}from"angular";import{HelpContentsRegistry as t,REST as n,NgReact as l,AccountService as r,StageConfigField as a,FormikFormField as i,NumberInput as o,SelectInput as c,FormikStageConfig as s,FormValidator as C,Registry as d,CheckboxInput as u,ReactInject as p,ApplicationNameValidator as v,FirewallLabels as m,CloudProviderRegistry as g,DeploymentStrategyRegistry as h,SETTINGS as f}from"@spinnaker/core";import{$q as E}from"ngimport";import b from"react";import{cloneDeep as w}from"lodash";const F={};Object.keys(F).forEach(e=>t.register(e,F[e]));class y{findImages(e){return!e.q||e.q.length<3?E.when([{message:"Please enter at least 3 characters...",disabled:!0}]):n("/images/find").query({...e,provider:"tencentcloud"}).get().catch(()=>[])}getImage(e,t,l){return n("/images").path(l,t,e).query({provider:"tencentcloud"}).get().then(e=>e&&e.length?e[0]:null).catch(()=>null)}}const{useEffect:S,useState:D}=b,{AccountRegionClusterSelector:k}=l;function N({application:e,formik:t,pipeline:n}){const l=t.values,{setFieldValue:s}=t,[C,d]=D([]);S(()=>{var t,n,a,i,o,c,C;r.listAccounts("tencentcloud").then(e=>{d(e)}),l.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(n=null==e?void 0:e.attributes)?void 0:n.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!l.credentials&&(null==(a=null==e?void 0:e.defaultCredentials)?void 0:a.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==l?void 0:l.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...l.regions,null==(C=null==e?void 0:e.defaultRegions)?void 0:C.tencentcloud]),void 0===l.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===l.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);return b.createElement("div",{className:"form-horizontal"},!n.strategy&&b.createElement(k,{application:e,clusterField:"cluster",component:l,accounts:C}),b.createElement(a,{label:"Disable Options"},b.createElement("div",{className:"form-inline"},"Keep the",b.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>b.createElement(o,{...e,min:0})}),b.createElement(i,{name:"preferLargerOverNewer",required:!0,input:e=>b.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),(u="server group",1===l.remainingEnabledServerGroups?u:u+"s")," enabled.")));var u}d.pipeline.registerStage({provides:"disableCluster",key:"disableCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:n,updateStage:l}){const r=b.useMemo(()=>({cloudProvider:"tencentcloud",regions:n.regions||[],...w(n)}),[]);return b.createElement(s,{application:e,onChange:l,pipeline:t,stage:r,render:e=>b.createElement(N,{...e})})},validateFn:e=>{const t=new C(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:O,useState:A}=b,{AccountRegionClusterSelector:x}=l;function q({application:e,formik:t,pipeline:n}){const l=t.values,{setFieldValue:c}=t,[s,C]=A([]);return O(()=>{var t,n,a,i,o,s,d;r.listAccounts("tencentcloud").then(e=>{C(e)}),l.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(n=null==e?void 0:e.attributes)?void 0:n.platformHealthOnly)&&c("interestingHealthProviderNames",["Tencentcloud"]),!l.credentials&&(null==(a=null==e?void 0:e.defaultCredentials)?void 0:a.tencentcloud)&&c("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==l?void 0:l.regions)?void 0:o.length)&&(null==(s=null==e?void 0:e.defaultRegions)?void 0:s.tencentcloud)&&c("regions",[...l.regions,null==(d=null==e?void 0:e.defaultRegions)?void 0:d.tencentcloud]),void 0===l.remainingEnabledServerGroups&&c("remainingEnabledServerGroups",1),void 0===l.preferLargerOverNewer&&c("preferLargerOverNewer","false")},[]),b.createElement("div",{className:"form-horizontal"},!n.strategy&&b.createElement(x,{application:e,clusterField:"cluster",component:l,accounts:s}),b.createElement(a,{label:"Rollback Options"},b.createElement("div",{className:"row"},b.createElement("div",{className:"col-sm-10 col-sm-offset-2"},"Wait",b.createElement(i,{name:"wait",required:!0,input:e=>b.createElement(o,{...e,min:0})}),"seconds between regional rollbacks."),b.createElement("div",{className:"col-sm-10 col-sm-offset-2"},"Consider rollback successful when",b.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>b.createElement(o,{...e,min:0,max:100})}),"percent of instances are healthy."))))}d.pipeline.registerStage({provides:"rollbackCluster",key:"rollbackCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:n,updateStage:l}){const r=b.useMemo(()=>({cloudProvider:"tencentcloud",regions:n.regions||[],...w(n)}),[]);return b.createElement(s,{application:e,onChange:l,pipeline:t,stage:r,render:e=>b.createElement(q,{...e})})},validateFn:e=>{const t=new C(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:z,useState:H}=b,{AccountRegionClusterSelector:R}=l;function M({application:e,formik:t,pipeline:n}){const l=t.values,{setFieldValue:s}=t,[C,d]=H([]);z(()=>{var t,n,a,i,o,c,C;r.listAccounts("tencentcloud").then(e=>{d(e)}),l.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(n=null==e?void 0:e.attributes)?void 0:n.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!l.credentials&&(null==(a=null==e?void 0:e.defaultCredentials)?void 0:a.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==l?void 0:l.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...l.regions,null==(C=null==e?void 0:e.defaultRegions)?void 0:C.tencentcloud]),void 0===l.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===l.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);return b.createElement("div",{className:"form-horizontal"},!n.strategy&&b.createElement(R,{application:e,clusterField:"cluster",component:l,accounts:C}),b.createElement(a,{label:"ScaleDown Options"},b.createElement("div",{className:"form-inline"},"Keep the",b.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>b.createElement(o,{...e,min:0})}),b.createElement(i,{name:"preferLargerOverNewer",required:!0,input:e=>b.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),(p="server group",1===l.remainingFullSizeServerGroups?p:p+"s")," at current size.",b.createElement("p",null,"The remaining server groups will be scaled down to zero instances."))),b.createElement("div",{className:"form-group"},b.createElement(i,{name:"allowScaleDownActive",input:e=>b.createElement(u,{...e,text:"Allow scale down of active server groups"})})));var p}d.pipeline.registerStage({provides:"scaleDownCluster",key:"scaleDownCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:n,updateStage:l}){const r=b.useMemo(()=>({cloudProvider:"tencentcloud",regions:n.regions||[],...w(n)}),[]);return b.createElement(s,{application:e,onChange:l,pipeline:t,stage:r,render:e=>b.createElement(M,{...e})})},validateFn:e=>{const t=new C(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:P,useState:L}=b,{AccountRegionClusterSelector:G}=l;function V({application:e,formik:t,pipeline:n}){const l=t.values,{setFieldValue:s}=t,[C,d]=L([]);P(()=>{var t,n,a,i,o,c,C;r.listAccounts("tencentcloud").then(e=>{d(e)}),l.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(n=null==e?void 0:e.attributes)?void 0:n.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!l.credentials&&(null==(a=null==e?void 0:e.defaultCredentials)?void 0:a.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==l?void 0:l.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...l.regions,null==(C=null==e?void 0:e.defaultRegions)?void 0:C.tencentcloud]),void 0===l.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===l.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);const p=function(e,t){return 1===t?e:e+"s"};return b.createElement("div",{className:"form-horizontal"},!n.strategy&&b.createElement(G,{application:e,clusterField:"cluster",component:l,accounts:C}),b.createElement(a,{label:"Shrink Options"},b.createElement("div",{className:"form-inline"},"Shrink to",b.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>b.createElement(o,{...e,min:0})}),p("server group",l.shrinkToSize),", keeping the",b.createElement(i,{name:"retainLargerOverNewer",required:!0,input:e=>b.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),p("server group",l.remainingEnabledServerGroups)," enabled.")),b.createElement("div",{className:"form-group"},b.createElement("div",{className:"col-md-offset-3 col-md-6 checkbox"},b.createElement(i,{name:"allowDeleteActive",input:e=>b.createElement(u,{...e,text:"Allow deletion of active server groups"})}))))}d.pipeline.registerStage({provides:"shrinkCluster",key:"shrinkCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:n,updateStage:l}){const r=b.useMemo(()=>({cloudProvider:"tencentcloud",regions:n.regions||[],...w(n)}),[]);return b.createElement(s,{application:e,onChange:l,pipeline:t,stage:r,render:e=>b.createElement(V,{...e})})},validateFn:e=>{const t=new C(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const B=new class extends p{constructor(){super(...arguments),this.$injectorProxy={}}initialize(e){const t=e,n=this.$injectorProxy;Object.keys(e).filter(e=>"function"==typeof t[e]).forEach(e=>n[e]=t[e].bind(t))}};const T=new class extends p{initialize(e){this.$injector=e}},$="spinnaker.tencentcloud.react";e($,[]).run(["$injector",function(e){T.initialize(e),B.initialize(e)}]);const j="spinnaker.tencentcloud.search.searchResultFormatter";e(j,[]).factory("tencentcloudSearchResultFormatter",function(){return{securityGroups:function(e){}}});v.registerValidator("tencentcloud",new class{validateSpecialCharacters(e,t){/^[a-zA-Z_0-9.]*$/g.test(e)||t.push("Only dot(.) and underscore(_) special characters are allowed.")}validateLoadBalancerCharacters(e,t){(e.includes(".")||e.includes("_"))&&t.push("If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.")}validateLength(e,t,n){if(e.length>250)n.push("The maximum length for an application in Tencentcloud is 250 characters.");else{if(e.length>240)if(e.length>=248)t.push(`You will not be able to include a stack or detail field for clusters or ${m.get("firewalls")}.`);else{const n=248-e.length;t.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${n} characters to do so.`)}if(e.length>20)if(e.length>32)t.push(`You will not be able to create an Tencentcloud load balancer for this application if the\n application's name is longer than 32 characters (currently: ${e.length} characters)`);else if(e.length>=30)t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${e.length} characters). With separators ("-"), you will not\n be able to add a stack and detail field to any load balancer.`);else{const n=30-e.length;t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${n} characters to add a stack or detail\n field to any load balancer.`)}}}validate(e=""){const t=[],n=[];return e.length&&(this.validateSpecialCharacters(e,n),this.validateLoadBalancerCharacters(e,t),this.validateLength(e,t,n)),{warnings:t,errors:n}}});const I="spinnaker.tencentcloud";e(I,[$,j]).config(()=>{g.registerProvider("tencentcloud",{name:"tencentcloud",logo:{path:"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csvg%20version%3D%221.1%22%20id%3D%22%E5%9B%BE%E5%B1%82_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20%20width%3D%22120px%22%20height%3D%2248px%22%20viewBox%3D%220%200%20120%2048%22%20style%3D%22enable-background%3Anew%200%200%20120%2048%3B%22%20xml%3Aspace%3D%22preserve%22%3E%3Cg%3E%20%3Cg%3E%20%20%3Cpath%20d%3D%22M93.829%2C13.731H81.181v1.83h3.808v6.673h-4.364v1.83h4.364v11.19h2.013v-11.19h4.814V35.02h3.802v-1.831h-1.788V13.731z%20%20%20%20M87.002%2C22.234v-6.673h4.814v6.673H87.002z%22%2F%3E%20%20%3Crect%20x%3D%2258.743%22%20y%3D%2230.136%22%20width%3D%229.979%22%20height%3D%221.83%22%2F%3E%20%20%3Cpath%20d%3D%22M51.944%2C26.749c0%2C3.328-0.269%2C5.854-0.823%2C8.093c-0.058%2C0.207%2C0.004%2C0.263%2C0.113%2C0.263c0.038%2C0%2C1.525%2C0%2C1.835%2C0%20%20%20c0.613-3.075%2C0.693-5.626%2C0.703-7.477h2.565v5.69h-1.821c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h3.257V13.777h-6.22V26.749z%20%20%20%20M53.774%2C25.98V21.6h2.563v4.38H53.774z%20M56.337%2C15.607v4.346h-2.563v-4.346H56.337z%22%2F%3E%20%20%3Cpath%20d%3D%22M69.429%2C21.196h2.457v-1.647h-7.16c0.216-0.526%2C0.41-1.091%2C0.588-1.702h6.123V16.2h-1.794%20%20%20c0.299-1.018%2C0.651-2.219%2C0.672-2.288c0.036-0.122-0.028-0.169-0.107-0.169h-1.558L67.927%2C16.2h-2.202%20%20%20c0.205-0.952%2C0.384-2.007%2C0.547-3.191c0.019-0.137-0.055-0.164-0.146-0.164c-0.073%2C0-1.278%2C0-1.774%2C0%20%20%20c-0.181%2C1.258-0.371%2C2.342-0.614%2C3.355h-1.08l-0.722-2.457h-1.558c-0.079%2C0-0.143%2C0.047-0.107%2C0.169%20%20%20c0.02%2C0.07%2C0.373%2C1.271%2C0.672%2C2.288h-1.747v1.647h4.079c-0.166%2C0.52-0.41%2C1.133-0.67%2C1.702h-3.858v1.647h2.898%20%20%20c-1.168%2C1.659-2.417%2C2.422-2.915%2C2.727c0%2C0.234%2C0%2C1.83%2C0%2C1.884c0%2C0.095%2C0.075%2C0.196%2C0.373%2C0.027%20%20%20c0.542-0.307%2C1.12-0.655%2C1.705-1.087h6.817l-0.058%2C2.467h-5.382l0.082-1.475c0-0.064-0.046-0.111-0.112-0.111%20%20%20c-0.102%2C0-1.721%2C0-1.721%2C0l-0.173%2C3.122c0%2C0.064%2C0.046%2C0.111%2C0.112%2C0.111c0.102%2C0%2C9.285%2C0%2C9.285%2C0v4.454h-4.185%20%20%20c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h5.807v-7.931h-2.273l0.075-3.203c0.85%2C0.79%2C1.712%2C1.379%2C2.497%2C1.824%20%20%20c0.298%2C0.169%2C0.373%2C0.068%2C0.373-0.027c0-0.054%2C0-1.651%2C0-1.884C71.844%2C23.618%2C70.597%2C22.853%2C69.429%2C21.196z%20M67.188%2C21.196%20%20%20c0.438%2C0.721%2C0.91%2C1.351%2C1.398%2C1.903h-5.991c0.465-0.537%2C0.915-1.163%2C1.335-1.903H67.188z%22%2F%3E%20%20%3Cpath%20d%3D%22M82.457%2C28.864c-0.034%2C0.026-1.742%2C1.32-3.395%2C2.572V19.538h-4.704v2.013h2.704v11.4%20%20%20c-0.644%2C0.488-1.081%2C0.819-1.081%2C0.819l1.105%2C1.459l5.552-4.207c0%2C0%2C0-2.021%2C0-2.073C82.639%2C28.851%2C82.529%2C28.809%2C82.457%2C28.864z%22%20%20%20%2F%3E%20%20%3Cpath%20d%3D%22M77.329%2C17.736c0%2C0%2C2.15%2C0%2C2.2%2C0c0.098%2C0%2C0.137-0.106%2C0.094-0.171c-0.04-0.061-2.775-4.238-2.775-4.238s-2.117%2C0-2.2%2C0%20%20%20c-0.083%2C0-0.144%2C0.096-0.098%2C0.166C74.596%2C13.562%2C77.329%2C17.736%2C77.329%2C17.736z%22%2F%3E%20%20%3Crect%20x%3D%2299.874%22%20y%3D%2214.22%22%20width%3D%2215.888%22%20height%3D%222.013%22%2F%3E%20%20%3Cpath%20d%3D%22M105.637%2C23.841H118v-2.013H97.636v2.013h5.65c-1.167%2C3.064-4.095%2C10.753-4.115%2C10.809%20%20%20c-0.032%2C0.089%2C0.026%2C0.155%2C0.104%2C0.155c0.049%2C0%2C17.523%2C0%2C17.564%2C0c0.083%2C0%2C0.131-0.082%2C0.101-0.16%20%20%20c-0.019-0.049-2.619-6.885-2.619-6.885s-2.103%2C0-2.186%2C0s-0.133%2C0.08-0.105%2C0.153c0.028%2C0.073%2C1.853%2C4.879%2C1.853%2C4.879h-11.646%20%20%20L105.637%2C23.841z%22%2F%3E%20%3C%2Fg%3E%20%3Cg%3E%20%20%3Cpath%20style%3D%22fill%3A%2300A3FF%3B%22%20d%3D%22M39.157%2C33.89c-0.764%2C0.756-2.125%2C1.613-4.361%2C1.689c-1.034%2C0.035-2.241%2C0.039-2.793%2C0.039%20%20%20c-0.603%2C0-5.918%2C0-12.012%2C0c4.37-4.245%2C8.182-7.947%2C8.615-8.367c0.396-0.385%2C1.287-1.237%2C2.056-1.929%20%20%20c1.687-1.519%2C3.206-1.825%2C4.28-1.815c1.683%2C0.016%2C3.214%2C0.703%2C4.308%2C1.813C41.591%2C27.712%2C41.535%2C31.536%2C39.157%2C33.89%20%20%20%20M42.034%2C22.597c-1.795-1.83-4.296-2.983-7.077-2.984c-2.404%2C0-4.474%2C0.829-6.281%2C2.3c-0.788%2C0.641-1.614%2C1.409-2.653%2C2.419%20%20%20c-0.516%2C0.501-15.485%2C15.026-15.485%2C15.026c0.785%2C0.112%2C1.864%2C0.145%2C2.826%2C0.151c0.902%2C0.006%2C18.1%2C0.004%2C18.82%2C0.004%20%20%20c1.449%2C0%2C2.392-0.002%2C3.405-0.076c2.323-0.17%2C4.518-1.022%2C6.292-2.764C45.82%2C32.805%2C45.879%2C26.526%2C42.034%2C22.597z%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%2300C8DC%3B%22%20d%3D%22M17.883%2C21.663c-1.76-1.317-3.729-2.053-5.963-2.05c-2.781%2C0-5.283%2C1.153-7.077%2C2.984%20%20%20c-3.845%2C3.93-3.786%2C10.209%2C0.154%2C14.077c1.582%2C1.553%2C3.498%2C2.398%2C5.541%2C2.684l3.854-3.74c-0.623-0.003-1.518-0.011-2.311-0.038%20%20%20c-2.235-0.076-3.597-0.934-4.361-1.689c-2.379-2.354-2.434-6.178-0.094-8.57c1.094-1.11%2C2.625-1.797%2C4.308-1.813%20%20%20c1.055-0.004%2C2.486%2C0.302%2C4.103%2C1.643c0.772%2C0.64%2C2.486%2C2.147%2C3.239%2C2.825c0.038%2C0.035%2C0.084%2C0.038%2C0.129%2C0.001l2.654-2.589%20%20%20c0.046-0.045%2C0.043-0.105-0.002-0.146C20.781%2C24.088%2C18.972%2C22.474%2C17.883%2C21.663%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%23006EFF%3B%22%20d%3D%22M36%2C17.365c-1.831-5.172-6.762-8.879-12.562-8.879c-6.652%2C0-12.165%2C4.892-13.164%2C11.264%20%20%20c0.535-0.09%2C1.085-0.138%2C1.646-0.138c0.781-0.001%2C1.529%2C0.09%2C2.248%2C0.263c0.014%2C0.003%2C0.028%2C0.005%2C0.042%2C0.008%20%20%20c0.901-4.302%2C4.705-7.498%2C9.228-7.498c3.767%2C0%2C7.072%2C2.272%2C8.562%2C5.492c0.023%2C0.051%2C0.063%2C0.067%2C0.104%2C0.056%20%20%20c1.121-0.308%2C2.464-0.487%2C3.762-0.391C35.992%2C17.552%2C36.04%2C17.481%2C36%2C17.365%22%2F%3E%20%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E"},image:{reader:y}})}),h.registerProvider("tencentcloud",["custom","redblack","rollingpush","rollingredblack"]);const _=f.providers.tencentcloud||{defaults:{}};_&&(_.resetToOriginal=f.resetProvider("tencentcloud"));export{I as TENCENTCLOUD_MODULE,_ as TencentcloudProviderSettings};
1
+ import{HelpContentsRegistry as e,REST as t,AppListExtractor as l,StageConfigField as n,ReactSelectInput as r,AccountService as a,FormikFormField as i,NumberInput as o,SelectInput as c,FormikStageConfig as s,FormValidator as u,Registry as d,CheckboxInput as C,ApplicationNameValidator as p,FirewallLabels as v,CloudProviderRegistry as m,DeploymentStrategyRegistry as g,SETTINGS as h}from"@spinnaker/core";import f from"react";import{uniq as E,first as b,isNil as w,cloneDeep as F}from"lodash";const y={};Object.keys(y).forEach(t=>e.register(t,y[t]));function S({accounts:e,application:t,clusterField:a="cluster",component:i,setFieldValue:o}){const[c,s]=f.useState([]),[u,d]=f.useState([]),[C,p]=f.useState(!1),v=f.useRef(i[a]);v.current=i[a],f.useEffect(()=>{let n=!0;const r=e=>!e||e.account===i.credentials;return t.ready().then(()=>{if(!n)return;const a=l.getRegions([t],r);s(function(e,t,l,n=[],r=!1){const a=t.filter(e=>!l||e.name===l).flatMap(e=>e.regions||[]).map(e=>e.name).filter(Boolean),i=n.some(t=>!e.includes(t)&&a.includes(t));return!e.length||i||r?E(a).sort():E(e).sort()}(a,e,i.credentials,i.regions||[],C))}),()=>{n=!1}},[e,t,i.credentials,i.regions,C]),f.useEffect(()=>{let e=!0;return t.ready().then(()=>{if(!e)return;const n=l.clusterFilterForCredentialsAndRegion(i.credentials,i.regions||[]),r=l.getClusters([t],n),{clusters:a,isCustomClusterInput:o}=function(e,t,l){const n=[...e];return t&&!n.includes(t)?(n.push(t),{clusters:n,isCustomClusterInput:!0}):{clusters:n,isCustomClusterInput:l}}(r,v.current,C);p(o),d(a)}),()=>{e=!1}},[t,a,i.credentials,i.regions,C]);const m=e=>{const n=l.monikerClusterNameFilter(e),r=b(E(l.getMonikers([t],n)));let i;i=w(r)?void 0:{...r,sequence:null},o(a,e),o("moniker",i)};return f.createElement(f.Fragment,null,f.createElement(n,{label:"Account"},f.createElement(r,{clearable:!1,name:"credentials",onChange:e=>{o("credentials",e.target.value),o("regions",[]),o(a,void 0)},options:e.map(e=>({label:e.name,value:e.name})),value:i.credentials})),f.createElement(n,{label:"Region"},f.createElement(r,{clearable:!1,multi:!0,name:"regions",onChange:e=>{o("regions",e.target.value),C||o(a,void 0)},options:c.map(e=>({label:e,value:e})),value:i.regions})),f.createElement(n,{helpKey:"pipeline.config.findAmi.cluster",label:"Cluster"},C?f.createElement("input",{className:"form-control input-sm",name:a,onBlur:e=>{m(e.target.value)},onChange:e=>o(a,e.target.value),type:"text",value:i[a]||""}):f.createElement("select",{className:"form-control input-sm",name:a,onChange:e=>{m(e.target.value)},value:i[a]||""},f.createElement("option",{value:""},"-- select cluster --"),u.map(e=>f.createElement("option",{key:e,value:e},e))),f.createElement("div",{className:"pull-right"},f.createElement("a",{className:"clickable",href:"#",onClick:e=>{e.preventDefault();const t=!C;p(t),t||o(a,void 0)}},C?"Toggle for list of existing clusters":"Toggle for text input"))))}const{useEffect:D,useState:k}=f;function N({application:e,formik:t,pipeline:l}){const r=t.values,{setFieldValue:s}=t,[u,d]=k([]);D(()=>{var t,l,n,i,o,c,u;a.listAccounts("tencentcloud").then(e=>{d(e)}),r.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(l=null==e?void 0:e.attributes)?void 0:l.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!r.credentials&&(null==(n=null==e?void 0:e.defaultCredentials)?void 0:n.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==r?void 0:r.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...r.regions,null==(u=null==e?void 0:e.defaultRegions)?void 0:u.tencentcloud]),void 0===r.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===r.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);return f.createElement("div",{className:"form-horizontal"},!l.strategy&&f.createElement(S,{application:e,clusterField:"cluster",component:r,accounts:u,setFieldValue:s}),f.createElement(n,{label:"Disable Options"},f.createElement("div",{className:"form-inline"},"Keep the",f.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>f.createElement(o,{...e,min:0})}),f.createElement(i,{name:"preferLargerOverNewer",required:!0,input:e=>f.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),(C="server group",1===r.remainingEnabledServerGroups?C:C+"s")," enabled.")));var C}d.pipeline.registerStage({provides:"disableCluster",key:"disableCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:l,updateStage:n}){const r=f.useMemo(()=>({cloudProvider:"tencentcloud",regions:l.regions||[],...F(l)}),[]);return f.createElement(s,{application:e,onChange:n,pipeline:t,stage:r,render:e=>f.createElement(N,{...e})})},validateFn:e=>{const t=new u(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:O,useState:q}=f;function A({application:e,formik:t,pipeline:l}){const r=t.values,{setFieldValue:c}=t,[s,u]=q([]);return O(()=>{var t,l,n,i,o,s,d;a.listAccounts("tencentcloud").then(e=>{u(e)}),r.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(l=null==e?void 0:e.attributes)?void 0:l.platformHealthOnly)&&c("interestingHealthProviderNames",["Tencentcloud"]),!r.credentials&&(null==(n=null==e?void 0:e.defaultCredentials)?void 0:n.tencentcloud)&&c("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==r?void 0:r.regions)?void 0:o.length)&&(null==(s=null==e?void 0:e.defaultRegions)?void 0:s.tencentcloud)&&c("regions",[...r.regions,null==(d=null==e?void 0:e.defaultRegions)?void 0:d.tencentcloud]),void 0===r.remainingEnabledServerGroups&&c("remainingEnabledServerGroups",1),void 0===r.preferLargerOverNewer&&c("preferLargerOverNewer","false")},[]),f.createElement("div",{className:"form-horizontal"},!l.strategy&&f.createElement(S,{application:e,clusterField:"cluster",component:r,accounts:s,setFieldValue:c}),f.createElement(n,{label:"Rollback Options"},f.createElement("div",{className:"row"},f.createElement("div",{className:"col-sm-10 col-sm-offset-2"},"Wait",f.createElement(i,{name:"wait",required:!0,input:e=>f.createElement(o,{...e,min:0})}),"seconds between regional rollbacks."),f.createElement("div",{className:"col-sm-10 col-sm-offset-2"},"Consider rollback successful when",f.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>f.createElement(o,{...e,min:0,max:100})}),"percent of instances are healthy."))))}d.pipeline.registerStage({provides:"rollbackCluster",key:"rollbackCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:l,updateStage:n}){const r=f.useMemo(()=>({cloudProvider:"tencentcloud",regions:l.regions||[],...F(l)}),[]);return f.createElement(s,{application:e,onChange:n,pipeline:t,stage:r,render:e=>f.createElement(A,{...e})})},validateFn:e=>{const t=new u(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:x,useState:z}=f;function M({application:e,formik:t,pipeline:l}){const r=t.values,{setFieldValue:s}=t,[u,d]=z([]);x(()=>{var t,l,n,i,o,c,u;a.listAccounts("tencentcloud").then(e=>{d(e)}),r.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(l=null==e?void 0:e.attributes)?void 0:l.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!r.credentials&&(null==(n=null==e?void 0:e.defaultCredentials)?void 0:n.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==r?void 0:r.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...r.regions,null==(u=null==e?void 0:e.defaultRegions)?void 0:u.tencentcloud]),void 0===r.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===r.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);return f.createElement("div",{className:"form-horizontal"},!l.strategy&&f.createElement(S,{application:e,clusterField:"cluster",component:r,accounts:u,setFieldValue:s}),f.createElement(n,{label:"ScaleDown Options"},f.createElement("div",{className:"form-inline"},"Keep the",f.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>f.createElement(o,{...e,min:0})}),f.createElement(i,{name:"preferLargerOverNewer",required:!0,input:e=>f.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),(p="server group",1===r.remainingFullSizeServerGroups?p:p+"s")," at current size.",f.createElement("p",null,"The remaining server groups will be scaled down to zero instances."))),f.createElement("div",{className:"form-group"},f.createElement(i,{name:"allowScaleDownActive",input:e=>f.createElement(C,{...e,text:"Allow scale down of active server groups"})})));var p}d.pipeline.registerStage({provides:"scaleDownCluster",key:"scaleDownCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:l,updateStage:n}){const r=f.useMemo(()=>({cloudProvider:"tencentcloud",regions:l.regions||[],...F(l)}),[]);return f.createElement(s,{application:e,onChange:n,pipeline:t,stage:r,render:e=>f.createElement(M,{...e})})},validateFn:e=>{const t=new u(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});const{useEffect:H,useState:L}=f;function P({application:e,formik:t,pipeline:l}){const r=t.values,{setFieldValue:s}=t,[u,d]=L([]);H(()=>{var t,l,n,i,o,c,u;a.listAccounts("tencentcloud").then(e=>{d(e)}),r.isNew&&(null==(t=null==e?void 0:e.attributes)?void 0:t.platformHealthOnlyShowOverride)&&(null==(l=null==e?void 0:e.attributes)?void 0:l.platformHealthOnly)&&s("interestingHealthProviderNames",["Tencentcloud"]),!r.credentials&&(null==(n=null==e?void 0:e.defaultCredentials)?void 0:n.tencentcloud)&&s("credentials",null==(i=null==e?void 0:e.defaultCredentials)?void 0:i.tencentcloud),!(null==(o=null==r?void 0:r.regions)?void 0:o.length)&&(null==(c=null==e?void 0:e.defaultRegions)?void 0:c.tencentcloud)&&s("regions",[...r.regions,null==(u=null==e?void 0:e.defaultRegions)?void 0:u.tencentcloud]),void 0===r.remainingEnabledServerGroups&&s("remainingEnabledServerGroups",1),void 0===r.preferLargerOverNewer&&s("preferLargerOverNewer","false")},[]);const p=function(e,t){return 1===t?e:e+"s"};return f.createElement("div",{className:"form-horizontal"},!l.strategy&&f.createElement(S,{application:e,clusterField:"cluster",component:r,accounts:u,setFieldValue:s}),f.createElement(n,{label:"Shrink Options"},f.createElement("div",{className:"form-inline"},"Shrink to",f.createElement(i,{name:"remainingEnabledServerGroups",required:!0,input:e=>f.createElement(o,{...e,min:0})}),p("server group",r.shrinkToSize),", keeping the",f.createElement(i,{name:"retainLargerOverNewer",required:!0,input:e=>f.createElement(c,{options:[{label:"largest",value:"true"},{label:"newest",value:"false"}],...e})}),p("server group",r.remainingEnabledServerGroups)," enabled.")),f.createElement("div",{className:"form-group"},f.createElement("div",{className:"col-md-offset-3 col-md-6 checkbox"},f.createElement(i,{name:"allowDeleteActive",input:e=>f.createElement(C,{...e,text:"Allow deletion of active server groups"})}))))}d.pipeline.registerStage({provides:"shrinkCluster",key:"shrinkCluster",cloudProvider:"tencentcloud",component:function({application:e,pipeline:t,stage:l,updateStage:n}){const r=f.useMemo(()=>({cloudProvider:"tencentcloud",regions:l.regions||[],...F(l)}),[]);return f.createElement(s,{application:e,onChange:n,pipeline:t,stage:r,render:e=>f.createElement(P,{...e})})},validateFn:e=>{const t=new u(e);return t.field("credentials","Account").required(),t.field("regions","Regions").required(),t.field("cluster","Cluster").required(),t.validateForm()}});p.registerValidator("tencentcloud",new class{validateSpecialCharacters(e,t){/^[a-zA-Z_0-9.]*$/g.test(e)||t.push("Only dot(.) and underscore(_) special characters are allowed.")}validateLoadBalancerCharacters(e,t){(e.includes(".")||e.includes("_"))&&t.push("If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.")}validateLength(e,t,l){if(e.length>250)l.push("The maximum length for an application in Tencentcloud is 250 characters.");else{if(e.length>240)if(e.length>=248)t.push(`You will not be able to include a stack or detail field for clusters or ${v.get("firewalls")}.`);else{const l=248-e.length;t.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${l} characters to do so.`)}if(e.length>20)if(e.length>32)t.push(`You will not be able to create an Tencentcloud load balancer for this application if the\n application's name is longer than 32 characters (currently: ${e.length} characters)`);else if(e.length>=30)t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${e.length} characters). With separators ("-"), you will not\n be able to add a stack and detail field to any load balancer.`);else{const l=30-e.length;t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${l} characters to add a stack or detail\n field to any load balancer.`)}}}validate(e=""){const t=[],l=[];return e.length&&(this.validateSpecialCharacters(e,l),this.validateLoadBalancerCharacters(e,t),this.validateLength(e,t,l)),{warnings:t,errors:l}}}),m.registerProvider("tencentcloud",{name:"tencentcloud",logo:{path:"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csvg%20version%3D%221.1%22%20id%3D%22%E5%9B%BE%E5%B1%82_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20%20width%3D%22120px%22%20height%3D%2248px%22%20viewBox%3D%220%200%20120%2048%22%20style%3D%22enable-background%3Anew%200%200%20120%2048%3B%22%20xml%3Aspace%3D%22preserve%22%3E%3Cg%3E%20%3Cg%3E%20%20%3Cpath%20d%3D%22M93.829%2C13.731H81.181v1.83h3.808v6.673h-4.364v1.83h4.364v11.19h2.013v-11.19h4.814V35.02h3.802v-1.831h-1.788V13.731z%20%20%20%20M87.002%2C22.234v-6.673h4.814v6.673H87.002z%22%2F%3E%20%20%3Crect%20x%3D%2258.743%22%20y%3D%2230.136%22%20width%3D%229.979%22%20height%3D%221.83%22%2F%3E%20%20%3Cpath%20d%3D%22M51.944%2C26.749c0%2C3.328-0.269%2C5.854-0.823%2C8.093c-0.058%2C0.207%2C0.004%2C0.263%2C0.113%2C0.263c0.038%2C0%2C1.525%2C0%2C1.835%2C0%20%20%20c0.613-3.075%2C0.693-5.626%2C0.703-7.477h2.565v5.69h-1.821c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h3.257V13.777h-6.22V26.749z%20%20%20%20M53.774%2C25.98V21.6h2.563v4.38H53.774z%20M56.337%2C15.607v4.346h-2.563v-4.346H56.337z%22%2F%3E%20%20%3Cpath%20d%3D%22M69.429%2C21.196h2.457v-1.647h-7.16c0.216-0.526%2C0.41-1.091%2C0.588-1.702h6.123V16.2h-1.794%20%20%20c0.299-1.018%2C0.651-2.219%2C0.672-2.288c0.036-0.122-0.028-0.169-0.107-0.169h-1.558L67.927%2C16.2h-2.202%20%20%20c0.205-0.952%2C0.384-2.007%2C0.547-3.191c0.019-0.137-0.055-0.164-0.146-0.164c-0.073%2C0-1.278%2C0-1.774%2C0%20%20%20c-0.181%2C1.258-0.371%2C2.342-0.614%2C3.355h-1.08l-0.722-2.457h-1.558c-0.079%2C0-0.143%2C0.047-0.107%2C0.169%20%20%20c0.02%2C0.07%2C0.373%2C1.271%2C0.672%2C2.288h-1.747v1.647h4.079c-0.166%2C0.52-0.41%2C1.133-0.67%2C1.702h-3.858v1.647h2.898%20%20%20c-1.168%2C1.659-2.417%2C2.422-2.915%2C2.727c0%2C0.234%2C0%2C1.83%2C0%2C1.884c0%2C0.095%2C0.075%2C0.196%2C0.373%2C0.027%20%20%20c0.542-0.307%2C1.12-0.655%2C1.705-1.087h6.817l-0.058%2C2.467h-5.382l0.082-1.475c0-0.064-0.046-0.111-0.112-0.111%20%20%20c-0.102%2C0-1.721%2C0-1.721%2C0l-0.173%2C3.122c0%2C0.064%2C0.046%2C0.111%2C0.112%2C0.111c0.102%2C0%2C9.285%2C0%2C9.285%2C0v4.454h-4.185%20%20%20c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h5.807v-7.931h-2.273l0.075-3.203c0.85%2C0.79%2C1.712%2C1.379%2C2.497%2C1.824%20%20%20c0.298%2C0.169%2C0.373%2C0.068%2C0.373-0.027c0-0.054%2C0-1.651%2C0-1.884C71.844%2C23.618%2C70.597%2C22.853%2C69.429%2C21.196z%20M67.188%2C21.196%20%20%20c0.438%2C0.721%2C0.91%2C1.351%2C1.398%2C1.903h-5.991c0.465-0.537%2C0.915-1.163%2C1.335-1.903H67.188z%22%2F%3E%20%20%3Cpath%20d%3D%22M82.457%2C28.864c-0.034%2C0.026-1.742%2C1.32-3.395%2C2.572V19.538h-4.704v2.013h2.704v11.4%20%20%20c-0.644%2C0.488-1.081%2C0.819-1.081%2C0.819l1.105%2C1.459l5.552-4.207c0%2C0%2C0-2.021%2C0-2.073C82.639%2C28.851%2C82.529%2C28.809%2C82.457%2C28.864z%22%20%20%20%2F%3E%20%20%3Cpath%20d%3D%22M77.329%2C17.736c0%2C0%2C2.15%2C0%2C2.2%2C0c0.098%2C0%2C0.137-0.106%2C0.094-0.171c-0.04-0.061-2.775-4.238-2.775-4.238s-2.117%2C0-2.2%2C0%20%20%20c-0.083%2C0-0.144%2C0.096-0.098%2C0.166C74.596%2C13.562%2C77.329%2C17.736%2C77.329%2C17.736z%22%2F%3E%20%20%3Crect%20x%3D%2299.874%22%20y%3D%2214.22%22%20width%3D%2215.888%22%20height%3D%222.013%22%2F%3E%20%20%3Cpath%20d%3D%22M105.637%2C23.841H118v-2.013H97.636v2.013h5.65c-1.167%2C3.064-4.095%2C10.753-4.115%2C10.809%20%20%20c-0.032%2C0.089%2C0.026%2C0.155%2C0.104%2C0.155c0.049%2C0%2C17.523%2C0%2C17.564%2C0c0.083%2C0%2C0.131-0.082%2C0.101-0.16%20%20%20c-0.019-0.049-2.619-6.885-2.619-6.885s-2.103%2C0-2.186%2C0s-0.133%2C0.08-0.105%2C0.153c0.028%2C0.073%2C1.853%2C4.879%2C1.853%2C4.879h-11.646%20%20%20L105.637%2C23.841z%22%2F%3E%20%3C%2Fg%3E%20%3Cg%3E%20%20%3Cpath%20style%3D%22fill%3A%2300A3FF%3B%22%20d%3D%22M39.157%2C33.89c-0.764%2C0.756-2.125%2C1.613-4.361%2C1.689c-1.034%2C0.035-2.241%2C0.039-2.793%2C0.039%20%20%20c-0.603%2C0-5.918%2C0-12.012%2C0c4.37-4.245%2C8.182-7.947%2C8.615-8.367c0.396-0.385%2C1.287-1.237%2C2.056-1.929%20%20%20c1.687-1.519%2C3.206-1.825%2C4.28-1.815c1.683%2C0.016%2C3.214%2C0.703%2C4.308%2C1.813C41.591%2C27.712%2C41.535%2C31.536%2C39.157%2C33.89%20%20%20%20M42.034%2C22.597c-1.795-1.83-4.296-2.983-7.077-2.984c-2.404%2C0-4.474%2C0.829-6.281%2C2.3c-0.788%2C0.641-1.614%2C1.409-2.653%2C2.419%20%20%20c-0.516%2C0.501-15.485%2C15.026-15.485%2C15.026c0.785%2C0.112%2C1.864%2C0.145%2C2.826%2C0.151c0.902%2C0.006%2C18.1%2C0.004%2C18.82%2C0.004%20%20%20c1.449%2C0%2C2.392-0.002%2C3.405-0.076c2.323-0.17%2C4.518-1.022%2C6.292-2.764C45.82%2C32.805%2C45.879%2C26.526%2C42.034%2C22.597z%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%2300C8DC%3B%22%20d%3D%22M17.883%2C21.663c-1.76-1.317-3.729-2.053-5.963-2.05c-2.781%2C0-5.283%2C1.153-7.077%2C2.984%20%20%20c-3.845%2C3.93-3.786%2C10.209%2C0.154%2C14.077c1.582%2C1.553%2C3.498%2C2.398%2C5.541%2C2.684l3.854-3.74c-0.623-0.003-1.518-0.011-2.311-0.038%20%20%20c-2.235-0.076-3.597-0.934-4.361-1.689c-2.379-2.354-2.434-6.178-0.094-8.57c1.094-1.11%2C2.625-1.797%2C4.308-1.813%20%20%20c1.055-0.004%2C2.486%2C0.302%2C4.103%2C1.643c0.772%2C0.64%2C2.486%2C2.147%2C3.239%2C2.825c0.038%2C0.035%2C0.084%2C0.038%2C0.129%2C0.001l2.654-2.589%20%20%20c0.046-0.045%2C0.043-0.105-0.002-0.146C20.781%2C24.088%2C18.972%2C22.474%2C17.883%2C21.663%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%23006EFF%3B%22%20d%3D%22M36%2C17.365c-1.831-5.172-6.762-8.879-12.562-8.879c-6.652%2C0-12.165%2C4.892-13.164%2C11.264%20%20%20c0.535-0.09%2C1.085-0.138%2C1.646-0.138c0.781-0.001%2C1.529%2C0.09%2C2.248%2C0.263c0.014%2C0.003%2C0.028%2C0.005%2C0.042%2C0.008%20%20%20c0.901-4.302%2C4.705-7.498%2C9.228-7.498c3.767%2C0%2C7.072%2C2.272%2C8.562%2C5.492c0.023%2C0.051%2C0.063%2C0.067%2C0.104%2C0.056%20%20%20c1.121-0.308%2C2.464-0.487%2C3.762-0.391C35.992%2C17.552%2C36.04%2C17.481%2C36%2C17.365%22%2F%3E%20%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E"},image:{reader:class{findImages(e){return!e.q||e.q.length<3?Promise.resolve([{message:"Please enter at least 3 characters...",disabled:!0}]):t("/images/find").query({...e,provider:"tencentcloud"}).get().catch(()=>[])}getImage(e,l,n){return t("/images").path(n,l,e).query({provider:"tencentcloud"}).get().then(e=>e&&e.length?e[0]:null).catch(()=>null)}}}}),g.registerProvider("tencentcloud",["custom","redblack","rollingpush","rollingredblack"]);const R=h.providers.tencentcloud||{defaults:{}};R&&(R.resetToOriginal=h.resetProvider("tencentcloud"));export{R as TencentcloudProviderSettings};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/help/tencentcloud.help.ts","../src/image/image.reader.ts","../src/pipeline/stages/disableCluster/DisableClusterStageForm.tsx","../src/pipeline/stages/disableCluster/disableClusterStage.ts","../src/pipeline/stages/disableCluster/DisableClusterConfig.tsx","../src/pipeline/stages/disableCluster/disableClusterValidators.ts","../src/pipeline/stages/rollbackCluster/RollbackClusterStageForm.tsx","../src/pipeline/stages/rollbackCluster/rollbackClusterStage.ts","../src/pipeline/stages/rollbackCluster/RollbackClusterConfig.tsx","../src/pipeline/stages/rollbackCluster/rollbackClusterValidators.ts","../src/pipeline/stages/scaleDownCluster/ScaleDownClusterStageForm.tsx","../src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.ts","../src/pipeline/stages/scaleDownCluster/ScaleDownClusterConfig.tsx","../src/pipeline/stages/scaleDownCluster/scaledownClusterValidators.ts","../src/pipeline/stages/shrinkCluster/ShrinkClusterStageForm.tsx","../src/pipeline/stages/shrinkCluster/shrinkClusterStage.ts","../src/pipeline/stages/shrinkCluster/ShrinkClusterConfig.tsx","../src/pipeline/stages/shrinkCluster/shrinkClusterValidators.ts","../src/reactShims/tencentcloud.ngReact.ts","../src/reactShims/tencentcloud.react.injector.ts","../src/reactShims/tencentcloud.react.module.ts","../src/search/searchResultFormatter.js","../src/validation/ApplicationNameValidator.ts","../src/tencentcloud.module.ts","../src/logo/tencentcloud.logo.svg","../src/tencentcloud.settings.ts"],"sourcesContent":["import { HelpContentsRegistry } from '@spinnaker/core';\n\nconst helpContents: { [key: string]: string } = {};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","import { $q } from 'ngimport';\n\nimport { REST } from '@spinnaker/core';\nexport interface ITencentcloudSnapshot {\n diskSize: string;\n diskType: string;\n diskUsage: 'SYSTEM_DISK' | 'DATA_DISK';\n snapshotId: string;\n}\nexport interface ITencentcloudImage {\n accounts: string[];\n images: {\n [region: string]: string[];\n };\n imgIds: {\n [region: string]: string[];\n };\n attributes: {\n createdTime?: string;\n creationDate?: string;\n snapshotSet?: ITencentcloudSnapshot[];\n osPlatform: string;\n };\n imageName: string;\n tags: {\n [tag: string]: string;\n };\n tagsByImageId: {\n [imageId: string]: ITencentcloudImage['tags'];\n };\n}\n\nexport class TencentcloudImageReader {\n public findImages(params: { q: string; region?: string }): PromiseLike<ITencentcloudImage[]> {\n if (!params.q || params.q.length < 3) {\n return $q.when([{ message: 'Please enter at least 3 characters...', disabled: true }]) as any;\n }\n\n return REST('/images/find')\n .query({ ...params, provider: 'tencentcloud' })\n .get()\n .catch(() => [] as ITencentcloudImage[]);\n }\n\n public getImage(name: string, region: string, credentials: string): PromiseLike<ITencentcloudImage> {\n return REST('/images')\n .path(credentials, region, name)\n .query({ provider: 'tencentcloud' })\n .get()\n .then((results: any[]) => (results && results.length ? results[0] : null))\n .catch(() => null as ITencentcloudImage);\n }\n}\n","import React from 'react';\n\nimport type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport { AccountService, FormikFormField, NgReact, NumberInput, SelectInput, StageConfigField } from '@spinnaker/core';\n\nconst { useEffect, useState } = React;\nconst { AccountRegionClusterSelector } = NgReact;\n\nexport function DisableClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <AccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n />\n )}\n <StageConfigField label=\"Disable Options\">\n <div className=\"form-inline\">\n Keep the\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n <FormikFormField\n name=\"preferLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingEnabledServerGroups)} enabled.\n </div>\n </StageConfigField>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { DisableClusterConfig } from './DisableClusterConfig';\nimport { validate } from './disableClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'disableCluster',\n key: 'disableCluster',\n cloudProvider: 'tencentcloud',\n component: DisableClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { DisableClusterStageForm } from './DisableClusterStageForm';\n\nexport function DisableClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <DisableClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport { AccountService, FormikFormField, NgReact, NumberInput, StageConfigField } from '@spinnaker/core';\n\nconst { useEffect, useState } = React;\nconst { AccountRegionClusterSelector } = NgReact;\n\nexport function RollbackClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <AccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n />\n )}\n <StageConfigField label=\"Rollback Options\">\n <div className=\"row\">\n <div className=\"col-sm-10 col-sm-offset-2\">\n Wait\n <FormikFormField name=\"wait\" required input={(props) => <NumberInput {...props} min={0} />} />\n seconds between regional rollbacks.\n </div>\n <div className=\"col-sm-10 col-sm-offset-2\">\n Consider rollback successful when\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} max={100} />}\n />\n percent of instances are healthy.\n </div>\n </div>\n </StageConfigField>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { RollbackClusterConfig } from './RollbackClusterConfig';\nimport { validate } from './rollbackClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'rollbackCluster',\n key: 'rollbackCluster',\n cloudProvider: 'tencentcloud',\n component: RollbackClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { RollbackClusterStageForm } from './RollbackClusterStageForm';\n\nexport function RollbackClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <RollbackClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport {\n AccountService,\n CheckboxInput,\n FormikFormField,\n NgReact,\n NumberInput,\n SelectInput,\n StageConfigField,\n} from '@spinnaker/core';\n\nconst { useEffect, useState } = React;\nconst { AccountRegionClusterSelector } = NgReact;\n\nexport function ScaleDownClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <AccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n />\n )}\n <StageConfigField label=\"ScaleDown Options\">\n <div className=\"form-inline\">\n Keep the\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n <FormikFormField\n name=\"preferLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingFullSizeServerGroups)} at current size.\n <p>The remaining server groups will be scaled down to zero instances.</p>\n </div>\n </StageConfigField>\n <div className=\"form-group\">\n <FormikFormField\n name=\"allowScaleDownActive\"\n input={(props) => <CheckboxInput {...props} text=\"Allow scale down of active server groups\" />}\n />\n </div>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { ScaleDownClusterConfig } from './ScaleDownClusterConfig';\nimport { validate } from './scaledownClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'scaleDownCluster',\n key: 'scaleDownCluster',\n cloudProvider: 'tencentcloud',\n component: ScaleDownClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { ScaleDownClusterStageForm } from './ScaleDownClusterStageForm';\n\nexport function ScaleDownClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <ScaleDownClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport {\n AccountService,\n CheckboxInput,\n FormikFormField,\n NgReact,\n NumberInput,\n SelectInput,\n StageConfigField,\n} from '@spinnaker/core';\n\nconst { useEffect, useState } = React;\nconst { AccountRegionClusterSelector } = NgReact;\n\nexport function ShrinkClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <AccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n />\n )}\n <StageConfigField label=\"Shrink Options\">\n <div className=\"form-inline\">\n Shrink to\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n {pluralize('server group', stage.shrinkToSize)}, keeping the\n <FormikFormField\n name=\"retainLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingEnabledServerGroups)} enabled.\n </div>\n </StageConfigField>\n <div className=\"form-group\">\n <div className=\"col-md-offset-3 col-md-6 checkbox\">\n <FormikFormField\n name=\"allowDeleteActive\"\n input={(props) => <CheckboxInput {...props} text=\"Allow deletion of active server groups\" />}\n />\n </div>\n </div>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { ShrinkClusterConfig } from './ShrinkClusterConfig';\nimport { validate } from './shrinkClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'shrinkCluster',\n key: 'shrinkCluster',\n cloudProvider: 'tencentcloud',\n component: ShrinkClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { ShrinkClusterStageForm } from './ShrinkClusterStageForm';\n\nexport function ShrinkClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <ShrinkClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import IInjectorService = angular.auto.IInjectorService;\n\nimport { ReactInject } from '@spinnaker/core';\n\n// prettier-ignore\nexport class TencentcloudNgReactInjector extends ReactInject {\n public $injectorProxy = {} as IInjectorService;\n\n // Reactified components\n\n public initialize($injector: IInjectorService) {\n const realInjector: { [key: string]: Function } = $injector as any;\n const proxyInjector: { [key: string]: Function } = this.$injectorProxy as any;\n\n Object.keys($injector)\n .filter(key => typeof realInjector[key] === 'function')\n .forEach(key => proxyInjector[key] = realInjector[key].bind(realInjector));\n }\n}\n\nexport const TencentcloudNgReact = new TencentcloudNgReactInjector();\n","import IInjectorService = angular.auto.IInjectorService;\n\nimport { ReactInject } from '@spinnaker/core';\n\n// prettier-ignore\nexport class TencentcloudReactInject extends ReactInject {\n\n\n public initialize($injector: IInjectorService) {\n this.$injector = $injector;\n }\n}\n\nexport const TencentcloudReactInjector: TencentcloudReactInject = new TencentcloudReactInject();\n","import { module } from 'angular';\n\nimport { TencentcloudNgReact } from './tencentcloud.ngReact';\nimport { TencentcloudReactInjector } from './tencentcloud.react.injector';\n\nexport const TENCENTCLOUD_REACT_MODULE = 'spinnaker.tencentcloud.react';\nmodule(TENCENTCLOUD_REACT_MODULE, []).run([\n '$injector',\n function ($injector: any) {\n // Make angular services importable and (TODO when relevant) convert angular components to react\n TencentcloudReactInjector.initialize($injector);\n TencentcloudNgReact.initialize($injector);\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER = 'spinnaker.tencentcloud.search.searchResultFormatter';\nmodule(TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER, []).factory('tencentcloudSearchResultFormatter', function () {\n return {\n securityGroups: function (entry) {},\n };\n});\n","import type { IApplicationNameValidator } from '@spinnaker/core';\nimport { ApplicationNameValidator, FirewallLabels } from '@spinnaker/core';\n\nclass TencentcloudApplicationNameValidator implements IApplicationNameValidator {\n private validateSpecialCharacters(name: string, errors: string[]): void {\n const pattern = /^[a-zA-Z_0-9.]*$/g;\n if (!pattern.test(name)) {\n errors.push('Only dot(.) and underscore(_) special characters are allowed.');\n }\n }\n\n private validateLoadBalancerCharacters(name: string, warnings: string[]) {\n if (name.includes('.') || name.includes('_')) {\n warnings.push(`If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.`);\n }\n }\n\n private validateLength(name: string, warnings: string[], errors: string[]) {\n if (name.length > 250) {\n errors.push('The maximum length for an application in Tencentcloud is 250 characters.');\n return;\n }\n if (name.length > 240) {\n if (name.length >= 248) {\n warnings.push(\n `You will not be able to include a stack or detail field for clusters or ${FirewallLabels.get('firewalls')}.`,\n );\n } else {\n const remaining = 248 - name.length;\n warnings.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n if (name.length > 20) {\n if (name.length > 32) {\n warnings.push(`You will not be able to create an Tencentcloud load balancer for this application if the\n application's name is longer than 32 characters (currently: ${name.length} characters)`);\n } else {\n if (name.length >= 30) {\n warnings.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${name.length} characters). With separators (\"-\"), you will not\n be able to add a stack and detail field to any load balancer.`);\n } else {\n const remaining = 30 - name.length;\n warnings.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${remaining} characters to add a stack or detail\n field to any load balancer.`);\n }\n }\n }\n }\n\n public validate(name = '') {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (name.length) {\n this.validateSpecialCharacters(name, errors);\n this.validateLoadBalancerCharacters(name, warnings);\n this.validateLength(name, warnings, errors);\n }\n\n return {\n warnings,\n errors,\n };\n }\n}\nApplicationNameValidator.registerValidator('tencentcloud', new TencentcloudApplicationNameValidator());\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';\n\nimport './help/tencentcloud.help';\nimport { TencentcloudImageReader } from './image';\nimport logo from './logo/tencentcloud.logo.svg';\n// load pipeline stage\nimport './pipeline/stages/disableCluster/disableClusterStage';\nimport './pipeline/stages/rollbackCluster/rollbackClusterStage';\nimport './pipeline/stages/scaleDownCluster/scaleDownClusterStage';\nimport './pipeline/stages/shrinkCluster/shrinkClusterStage';\nimport { TENCENTCLOUD_REACT_MODULE } from './reactShims/tencentcloud.react.module';\nimport { TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER } from './search/searchResultFormatter';\nimport './validation/ApplicationNameValidator';\n\nexport const TENCENTCLOUD_MODULE = 'spinnaker.tencentcloud';\nmodule(TENCENTCLOUD_MODULE, [TENCENTCLOUD_REACT_MODULE, TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER]).config(() => {\n CloudProviderRegistry.registerProvider('tencentcloud', {\n name: 'tencentcloud',\n logo: {\n path: logo,\n },\n image: {\n reader: TencentcloudImageReader,\n },\n });\n});\n\nDeploymentStrategyRegistry.registerProvider('tencentcloud', ['custom', 'redblack', 'rollingpush', 'rollingredblack']);\n","export default \"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csvg%20version%3D%221.1%22%20id%3D%22%E5%9B%BE%E5%B1%82_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20%20width%3D%22120px%22%20height%3D%2248px%22%20viewBox%3D%220%200%20120%2048%22%20style%3D%22enable-background%3Anew%200%200%20120%2048%3B%22%20xml%3Aspace%3D%22preserve%22%3E%3Cg%3E%20%3Cg%3E%20%20%3Cpath%20d%3D%22M93.829%2C13.731H81.181v1.83h3.808v6.673h-4.364v1.83h4.364v11.19h2.013v-11.19h4.814V35.02h3.802v-1.831h-1.788V13.731z%20%20%20%20M87.002%2C22.234v-6.673h4.814v6.673H87.002z%22%2F%3E%20%20%3Crect%20x%3D%2258.743%22%20y%3D%2230.136%22%20width%3D%229.979%22%20height%3D%221.83%22%2F%3E%20%20%3Cpath%20d%3D%22M51.944%2C26.749c0%2C3.328-0.269%2C5.854-0.823%2C8.093c-0.058%2C0.207%2C0.004%2C0.263%2C0.113%2C0.263c0.038%2C0%2C1.525%2C0%2C1.835%2C0%20%20%20c0.613-3.075%2C0.693-5.626%2C0.703-7.477h2.565v5.69h-1.821c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h3.257V13.777h-6.22V26.749z%20%20%20%20M53.774%2C25.98V21.6h2.563v4.38H53.774z%20M56.337%2C15.607v4.346h-2.563v-4.346H56.337z%22%2F%3E%20%20%3Cpath%20d%3D%22M69.429%2C21.196h2.457v-1.647h-7.16c0.216-0.526%2C0.41-1.091%2C0.588-1.702h6.123V16.2h-1.794%20%20%20c0.299-1.018%2C0.651-2.219%2C0.672-2.288c0.036-0.122-0.028-0.169-0.107-0.169h-1.558L67.927%2C16.2h-2.202%20%20%20c0.205-0.952%2C0.384-2.007%2C0.547-3.191c0.019-0.137-0.055-0.164-0.146-0.164c-0.073%2C0-1.278%2C0-1.774%2C0%20%20%20c-0.181%2C1.258-0.371%2C2.342-0.614%2C3.355h-1.08l-0.722-2.457h-1.558c-0.079%2C0-0.143%2C0.047-0.107%2C0.169%20%20%20c0.02%2C0.07%2C0.373%2C1.271%2C0.672%2C2.288h-1.747v1.647h4.079c-0.166%2C0.52-0.41%2C1.133-0.67%2C1.702h-3.858v1.647h2.898%20%20%20c-1.168%2C1.659-2.417%2C2.422-2.915%2C2.727c0%2C0.234%2C0%2C1.83%2C0%2C1.884c0%2C0.095%2C0.075%2C0.196%2C0.373%2C0.027%20%20%20c0.542-0.307%2C1.12-0.655%2C1.705-1.087h6.817l-0.058%2C2.467h-5.382l0.082-1.475c0-0.064-0.046-0.111-0.112-0.111%20%20%20c-0.102%2C0-1.721%2C0-1.721%2C0l-0.173%2C3.122c0%2C0.064%2C0.046%2C0.111%2C0.112%2C0.111c0.102%2C0%2C9.285%2C0%2C9.285%2C0v4.454h-4.185%20%20%20c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h5.807v-7.931h-2.273l0.075-3.203c0.85%2C0.79%2C1.712%2C1.379%2C2.497%2C1.824%20%20%20c0.298%2C0.169%2C0.373%2C0.068%2C0.373-0.027c0-0.054%2C0-1.651%2C0-1.884C71.844%2C23.618%2C70.597%2C22.853%2C69.429%2C21.196z%20M67.188%2C21.196%20%20%20c0.438%2C0.721%2C0.91%2C1.351%2C1.398%2C1.903h-5.991c0.465-0.537%2C0.915-1.163%2C1.335-1.903H67.188z%22%2F%3E%20%20%3Cpath%20d%3D%22M82.457%2C28.864c-0.034%2C0.026-1.742%2C1.32-3.395%2C2.572V19.538h-4.704v2.013h2.704v11.4%20%20%20c-0.644%2C0.488-1.081%2C0.819-1.081%2C0.819l1.105%2C1.459l5.552-4.207c0%2C0%2C0-2.021%2C0-2.073C82.639%2C28.851%2C82.529%2C28.809%2C82.457%2C28.864z%22%20%20%20%2F%3E%20%20%3Cpath%20d%3D%22M77.329%2C17.736c0%2C0%2C2.15%2C0%2C2.2%2C0c0.098%2C0%2C0.137-0.106%2C0.094-0.171c-0.04-0.061-2.775-4.238-2.775-4.238s-2.117%2C0-2.2%2C0%20%20%20c-0.083%2C0-0.144%2C0.096-0.098%2C0.166C74.596%2C13.562%2C77.329%2C17.736%2C77.329%2C17.736z%22%2F%3E%20%20%3Crect%20x%3D%2299.874%22%20y%3D%2214.22%22%20width%3D%2215.888%22%20height%3D%222.013%22%2F%3E%20%20%3Cpath%20d%3D%22M105.637%2C23.841H118v-2.013H97.636v2.013h5.65c-1.167%2C3.064-4.095%2C10.753-4.115%2C10.809%20%20%20c-0.032%2C0.089%2C0.026%2C0.155%2C0.104%2C0.155c0.049%2C0%2C17.523%2C0%2C17.564%2C0c0.083%2C0%2C0.131-0.082%2C0.101-0.16%20%20%20c-0.019-0.049-2.619-6.885-2.619-6.885s-2.103%2C0-2.186%2C0s-0.133%2C0.08-0.105%2C0.153c0.028%2C0.073%2C1.853%2C4.879%2C1.853%2C4.879h-11.646%20%20%20L105.637%2C23.841z%22%2F%3E%20%3C%2Fg%3E%20%3Cg%3E%20%20%3Cpath%20style%3D%22fill%3A%2300A3FF%3B%22%20d%3D%22M39.157%2C33.89c-0.764%2C0.756-2.125%2C1.613-4.361%2C1.689c-1.034%2C0.035-2.241%2C0.039-2.793%2C0.039%20%20%20c-0.603%2C0-5.918%2C0-12.012%2C0c4.37-4.245%2C8.182-7.947%2C8.615-8.367c0.396-0.385%2C1.287-1.237%2C2.056-1.929%20%20%20c1.687-1.519%2C3.206-1.825%2C4.28-1.815c1.683%2C0.016%2C3.214%2C0.703%2C4.308%2C1.813C41.591%2C27.712%2C41.535%2C31.536%2C39.157%2C33.89%20%20%20%20M42.034%2C22.597c-1.795-1.83-4.296-2.983-7.077-2.984c-2.404%2C0-4.474%2C0.829-6.281%2C2.3c-0.788%2C0.641-1.614%2C1.409-2.653%2C2.419%20%20%20c-0.516%2C0.501-15.485%2C15.026-15.485%2C15.026c0.785%2C0.112%2C1.864%2C0.145%2C2.826%2C0.151c0.902%2C0.006%2C18.1%2C0.004%2C18.82%2C0.004%20%20%20c1.449%2C0%2C2.392-0.002%2C3.405-0.076c2.323-0.17%2C4.518-1.022%2C6.292-2.764C45.82%2C32.805%2C45.879%2C26.526%2C42.034%2C22.597z%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%2300C8DC%3B%22%20d%3D%22M17.883%2C21.663c-1.76-1.317-3.729-2.053-5.963-2.05c-2.781%2C0-5.283%2C1.153-7.077%2C2.984%20%20%20c-3.845%2C3.93-3.786%2C10.209%2C0.154%2C14.077c1.582%2C1.553%2C3.498%2C2.398%2C5.541%2C2.684l3.854-3.74c-0.623-0.003-1.518-0.011-2.311-0.038%20%20%20c-2.235-0.076-3.597-0.934-4.361-1.689c-2.379-2.354-2.434-6.178-0.094-8.57c1.094-1.11%2C2.625-1.797%2C4.308-1.813%20%20%20c1.055-0.004%2C2.486%2C0.302%2C4.103%2C1.643c0.772%2C0.64%2C2.486%2C2.147%2C3.239%2C2.825c0.038%2C0.035%2C0.084%2C0.038%2C0.129%2C0.001l2.654-2.589%20%20%20c0.046-0.045%2C0.043-0.105-0.002-0.146C20.781%2C24.088%2C18.972%2C22.474%2C17.883%2C21.663%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%23006EFF%3B%22%20d%3D%22M36%2C17.365c-1.831-5.172-6.762-8.879-12.562-8.879c-6.652%2C0-12.165%2C4.892-13.164%2C11.264%20%20%20c0.535-0.09%2C1.085-0.138%2C1.646-0.138c0.781-0.001%2C1.529%2C0.09%2C2.248%2C0.263c0.014%2C0.003%2C0.028%2C0.005%2C0.042%2C0.008%20%20%20c0.901-4.302%2C4.705-7.498%2C9.228-7.498c3.767%2C0%2C7.072%2C2.272%2C8.562%2C5.492c0.023%2C0.051%2C0.063%2C0.067%2C0.104%2C0.056%20%20%20c1.121-0.308%2C2.464-0.487%2C3.762-0.391C35.992%2C17.552%2C36.04%2C17.481%2C36%2C17.365%22%2F%3E%20%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E\"","import type { IProviderSettings } from '@spinnaker/core';\nimport { SETTINGS } from '@spinnaker/core';\n\nexport interface IClassicLaunchAllowlist {\n region: string;\n credentials: string;\n}\n\nexport interface ITencentcloudProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n subnetType?: string;\n vpc?: string;\n };\n defaultSecurityGroups?: string[];\n loadBalancers?: {\n inferInternalFlagFromSubnet: boolean;\n certificateTypes?: string[];\n };\n classicLaunchLockout?: number;\n classicLaunchAllowlist?: IClassicLaunchAllowlist[];\n metrics?: {\n customNamespaces?: string[];\n };\n minRootVolumeSize?: number;\n disableSpotPricing?: boolean;\n}\n\nexport const TencentcloudProviderSettings: ITencentcloudProviderSettings = (SETTINGS.providers\n .tencentcloud as ITencentcloudProviderSettings) || { defaults: {} };\n\nif (TencentcloudProviderSettings) {\n TencentcloudProviderSettings.resetToOriginal = SETTINGS.resetProvider('tencentcloud');\n}\n"],"names":["helpContents","Object","keys","forEach","key","HelpContentsRegistry","register","TencentcloudImageReader","findImages","params","q","length","$q","when","message","disabled","REST","query","provider","get","catch","getImage","name","region","credentials","path","then","results","useEffect","useState","React","AccountRegionClusterSelector","NgReact","DisableClusterStageForm","application","formik","pipeline","stage","values","setFieldValue","accounts","setAccounts","_a","_b","_c","_d","_e","_f","_g","AccountService","listAccounts","isNew","attributes","platformHealthOnlyShowOverride","platformHealthOnly","defaultCredentials","tencentcloud","regions","defaultRegions","remainingEnabledServerGroups","preferLargerOverNewer","className","strategy","createElement","clusterField","component","StageConfigField","label","FormikFormField","required","input","props","NumberInput","min","SelectInput","options","value","str","Registry","registerStage","provides","cloudProvider","updateStage","stageWithDefaults","useMemo","cloneDeep","FormikStageConfig","onChange","render","validateFn","formValidator","FormValidator","field","validateForm","RollbackClusterStageForm","max","ScaleDownClusterStageForm","remainingFullSizeServerGroups","CheckboxInput","text","ShrinkClusterStageForm","pluralize","val","shrinkToSize","TencentcloudNgReact","ReactInject","constructor","super","arguments","this","$injectorProxy","initialize","$injector","realInjector","proxyInjector","filter","bind","TencentcloudReactInjector","TENCENTCLOUD_REACT_MODULE","module","run","TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER","factory","securityGroups","entry","ApplicationNameValidator","registerValidator","validateSpecialCharacters","errors","test","push","validateLoadBalancerCharacters","warnings","includes","validateLength","FirewallLabels","remaining","validate","TENCENTCLOUD_MODULE","config","CloudProviderRegistry","registerProvider","logo","image","reader","DeploymentStrategyRegistry","TencentcloudProviderSettings","SETTINGS","providers","defaults","resetToOriginal","resetProvider"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/help/tencentcloud.help.ts","../src/pipeline/stages/TencentcloudAccountRegionClusterSelector.tsx","../src/pipeline/stages/disableCluster/DisableClusterStageForm.tsx","../src/pipeline/stages/disableCluster/disableClusterStage.ts","../src/pipeline/stages/disableCluster/DisableClusterConfig.tsx","../src/pipeline/stages/disableCluster/disableClusterValidators.ts","../src/pipeline/stages/rollbackCluster/RollbackClusterStageForm.tsx","../src/pipeline/stages/rollbackCluster/rollbackClusterStage.ts","../src/pipeline/stages/rollbackCluster/RollbackClusterConfig.tsx","../src/pipeline/stages/rollbackCluster/rollbackClusterValidators.ts","../src/pipeline/stages/scaleDownCluster/ScaleDownClusterStageForm.tsx","../src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.ts","../src/pipeline/stages/scaleDownCluster/ScaleDownClusterConfig.tsx","../src/pipeline/stages/scaleDownCluster/scaledownClusterValidators.ts","../src/pipeline/stages/shrinkCluster/ShrinkClusterStageForm.tsx","../src/pipeline/stages/shrinkCluster/shrinkClusterStage.ts","../src/pipeline/stages/shrinkCluster/ShrinkClusterConfig.tsx","../src/pipeline/stages/shrinkCluster/shrinkClusterValidators.ts","../src/validation/ApplicationNameValidator.ts","../src/tencentcloud.module.ts","../src/logo/tencentcloud.logo.svg","../src/image/image.reader.ts","../src/tencentcloud.settings.ts"],"sourcesContent":["import { HelpContentsRegistry } from '@spinnaker/core';\n\nconst helpContents: { [key: string]: string } = {};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","import { first, isNil, uniq } from 'lodash';\nimport React from 'react';\n\nimport type { Application, IAccountDetails, IMoniker, IServerGroup, IServerGroupFilter } from '@spinnaker/core';\nimport { AppListExtractor, ReactSelectInput, StageConfigField } from '@spinnaker/core';\n\nexport interface ITencentcloudAccountRegionClusterSelectorProps {\n accounts: IAccountDetails[];\n application: Application;\n clusterField?: string;\n component: any;\n setFieldValue: (field: string, value: any) => void;\n}\n\nexport function getRegionNamesWithAccountFallback(\n applicationRegions: string[],\n accounts: IAccountDetails[],\n credentials: string,\n selectedRegions: string[] = [],\n useAccountRegions = false,\n): string[] {\n const accountRegions = accounts\n .filter((account) => !credentials || account.name === credentials)\n .flatMap((account) => account.regions || [])\n .map((region) => region.name)\n .filter(Boolean);\n\n const selectedRegionMissingFromApplication = selectedRegions.some(\n (region) => !applicationRegions.includes(region) && accountRegions.includes(region),\n );\n\n if (applicationRegions.length && !selectedRegionMissingFromApplication && !useAccountRegions) {\n return uniq(applicationRegions).sort();\n }\n\n return uniq(accountRegions).sort();\n}\n\nexport function getClusterSelectorState(\n clusterNames: string[],\n selectedCluster: string,\n currentCustomMode: boolean,\n): { clusters: string[]; isCustomClusterInput: boolean } {\n const clusters = [...clusterNames];\n if (selectedCluster && !clusters.includes(selectedCluster)) {\n clusters.push(selectedCluster);\n return { clusters, isCustomClusterInput: true };\n }\n\n return { clusters, isCustomClusterInput: currentCustomMode };\n}\n\nexport function TencentcloudAccountRegionClusterSelector({\n accounts,\n application,\n clusterField = 'cluster',\n component,\n setFieldValue,\n}: ITencentcloudAccountRegionClusterSelectorProps) {\n const [availableRegions, setAvailableRegions] = React.useState<string[]>([]);\n const [clusters, setClusters] = React.useState<string[]>([]);\n const [isCustomClusterInput, setIsCustomClusterInput] = React.useState(false);\n const selectedClusterRef = React.useRef(component[clusterField]);\n selectedClusterRef.current = component[clusterField];\n\n React.useEffect(() => {\n let mounted = true;\n const accountFilter: IServerGroupFilter = (serverGroup: IServerGroup) =>\n serverGroup ? serverGroup.account === component.credentials : true;\n\n application.ready().then(() => {\n if (!mounted) {\n return;\n }\n const applicationRegions = AppListExtractor.getRegions([application], accountFilter);\n setAvailableRegions(\n getRegionNamesWithAccountFallback(\n applicationRegions,\n accounts,\n component.credentials,\n component.regions || [],\n isCustomClusterInput,\n ),\n );\n });\n\n return () => {\n mounted = false;\n };\n }, [accounts, application, component.credentials, component.regions, isCustomClusterInput]);\n\n React.useEffect(() => {\n let mounted = true;\n\n application.ready().then(() => {\n if (!mounted) {\n return;\n }\n\n const clusterFilter = AppListExtractor.clusterFilterForCredentialsAndRegion(\n component.credentials,\n component.regions || [],\n );\n const clusterNames = AppListExtractor.getClusters([application], clusterFilter);\n const { clusters: nextClusters, isCustomClusterInput: nextIsCustomClusterInput } = getClusterSelectorState(\n clusterNames,\n selectedClusterRef.current,\n isCustomClusterInput,\n );\n setIsCustomClusterInput(nextIsCustomClusterInput);\n setClusters(nextClusters);\n });\n\n return () => {\n mounted = false;\n };\n }, [application, clusterField, component.credentials, component.regions, isCustomClusterInput]);\n\n const onAccountUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {\n setFieldValue('credentials', event.target.value);\n setFieldValue('regions', []);\n setFieldValue(clusterField, undefined);\n };\n\n const onRegionsUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {\n setFieldValue('regions', event.target.value);\n if (!isCustomClusterInput) {\n setFieldValue(clusterField, undefined);\n }\n };\n\n const onClusterUpdate = (clusterName: string) => {\n const filterByCluster = AppListExtractor.monikerClusterNameFilter(clusterName);\n const clusterMoniker = first(uniq(AppListExtractor.getMonikers([application], filterByCluster))) as IMoniker;\n let moniker: IMoniker;\n\n if (isNil(clusterMoniker)) {\n moniker = undefined;\n } else {\n moniker = { ...clusterMoniker, sequence: null };\n }\n\n setFieldValue(clusterField, clusterName);\n setFieldValue('moniker', moniker);\n };\n\n const onClusterSelectUpdate = (event: React.ChangeEvent<HTMLSelectElement>) => {\n onClusterUpdate(event.target.value);\n };\n\n const onCustomClusterUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {\n onClusterUpdate(event.target.value);\n };\n\n const toggleCustomClusterInput = (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n const nextIsCustomClusterInput = !isCustomClusterInput;\n setIsCustomClusterInput(nextIsCustomClusterInput);\n if (!nextIsCustomClusterInput) {\n setFieldValue(clusterField, undefined);\n }\n };\n\n return (\n <>\n <StageConfigField label=\"Account\">\n <ReactSelectInput\n clearable={false}\n name=\"credentials\"\n onChange={onAccountUpdate}\n options={accounts.map((account) => ({ label: account.name, value: account.name }))}\n value={component.credentials}\n />\n </StageConfigField>\n <StageConfigField label=\"Region\">\n <ReactSelectInput\n clearable={false}\n multi={true}\n name=\"regions\"\n onChange={onRegionsUpdate}\n options={availableRegions.map((region) => ({ label: region, value: region }))}\n value={component.regions}\n />\n </StageConfigField>\n <StageConfigField helpKey=\"pipeline.config.findAmi.cluster\" label=\"Cluster\">\n {isCustomClusterInput ? (\n <input\n className=\"form-control input-sm\"\n name={clusterField}\n onBlur={onCustomClusterUpdate}\n onChange={(event) => setFieldValue(clusterField, event.target.value)}\n type=\"text\"\n value={component[clusterField] || ''}\n />\n ) : (\n <select\n className=\"form-control input-sm\"\n name={clusterField}\n onChange={onClusterSelectUpdate}\n value={component[clusterField] || ''}\n >\n <option value=\"\">-- select cluster --</option>\n {clusters.map((cluster) => (\n <option key={cluster} value={cluster}>\n {cluster}\n </option>\n ))}\n </select>\n )}\n <div className=\"pull-right\">\n <a className=\"clickable\" href=\"#\" onClick={toggleCustomClusterInput}>\n {isCustomClusterInput ? 'Toggle for list of existing clusters' : 'Toggle for text input'}\n </a>\n </div>\n </StageConfigField>\n </>\n );\n}\n","import React from 'react';\n\nimport type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport { AccountService, FormikFormField, NumberInput, SelectInput, StageConfigField } from '@spinnaker/core';\n\nimport { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';\n\nconst { useEffect, useState } = React;\n\nexport function DisableClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState<IAccountDetails[]>([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <TencentcloudAccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n setFieldValue={setFieldValue}\n />\n )}\n <StageConfigField label=\"Disable Options\">\n <div className=\"form-inline\">\n Keep the\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n <FormikFormField\n name=\"preferLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingEnabledServerGroups)} enabled.\n </div>\n </StageConfigField>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { DisableClusterConfig } from './DisableClusterConfig';\nimport { validate } from './disableClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'disableCluster',\n key: 'disableCluster',\n cloudProvider: 'tencentcloud',\n component: DisableClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { DisableClusterStageForm } from './DisableClusterStageForm';\n\nexport function DisableClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <DisableClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport { AccountService, FormikFormField, NumberInput, StageConfigField } from '@spinnaker/core';\n\nimport { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';\n\nconst { useEffect, useState } = React;\n\nexport function RollbackClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState<IAccountDetails[]>([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <TencentcloudAccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n setFieldValue={setFieldValue}\n />\n )}\n <StageConfigField label=\"Rollback Options\">\n <div className=\"row\">\n <div className=\"col-sm-10 col-sm-offset-2\">\n Wait\n <FormikFormField name=\"wait\" required input={(props) => <NumberInput {...props} min={0} />} />\n seconds between regional rollbacks.\n </div>\n <div className=\"col-sm-10 col-sm-offset-2\">\n Consider rollback successful when\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} max={100} />}\n />\n percent of instances are healthy.\n </div>\n </div>\n </StageConfigField>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { RollbackClusterConfig } from './RollbackClusterConfig';\nimport { validate } from './rollbackClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'rollbackCluster',\n key: 'rollbackCluster',\n cloudProvider: 'tencentcloud',\n component: RollbackClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { RollbackClusterStageForm } from './RollbackClusterStageForm';\n\nexport function RollbackClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <RollbackClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport {\n AccountService,\n CheckboxInput,\n FormikFormField,\n NumberInput,\n SelectInput,\n StageConfigField,\n} from '@spinnaker/core';\n\nimport { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';\n\nconst { useEffect, useState } = React;\n\nexport function ScaleDownClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState<IAccountDetails[]>([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <TencentcloudAccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n setFieldValue={setFieldValue}\n />\n )}\n <StageConfigField label=\"ScaleDown Options\">\n <div className=\"form-inline\">\n Keep the\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n <FormikFormField\n name=\"preferLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingFullSizeServerGroups)} at current size.\n <p>The remaining server groups will be scaled down to zero instances.</p>\n </div>\n </StageConfigField>\n <div className=\"form-group\">\n <FormikFormField\n name=\"allowScaleDownActive\"\n input={(props) => <CheckboxInput {...props} text=\"Allow scale down of active server groups\" />}\n />\n </div>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { ScaleDownClusterConfig } from './ScaleDownClusterConfig';\nimport { validate } from './scaledownClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'scaleDownCluster',\n key: 'scaleDownCluster',\n cloudProvider: 'tencentcloud',\n component: ScaleDownClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { ScaleDownClusterStageForm } from './ScaleDownClusterStageForm';\n\nexport function ScaleDownClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <ScaleDownClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import React from 'react';\n\nimport type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';\nimport {\n AccountService,\n CheckboxInput,\n FormikFormField,\n NumberInput,\n SelectInput,\n StageConfigField,\n} from '@spinnaker/core';\n\nimport { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';\n\nconst { useEffect, useState } = React;\n\nexport function ShrinkClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {\n const stage = formik.values;\n const { setFieldValue } = formik;\n const [accounts, setAccounts] = useState<IAccountDetails[]>([]);\n\n useEffect(() => {\n AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {\n setAccounts(accounts);\n });\n\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application?.attributes?.platformHealthOnly\n ) {\n setFieldValue('interestingHealthProviderNames', ['Tencentcloud']);\n }\n\n if (!stage.credentials && application?.defaultCredentials?.tencentcloud) {\n setFieldValue('credentials', application?.defaultCredentials?.tencentcloud);\n }\n\n if (!stage?.regions?.length && application?.defaultRegions?.tencentcloud) {\n setFieldValue('regions', [...stage.regions, application?.defaultRegions?.tencentcloud]);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n setFieldValue('remainingEnabledServerGroups', 1);\n }\n\n if (stage.preferLargerOverNewer === undefined) {\n setFieldValue('preferLargerOverNewer', 'false');\n }\n }, []);\n\n const pluralize = function (str: string, val: string | number) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n return (\n <div className=\"form-horizontal\">\n {!pipeline.strategy && (\n <TencentcloudAccountRegionClusterSelector\n application={application}\n clusterField=\"cluster\"\n component={stage}\n accounts={accounts}\n setFieldValue={setFieldValue}\n />\n )}\n <StageConfigField label=\"Shrink Options\">\n <div className=\"form-inline\">\n Shrink to\n <FormikFormField\n name=\"remainingEnabledServerGroups\"\n required\n input={(props) => <NumberInput {...props} min={0} />}\n />\n {pluralize('server group', stage.shrinkToSize)}, keeping the\n <FormikFormField\n name=\"retainLargerOverNewer\"\n required\n input={(props) => (\n <SelectInput\n options={[\n { label: 'largest', value: 'true' },\n { label: 'newest', value: 'false' },\n ]}\n {...props}\n />\n )}\n />\n {pluralize('server group', stage.remainingEnabledServerGroups)} enabled.\n </div>\n </StageConfigField>\n <div className=\"form-group\">\n <div className=\"col-md-offset-3 col-md-6 checkbox\">\n <FormikFormField\n name=\"allowDeleteActive\"\n input={(props) => <CheckboxInput {...props} text=\"Allow deletion of active server groups\" />}\n />\n </div>\n </div>\n </div>\n );\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { ShrinkClusterConfig } from './ShrinkClusterConfig';\nimport { validate } from './shrinkClusterValidators';\n\nRegistry.pipeline.registerStage({\n provides: 'shrinkCluster',\n key: 'shrinkCluster',\n cloudProvider: 'tencentcloud',\n component: ShrinkClusterConfig,\n validateFn: validate,\n});\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { IStageConfigProps } from '@spinnaker/core';\nimport { FormikStageConfig } from '@spinnaker/core';\n\nimport { ShrinkClusterStageForm } from './ShrinkClusterStageForm';\n\nexport function ShrinkClusterConfig({ application, pipeline, stage, updateStage }: IStageConfigProps) {\n const stageWithDefaults = React.useMemo(() => {\n return {\n cloudProvider: 'tencentcloud',\n regions: stage.regions || [],\n ...cloneDeep(stage),\n };\n }, []);\n\n return (\n <FormikStageConfig\n application={application}\n onChange={updateStage}\n pipeline={pipeline}\n stage={stageWithDefaults}\n render={(props) => <ShrinkClusterStageForm {...props} />}\n />\n );\n}\n","import type { IContextualValidator, IStage } from '@spinnaker/core';\nimport { FormValidator } from '@spinnaker/core';\n\nexport const validate: IContextualValidator = (stage: IStage) => {\n const formValidator = new FormValidator(stage);\n formValidator.field('credentials', 'Account').required();\n formValidator.field('regions', 'Regions').required();\n formValidator.field('cluster', 'Cluster').required();\n return formValidator.validateForm();\n};\n","import type { IApplicationNameValidator } from '@spinnaker/core';\nimport { ApplicationNameValidator, FirewallLabels } from '@spinnaker/core';\n\nclass TencentcloudApplicationNameValidator implements IApplicationNameValidator {\n private validateSpecialCharacters(name: string, errors: string[]): void {\n const pattern = /^[a-zA-Z_0-9.]*$/g;\n if (!pattern.test(name)) {\n errors.push('Only dot(.) and underscore(_) special characters are allowed.');\n }\n }\n\n private validateLoadBalancerCharacters(name: string, warnings: string[]) {\n if (name.includes('.') || name.includes('_')) {\n warnings.push(`If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.`);\n }\n }\n\n private validateLength(name: string, warnings: string[], errors: string[]) {\n if (name.length > 250) {\n errors.push('The maximum length for an application in Tencentcloud is 250 characters.');\n return;\n }\n if (name.length > 240) {\n if (name.length >= 248) {\n warnings.push(\n `You will not be able to include a stack or detail field for clusters or ${FirewallLabels.get('firewalls')}.`,\n );\n } else {\n const remaining = 248 - name.length;\n warnings.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n if (name.length > 20) {\n if (name.length > 32) {\n warnings.push(`You will not be able to create an Tencentcloud load balancer for this application if the\n application's name is longer than 32 characters (currently: ${name.length} characters)`);\n } else {\n if (name.length >= 30) {\n warnings.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${name.length} characters). With separators (\"-\"), you will not\n be able to add a stack and detail field to any load balancer.`);\n } else {\n const remaining = 30 - name.length;\n warnings.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${remaining} characters to add a stack or detail\n field to any load balancer.`);\n }\n }\n }\n }\n\n public validate(name = '') {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (name.length) {\n this.validateSpecialCharacters(name, errors);\n this.validateLoadBalancerCharacters(name, warnings);\n this.validateLength(name, warnings, errors);\n }\n\n return {\n warnings,\n errors,\n };\n }\n}\nApplicationNameValidator.registerValidator('tencentcloud', new TencentcloudApplicationNameValidator());\n","import { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';\n\nimport './help/tencentcloud.help';\nimport { TencentcloudImageReader } from './image';\nimport logo from './logo/tencentcloud.logo.svg';\n// load pipeline stage\nimport './pipeline/stages/disableCluster/disableClusterStage';\nimport './pipeline/stages/rollbackCluster/rollbackClusterStage';\nimport './pipeline/stages/scaleDownCluster/scaleDownClusterStage';\nimport './pipeline/stages/shrinkCluster/shrinkClusterStage';\nimport './validation/ApplicationNameValidator';\n\nCloudProviderRegistry.registerProvider('tencentcloud', {\n name: 'tencentcloud',\n logo: {\n path: logo,\n },\n image: {\n reader: TencentcloudImageReader,\n },\n});\n\nDeploymentStrategyRegistry.registerProvider('tencentcloud', ['custom', 'redblack', 'rollingpush', 'rollingredblack']);\n","export default \"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csvg%20version%3D%221.1%22%20id%3D%22%E5%9B%BE%E5%B1%82_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20%20width%3D%22120px%22%20height%3D%2248px%22%20viewBox%3D%220%200%20120%2048%22%20style%3D%22enable-background%3Anew%200%200%20120%2048%3B%22%20xml%3Aspace%3D%22preserve%22%3E%3Cg%3E%20%3Cg%3E%20%20%3Cpath%20d%3D%22M93.829%2C13.731H81.181v1.83h3.808v6.673h-4.364v1.83h4.364v11.19h2.013v-11.19h4.814V35.02h3.802v-1.831h-1.788V13.731z%20%20%20%20M87.002%2C22.234v-6.673h4.814v6.673H87.002z%22%2F%3E%20%20%3Crect%20x%3D%2258.743%22%20y%3D%2230.136%22%20width%3D%229.979%22%20height%3D%221.83%22%2F%3E%20%20%3Cpath%20d%3D%22M51.944%2C26.749c0%2C3.328-0.269%2C5.854-0.823%2C8.093c-0.058%2C0.207%2C0.004%2C0.263%2C0.113%2C0.263c0.038%2C0%2C1.525%2C0%2C1.835%2C0%20%20%20c0.613-3.075%2C0.693-5.626%2C0.703-7.477h2.565v5.69h-1.821c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h3.257V13.777h-6.22V26.749z%20%20%20%20M53.774%2C25.98V21.6h2.563v4.38H53.774z%20M56.337%2C15.607v4.346h-2.563v-4.346H56.337z%22%2F%3E%20%20%3Cpath%20d%3D%22M69.429%2C21.196h2.457v-1.647h-7.16c0.216-0.526%2C0.41-1.091%2C0.588-1.702h6.123V16.2h-1.794%20%20%20c0.299-1.018%2C0.651-2.219%2C0.672-2.288c0.036-0.122-0.028-0.169-0.107-0.169h-1.558L67.927%2C16.2h-2.202%20%20%20c0.205-0.952%2C0.384-2.007%2C0.547-3.191c0.019-0.137-0.055-0.164-0.146-0.164c-0.073%2C0-1.278%2C0-1.774%2C0%20%20%20c-0.181%2C1.258-0.371%2C2.342-0.614%2C3.355h-1.08l-0.722-2.457h-1.558c-0.079%2C0-0.143%2C0.047-0.107%2C0.169%20%20%20c0.02%2C0.07%2C0.373%2C1.271%2C0.672%2C2.288h-1.747v1.647h4.079c-0.166%2C0.52-0.41%2C1.133-0.67%2C1.702h-3.858v1.647h2.898%20%20%20c-1.168%2C1.659-2.417%2C2.422-2.915%2C2.727c0%2C0.234%2C0%2C1.83%2C0%2C1.884c0%2C0.095%2C0.075%2C0.196%2C0.373%2C0.027%20%20%20c0.542-0.307%2C1.12-0.655%2C1.705-1.087h6.817l-0.058%2C2.467h-5.382l0.082-1.475c0-0.064-0.046-0.111-0.112-0.111%20%20%20c-0.102%2C0-1.721%2C0-1.721%2C0l-0.173%2C3.122c0%2C0.064%2C0.046%2C0.111%2C0.112%2C0.111c0.102%2C0%2C9.285%2C0%2C9.285%2C0v4.454h-4.185%20%20%20c-0.089%2C0-0.157%2C0.058-0.11%2C0.184l0.502%2C1.646h5.807v-7.931h-2.273l0.075-3.203c0.85%2C0.79%2C1.712%2C1.379%2C2.497%2C1.824%20%20%20c0.298%2C0.169%2C0.373%2C0.068%2C0.373-0.027c0-0.054%2C0-1.651%2C0-1.884C71.844%2C23.618%2C70.597%2C22.853%2C69.429%2C21.196z%20M67.188%2C21.196%20%20%20c0.438%2C0.721%2C0.91%2C1.351%2C1.398%2C1.903h-5.991c0.465-0.537%2C0.915-1.163%2C1.335-1.903H67.188z%22%2F%3E%20%20%3Cpath%20d%3D%22M82.457%2C28.864c-0.034%2C0.026-1.742%2C1.32-3.395%2C2.572V19.538h-4.704v2.013h2.704v11.4%20%20%20c-0.644%2C0.488-1.081%2C0.819-1.081%2C0.819l1.105%2C1.459l5.552-4.207c0%2C0%2C0-2.021%2C0-2.073C82.639%2C28.851%2C82.529%2C28.809%2C82.457%2C28.864z%22%20%20%20%2F%3E%20%20%3Cpath%20d%3D%22M77.329%2C17.736c0%2C0%2C2.15%2C0%2C2.2%2C0c0.098%2C0%2C0.137-0.106%2C0.094-0.171c-0.04-0.061-2.775-4.238-2.775-4.238s-2.117%2C0-2.2%2C0%20%20%20c-0.083%2C0-0.144%2C0.096-0.098%2C0.166C74.596%2C13.562%2C77.329%2C17.736%2C77.329%2C17.736z%22%2F%3E%20%20%3Crect%20x%3D%2299.874%22%20y%3D%2214.22%22%20width%3D%2215.888%22%20height%3D%222.013%22%2F%3E%20%20%3Cpath%20d%3D%22M105.637%2C23.841H118v-2.013H97.636v2.013h5.65c-1.167%2C3.064-4.095%2C10.753-4.115%2C10.809%20%20%20c-0.032%2C0.089%2C0.026%2C0.155%2C0.104%2C0.155c0.049%2C0%2C17.523%2C0%2C17.564%2C0c0.083%2C0%2C0.131-0.082%2C0.101-0.16%20%20%20c-0.019-0.049-2.619-6.885-2.619-6.885s-2.103%2C0-2.186%2C0s-0.133%2C0.08-0.105%2C0.153c0.028%2C0.073%2C1.853%2C4.879%2C1.853%2C4.879h-11.646%20%20%20L105.637%2C23.841z%22%2F%3E%20%3C%2Fg%3E%20%3Cg%3E%20%20%3Cpath%20style%3D%22fill%3A%2300A3FF%3B%22%20d%3D%22M39.157%2C33.89c-0.764%2C0.756-2.125%2C1.613-4.361%2C1.689c-1.034%2C0.035-2.241%2C0.039-2.793%2C0.039%20%20%20c-0.603%2C0-5.918%2C0-12.012%2C0c4.37-4.245%2C8.182-7.947%2C8.615-8.367c0.396-0.385%2C1.287-1.237%2C2.056-1.929%20%20%20c1.687-1.519%2C3.206-1.825%2C4.28-1.815c1.683%2C0.016%2C3.214%2C0.703%2C4.308%2C1.813C41.591%2C27.712%2C41.535%2C31.536%2C39.157%2C33.89%20%20%20%20M42.034%2C22.597c-1.795-1.83-4.296-2.983-7.077-2.984c-2.404%2C0-4.474%2C0.829-6.281%2C2.3c-0.788%2C0.641-1.614%2C1.409-2.653%2C2.419%20%20%20c-0.516%2C0.501-15.485%2C15.026-15.485%2C15.026c0.785%2C0.112%2C1.864%2C0.145%2C2.826%2C0.151c0.902%2C0.006%2C18.1%2C0.004%2C18.82%2C0.004%20%20%20c1.449%2C0%2C2.392-0.002%2C3.405-0.076c2.323-0.17%2C4.518-1.022%2C6.292-2.764C45.82%2C32.805%2C45.879%2C26.526%2C42.034%2C22.597z%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%2300C8DC%3B%22%20d%3D%22M17.883%2C21.663c-1.76-1.317-3.729-2.053-5.963-2.05c-2.781%2C0-5.283%2C1.153-7.077%2C2.984%20%20%20c-3.845%2C3.93-3.786%2C10.209%2C0.154%2C14.077c1.582%2C1.553%2C3.498%2C2.398%2C5.541%2C2.684l3.854-3.74c-0.623-0.003-1.518-0.011-2.311-0.038%20%20%20c-2.235-0.076-3.597-0.934-4.361-1.689c-2.379-2.354-2.434-6.178-0.094-8.57c1.094-1.11%2C2.625-1.797%2C4.308-1.813%20%20%20c1.055-0.004%2C2.486%2C0.302%2C4.103%2C1.643c0.772%2C0.64%2C2.486%2C2.147%2C3.239%2C2.825c0.038%2C0.035%2C0.084%2C0.038%2C0.129%2C0.001l2.654-2.589%20%20%20c0.046-0.045%2C0.043-0.105-0.002-0.146C20.781%2C24.088%2C18.972%2C22.474%2C17.883%2C21.663%22%2F%3E%20%20%3Cpath%20style%3D%22fill%3A%23006EFF%3B%22%20d%3D%22M36%2C17.365c-1.831-5.172-6.762-8.879-12.562-8.879c-6.652%2C0-12.165%2C4.892-13.164%2C11.264%20%20%20c0.535-0.09%2C1.085-0.138%2C1.646-0.138c0.781-0.001%2C1.529%2C0.09%2C2.248%2C0.263c0.014%2C0.003%2C0.028%2C0.005%2C0.042%2C0.008%20%20%20c0.901-4.302%2C4.705-7.498%2C9.228-7.498c3.767%2C0%2C7.072%2C2.272%2C8.562%2C5.492c0.023%2C0.051%2C0.063%2C0.067%2C0.104%2C0.056%20%20%20c1.121-0.308%2C2.464-0.487%2C3.762-0.391C35.992%2C17.552%2C36.04%2C17.481%2C36%2C17.365%22%2F%3E%20%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E\"","import { REST } from '@spinnaker/core';\n\nexport interface ITencentcloudSnapshot {\n diskSize: string;\n diskType: string;\n diskUsage: 'SYSTEM_DISK' | 'DATA_DISK';\n snapshotId: string;\n}\nexport interface ITencentcloudImage {\n accounts: string[];\n images: {\n [region: string]: string[];\n };\n imgIds: {\n [region: string]: string[];\n };\n attributes: {\n createdTime?: string;\n creationDate?: string;\n snapshotSet?: ITencentcloudSnapshot[];\n osPlatform: string;\n };\n imageName: string;\n tags: {\n [tag: string]: string;\n };\n tagsByImageId: {\n [imageId: string]: ITencentcloudImage['tags'];\n };\n}\n\nexport class TencentcloudImageReader {\n public findImages(params: { q: string; region?: string }): Promise<ITencentcloudImage[]> {\n if (!params.q || params.q.length < 3) {\n return Promise.resolve([{ message: 'Please enter at least 3 characters...', disabled: true }] as any);\n }\n\n return REST('/images/find')\n .query({ ...params, provider: 'tencentcloud' })\n .get()\n .catch(() => [] as ITencentcloudImage[]);\n }\n\n public getImage(name: string, region: string, credentials: string): Promise<ITencentcloudImage> {\n return REST('/images')\n .path(credentials, region, name)\n .query({ provider: 'tencentcloud' })\n .get()\n .then((results: any[]) => (results && results.length ? results[0] : null))\n .catch(() => null as ITencentcloudImage);\n }\n}\n","import type { IProviderSettings } from '@spinnaker/core';\nimport { SETTINGS } from '@spinnaker/core';\n\nexport interface IClassicLaunchAllowlist {\n region: string;\n credentials: string;\n}\n\nexport interface ITencentcloudProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n subnetType?: string;\n vpc?: string;\n };\n defaultSecurityGroups?: string[];\n loadBalancers?: {\n inferInternalFlagFromSubnet: boolean;\n certificateTypes?: string[];\n };\n classicLaunchLockout?: number;\n classicLaunchAllowlist?: IClassicLaunchAllowlist[];\n metrics?: {\n customNamespaces?: string[];\n };\n minRootVolumeSize?: number;\n disableSpotPricing?: boolean;\n}\n\nexport const TencentcloudProviderSettings: ITencentcloudProviderSettings = (SETTINGS.providers\n .tencentcloud as ITencentcloudProviderSettings) || { defaults: {} };\n\nif (TencentcloudProviderSettings) {\n TencentcloudProviderSettings.resetToOriginal = SETTINGS.resetProvider('tencentcloud');\n}\n"],"names":["helpContents","Object","keys","forEach","key","HelpContentsRegistry","register","TencentcloudAccountRegionClusterSelector","accounts","application","clusterField","component","setFieldValue","availableRegions","setAvailableRegions","React","useState","clusters","setClusters","isCustomClusterInput","setIsCustomClusterInput","selectedClusterRef","useRef","current","useEffect","mounted","accountFilter","serverGroup","account","credentials","ready","then","applicationRegions","AppListExtractor","getRegions","selectedRegions","useAccountRegions","accountRegions","filter","name","flatMap","regions","map","region","Boolean","selectedRegionMissingFromApplication","some","includes","length","uniq","sort","getRegionNamesWithAccountFallback","clusterFilter","clusterFilterForCredentialsAndRegion","clusterNames","getClusters","nextClusters","nextIsCustomClusterInput","selectedCluster","currentCustomMode","push","getClusterSelectorState","onClusterUpdate","clusterName","filterByCluster","monikerClusterNameFilter","clusterMoniker","first","getMonikers","moniker","isNil","sequence","createElement","Fragment","StageConfigField","label","ReactSelectInput","clearable","onChange","event","target","value","options","multi","helpKey","className","onBlur","type","cluster","href","onClick","preventDefault","DisableClusterStageForm","formik","pipeline","stage","values","setAccounts","_a","_b","_c","_d","_e","_f","_g","AccountService","listAccounts","isNew","attributes","platformHealthOnlyShowOverride","platformHealthOnly","defaultCredentials","tencentcloud","defaultRegions","remainingEnabledServerGroups","preferLargerOverNewer","strategy","FormikFormField","required","input","props","NumberInput","min","SelectInput","str","Registry","registerStage","provides","cloudProvider","updateStage","stageWithDefaults","useMemo","cloneDeep","FormikStageConfig","render","validateFn","formValidator","FormValidator","field","validateForm","RollbackClusterStageForm","max","ScaleDownClusterStageForm","remainingFullSizeServerGroups","CheckboxInput","text","ShrinkClusterStageForm","pluralize","val","shrinkToSize","ApplicationNameValidator","registerValidator","validateSpecialCharacters","errors","test","validateLoadBalancerCharacters","warnings","validateLength","FirewallLabels","get","remaining","validate","this","CloudProviderRegistry","registerProvider","logo","path","image","reader","findImages","params","q","Promise","resolve","message","disabled","REST","query","provider","catch","getImage","results","DeploymentStrategyRegistry","TencentcloudProviderSettings","SETTINGS","providers","defaults","resetToOriginal","resetProvider"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import type { IKeyPair } from '../domain';
2
2
  export declare class KeyPairsReader {
3
- static listKeyPairs(): PromiseLike<IKeyPair[]>;
3
+ static listKeyPairs(): Promise<IKeyPair[]>;
4
4
  }
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import type { Application, IAccountDetails } from '@spinnaker/core';
3
+ export interface ITencentcloudAccountRegionClusterSelectorProps {
4
+ accounts: IAccountDetails[];
5
+ application: Application;
6
+ clusterField?: string;
7
+ component: any;
8
+ setFieldValue: (field: string, value: any) => void;
9
+ }
10
+ export declare function getRegionNamesWithAccountFallback(applicationRegions: string[], accounts: IAccountDetails[], credentials: string, selectedRegions?: string[], useAccountRegions?: boolean): string[];
11
+ export declare function getClusterSelectorState(clusterNames: string[], selectedCluster: string, currentCustomMode: boolean): {
12
+ clusters: string[];
13
+ isCustomClusterInput: boolean;
14
+ };
15
+ export declare function TencentcloudAccountRegionClusterSelector({ accounts, application, clusterField, component, setFieldValue, }: ITencentcloudAccountRegionClusterSelectorProps): JSX.Element;
@@ -4,4 +4,3 @@ import './pipeline/stages/rollbackCluster/rollbackClusterStage';
4
4
  import './pipeline/stages/scaleDownCluster/scaleDownClusterStage';
5
5
  import './pipeline/stages/shrinkCluster/shrinkClusterStage';
6
6
  import './validation/ApplicationNameValidator';
7
- export declare const TENCENTCLOUD_MODULE = "spinnaker.tencentcloud";
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/spinnaker/spinnaker.git"
6
6
  },
7
7
  "license": "Apache-2.0",
8
- "version": "2026.2.3",
8
+ "version": "2026.3.0",
9
9
  "module": "dist/index.js",
10
10
  "typings": "dist/index.d.ts",
11
11
  "publishConfig": {
@@ -22,20 +22,17 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@spinnaker/core": "^0.29.1",
25
- "angular": "1.8.3",
26
25
  "lodash": "^4.17.19",
27
- "ngimport": "^0.6.0",
28
26
  "react": "~16.14.0"
29
27
  },
30
28
  "devDependencies": {
31
29
  "@spinnaker/eslint-plugin": "^3.0.2",
32
30
  "@spinnaker/scripts": "^0.4.0",
33
- "@types/angular": "1.6.26",
34
31
  "@types/lodash": "4.14.64",
35
32
  "@types/node": "7.0.5",
36
33
  "@types/react": "16.14.10",
37
34
  "shx": "0.3.3",
38
35
  "typescript": "5.0.4"
39
36
  },
40
- "gitHead": "a4e60ac0d767ffea0a41057a8bd9b0df110dfaa4"
37
+ "gitHead": "0f7d75f5d4b42c1675e2ecc69a53f8eb73090eb9"
41
38
  }
@@ -1,6 +1,5 @@
1
- import { $q } from 'ngimport';
2
-
3
1
  import { REST } from '@spinnaker/core';
2
+
4
3
  export interface ITencentcloudSnapshot {
5
4
  diskSize: string;
6
5
  diskType: string;
@@ -31,9 +30,9 @@ export interface ITencentcloudImage {
31
30
  }
32
31
 
33
32
  export class TencentcloudImageReader {
34
- public findImages(params: { q: string; region?: string }): PromiseLike<ITencentcloudImage[]> {
33
+ public findImages(params: { q: string; region?: string }): Promise<ITencentcloudImage[]> {
35
34
  if (!params.q || params.q.length < 3) {
36
- return $q.when([{ message: 'Please enter at least 3 characters...', disabled: true }]) as any;
35
+ return Promise.resolve([{ message: 'Please enter at least 3 characters...', disabled: true }] as any);
37
36
  }
38
37
 
39
38
  return REST('/images/find')
@@ -42,7 +41,7 @@ export class TencentcloudImageReader {
42
41
  .catch(() => [] as ITencentcloudImage[]);
43
42
  }
44
43
 
45
- public getImage(name: string, region: string, credentials: string): PromiseLike<ITencentcloudImage> {
44
+ public getImage(name: string, region: string, credentials: string): Promise<ITencentcloudImage> {
46
45
  return REST('/images')
47
46
  .path(credentials, region, name)
48
47
  .query({ provider: 'tencentcloud' })
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { TENCENTCLOUD_MODULE } from './tencentcloud.module';
1
+ import './tencentcloud.module';
2
+
2
3
  export * from './tencentcloud.settings';
@@ -2,7 +2,7 @@ import { REST } from '@spinnaker/core';
2
2
  import type { IKeyPair } from '../domain';
3
3
 
4
4
  export class KeyPairsReader {
5
- public static listKeyPairs(): PromiseLike<IKeyPair[]> {
5
+ public static listKeyPairs(): Promise<IKeyPair[]> {
6
6
  return REST('/keyPairs')
7
7
  .useCache()
8
8
  .get()
@@ -0,0 +1,114 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+
4
+ import type { Application, IAccountDetails, IMoniker, IServerGroup } from '@spinnaker/core';
5
+
6
+ import {
7
+ getClusterSelectorState,
8
+ getRegionNamesWithAccountFallback,
9
+ TencentcloudAccountRegionClusterSelector,
10
+ } from './TencentcloudAccountRegionClusterSelector';
11
+
12
+ describe('<TencentcloudAccountRegionClusterSelector />', () => {
13
+ it('does not mutate the cached server group moniker when storing the selected cluster moniker', () => {
14
+ const cachedMoniker: IMoniker = { app: 'fnord', cluster: 'fnord-prod', stack: 'prod', sequence: 7 };
15
+ const application = {
16
+ ready: () => Promise.resolve(),
17
+ getDataSource: () => ({
18
+ data: [{ account: 'test', cluster: 'fnord-prod', moniker: cachedMoniker, region: 'us-east-1' } as IServerGroup],
19
+ }),
20
+ } as Application;
21
+ const setFieldValue = jasmine.createSpy('setFieldValue');
22
+
23
+ const component = shallow(
24
+ React.createElement(TencentcloudAccountRegionClusterSelector, {
25
+ accounts: [],
26
+ application,
27
+ component: { credentials: 'test', regions: ['us-east-1'] },
28
+ setFieldValue,
29
+ }),
30
+ );
31
+
32
+ component.find('select').simulate('change', { target: { value: 'fnord-prod' } });
33
+
34
+ expect(cachedMoniker.sequence).toBe(7);
35
+ expect(setFieldValue).toHaveBeenCalledWith('moniker', { ...cachedMoniker, sequence: null });
36
+ expect(setFieldValue.calls.mostRecent().args[1]).not.toBe(cachedMoniker);
37
+ });
38
+
39
+ it('updates custom cluster text without recalculating the moniker until blur', () => {
40
+ const cachedMoniker: IMoniker = { app: 'fnord', cluster: 'fnord-prod', stack: 'prod', sequence: 7 };
41
+ const application = {
42
+ ready: () => Promise.resolve(),
43
+ getDataSource: () => ({
44
+ data: [{ account: 'test', cluster: 'fnord-prod', moniker: cachedMoniker, region: 'us-east-1' } as IServerGroup],
45
+ }),
46
+ } as Application;
47
+ const setFieldValue = jasmine.createSpy('setFieldValue');
48
+ const component = shallow(
49
+ React.createElement(TencentcloudAccountRegionClusterSelector, {
50
+ accounts: [],
51
+ application,
52
+ component: { credentials: 'test', regions: ['us-east-1'] },
53
+ setFieldValue,
54
+ }),
55
+ );
56
+
57
+ component.find('a').simulate('click', { preventDefault: jasmine.createSpy('preventDefault') });
58
+ setFieldValue.calls.reset();
59
+ component.find('input').simulate('change', { target: { value: 'fnord' } });
60
+
61
+ expect(setFieldValue.calls.allArgs()).toEqual([['cluster', 'fnord']]);
62
+
63
+ component.find('input').simulate('blur', { target: { value: 'fnord-prod' } });
64
+
65
+ expect(setFieldValue).toHaveBeenCalledWith('moniker', { ...cachedMoniker, sequence: null });
66
+ });
67
+ });
68
+
69
+ describe('getRegionNamesWithAccountFallback', () => {
70
+ const accounts = [
71
+ {
72
+ name: 'test',
73
+ regions: [{ name: 'us-east-1' }, { name: 'eu-west-1' }],
74
+ },
75
+ ] as IAccountDetails[];
76
+
77
+ it('uses application regions when clusters provide them', () => {
78
+ expect(getRegionNamesWithAccountFallback(['us-west-2'], accounts, 'test', ['us-west-2'])).toEqual(['us-west-2']);
79
+ });
80
+
81
+ it('falls back to account regions when the application has no regions for the account', () => {
82
+ expect(getRegionNamesWithAccountFallback([], accounts, 'test', [])).toEqual(['eu-west-1', 'us-east-1']);
83
+ });
84
+
85
+ it('falls back to account regions when a selected region is missing from application regions', () => {
86
+ expect(getRegionNamesWithAccountFallback(['us-west-2'], accounts, 'test', ['eu-west-1'])).toEqual([
87
+ 'eu-west-1',
88
+ 'us-east-1',
89
+ ]);
90
+ });
91
+
92
+ it('uses account regions for custom cluster input even when application regions exist', () => {
93
+ expect(getRegionNamesWithAccountFallback(['us-east-1'], accounts, 'test', [], true)).toEqual([
94
+ 'eu-west-1',
95
+ 'us-east-1',
96
+ ]);
97
+ });
98
+ });
99
+
100
+ describe('getClusterSelectorState', () => {
101
+ it('preserves custom input mode when a typed value matches an existing cluster', () => {
102
+ expect(getClusterSelectorState(['prod'], 'prod', true)).toEqual({
103
+ clusters: ['prod'],
104
+ isCustomClusterInput: true,
105
+ });
106
+ });
107
+
108
+ it('restores custom input mode for a persisted custom cluster name', () => {
109
+ expect(getClusterSelectorState(['prod'], 'custom', false)).toEqual({
110
+ clusters: ['prod', 'custom'],
111
+ isCustomClusterInput: true,
112
+ });
113
+ });
114
+ });
@@ -0,0 +1,218 @@
1
+ import { first, isNil, uniq } from 'lodash';
2
+ import React from 'react';
3
+
4
+ import type { Application, IAccountDetails, IMoniker, IServerGroup, IServerGroupFilter } from '@spinnaker/core';
5
+ import { AppListExtractor, ReactSelectInput, StageConfigField } from '@spinnaker/core';
6
+
7
+ export interface ITencentcloudAccountRegionClusterSelectorProps {
8
+ accounts: IAccountDetails[];
9
+ application: Application;
10
+ clusterField?: string;
11
+ component: any;
12
+ setFieldValue: (field: string, value: any) => void;
13
+ }
14
+
15
+ export function getRegionNamesWithAccountFallback(
16
+ applicationRegions: string[],
17
+ accounts: IAccountDetails[],
18
+ credentials: string,
19
+ selectedRegions: string[] = [],
20
+ useAccountRegions = false,
21
+ ): string[] {
22
+ const accountRegions = accounts
23
+ .filter((account) => !credentials || account.name === credentials)
24
+ .flatMap((account) => account.regions || [])
25
+ .map((region) => region.name)
26
+ .filter(Boolean);
27
+
28
+ const selectedRegionMissingFromApplication = selectedRegions.some(
29
+ (region) => !applicationRegions.includes(region) && accountRegions.includes(region),
30
+ );
31
+
32
+ if (applicationRegions.length && !selectedRegionMissingFromApplication && !useAccountRegions) {
33
+ return uniq(applicationRegions).sort();
34
+ }
35
+
36
+ return uniq(accountRegions).sort();
37
+ }
38
+
39
+ export function getClusterSelectorState(
40
+ clusterNames: string[],
41
+ selectedCluster: string,
42
+ currentCustomMode: boolean,
43
+ ): { clusters: string[]; isCustomClusterInput: boolean } {
44
+ const clusters = [...clusterNames];
45
+ if (selectedCluster && !clusters.includes(selectedCluster)) {
46
+ clusters.push(selectedCluster);
47
+ return { clusters, isCustomClusterInput: true };
48
+ }
49
+
50
+ return { clusters, isCustomClusterInput: currentCustomMode };
51
+ }
52
+
53
+ export function TencentcloudAccountRegionClusterSelector({
54
+ accounts,
55
+ application,
56
+ clusterField = 'cluster',
57
+ component,
58
+ setFieldValue,
59
+ }: ITencentcloudAccountRegionClusterSelectorProps) {
60
+ const [availableRegions, setAvailableRegions] = React.useState<string[]>([]);
61
+ const [clusters, setClusters] = React.useState<string[]>([]);
62
+ const [isCustomClusterInput, setIsCustomClusterInput] = React.useState(false);
63
+ const selectedClusterRef = React.useRef(component[clusterField]);
64
+ selectedClusterRef.current = component[clusterField];
65
+
66
+ React.useEffect(() => {
67
+ let mounted = true;
68
+ const accountFilter: IServerGroupFilter = (serverGroup: IServerGroup) =>
69
+ serverGroup ? serverGroup.account === component.credentials : true;
70
+
71
+ application.ready().then(() => {
72
+ if (!mounted) {
73
+ return;
74
+ }
75
+ const applicationRegions = AppListExtractor.getRegions([application], accountFilter);
76
+ setAvailableRegions(
77
+ getRegionNamesWithAccountFallback(
78
+ applicationRegions,
79
+ accounts,
80
+ component.credentials,
81
+ component.regions || [],
82
+ isCustomClusterInput,
83
+ ),
84
+ );
85
+ });
86
+
87
+ return () => {
88
+ mounted = false;
89
+ };
90
+ }, [accounts, application, component.credentials, component.regions, isCustomClusterInput]);
91
+
92
+ React.useEffect(() => {
93
+ let mounted = true;
94
+
95
+ application.ready().then(() => {
96
+ if (!mounted) {
97
+ return;
98
+ }
99
+
100
+ const clusterFilter = AppListExtractor.clusterFilterForCredentialsAndRegion(
101
+ component.credentials,
102
+ component.regions || [],
103
+ );
104
+ const clusterNames = AppListExtractor.getClusters([application], clusterFilter);
105
+ const { clusters: nextClusters, isCustomClusterInput: nextIsCustomClusterInput } = getClusterSelectorState(
106
+ clusterNames,
107
+ selectedClusterRef.current,
108
+ isCustomClusterInput,
109
+ );
110
+ setIsCustomClusterInput(nextIsCustomClusterInput);
111
+ setClusters(nextClusters);
112
+ });
113
+
114
+ return () => {
115
+ mounted = false;
116
+ };
117
+ }, [application, clusterField, component.credentials, component.regions, isCustomClusterInput]);
118
+
119
+ const onAccountUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
120
+ setFieldValue('credentials', event.target.value);
121
+ setFieldValue('regions', []);
122
+ setFieldValue(clusterField, undefined);
123
+ };
124
+
125
+ const onRegionsUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
126
+ setFieldValue('regions', event.target.value);
127
+ if (!isCustomClusterInput) {
128
+ setFieldValue(clusterField, undefined);
129
+ }
130
+ };
131
+
132
+ const onClusterUpdate = (clusterName: string) => {
133
+ const filterByCluster = AppListExtractor.monikerClusterNameFilter(clusterName);
134
+ const clusterMoniker = first(uniq(AppListExtractor.getMonikers([application], filterByCluster))) as IMoniker;
135
+ let moniker: IMoniker;
136
+
137
+ if (isNil(clusterMoniker)) {
138
+ moniker = undefined;
139
+ } else {
140
+ moniker = { ...clusterMoniker, sequence: null };
141
+ }
142
+
143
+ setFieldValue(clusterField, clusterName);
144
+ setFieldValue('moniker', moniker);
145
+ };
146
+
147
+ const onClusterSelectUpdate = (event: React.ChangeEvent<HTMLSelectElement>) => {
148
+ onClusterUpdate(event.target.value);
149
+ };
150
+
151
+ const onCustomClusterUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
152
+ onClusterUpdate(event.target.value);
153
+ };
154
+
155
+ const toggleCustomClusterInput = (event: React.MouseEvent<HTMLAnchorElement>) => {
156
+ event.preventDefault();
157
+ const nextIsCustomClusterInput = !isCustomClusterInput;
158
+ setIsCustomClusterInput(nextIsCustomClusterInput);
159
+ if (!nextIsCustomClusterInput) {
160
+ setFieldValue(clusterField, undefined);
161
+ }
162
+ };
163
+
164
+ return (
165
+ <>
166
+ <StageConfigField label="Account">
167
+ <ReactSelectInput
168
+ clearable={false}
169
+ name="credentials"
170
+ onChange={onAccountUpdate}
171
+ options={accounts.map((account) => ({ label: account.name, value: account.name }))}
172
+ value={component.credentials}
173
+ />
174
+ </StageConfigField>
175
+ <StageConfigField label="Region">
176
+ <ReactSelectInput
177
+ clearable={false}
178
+ multi={true}
179
+ name="regions"
180
+ onChange={onRegionsUpdate}
181
+ options={availableRegions.map((region) => ({ label: region, value: region }))}
182
+ value={component.regions}
183
+ />
184
+ </StageConfigField>
185
+ <StageConfigField helpKey="pipeline.config.findAmi.cluster" label="Cluster">
186
+ {isCustomClusterInput ? (
187
+ <input
188
+ className="form-control input-sm"
189
+ name={clusterField}
190
+ onBlur={onCustomClusterUpdate}
191
+ onChange={(event) => setFieldValue(clusterField, event.target.value)}
192
+ type="text"
193
+ value={component[clusterField] || ''}
194
+ />
195
+ ) : (
196
+ <select
197
+ className="form-control input-sm"
198
+ name={clusterField}
199
+ onChange={onClusterSelectUpdate}
200
+ value={component[clusterField] || ''}
201
+ >
202
+ <option value="">-- select cluster --</option>
203
+ {clusters.map((cluster) => (
204
+ <option key={cluster} value={cluster}>
205
+ {cluster}
206
+ </option>
207
+ ))}
208
+ </select>
209
+ )}
210
+ <div className="pull-right">
211
+ <a className="clickable" href="#" onClick={toggleCustomClusterInput}>
212
+ {isCustomClusterInput ? 'Toggle for list of existing clusters' : 'Toggle for text input'}
213
+ </a>
214
+ </div>
215
+ </StageConfigField>
216
+ </>
217
+ );
218
+ }
@@ -1,18 +1,19 @@
1
1
  import React from 'react';
2
2
 
3
- import type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
- import { AccountService, FormikFormField, NgReact, NumberInput, SelectInput, StageConfigField } from '@spinnaker/core';
3
+ import type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
+ import { AccountService, FormikFormField, NumberInput, SelectInput, StageConfigField } from '@spinnaker/core';
5
+
6
+ import { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';
5
7
 
6
8
  const { useEffect, useState } = React;
7
- const { AccountRegionClusterSelector } = NgReact;
8
9
 
9
10
  export function DisableClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {
10
11
  const stage = formik.values;
11
12
  const { setFieldValue } = formik;
12
- const [accounts, setAccounts] = useState([]);
13
+ const [accounts, setAccounts] = useState<IAccountDetails[]>([]);
13
14
 
14
15
  useEffect(() => {
15
- AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {
16
+ AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {
16
17
  setAccounts(accounts);
17
18
  });
18
19
 
@@ -51,11 +52,12 @@ export function DisableClusterStageForm({ application, formik, pipeline }: IForm
51
52
  return (
52
53
  <div className="form-horizontal">
53
54
  {!pipeline.strategy && (
54
- <AccountRegionClusterSelector
55
+ <TencentcloudAccountRegionClusterSelector
55
56
  application={application}
56
57
  clusterField="cluster"
57
58
  component={stage}
58
59
  accounts={accounts}
60
+ setFieldValue={setFieldValue}
59
61
  />
60
62
  )}
61
63
  <StageConfigField label="Disable Options">
@@ -1,18 +1,19 @@
1
1
  import React from 'react';
2
2
 
3
- import type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
- import { AccountService, FormikFormField, NgReact, NumberInput, StageConfigField } from '@spinnaker/core';
3
+ import type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
+ import { AccountService, FormikFormField, NumberInput, StageConfigField } from '@spinnaker/core';
5
+
6
+ import { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';
5
7
 
6
8
  const { useEffect, useState } = React;
7
- const { AccountRegionClusterSelector } = NgReact;
8
9
 
9
10
  export function RollbackClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {
10
11
  const stage = formik.values;
11
12
  const { setFieldValue } = formik;
12
- const [accounts, setAccounts] = useState([]);
13
+ const [accounts, setAccounts] = useState<IAccountDetails[]>([]);
13
14
 
14
15
  useEffect(() => {
15
- AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {
16
+ AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {
16
17
  setAccounts(accounts);
17
18
  });
18
19
 
@@ -44,11 +45,12 @@ export function RollbackClusterStageForm({ application, formik, pipeline }: IFor
44
45
  return (
45
46
  <div className="form-horizontal">
46
47
  {!pipeline.strategy && (
47
- <AccountRegionClusterSelector
48
+ <TencentcloudAccountRegionClusterSelector
48
49
  application={application}
49
50
  clusterField="cluster"
50
51
  component={stage}
51
52
  accounts={accounts}
53
+ setFieldValue={setFieldValue}
52
54
  />
53
55
  )}
54
56
  <StageConfigField label="Rollback Options">
@@ -1,26 +1,26 @@
1
1
  import React from 'react';
2
2
 
3
- import type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';
3
+ import type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
4
  import {
5
5
  AccountService,
6
6
  CheckboxInput,
7
7
  FormikFormField,
8
- NgReact,
9
8
  NumberInput,
10
9
  SelectInput,
11
10
  StageConfigField,
12
11
  } from '@spinnaker/core';
13
12
 
13
+ import { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';
14
+
14
15
  const { useEffect, useState } = React;
15
- const { AccountRegionClusterSelector } = NgReact;
16
16
 
17
17
  export function ScaleDownClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {
18
18
  const stage = formik.values;
19
19
  const { setFieldValue } = formik;
20
- const [accounts, setAccounts] = useState([]);
20
+ const [accounts, setAccounts] = useState<IAccountDetails[]>([]);
21
21
 
22
22
  useEffect(() => {
23
- AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {
23
+ AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {
24
24
  setAccounts(accounts);
25
25
  });
26
26
 
@@ -59,11 +59,12 @@ export function ScaleDownClusterStageForm({ application, formik, pipeline }: IFo
59
59
  return (
60
60
  <div className="form-horizontal">
61
61
  {!pipeline.strategy && (
62
- <AccountRegionClusterSelector
62
+ <TencentcloudAccountRegionClusterSelector
63
63
  application={application}
64
64
  clusterField="cluster"
65
65
  component={stage}
66
66
  accounts={accounts}
67
+ setFieldValue={setFieldValue}
67
68
  />
68
69
  )}
69
70
  <StageConfigField label="ScaleDown Options">
@@ -1,26 +1,26 @@
1
1
  import React from 'react';
2
2
 
3
- import type { IAccount, IFormikStageConfigInjectedProps } from '@spinnaker/core';
3
+ import type { IAccountDetails, IFormikStageConfigInjectedProps } from '@spinnaker/core';
4
4
  import {
5
5
  AccountService,
6
6
  CheckboxInput,
7
7
  FormikFormField,
8
- NgReact,
9
8
  NumberInput,
10
9
  SelectInput,
11
10
  StageConfigField,
12
11
  } from '@spinnaker/core';
13
12
 
13
+ import { TencentcloudAccountRegionClusterSelector } from '../TencentcloudAccountRegionClusterSelector';
14
+
14
15
  const { useEffect, useState } = React;
15
- const { AccountRegionClusterSelector } = NgReact;
16
16
 
17
17
  export function ShrinkClusterStageForm({ application, formik, pipeline }: IFormikStageConfigInjectedProps) {
18
18
  const stage = formik.values;
19
19
  const { setFieldValue } = formik;
20
- const [accounts, setAccounts] = useState([]);
20
+ const [accounts, setAccounts] = useState<IAccountDetails[]>([]);
21
21
 
22
22
  useEffect(() => {
23
- AccountService.listAccounts('tencentcloud').then((accounts: IAccount[]) => {
23
+ AccountService.listAccounts('tencentcloud').then((accounts: IAccountDetails[]) => {
24
24
  setAccounts(accounts);
25
25
  });
26
26
 
@@ -59,11 +59,12 @@ export function ShrinkClusterStageForm({ application, formik, pipeline }: IFormi
59
59
  return (
60
60
  <div className="form-horizontal">
61
61
  {!pipeline.strategy && (
62
- <AccountRegionClusterSelector
62
+ <TencentcloudAccountRegionClusterSelector
63
63
  application={application}
64
64
  clusterField="cluster"
65
65
  component={stage}
66
66
  accounts={accounts}
67
+ setFieldValue={setFieldValue}
67
68
  />
68
69
  )}
69
70
  <StageConfigField label="Shrink Options">
@@ -1,7 +1,3 @@
1
- 'use strict';
2
-
3
- import { module } from 'angular';
4
-
5
1
  import { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';
6
2
 
7
3
  import './help/tencentcloud.help';
@@ -12,21 +8,16 @@ import './pipeline/stages/disableCluster/disableClusterStage';
12
8
  import './pipeline/stages/rollbackCluster/rollbackClusterStage';
13
9
  import './pipeline/stages/scaleDownCluster/scaleDownClusterStage';
14
10
  import './pipeline/stages/shrinkCluster/shrinkClusterStage';
15
- import { TENCENTCLOUD_REACT_MODULE } from './reactShims/tencentcloud.react.module';
16
- import { TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER } from './search/searchResultFormatter';
17
11
  import './validation/ApplicationNameValidator';
18
12
 
19
- export const TENCENTCLOUD_MODULE = 'spinnaker.tencentcloud';
20
- module(TENCENTCLOUD_MODULE, [TENCENTCLOUD_REACT_MODULE, TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER]).config(() => {
21
- CloudProviderRegistry.registerProvider('tencentcloud', {
22
- name: 'tencentcloud',
23
- logo: {
24
- path: logo,
25
- },
26
- image: {
27
- reader: TencentcloudImageReader,
28
- },
29
- });
13
+ CloudProviderRegistry.registerProvider('tencentcloud', {
14
+ name: 'tencentcloud',
15
+ logo: {
16
+ path: logo,
17
+ },
18
+ image: {
19
+ reader: TencentcloudImageReader,
20
+ },
30
21
  });
31
22
 
32
23
  DeploymentStrategyRegistry.registerProvider('tencentcloud', ['custom', 'redblack', 'rollingpush', 'rollingredblack']);
@@ -0,0 +1,20 @@
1
+ import { CloudProviderRegistry, SETTINGS } from '@spinnaker/core';
2
+
3
+ import { TencentcloudImageReader } from './image';
4
+
5
+ describe('Tencentcloud package entrypoint', () => {
6
+ let tencentcloudPackage: any;
7
+
8
+ beforeAll(() => {
9
+ SETTINGS.providers.tencentcloud = {};
10
+ tencentcloudPackage = require('./index');
11
+ });
12
+
13
+ it('loads successfully', () => {
14
+ expect(tencentcloudPackage).toBeDefined();
15
+ });
16
+
17
+ it('registers the provider configuration', () => {
18
+ expect(CloudProviderRegistry.getValue('tencentcloud', 'image.reader')).toBe(TencentcloudImageReader);
19
+ });
20
+ });
@@ -1,2 +0,0 @@
1
- export * from './tencentcloud.ngReact';
2
- export * from './tencentcloud.react.injector';
@@ -1,8 +0,0 @@
1
- /// <reference types="angular" />
2
- import IInjectorService = angular.auto.IInjectorService;
3
- import { ReactInject } from '@spinnaker/core';
4
- export declare class TencentcloudNgReactInjector extends ReactInject {
5
- $injectorProxy: IInjectorService;
6
- initialize($injector: IInjectorService): void;
7
- }
8
- export declare const TencentcloudNgReact: TencentcloudNgReactInjector;
@@ -1,7 +0,0 @@
1
- /// <reference types="angular" />
2
- import IInjectorService = angular.auto.IInjectorService;
3
- import { ReactInject } from '@spinnaker/core';
4
- export declare class TencentcloudReactInject extends ReactInject {
5
- initialize($injector: IInjectorService): void;
6
- }
7
- export declare const TencentcloudReactInjector: TencentcloudReactInject;
@@ -1 +0,0 @@
1
- export declare const TENCENTCLOUD_REACT_MODULE = "spinnaker.tencentcloud.react";
@@ -1 +0,0 @@
1
- export const TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER: "spinnaker.tencentcloud.search.searchResultFormatter";
@@ -1,2 +0,0 @@
1
- export * from './tencentcloud.ngReact';
2
- export * from './tencentcloud.react.injector';
@@ -1,21 +0,0 @@
1
- import IInjectorService = angular.auto.IInjectorService;
2
-
3
- import { ReactInject } from '@spinnaker/core';
4
-
5
- // prettier-ignore
6
- export class TencentcloudNgReactInjector extends ReactInject {
7
- public $injectorProxy = {} as IInjectorService;
8
-
9
- // Reactified components
10
-
11
- public initialize($injector: IInjectorService) {
12
- const realInjector: { [key: string]: Function } = $injector as any;
13
- const proxyInjector: { [key: string]: Function } = this.$injectorProxy as any;
14
-
15
- Object.keys($injector)
16
- .filter(key => typeof realInjector[key] === 'function')
17
- .forEach(key => proxyInjector[key] = realInjector[key].bind(realInjector));
18
- }
19
- }
20
-
21
- export const TencentcloudNgReact = new TencentcloudNgReactInjector();
@@ -1,14 +0,0 @@
1
- import IInjectorService = angular.auto.IInjectorService;
2
-
3
- import { ReactInject } from '@spinnaker/core';
4
-
5
- // prettier-ignore
6
- export class TencentcloudReactInject extends ReactInject {
7
-
8
-
9
- public initialize($injector: IInjectorService) {
10
- this.$injector = $injector;
11
- }
12
- }
13
-
14
- export const TencentcloudReactInjector: TencentcloudReactInject = new TencentcloudReactInject();
@@ -1,14 +0,0 @@
1
- import { module } from 'angular';
2
-
3
- import { TencentcloudNgReact } from './tencentcloud.ngReact';
4
- import { TencentcloudReactInjector } from './tencentcloud.react.injector';
5
-
6
- export const TENCENTCLOUD_REACT_MODULE = 'spinnaker.tencentcloud.react';
7
- module(TENCENTCLOUD_REACT_MODULE, []).run([
8
- '$injector',
9
- function ($injector: any) {
10
- // Make angular services importable and (TODO when relevant) convert angular components to react
11
- TencentcloudReactInjector.initialize($injector);
12
- TencentcloudNgReact.initialize($injector);
13
- },
14
- ]);
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- import { module } from 'angular';
4
-
5
- export const TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER = 'spinnaker.tencentcloud.search.searchResultFormatter';
6
- module(TENCENTCLOUD_SEARCH_SEARCHRESULTFORMATTER, []).factory('tencentcloudSearchResultFormatter', function () {
7
- return {
8
- securityGroups: function (entry) {},
9
- };
10
- });