1- import { ContainerServiceClient } from "@azure/arm-containerservice" ;
2- import { ResourceGroup as ARMResourceGroup , Deployment , ResourceManagementClient } from "@azure/arm-resources" ;
1+ import { ContainerServiceClient , KubernetesVersion } from "@azure/arm-containerservice" ;
2+ import { ResourceGroup as ARMResourceGroup , ResourceManagementClient } from "@azure/arm-resources" ;
33import { RestError } from "@azure/storage-blob" ;
44import { ISubscriptionContext } from "@microsoft/vscode-azext-utils" ;
55import { Uri , window } from "vscode" ;
6- import meta from ' ../../package.json' ;
6+ import meta from " ../../package.json" ;
77import { getResourceGroupList } from "../commands/utils/clusters" ;
88import { failed , getErrorMessage } from "../commands/utils/errorable" ;
99import { isObject } from "../commands/utils/runtimeTypes" ;
1010import { MessageHandler , MessageSink } from "../webview-contract/messaging" ;
11- import { InitialState , ProgressEventType , ToVsCodeMsgDef , ToWebViewMsgDef , ResourceGroup as WebviewResourceGroup } from "../webview-contract/webviewDefinitions/createCluster" ;
11+ import {
12+ InitialState ,
13+ Preset ,
14+ ProgressEventType ,
15+ ToVsCodeMsgDef ,
16+ ToWebViewMsgDef ,
17+ ResourceGroup as WebviewResourceGroup ,
18+ } from "../webview-contract/webviewDefinitions/createCluster" ;
1219import { BasePanel , PanelDataProvider } from "./BasePanel" ;
13- import { ClusterSpec , ClusterSpecBuilder } from "./utilities/ClusterSpecCreationBuilder" ;
20+ import { ClusterSpec , ClusterDeploymentBuilder } from "./utilities/ClusterSpecCreationBuilder" ;
1421
1522export class CreateClusterPanel extends BasePanel < "createCluster" > {
1623 constructor ( extensionUri : Uri ) {
@@ -27,8 +34,8 @@ export class CreateClusterDataProvider implements PanelDataProvider<"createClust
2734 readonly resourceManagementClient : ResourceManagementClient ,
2835 readonly containerServiceClient : ContainerServiceClient ,
2936 readonly portalUrl : string ,
30- readonly subscriptionContext : ISubscriptionContext
31- ) { }
37+ readonly subscriptionContext : ISubscriptionContext ,
38+ ) { }
3239
3340 getTitle ( ) : string {
3441 return `Create Cluster in ${ this . subscriptionContext . subscriptionDisplayName } ` ;
@@ -106,14 +113,23 @@ export class CreateClusterDataProvider implements PanelDataProvider<"createClust
106113 group : WebviewResourceGroup ,
107114 location : string ,
108115 name : string ,
109- preset : string ,
116+ preset : Preset ,
110117 webview : MessageSink < ToWebViewMsgDef > ,
111118 ) {
112119 if ( isNewResourceGroup ) {
113120 await createResourceGroup ( group , webview , this . resourceManagementClient ) ;
114121 }
115122
116- await createCluster ( group , location , name , preset , webview , this . containerServiceClient , this . resourceManagementClient , this . subscriptionContext ) ;
123+ await createCluster (
124+ group ,
125+ location ,
126+ name ,
127+ preset ,
128+ webview ,
129+ this . containerServiceClient ,
130+ this . resourceManagementClient ,
131+ this . subscriptionContext ,
132+ ) ;
117133 }
118134}
119135
@@ -151,11 +167,11 @@ async function createCluster(
151167 group : WebviewResourceGroup ,
152168 location : string ,
153169 name : string ,
154- preset : string ,
170+ preset : Preset ,
155171 webview : MessageSink < ToWebViewMsgDef > ,
156172 containerServiceClient : ContainerServiceClient ,
157173 resourceManagementClient : ResourceManagementClient ,
158- subscriptionContext : ISubscriptionContext
174+ subscriptionContext : ISubscriptionContext ,
159175) {
160176 const operationDescription = `Creating cluster ${ name } ` ;
161177 webview . postProgressUpdate ( {
@@ -165,8 +181,11 @@ async function createCluster(
165181 } ) ;
166182
167183 // kubernetes version is required to create a cluster via deployments
168- const kubernetesVersion = await containerServiceClient . managedClusters . listKubernetesVersions ( location ) ;
169- if ( ! kubernetesVersion || ! kubernetesVersion . values || kubernetesVersion . values . length === 0 || ! kubernetesVersion . values [ 0 ] . version ) {
184+ const kubernetesVersionsResult = await containerServiceClient . managedClusters . listKubernetesVersions ( location ) ;
185+ const kubernetesVersions = kubernetesVersionsResult . values || [ ] ;
186+ const hasDefaultVersion = kubernetesVersions . some ( isDefaultK8sVersion ) ;
187+ const [ kubernetesVersion ] = hasDefaultVersion ? kubernetesVersions . filter ( isDefaultK8sVersion ) : kubernetesVersions ;
188+ if ( ! kubernetesVersion ?. version ) {
170189 window . showErrorMessage ( `No Kubernetes versions available for location ${ location } ` ) ;
171190 webview . postProgressUpdate ( {
172191 event : ProgressEventType . Failed ,
@@ -181,15 +200,24 @@ async function createCluster(
181200 name,
182201 resourceGroupName : group . name ,
183202 subscriptionId : subscriptionContext . subscriptionId ,
184- kubernetesVersion : kubernetesVersion . values [ 0 ] . version , // selecting the latest version since versions come in descending order
185- username : subscriptionContext . userId
203+ kubernetesVersion : kubernetesVersion . version , // selecting the latest version since versions come in descending order
204+ username : subscriptionContext . userId ,
186205 } ;
187206
188- const deploymentSpec = getManagedClusterSpec ( clusterSpec , preset ) ;
207+ // Create a unique deployment name.
208+ const deploymentName = `${ name } -${ Math . random ( ) . toString ( 36 ) . substring ( 5 ) } ` ;
209+ const deploymentSpec = new ClusterDeploymentBuilder ( )
210+ . buildCommonParameters ( clusterSpec )
211+ . buildTemplate ( preset )
212+ . getDeployment ( ) ;
189213
190214 try {
191- const poller = await resourceManagementClient . deployments . beginCreateOrUpdate ( group . name , name , deploymentSpec ) ;
192- poller . onProgress ( state => {
215+ const poller = await resourceManagementClient . deployments . beginCreateOrUpdate (
216+ group . name ,
217+ deploymentName ,
218+ deploymentSpec ,
219+ ) ;
220+ poller . onProgress ( ( state ) => {
193221 if ( state . status === "canceled" ) {
194222 webview . postProgressUpdate ( {
195223 event : ProgressEventType . Cancelled ,
@@ -227,20 +255,6 @@ async function createCluster(
227255 }
228256}
229257
230- function getManagedClusterSpec ( clusterSpec : ClusterSpec , preset : string ) : Deployment {
231- const specBuilder : ClusterSpecBuilder = new ClusterSpecBuilder ( ) ;
232- switch ( preset ) {
233- case "dev" :
234- return specBuilder . buildDevTestClusterSpec ( clusterSpec ) ;
235- case "economy" :
236- return specBuilder . buildProdEconomyClusterSpec ( clusterSpec )
237- case "enterprise" :
238- return specBuilder . buildProdEnterpriseClusterSpec ( clusterSpec )
239- default :
240- return specBuilder . buildProdStandardClusterSpec ( clusterSpec )
241- }
242- }
243-
244258function getInvalidTemplateErrorMessage ( ex : InvalidTemplateDeploymentRestError ) : string {
245259 const innerDetails = ex . details . error ?. details || [ ] ;
246260 if ( innerDetails . length > 0 ) {
@@ -275,4 +289,8 @@ function isInvalidTemplateDeploymentError(ex: unknown): ex is InvalidTemplateDep
275289
276290function isRestError ( ex : unknown ) : ex is RestError {
277291 return isObject ( ex ) && ex . constructor . name === "RestError" ;
278- }
292+ }
293+
294+ function isDefaultK8sVersion ( version : KubernetesVersion ) : boolean {
295+ return "isDefault" in version && version . isDefault === true ;
296+ }
0 commit comments