import { readFileSync } from 'fs' ; import { Disposable , Uri , ViewColumn , Webview , WebviewPanel , window } from 'vscode' ; import { AzureClusterProvider } from '../azure/azureTools' ; import { createGitRepositoryAzureCluster , createGitRepositoryGenericCluster } from '../commands/createSource' ; import { asAbsolutePath } from '../extensionContext' ; import { GitInfo } from '../git/getOpenedFolderGitInfo' ; import { ClusterProvider } from '../kubernetes/kubernetesTypes' ; import { getCurrentClusterInfo } from '../views/treeViews' ; import { getNonce , getWebviewOptions } from './webviewUtils' ; /**
 * Message sent to webview to initialize it.
 */ interface CreateSourceUpdateWebviewContent { type : 'updateWebviewContent' ; value : { clusterName : string ; contextName : string ; clusterProvider : string ; isAzure : boolean ; newSourceName : string ; newSourceUrl : string ; newSourceBranch : string ; } ; } /**
 * Message sent from webview to create a source on a generic cluster
 */ export interface CreateSourceGenericCluster { type : 'createSourceGenericCluster' ; value : { contextName : string ; sourceName : string ; url : string ; branch : string ; tag : string ; semver : string ; interval : string ; timeout : string ; caFile : string ; privateKeyFile : string ; username : string ; password : string ; secretRef : string ; gitImplementation : string ; recurseSubmodules : boolean ; sshKeyAlgorithm : string ; sshEcdsaCurve : string ; sshRsaBits : string ; } ; } /**
 * Message sent from webview to create source on Azure cluster
 */ export interface CreateSourceAzureCluster { type : 'createSourceAzureCluster' ; value : { contextName : string ; clusterProvider : AzureClusterProvider ; sourceKind : 'git' ; sourceName : string ; url : string ; branch : string ; tag : string ; semver : string ; commit : string ; interval : string ; timeout : string ; caCert : string ; caCertFile : string ; httpsKey : string ; httpsUser : string ; knownHosts : string ; knownHostsFile : string ; localAuthRef : string ; sshPrivateKey : string ; sshPrivateKeyFile : string ; kustomizationName : string ; kustomizationPath : string ; kustomizationDependsOn : string ; kustomizationTimeout : string ; kustomizationSyncInterval : string ; kustomizationRetryInterval : string ; kustomizationPrune : boolean ; kustomizationForce : boolean ; } ; } /**
 * Message sent from webview to show VSCode notificaion
 */ export interface ShowNotification { type : 'showNotification' ; value : { text : string ; isModal : boolean ; } ; } export type MessageToWebview = CreateSourceUpdateWebviewContent ; export type MessageFromWebview = CreateSourceGenericCluster | CreateSourceAzureCluster | ShowNotification ; /**
 * Manages create source webview panel.
 */ export class CreateSourcePanel { /**
     * Track the currently panel. Only allow a single panel to exist at a time.
     */ public static currentPanel : CreateSourcePanel | undefined ; public static readonly viewType = 'createSource' ; private readonly _panel : WebviewPanel ; private readonly _extensionUri : Uri ; private _disposables : Disposable [ ] = [ ] ; public static createOrShow ( extensionUri , gitInfo ) { const column = window . activeTextEditor ? window . activeTextEditor . viewColumn : undefined ; if ( CreateSourcePanel . currentPanel ) { CreateSourcePanel . currentPanel . _panel . reveal ( column ) ; return ; } const panel = window . createWebviewPanel ( CreateSourcePanel . viewType , 'Create Source' , column || ViewColumn . One , getWebviewOptions ( extensionUri ) ) ; CreateSourcePanel . currentPanel = new CreateSourcePanel ( panel , extensionUri , gitInfo ) ; } public static revive ( panel , extensionUri , gitInfo ) { CreateSourcePanel . currentPanel = new CreateSourcePanel ( panel , extensionUri , gitInfo ) ; } private constructor ( panel , extensionUri , gitInfo ) { this . _panel = panel ; this . _extensionUri = extensionUri ; this . _update ( gitInfo ) ; this . _panel . onDidDispose ( ( ) => this . dispose ( ) , null , this . _disposables ) ; this . _panel . onDidChangeViewState ( e => { if ( this . _panel . visible ) { this . _update ( gitInfo ) ; } } , null , this . _disposables ) ; this . _panel . webview . onDidReceiveMessage ( async ( message ) => { switch ( message . type ) { case 'createSourceGenericCluster' : { await createGitRepositoryGenericCluster ( message . value ) ; break ; } case 'createSourceAzureCluster' : { await createGitRepositoryAzureCluster ( message . value ) ; break ; } case 'showNotification' : { window . showInformationMessage ( message . value . text , { modal : message . value . isModal , } ) ; break ; } } } , null , this . _disposables ) ; } public dispose ( ) { CreateSourcePanel . currentPanel = undefined ; this . _panel . dispose ( ) ; while ( this . _disposables . length ) { const x = this . _disposables . pop ( ) ; if ( x ) { x . dispose ( ) ; } } } private _postMessage ( message ) { this . _panel . webview . postMessage ( message ) ; } private async _updateWebviewContent ( gitInfo ) { const clusterInfo = await getCurrentClusterInfo ( ) ; if ( ! clusterInfo ) { return ; } this . _postMessage ( { type : 'updateWebviewContent' , value : { clusterName : clusterInfo . clusterNode . clusterName , contextName : clusterInfo . clusterNode . contextName , clusterProvider : clusterInfo . clusterProvider , isAzure : clusterInfo . clusterProvider === ClusterProvider . AKS || clusterInfo . clusterProvider === ClusterProvider . AzureARC , newSourceName : gitInfo ?. newRepoName || '' , newSourceUrl : gitInfo ?. url || '' , newSourceBranch : gitInfo ?. branch || '' , } , } ) ; } /**
     * Set webview html and send a message to update the contents.
     */ private _update ( gitInfo ) { this . _panel . webview . html = this . _getHtmlForWebview ( this . _panel . webview ) ; setTimeout ( ( ) => { this . _updateWebviewContent ( gitInfo ) ; } , 400 ) ; } private _getHtmlForWebview ( webview ) { const scriptPathOnDisk = Uri . joinPath ( this . _extensionUri , 'media' , 'createSource.js' ) ; const scriptUri = ( scriptPathOnDisk ) . with ( { 'scheme' : 'vscode-resource' } ) ; const styleResetPath = Uri . joinPath ( this . _extensionUri , 'media' , 'reset.css' ) ; const styleVSCodePath = Uri . joinPath ( this . _extensionUri , 'media' , 'vscode.css' ) ; const stylesPathMainPath = Uri . joinPath ( this . _extensionUri , 'media' , 'createSource.css' ) ; const stylesResetUri = webview . asWebviewUri ( styleResetPath ) ; const stylesVSCodeUri = webview . asWebviewUri ( styleVSCodePath ) ; const stylesMainUri = webview . asWebviewUri ( stylesPathMainPath ) ; const nonce = getNonce ( ) ; return `<!DOCTYPE html>
			<html lang="en">
			<head>
				<meta charset="UTF-8">
				<!--
					Use a content security policy to only allow loading images from https or from our extension directory,
					and only allow scripts that have a specific nonce.
				-->
				<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${ webview . cspSource }; img-src ${ webview . cspSource } https:; script-src 'nonce-${ nonce }';">

				<meta name="viewport" content="width=device-width, initial-scale=1.0">

				<link href="${ stylesResetUri }" rel="stylesheet">
				<link href="${ stylesVSCodeUri }" rel="stylesheet">
				<link href="${ stylesMainUri }" rel="stylesheet">

				<title>Create Source</title>
			</head>
			<body>
				<main class="app">
					<h2>Create Source on the <code id="cluster-name">Unknown</code> cluster</h2>
					<h3 id="cluster-provider"></h3>
					<hr>
					<div>
						<label class="header-label" for="source-name">Source Name</label>
						<input type="text" id="source-name">
					</div>
					<div>
						<label class="header-label" for="git">Source Kind <code></code></label>
						<input type="radio" id="git" name="kind" value="git" checked> <label for="git">Git Repository</label>
					</div>
					${ readFileSync ( asAbsolutePath ( './media/createSource.html' ) . fsPath ) . toString ( ) }
					<button type="button" id="create-source" class="submit-button">Create</button>
				</main>

				<script nonce="${ nonce }" src="${ scriptUri }" defer></script>
			</body>
			</html>` ; } }