diff --git a/extensions/big-data-cluster/src/config/config.ts b/extensions/big-data-cluster/src/config/config.ts index a81ce4a4eb..4ba6b5d8e1 100644 --- a/extensions/big-data-cluster/src/config/config.ts +++ b/extensions/big-data-cluster/src/config/config.ts @@ -7,9 +7,9 @@ import * as vscode from 'vscode'; import { Host } from '../kubectl/host'; import { Shell, Platform } from '../utility/shell'; -const EXTENSION_CONFIG_KEY = "mssql-bdc"; -const KUBECONFIG_PATH_KEY = "mssql-bdc.kubeconfig"; -const KNOWN_KUBECONFIGS_KEY = "mssql-bdc.knownKubeconfigs"; +const EXTENSION_CONFIG_KEY = 'mssql-bdc'; +const KUBECONFIG_PATH_KEY = 'mssql-bdc.kubeconfig'; +const KNOWN_KUBECONFIGS_KEY = 'mssql-bdc.knownKubeconfigs'; export async function addPathToConfig(configKey: string, value: string): Promise { await setConfigValue(configKey, value); diff --git a/extensions/big-data-cluster/src/installer/download.ts b/extensions/big-data-cluster/src/installer/download.ts index 42bdd4e40a..b616b99a0f 100644 --- a/extensions/big-data-cluster/src/installer/download.ts +++ b/extensions/big-data-cluster/src/installer/download.ts @@ -26,7 +26,7 @@ function ensureDownloadFunc() { } export async function toTempFile(sourceUrl: string): Promise> { - const tempFileObj = tmp.fileSync({ prefix: "mssql-bdc-autoinstall-" }); + const tempFileObj = tmp.fileSync({ prefix: 'mssql-bdc-autoinstall-' }); const downloadResult = await to(sourceUrl, tempFileObj.name); if (succeeded(downloadResult)) { return { succeeded: true, result: tempFileObj.name }; diff --git a/extensions/big-data-cluster/src/installer/installer.ts b/extensions/big-data-cluster/src/installer/installer.ts index 0587de5280..02e74daa15 100644 --- a/extensions/big-data-cluster/src/installer/installer.ts +++ b/extensions/big-data-cluster/src/installer/installer.ts @@ -8,6 +8,9 @@ import * as download from './download'; import * as fs from 'fs'; import mkdirp = require('mkdirp'); import * as path from 'path'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + import { Shell, Platform } from '../utility/shell'; import { Errorable, failed } from '../interfaces'; import { addPathToConfig, toolPathBaseKey } from '../config/config'; @@ -29,7 +32,7 @@ export async function installKubectl(shell: Shell): Promise> { const downloadFile = path.join(installFolder, binFile); const downloadResult = await download.to(kubectlUrl, downloadFile); if (failed(downloadResult)) { - return { succeeded: false, error: [`Failed to download kubectl: ${downloadResult.error[0]}`] }; + return { succeeded: false, error: [localize('downloadKubectlFailed', 'Failed to download kubectl: {0}', downloadResult.error[0])] }; } if (shell.isUnix()) { @@ -43,7 +46,7 @@ export async function installKubectl(shell: Shell): Promise> { async function getStableKubectlVersion(): Promise> { const downloadResult = await download.toTempFile('https://storage.googleapis.com/kubernetes-release/release/stable.txt'); if (failed(downloadResult)) { - return { succeeded: false, error: [`Failed to establish kubectl stable version: ${downloadResult.error[0]}`] }; + return { succeeded: false, error: [localize('kubectlVersionCheckFailed', 'Failed to establish kubectl stable version: {0}', downloadResult.error[0])] }; } const version = fs.readFileSync(downloadResult.result, 'utf-8'); fs.unlinkSync(downloadResult.result); diff --git a/extensions/big-data-cluster/src/kubectl/SqlServerBigDataClusterChannel.ts b/extensions/big-data-cluster/src/kubectl/SqlServerBigDataClusterChannel.ts index 31f1933ee1..8aeab7e359 100644 --- a/extensions/big-data-cluster/src/kubectl/SqlServerBigDataClusterChannel.ts +++ b/extensions/big-data-cluster/src/kubectl/SqlServerBigDataClusterChannel.ts @@ -3,14 +3,17 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from "vscode"; +import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); export interface ISqlServerBigDataClusterChannel { showOutput(message: any, title?: string): void; } +const outputChannelName = localize('bigDataClusterOutputChannel', 'SQL Server big data cluster'); class SqlServerBigDataCluster implements ISqlServerBigDataClusterChannel { - private readonly channel: vscode.OutputChannel = vscode.window.createOutputChannel("SQL Server big data cluster"); + private readonly channel: vscode.OutputChannel = vscode.window.createOutputChannel(outputChannelName); showOutput(message: any, title?: string): void { if (title) { diff --git a/extensions/big-data-cluster/src/kubectl/binutil.ts b/extensions/big-data-cluster/src/kubectl/binutil.ts index be7699de9f..33c275330d 100644 --- a/extensions/big-data-cluster/src/kubectl/binutil.ts +++ b/extensions/big-data-cluster/src/kubectl/binutil.ts @@ -3,6 +3,9 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + import { Shell } from '../utility/shell'; import { Host } from './host'; import { FS } from '../utility/fs'; @@ -53,17 +56,18 @@ export function execPath(shell: Shell, basePath: string): string { } type CheckPresentFailureReason = 'inferFailed' | 'configuredFileMissing'; - +const installDependenciesAction = localize('installDependenciesAction','Install dependencies'); +const learnMoreAction = localize('learnMoreAction','Learn more'); function alertNoBin(host: Host, binName: string, failureReason: CheckPresentFailureReason, message: string, installDependencies: () => void): void { switch (failureReason) { case 'inferFailed': - host.showErrorMessage(message, 'Install dependencies', 'Learn more').then( + host.showErrorMessage(message, installDependenciesAction, learnMoreAction).then( (str) => { switch (str) { - case 'Learn more': - host.showInformationMessage(`Add ${binName} directory to path, or set "mssql-bdc.${binName}-path" config to ${binName} binary.`); + case learnMoreAction: + host.showInformationMessage(localize('moreInfoMsg', 'Add {0} directory to path, or set "mssql-bdc.{0}-path" config to {0} binary.', binName)); break; - case 'Install dependencies': + case installDependenciesAction: installDependencies(); break; } @@ -72,9 +76,9 @@ function alertNoBin(host: Host, binName: string, failureReason: CheckPresentFail ); break; case 'configuredFileMissing': - host.showErrorMessage(message, 'Install dependencies').then( + host.showErrorMessage(message, installDependenciesAction).then( (str) => { - if (str === 'Install dependencies') { + if (str === installDependenciesAction) { installDependencies(); } } diff --git a/extensions/big-data-cluster/src/kubectl/kubectl.ts b/extensions/big-data-cluster/src/kubectl/kubectl.ts index 819764eaff..e97face4f2 100644 --- a/extensions/big-data-cluster/src/kubectl/kubectl.ts +++ b/extensions/big-data-cluster/src/kubectl/kubectl.ts @@ -3,6 +3,9 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + import { Host } from './host'; import { FS } from '../utility/fs'; import { Shell, ShellResult } from '../utility/shell'; @@ -72,17 +75,17 @@ async function checkForKubectlInternal(context: Context, errorMessageMode: Check const bin = getToolPath(context.host, context.shell, binName); const contextMessage = getCheckKubectlContextMessage(errorMessageMode); - const inferFailedMessage = `Could not find "${binName}" binary.${contextMessage}`; - const configuredFileMissingMessage = `${bin} is not installed. ${contextMessage}`; + const inferFailedMessage = localize('binaryNotFound', 'Could not find {0} binary. {1}', binName, contextMessage); + const configuredFileMissingMessage = localize('binaryNotInstalled', '{0} is not installed. {1}', bin, contextMessage); return await binutil.checkForBinary(context, bin, binName, inferFailedMessage, configuredFileMissingMessage, errorMessageMode !== CheckPresentMessageMode.Silent); } function getCheckKubectlContextMessage(errorMessageMode: CheckPresentMessageMode): string { if (errorMessageMode === CheckPresentMessageMode.Activation) { - return ' SQL Server Big data cluster requires kubernetes.'; + return localize('kubernetesRequired',' SQL Server Big data cluster requires kubernetes.'); } else if (errorMessageMode === CheckPresentMessageMode.Command) { - return ' Cannot execute command.'; + return localize('cannotExecuteCmd', ' Cannot execute command.'); } return ''; } @@ -111,7 +114,7 @@ async function checkPossibleIncompatibility(context: Context): Promise { checkedCompatibility = true; const compat = await compatibility.check((cmd) => asJson(context, cmd)); if (!compatibility.isGuaranteedCompatible(compat) && compat.didCheck) { - const versionAlert = `kubectl version ${compat.clientVersion} may be incompatible with cluster Kubernetes version ${compat.serverVersion}`; + const versionAlert = localize('kubectlVersionIncompatible', 'kubectl version ${0} may be incompatible with cluster Kubernetes version {1}', compat.clientVersion, compat.serverVersion); context.host.showWarningMessage(versionAlert); } } @@ -128,7 +131,7 @@ export function baseKubectlPath(context: Context): string { async function asJson(context: Context, command: string): Promise> { const shellResult = await invokeAsync(context, command); if (!shellResult) { - return { succeeded: false, error: [`Unable to run command (${command})`] }; + return { succeeded: false, error: [localize('cannotRunCommand', 'Unable to run command ({0})', command)] }; } if (shellResult.code === 0) { diff --git a/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts b/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts index 737e39c1e8..e5c250ea9b 100644 --- a/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts +++ b/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts @@ -3,9 +3,12 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from "vscode"; -import { Kubectl } from "./kubectl"; -import { failed, ClusterType } from "../interfaces"; +import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +import { Kubectl } from './kubectl'; +import { failed, ClusterType } from '../interfaces'; export interface KubectlContext { readonly clusterName: string; @@ -47,7 +50,7 @@ export interface ClusterConfig { async function getKubeconfig(kubectl: Kubectl): Promise { - const shellResult = await kubectl.asJson("config view -o json"); + const shellResult = await kubectl.asJson('config view -o json'); if (failed(shellResult)) { vscode.window.showErrorMessage(shellResult.error[0]); return null; @@ -60,11 +63,11 @@ export async function getCurrentClusterConfig(kubectl: Kubectl): Promise context.name === kubeConfig["current-context"])!; + const contextConfig = kubeConfig.contexts.find((context) => context.name === kubeConfig['current-context'])!; const clusterConfig = kubeConfig.clusters.find((cluster) => cluster.name === contextConfig.context.cluster)!; return { server: clusterConfig.cluster.server, - certificateAuthority: clusterConfig.cluster["certificate-authority"] + certificateAuthority: clusterConfig.cluster['certificate-authority'] }; } @@ -73,7 +76,7 @@ export async function getContexts(kubectl: Kubectl): Promise { if (!kubectlConfig) { return []; } - const currentContext = kubectlConfig["current-context"]; + const currentContext = kubectlConfig['current-context']; const contexts = kubectlConfig.contexts || []; return contexts.map((c) => { return { @@ -87,14 +90,15 @@ export async function getContexts(kubectl: Kubectl): Promise { export async function setContext(kubectl: Kubectl, targetContext: string): Promise { const shellResult = await kubectl.invokeAsync(`config use-context ${targetContext}`); - if (!shellResult || shellResult.code != 0) { + if (!shellResult || shellResult.code !== 0) { // TODO: Update error handling for now. - vscode.window.showErrorMessage(`Failed to set '${targetContext}' as current cluster: ${shellResult ? shellResult.stderr : "Unable to run kubectl"}`); + let errMsg = shellResult ? shellResult.stderr : localize('runKubectlFailed', 'Unable to run kubectl'); + vscode.window.showErrorMessage(localize('setClusterFailed', 'Failed to set \'{0}\' as current cluster: {1}', targetContext, errMsg)); } } export async function inferCurrentClusterType(kubectl: Kubectl): Promise { - let latestContextName = ""; + let latestContextName = ''; const ctxsr = await kubectl.invokeAsync('config current-context'); if (ctxsr && ctxsr.code === 0) { diff --git a/extensions/big-data-cluster/src/main.ts b/extensions/big-data-cluster/src/main.ts index b8fb635124..0d51cd5e51 100644 --- a/extensions/big-data-cluster/src/main.ts +++ b/extensions/big-data-cluster/src/main.ts @@ -5,12 +5,15 @@ 'use strict'; import vscode = require('vscode'); +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + import { MainController } from './mainController'; import { fs } from './utility/fs'; import { host } from './kubectl/host'; -import { sqlserverbigdataclusterchannel } from './kubectl/SqlServerBigDataClusterChannel'; +import { sqlserverbigdataclusterchannel } from './kubectl/sqlServerBigDataClusterChannel'; import { shell, Shell } from './utility/shell'; import { CheckPresentMessageMode, create as kubectlCreate } from './kubectl/kubectl'; import { installKubectl } from './installer/installer'; @@ -36,22 +39,22 @@ export async function installDependencies() { const installPromises = [ - installDependency("kubectl", gotKubectl, installKubectl), + installDependency('kubectl', gotKubectl, installKubectl) ]; await Promise.all(installPromises); - sqlserverbigdataclusterchannel.showOutput("Done"); + sqlserverbigdataclusterchannel.showOutput(localize('done', 'Done')); } async function installDependency(name: string, alreadyGot: boolean, installFunc: (shell: Shell) => Promise>): Promise { if (alreadyGot) { - sqlserverbigdataclusterchannel.showOutput(`Already got ${name}...`); + sqlserverbigdataclusterchannel.showOutput(localize('dependencyInstalled', '{0} already installed...', name)); } else { - sqlserverbigdataclusterchannel.showOutput(`Installing ${name}...`); + sqlserverbigdataclusterchannel.showOutput(localize('installingDependency', 'Installing {0}...', name)); const result = await installFunc(shell); if (failed(result)) { - sqlserverbigdataclusterchannel.showOutput(`Unable to install ${name}: ${result.error[0]}`); + sqlserverbigdataclusterchannel.showOutput(localize('installingDependencyFailed', 'Unable to install {0}: {1}', name, result.error[0])); } } } \ No newline at end of file diff --git a/extensions/big-data-cluster/src/scripting/scripting.ts b/extensions/big-data-cluster/src/scripting/scripting.ts index cec3aac18d..841b8c02e4 100644 --- a/extensions/big-data-cluster/src/scripting/scripting.ts +++ b/extensions/big-data-cluster/src/scripting/scripting.ts @@ -6,6 +6,7 @@ import { fs } from '../utility/fs'; import { Shell } from '../utility/shell'; import * as vscode from 'vscode'; import * as path from 'path'; +import * as os from 'os'; import mkdirp = require('mkdirp'); import { Kubectl, baseKubectlPath } from '../kubectl/kubectl'; import { KubectlContext } from '../kubectl/kubectlUtils'; @@ -42,13 +43,13 @@ export class ScriptGenerator { let deployFileName = `${deployFilePrefix}-${targetClusterName}-${timestamp}${deployFileSuffix}`; let deployFilePath = path.join(deployFolder, deployFileName); - let envVars = ""; + let envVars = ''; let propertiesDict = await scriptable.getScriptProperties(); for (let key in propertiesDict) { let value = propertiesDict[key]; envVars += this._shell.isWindows() ? `Set ${key} = ${value}\n` : `export ${key} = ${value}\n`; } - envVars += '\n'; + envVars += os.EOL; let kubeContextcommand = `${this._kubectlPath} config use-context ${targetContextName}\n`; // Todo: The API for mssqlctl may change per version, so need a version check to use proper syntax. diff --git a/extensions/big-data-cluster/src/utility/shell.ts b/extensions/big-data-cluster/src/utility/shell.ts index 6a7ca5c965..ce20ccd80d 100644 --- a/extensions/big-data-cluster/src/utility/shell.ts +++ b/extensions/big-data-cluster/src/utility/shell.ts @@ -172,12 +172,12 @@ export function shellEnvironment(baseEnvironment: any): any { function pathVariableName(env: any): string { if (isWindows()) { for (const v of Object.keys(env)) { - if (v.toLowerCase() === "path") { + if (v.toLowerCase() === 'path') { return v; } } } - return "PATH"; + return 'PATH'; } function pathEntrySeparator() {