in src/panels/CreateClusterPanel.ts [216:387]
async function createCluster(
sessionProvider: ReadyAzureSessionProvider,
subscriptionId: string,
groupName: string,
location: string,
name: string,
preset: PresetType,
webview: MessageSink<ToWebViewMsgDef>,
containerServiceClient: ContainerServiceClient,
resourceManagementClient: ResourceManagementClient,
featureClient: FeatureClient,
commandId: string,
) {
const operationDescription = `Creating cluster ${name}`;
webview.postProgressUpdate({
event: ProgressEventType.InProgress,
operationDescription,
errorMessage: null,
deploymentPortalUrl: null,
createdCluster: null,
});
// kubernetes version is required to create a cluster via deployments
const kubernetesVersionsResult = await containerServiceClient.managedClusters.listKubernetesVersions(location);
const kubernetesVersions = kubernetesVersionsResult.values || [];
const hasDefaultVersion = kubernetesVersions.some(isDefaultK8sVersion);
const [kubernetesVersion] = hasDefaultVersion ? kubernetesVersions.filter(isDefaultK8sVersion) : kubernetesVersions;
if (!kubernetesVersion?.version) {
window.showErrorMessage(`No Kubernetes versions available for location ${location}`);
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription,
errorMessage: "No Kubernetes versions available for location",
deploymentPortalUrl: null,
createdCluster: null,
});
return;
}
const session = await sessionProvider.getAuthSession();
if (failed(session)) {
window.showErrorMessage(`Error getting authentication session: ${session.error}`);
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription,
errorMessage: session.error,
deploymentPortalUrl: null,
createdCluster: null,
});
return;
}
// if automatic preset, we need role assignments for the cluster RBAC admin role which requires service principal id
let servicePrincipalId = "";
if (preset === PresetType.Automatic) {
servicePrincipalId = getServicePrincipalId(session.result);
if (!servicePrincipalId) {
window.showErrorMessage("No service principal id available for logged in user.");
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription,
errorMessage: "No service principal id available for logged in user.",
deploymentPortalUrl: null,
createdCluster: null,
});
return;
}
}
const clusterSpec: ClusterSpec = {
location,
name,
resourceGroupName: groupName,
subscriptionId: subscriptionId,
kubernetesVersion: kubernetesVersion.version,
username: session.result.account.label, // Account label seems to be email address
servicePrincipalId: servicePrincipalId,
};
// Create a unique deployment name.
const deploymentName = `${name}-${Math.random().toString(36).substring(5)}`;
const deploymentSpec = new ClusterDeploymentBuilder()
.buildCommonParameters(clusterSpec, preset)
.buildTemplate(preset)
.getDeployment();
const environment = getEnvironment();
// feature registration
try {
await doFeatureRegistration(preset, featureClient);
} catch (error) {
window.showErrorMessage(`Error Registering preview features for AKS cluster ${name}: ${error}`);
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription: "Error Registering preview features for AKS cluster",
errorMessage: getErrorMessage(error),
deploymentPortalUrl: null,
createdCluster: null,
});
return;
}
// event name for telemetry reporter
const eventName = commandId === "aks.createCluster" ? "command" : "aks.ghcp";
try {
const poller = await resourceManagementClient.deployments.beginCreateOrUpdate(
groupName,
deploymentName,
deploymentSpec,
);
const deploymentArmId = `/subscriptions/${subscriptionId}/resourcegroups/${groupName}/providers/Microsoft.Resources/deployments/${deploymentName}`;
const deploymentPortalUrl = getDeploymentPortalUrl(environment, deploymentArmId);
webview.postProgressUpdate({
event: ProgressEventType.InProgress,
operationDescription,
errorMessage: null,
deploymentPortalUrl,
createdCluster: null,
});
poller.onProgress((state) => {
if (state.status === "canceled") {
webview.postProgressUpdate({
event: ProgressEventType.Cancelled,
operationDescription,
errorMessage: null,
deploymentPortalUrl,
createdCluster: null,
});
} else if (state.status === "failed") {
reporter.sendTelemetryEvent(eventName, { command: commandId, clusterCreationSuccess: "false" });
const errorMessage = state.error ? getErrorMessage(state.error) : "Unknown error";
window.showErrorMessage(`Error creating AKS cluster ${name}: ${errorMessage}`);
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription,
errorMessage,
deploymentPortalUrl,
createdCluster: null,
});
} else if (state.status === "succeeded") {
reporter.sendTelemetryEvent(eventName, { command: commandId, clusterCreationSuccess: "true" });
window.showInformationMessage(`Successfully created AKS cluster ${name}.`);
const armId = `/subscriptions/${subscriptionId}/resourceGroups/${groupName}/providers/Microsoft.ContainerService/managedClusters/${name}`;
webview.postProgressUpdate({
event: ProgressEventType.Success,
operationDescription,
errorMessage: null,
deploymentPortalUrl,
createdCluster: {
portalUrl: getPortalResourceUrl(environment, armId),
},
});
}
});
await poller.pollUntilDone();
} catch (ex) {
const errorMessage = isInvalidTemplateDeploymentError(ex)
? getInvalidTemplateErrorMessage(ex)
: getErrorMessage(ex);
window.showErrorMessage(`Error creating AKS cluster ${name}: ${errorMessage}`);
webview.postProgressUpdate({
event: ProgressEventType.Failed,
operationDescription,
errorMessage,
deploymentPortalUrl: null,
createdCluster: null,
});
}
}