async function createCluster()

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,
        });
    }
}