in src/panels/DevHubAutoDeployPanel.ts [237:408]
private async handleCreateWorkflowRequest(webview: MessageSink<ToWebViewMsgDef>) {
//---Hardcoded values for testing purposes, will be replaced with webview input---
const user = "ReinierCC";
const repo = "contoso-air";
const branch = "main";
const subscriptionId = "feb5b150-60fe-4441-be73-8c02a524f55a";
const clusterResourceGroup = "rei-rg";
const clusterName = "reiCluster";
const acrName = "reiacr9";
const acrResourceGroup = "rei-rg";
const acrLocation = "eastus2";
//------
//---Run Neccesary Checks prior to making the call to DevHub to create a workflow ----
//Check if new resource group must be created //TODO
//Check for isNewNamespace, to see if new namespace must be created.
const isNewNamespace = true; //Actual Value Provided Later PR //PlaceHolder
if (isNewNamespace) {
//Create New Namespace
const subscriptionId = "feb5b150-60fe-4441-be73-8c02a524f55a"; // These values will be provided to the fuction call from the webview
const resourceGroup = "rei-rg"; //PlaceHolder
const clusterName = "reiCluster"; //PlaceHolder
const namespace = "not-default"; //PlaceHolder
const namespaceCreationResp = await createClusterNamespace(
this.sessionProvider,
this.kubectl,
subscriptionId,
resourceGroup,
clusterName,
namespace,
);
if (failed(namespaceCreationResp)) {
console.log("Failed to create namespace: ", namespace, "Error: ", namespaceCreationResp.error);
vscode.window.showErrorMessage(`Failed to create namespace: ${namespace}`);
return;
}
vscode.window.showInformationMessage(namespaceCreationResp.result);
}
//Create ACR if required
//ACR will be created based off user input for naming and resource group
const createNewAcrReq = true;
const createNewAcrResourceGroupReq = true;
if (createNewAcrReq) {
const acrCreationSucceeded = await createNewAcr(
this.sessionProvider,
this.subscriptionId,
acrResourceGroup,
acrName,
acrLocation,
this.resourceManagementClient,
createNewAcrResourceGroupReq,
);
if (!acrCreationSucceeded) {
console.log("Error creating ACR");
vscode.window.showErrorMessage("Error creating ACR");
return;
}
}
//Create a New App Registration representing the workflow
const newApp = await msGraph.createApplication(this.graphClient, generateRandomWorkflowName());
if (failed(newApp)) {
console.error("Error creating new App Registration for DevHub:", newApp.error);
vscode.window.showErrorMessage("Error creating new App Registration for DevHub");
return;
}
console.log("New App Registration created:", newApp.result);
//Create Service Principal for App Registration (Enterprise Application)
const newServicePrincipal = await msGraph.createServicePrincipal(this.graphClient, newApp.result.appId);
if (failed(newServicePrincipal)) {
console.error("Error creating new service principal for DevHub Workflow:", newServicePrincipal.error);
vscode.window.showErrorMessage("Error creating new service principal for DevHub Workflow");
return;
}
console.log("New Service Principal Created:", newServicePrincipal.result);
//Add Federated Credentials for GitHub repo in App Registration
const gitFedCredResp = await msGraph.createGitHubActionFederatedIdentityCredential(
this.graphClient,
newApp.result.appId,
user,
repo,
branch,
);
if (failed(gitFedCredResp)) {
console.error("Error creating GitHub Federated Credential:", gitFedCredResp.error);
vscode.window.showErrorMessage("Error creating GitHub Federated Credential");
return;
}
console.log("GitHub Federated Credential created:", gitFedCredResp.result);
const authManagmentClient = getAuthorizationManagementClient(this.sessionProvider, subscriptionId);
//Represent ArmID for ACR and Cluster
const acrScope = roleAssignmentsUtil.getScopeForAcr(subscriptionId, acrResourceGroup, acrName);
const clusterScope = roleAssignmentsUtil.getScopeForCluster(subscriptionId, clusterResourceGroup, clusterName);
//Assign Collaborator Role to Service Principal for ACR
const acrRoleCreation = await roleAssignmentsUtil.createRoleAssignment(
authManagmentClient,
subscriptionId,
newServicePrincipal.result.appId,
azureContributorRole,
acrScope,
"ServicePrincipal",
);
if (failed(acrRoleCreation)) {
console.error("Error creating role assignment:", acrRoleCreation.error);
vscode.window.showErrorMessage("Error creating role assignment for ACR");
return;
}
console.log("Role assignment created:", acrRoleCreation.result);
//Assign Collaborator Role to Service Principal for AKS cluster
const clusterRoleCreation = await roleAssignmentsUtil.createRoleAssignment(
authManagmentClient,
subscriptionId,
newServicePrincipal.result.appId,
azureContributorRole,
clusterScope,
"ServicePrincipal",
);
if (failed(clusterRoleCreation)) {
console.error("Error creating role assignment:", clusterRoleCreation.error);
vscode.window.showErrorMessage("Error creating role assignment for AKS cluster");
return;
}
console.log("Collab Role assignment created:", clusterRoleCreation.result);
//Get Cluster Principal ID for Role Assignment Check
const clusterPrincipalId = await getClusterPrincipalId(
this.sessionProvider,
subscriptionId,
clusterResourceGroup,
clusterName,
);
if (failed(clusterPrincipalId)) {
console.error("Error getting cluster principal ID:", clusterPrincipalId.error);
vscode.window.showErrorMessage("Error getting cluster principal ID");
return;
}
//Providing Cluster ACR Pull Role
const acrPullResp = await verifyAndAssignAcrPullRole(
authManagmentClient,
clusterPrincipalId.result,
acrResourceGroup,
acrName,
subscriptionId,
acrScope,
);
if (failed(acrPullResp)) {
console.error("Error verifying and assigning ACR pull role:", acrPullResp.error);
vscode.window.showErrorMessage("Error verifying and assigning ACR pull role");
return;
}
//---Run Neccesary Checks prior to making the call to DevHub to create a workflow ----
////////////TODO: Pass in neccesary parameters for workflow creation
const prUrl = await launchDevHubWorkflow(this.devHubClient);
if (prUrl !== undefined) {
vscode.window.showInformationMessage(`Workflow created successfully. PR: ${prUrl}`);
webview.postGetWorkflowCreationResponse(prUrl);
}
}