Files
azuredatastudio/extensions/resource-deployment/src/services/uriHandlerService.ts

92 lines
4.3 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ResourceTypeService } from './resourceTypeService';
import * as loc from '../localizedConstants';
interface IGalleryExtension {
name: string;
version: string;
date: string;
displayName: string;
publisherId: string;
publisher: string;
publisherDisplayName: string;
description: string;
preview: boolean;
}
export class UriHandlerService implements vscode.UriHandler {
constructor(private _resourceTypeService: ResourceTypeService) { }
async handleUri(uri: vscode.Uri): Promise<void> {
// Path to start a deployment
// Supported URI parameters :
// - type (optional) : The resource type to start the deployment for
// - extension (optional) : The ID of the extension that is required to start the deployment
// - params (optional) : A JSON blob of variable names/values to pass as initial values to the wizard. Note
// that the JSON blob must be URI-encoded in order to be properly handled
// Example URIs :
// azuredatastudio://Microsoft.resource-deployment/deploy
// azuredatastudio://Microsoft.resource-deployment/deploy?type=arc-controller
// azuredatastudio://Microsoft.resource-deployment/deploy?type=arc-controller&extension=Microsoft.arc
// azuredatastudio://Microsoft.resource-deployment/deploy?type=arc-controller&params=%7B%22AZDATA_NB_VAR_ARC_SUBSCRIPTION%22%3A%22abdcef12-3456-7890-abcd-ef1234567890%22%2C%22AZDATA_NB_VAR_ARC_RESOURCE_GROUP%22%3A%22my-rg%22%2C%22AZDATA_NB_VAR_ARC_DATA_CONTROLLER_LOCATION%22%3A%22westus%22%2C%22AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAME%22%3A%22arc-dc%22%7D
if (uri.path === '/deploy') {
const params = uri.query.split('&').map(kv => kv.split('='));
const paramType = params.find(param => param[0] === 'type')?.[1];
const extensionId = params.find(param => param[0] === 'extension')?.[1];
if (extensionId) {
const installedExtension = vscode.extensions.getExtension(extensionId);
if (!installedExtension) {
// The required extension isn't installed, prompt user to install it
const extensionGalleryInfo = await vscode.commands.executeCommand<IGalleryExtension>('workbench.extensions.getExtensionFromGallery', extensionId);
if (extensionGalleryInfo) {
const response = await vscode.window.showInformationMessage(
loc.extensionRequiredPrompt(extensionGalleryInfo.displayName),
loc.install);
if (response === loc.install) {
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: loc.installingExtension(extensionGalleryInfo.displayName),
cancellable: false
}, async (_progress, _token) => {
await vscode.commands.executeCommand('workbench.extensions.installExtension', extensionId);
}
);
} else {
// If user didn't install extension we wouldn't expect the deployment to work so just return
console.log(`User cancelled out of prompt to install required extension '${extensionId}' for Resource Deployment URI`);
return;
}
} else {
// If we can't find the extension in the gallery then we won't be able to install it - so just inform the user
// that the ID is invalid and return since we wouldn't expect the deployment to work without the extension
vscode.window.showErrorMessage(loc.unknownExtension(extensionId));
return;
}
} else {
// Extension is already installed, ensure that it's activated before continuing on
await installedExtension.activate();
}
}
const wizardParams = JSON.parse(params.find(param => param[0] === 'params')?.[1] ?? '{}');
const resourceType = this._resourceTypeService.getResourceTypes().find(type => type.name === paramType);
if (paramType && !resourceType) {
console.warn(`Unknown resource type ${paramType}`);
}
if (resourceType) {
this._resourceTypeService.startDeployment(resourceType, undefined, wizardParams);
} else {
return vscode.commands.executeCommand('azdata.resource.deploy');
}
}
}
}