diff --git a/extensions/big-data-cluster/images/aks.svg b/extensions/big-data-cluster/images/aks.svg
deleted file mode 100644
index 1df4bc8835..0000000000
--- a/extensions/big-data-cluster/images/aks.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/extensions/big-data-cluster/images/kubernetes.svg b/extensions/big-data-cluster/images/kubernetes.svg
deleted file mode 100644
index 0b17a4013a..0000000000
--- a/extensions/big-data-cluster/images/kubernetes.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/extensions/big-data-cluster/package.json b/extensions/big-data-cluster/package.json
index 24225c938c..62ee5b7376 100644
--- a/extensions/big-data-cluster/package.json
+++ b/extensions/big-data-cluster/package.json
@@ -1,94 +1,111 @@
{
- "name": "big-data-cluster",
- "displayName": "SQL Server big data cluster",
- "description": "SQL Server big data cluster",
- "version": "0.0.1",
- "publisher": "Microsoft",
- "preview": true,
- "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
- "icon": "images/sqlserver.png",
- "aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
- "engines": {
- "vscode": "*",
- "azdata": ">=1.4.0"
- },
- "activationEvents": [
- "*"
- ],
- "main": "./out/main",
- "repository": {
- "type": "git",
- "url": "https://github.com/Microsoft/azuredatastudio.git"
- },
- "extensionDependencies": [
- "Microsoft.mssql"
- ],
- "contributes": {
- "configuration": {
- "type": "object",
- "title": "Kubernetes configuration",
- "properties": {
- "mssql-bdc": {
- "type": "object",
- "description": "Kubernetes configuration",
- "properties": {
- "mssql-bdc.kubectl-path": {
- "type": "string",
- "description": "File path to a kubectl binary."
- },
- "mssql-bdc.kubectl-path.windows": {
- "type": "string",
- "description": "File path to a kubectl binary."
- },
- "mssql-bdc.kubectl-path.mac": {
- "type": "string",
- "description": "File path to a kubectl binary."
- },
- "mssql-bdc.kubectl-path.linux": {
- "type": "string",
- "description": "File path to a kubectl binary."
- },
- "mssql-bdc.kubeconfig": {
- "type": "string",
- "description": "File path to the kubeconfig file."
- },
- "mssql-bdc.knownKubeconfigs": {
- "type": "array",
- "description": "File paths to kubeconfig files from which you can select."
- },
- "mssql-bdc.outputFormat": {
- "enum": [
- "json",
- "yaml"
- ],
- "type": "string",
- "description": "Output format for Kubernetes specs. One of 'json' or 'yaml' (default)."
- }
- },
- "default": {
- "mssql-bdc.namespace": "",
- "mssql-bdc.kubectl-path": "",
- "mssql-bdc.kubeconfig": "",
- "mssql-bdc.knownKubeconfigs": []
- }
- }
- }
- },
- "commands": [
- {
- "command": "mssql.cluster.create",
- "title": "Create SQL Server big data cluster",
- "category": "SQL Server"
- }
- ]
- },
- "dependencies": {
- "vscode-nls": "^3.2.1",
- "download": "^6.2.5",
- "shelljs": "^0.8.3"
- },
- "devDependencies": {
- "mocha-junit-reporter": "^1.17.0",
- "mocha-multi-reporters": "^1.1.7"
- }
+ "name": "big-data-cluster",
+ "displayName": "%text.sqlServerBigDataClusters%",
+ "description": "%description%",
+ "version": "0.0.1",
+ "publisher": "Microsoft",
+ "preview": true,
+ "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
+ "icon": "images/sqlserver.png",
+ "engines": {
+ "vscode": "*",
+ "azdata": "*"
+ },
+ "activationEvents": [
+ "*"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Microsoft/azuredatastudio.git"
+ },
+ "main": "./out/extension",
+ "contributes": {
+ "dataExplorer": {
+ "sqlBigDataCluster": [
+ {
+ "id": "sqlBigDataCluster",
+ "name": "%text.sqlServerBigDataClusters%"
+ }
+ ]
+ },
+ "menus": {
+ "commandPalette": [
+ {
+ "command": "bigDataClusters.command.addController",
+ "when": "false"
+ },
+ {
+ "command": "bigDataClusters.command.deleteController",
+ "when": "false"
+ },
+ {
+ "command": "bigDataClusters.command.refreshController",
+ "when": "false"
+ }
+ ],
+ "view/title": [
+ {
+ "command": "bigDataClusters.command.addController",
+ "when": "view == sqlBigDataCluster",
+ "group": "navigation"
+ }
+ ],
+ "view/item/context": [
+ {
+ "command": "bigDataClusters.command.deleteController",
+ "when": "viewItem == bigDataClusters.itemType.controllerNode",
+ "group": "navigation@1"
+ },
+ {
+ "command": "bigDataClusters.command.refreshController",
+ "when": "viewItem == bigDataClusters.itemType.controllerNode",
+ "group": "navigation@1"
+ }
+ ]
+ },
+ "configuration": {
+ "type": "object",
+ "title": "%text.sqlServerBigDataClusters%",
+ "properties": {
+ "clusterControllers.controllers": {
+ "type": "array"
+ }
+ }
+ },
+ "commands": [
+ {
+ "command": "bigDataClusters.command.addController",
+ "title": "%command.addController.title%",
+ "icon": {
+ "light": "resources/light/add.svg",
+ "dark": "resources/dark/add_inverse.svg"
+ }
+ },
+ {
+ "command": "bigDataClusters.command.deleteController",
+ "title": "%command.deleteController.title%",
+ "when": "viewItem == bigDataClusters.itemType.controllerNode"
+ },
+ {
+ "command": "bigDataClusters.command.refreshController",
+ "title": "%command.refreshController.title%",
+ "icon": {
+ "light": "resources/light/refresh.svg",
+ "dark": "resources/dark/refresh_inverse.svg"
+ }
+ }
+ ]
+ },
+ "dependencies": {
+ "request": "^2.88.0",
+ "vscode-nls": "^4.0.0"
+ },
+ "devDependencies": {
+ "@types/mocha": "^5.2.5",
+ "@types/node": "^8.0.24",
+ "mocha": "^5.2.0",
+ "should": "^13.2.1",
+ "typemoq": "^2.1.0",
+ "vscode": "^1.1.26"
+ }
}
diff --git a/extensions/big-data-cluster/package.nls.json b/extensions/big-data-cluster/package.nls.json
new file mode 100644
index 0000000000..2dc924eda7
--- /dev/null
+++ b/extensions/big-data-cluster/package.nls.json
@@ -0,0 +1,7 @@
+{
+ "description": "Support for managing SQL Server Big Data Clusters",
+ "text.sqlServerBigDataClusters": "SQL Server Big Data Clusters",
+ "command.addController.title": "Connect to Controller",
+ "command.deleteController.title" : "Delete",
+ "command.refreshController.title" : "Refresh"
+}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/dark/add_inverse.svg b/extensions/big-data-cluster/resources/dark/add_inverse.svg
new file mode 100644
index 0000000000..7d3fd77ffd
--- /dev/null
+++ b/extensions/big-data-cluster/resources/dark/add_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/dark/bigDataCluster_controller.svg b/extensions/big-data-cluster/resources/dark/bigDataCluster_controller.svg
new file mode 100644
index 0000000000..428b8af38c
--- /dev/null
+++ b/extensions/big-data-cluster/resources/dark/bigDataCluster_controller.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/dark/folder_inverse.svg b/extensions/big-data-cluster/resources/dark/folder_inverse.svg
new file mode 100644
index 0000000000..f94d427cb1
--- /dev/null
+++ b/extensions/big-data-cluster/resources/dark/folder_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/dark/refresh_inverse.svg b/extensions/big-data-cluster/resources/dark/refresh_inverse.svg
new file mode 100644
index 0000000000..d79fdaa4e8
--- /dev/null
+++ b/extensions/big-data-cluster/resources/dark/refresh_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/dark/sql_bigdata_cluster_inverse.svg b/extensions/big-data-cluster/resources/dark/sql_bigdata_cluster_inverse.svg
new file mode 100644
index 0000000000..dbc823e9f0
--- /dev/null
+++ b/extensions/big-data-cluster/resources/dark/sql_bigdata_cluster_inverse.svg
@@ -0,0 +1,46 @@
+
+
diff --git a/extensions/big-data-cluster/resources/light/add.svg b/extensions/big-data-cluster/resources/light/add.svg
new file mode 100644
index 0000000000..2b679663e8
--- /dev/null
+++ b/extensions/big-data-cluster/resources/light/add.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/light/bigDataCluster_controller.svg b/extensions/big-data-cluster/resources/light/bigDataCluster_controller.svg
new file mode 100644
index 0000000000..428b8af38c
--- /dev/null
+++ b/extensions/big-data-cluster/resources/light/bigDataCluster_controller.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/light/folder.svg b/extensions/big-data-cluster/resources/light/folder.svg
new file mode 100644
index 0000000000..8442363a76
--- /dev/null
+++ b/extensions/big-data-cluster/resources/light/folder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/light/refresh.svg b/extensions/big-data-cluster/resources/light/refresh.svg
new file mode 100644
index 0000000000..e034574819
--- /dev/null
+++ b/extensions/big-data-cluster/resources/light/refresh.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/extensions/big-data-cluster/resources/light/sql_bigdata_cluster.svg b/extensions/big-data-cluster/resources/light/sql_bigdata_cluster.svg
new file mode 100644
index 0000000000..fcf1133186
--- /dev/null
+++ b/extensions/big-data-cluster/resources/light/sql_bigdata_cluster.svg
@@ -0,0 +1,45 @@
+
+
diff --git a/extensions/big-data-cluster/src/bigDataCluster/constants.ts b/extensions/big-data-cluster/src/bigDataCluster/constants.ts
new file mode 100644
index 0000000000..cf1ddfee2e
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/constants.ts
@@ -0,0 +1,41 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+
+export enum BdcItemType {
+ controllerRoot = 'bigDataClusters.itemType.controllerRootNode',
+ controller = 'bigDataClusters.itemType.controllerNode',
+ folder = 'bigDataClusters.itemType.folderNode',
+ sqlMaster = 'bigDataClusters.itemType.sqlMasterNode',
+ EndPoint = 'bigDataClusters.itemType.endPointNode',
+ addController = 'bigDataClusters.itemType.addControllerNode'
+}
+
+export class IconPath {
+ private static extensionContext: vscode.ExtensionContext;
+
+ public static controllerNode: { dark: string, light: string };
+ public static folderNode: { dark: string, light: string };
+ public static sqlMasterNode: { dark: string, light: string };
+
+ public static setExtensionContext(extensionContext: vscode.ExtensionContext) {
+ IconPath.extensionContext = extensionContext;
+ IconPath.controllerNode = {
+ dark: IconPath.extensionContext.asAbsolutePath('resources/dark/bigDataCluster_controller.svg'),
+ light: IconPath.extensionContext.asAbsolutePath('resources/light/bigDataCluster_controller.svg')
+ };
+ IconPath.folderNode = {
+ dark: IconPath.extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'),
+ light: IconPath.extensionContext.asAbsolutePath('resources/light/folder.svg')
+ };
+ IconPath.sqlMasterNode = {
+ dark: IconPath.extensionContext.asAbsolutePath('resources/dark/sql_bigdata_cluster_inverse.svg'),
+ light: IconPath.extensionContext.asAbsolutePath('resources/light/sql_bigdata_cluster.svg')
+ };
+ }
+}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts b/extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts
new file mode 100644
index 0000000000..15b2fbba13
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts
@@ -0,0 +1,1654 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as request from 'request';
+import * as http from 'http';
+
+let defaultBasePath = 'https://localhost';
+
+let primitives = [
+ 'string',
+ 'boolean',
+ 'double',
+ 'integer',
+ 'long',
+ 'float',
+ 'number',
+ 'any'
+];
+
+class ObjectSerializer {
+
+ public static findCorrectType(data: any, expectedType: string) {
+ if (data === undefined) {
+ return expectedType;
+ } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) {
+ return expectedType;
+ } else if (expectedType === 'Date') {
+ return expectedType;
+ } else {
+ if (enumsMap[expectedType]) {
+ return expectedType;
+ }
+
+ if (!typeMap[expectedType]) {
+ return expectedType; // w/e we don't know the type
+ }
+
+ // Check the discriminator
+ let discriminatorProperty = typeMap[expectedType].discriminator;
+ if (discriminatorProperty === null || discriminatorProperty === undefined) {
+ return expectedType; // the type does not have a discriminator. use it.
+ } else {
+ if (data[discriminatorProperty]) {
+ return data[discriminatorProperty]; // use the type given in the discriminator
+ } else {
+ return expectedType; // discriminator was not present (or an empty string)
+ }
+ }
+ }
+ }
+
+ public static serialize(data: any, type: string) {
+ if (data === undefined) {
+ return data;
+ } else if (primitives.indexOf(type.toLowerCase()) !== -1) {
+ return data;
+ } else if (type.lastIndexOf('Array<', 0) === 0) { // string.startsWith pre es6
+ let subType: string = type.replace('Array<', ''); // Array => Type>
+ subType = subType.substring(0, subType.length - 1); // Type> => Type
+ let transformedData: any[] = [];
+ for (let index in data) {
+ let date = data[index];
+ transformedData.push(ObjectSerializer.serialize(date, subType));
+ }
+ return transformedData;
+ } else if (type === 'Date') {
+ return data.toString();
+ } else {
+ if (enumsMap[type]) {
+ return data;
+ }
+ if (!typeMap[type]) { // in case we don't know the type
+ return data;
+ }
+
+ // get the map for the correct type.
+ let attributeTypes = typeMap[type].getAttributeTypeMap();
+ let instance: { [index: string]: any } = {};
+ for (let index in attributeTypes) {
+ let attributeType = attributeTypes[index];
+ instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type);
+ }
+ return instance;
+ }
+ }
+
+ public static deserialize(data: any, type: string) {
+ // polymorphism may change the actual type.
+ type = ObjectSerializer.findCorrectType(data, type);
+ if (data === undefined) {
+ return data;
+ } else if (primitives.indexOf(type.toLowerCase()) !== -1) {
+ return data;
+ } else if (type.lastIndexOf('Array<', 0) === 0) { // string.startsWith pre es6
+ let subType: string = type.replace('Array<', ''); // Array => Type>
+ subType = subType.substring(0, subType.length - 1); // Type> => Type
+ let transformedData: any[] = [];
+ for (let index in data) {
+ let date = data[index];
+ transformedData.push(ObjectSerializer.deserialize(date, subType));
+ }
+ return transformedData;
+ } else if (type === 'Date') {
+ return new Date(data);
+ } else {
+ if (enumsMap[type]) {// is Enum
+ return data;
+ }
+
+ if (!typeMap[type]) { // dont know the type
+ return data;
+ }
+ let instance = new typeMap[type]();
+ let attributeTypes = typeMap[type].getAttributeTypeMap();
+ for (let index in attributeTypes) {
+ let attributeType = attributeTypes[index];
+ instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type);
+ }
+ return instance;
+ }
+ }
+}
+
+export class AppMetadata {
+ 'name'?: string;
+ 'version'?: string;
+ 'description'?: string;
+ 'runtimeType'?: string;
+ 'initCode'?: string;
+ 'code'?: string;
+ 'azureFileSpec'?: Array;
+ 'inputDef'?: Array;
+ 'outputDef'?: Array;
+ 'replicas'?: number;
+ 'poolSizePerReplica'?: number;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'name',
+ 'baseName': 'name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'version',
+ 'baseName': 'version',
+ 'type': 'string'
+ },
+ {
+ 'name': 'description',
+ 'baseName': 'description',
+ 'type': 'string'
+ },
+ {
+ 'name': 'runtimeType',
+ 'baseName': 'runtimeType',
+ 'type': 'string'
+ },
+ {
+ 'name': 'initCode',
+ 'baseName': 'initCode',
+ 'type': 'string'
+ },
+ {
+ 'name': 'code',
+ 'baseName': 'code',
+ 'type': 'string'
+ },
+ {
+ 'name': 'azureFileSpec',
+ 'baseName': 'azureFileSpec',
+ 'type': 'Array'
+ },
+ {
+ 'name': 'inputDef',
+ 'baseName': 'inputDef',
+ 'type': 'Array'
+ },
+ {
+ 'name': 'outputDef',
+ 'baseName': 'outputDef',
+ 'type': 'Array'
+ },
+ {
+ 'name': 'replicas',
+ 'baseName': 'replicas',
+ 'type': 'number'
+ },
+ {
+ 'name': 'poolSizePerReplica',
+ 'baseName': 'poolSizePerReplica',
+ 'type': 'number'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return AppMetadata.attributeTypeMap;
+ }
+}
+
+export class AppModel {
+ 'name'?: string;
+ 'internalName'?: string;
+ 'version'?: string;
+ 'inputParamDefs'?: Array;
+ 'outputParamDefs'?: Array;
+ 'state'?: string;
+ 'links'?: { [key: string]: string; };
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'name',
+ 'baseName': 'name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'internalName',
+ 'baseName': 'internal_name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'version',
+ 'baseName': 'version',
+ 'type': 'string'
+ },
+ {
+ 'name': 'inputParamDefs',
+ 'baseName': 'input_param_defs',
+ 'type': 'Array'
+ },
+ {
+ 'name': 'outputParamDefs',
+ 'baseName': 'output_param_defs',
+ 'type': 'Array'
+ },
+ {
+ 'name': 'state',
+ 'baseName': 'state',
+ 'type': 'string'
+ },
+ {
+ 'name': 'links',
+ 'baseName': 'links',
+ 'type': '{ [key: string]: string; }'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return AppModel.attributeTypeMap;
+ }
+}
+
+export class AppModelParameterDefinition {
+ 'name'?: string;
+ 'type'?: string;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'name',
+ 'baseName': 'name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'type',
+ 'baseName': 'type',
+ 'type': 'string'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return AppModelParameterDefinition.attributeTypeMap;
+ }
+}
+
+export class AppRequest {
+ 'metadata'?: AppMetadata;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'metadata',
+ 'baseName': 'metadata',
+ 'type': 'AppMetadata'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return AppRequest.attributeTypeMap;
+ }
+}
+
+export class AzureFileSpecDefinition {
+ 'secretName'?: string;
+ 'mountPath'?: string;
+ 'fileShareName'?: string;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'secretName',
+ 'baseName': 'secretName',
+ 'type': 'string'
+ },
+ {
+ 'name': 'mountPath',
+ 'baseName': 'mountPath',
+ 'type': 'string'
+ },
+ {
+ 'name': 'fileShareName',
+ 'baseName': 'fileShareName',
+ 'type': 'string'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return AzureFileSpecDefinition.attributeTypeMap;
+ }
+}
+
+export class EndpointModel {
+ 'name'?: string;
+ 'description'?: string;
+ 'endpoint'?: string;
+ 'ip'?: string;
+ 'port'?: number;
+ 'path'?: string;
+ 'protocol'?: string;
+ 'service'?: string;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'name',
+ 'baseName': 'name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'description',
+ 'baseName': 'description',
+ 'type': 'string'
+ },
+ {
+ 'name': 'endpoint',
+ 'baseName': 'endpoint',
+ 'type': 'string'
+ },
+ {
+ 'name': 'ip',
+ 'baseName': 'ip',
+ 'type': 'string'
+ },
+ {
+ 'name': 'port',
+ 'baseName': 'port',
+ 'type': 'number'
+ },
+ {
+ 'name': 'path',
+ 'baseName': 'path',
+ 'type': 'string'
+ },
+ {
+ 'name': 'protocol',
+ 'baseName': 'protocol',
+ 'type': 'string'
+ },
+ {
+ 'name': 'service',
+ 'baseName': 'service',
+ 'type': 'string'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return EndpointModel.attributeTypeMap;
+ }
+}
+
+export class ParameterDefinition {
+ 'name'?: string;
+ 'type'?: string;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'name',
+ 'baseName': 'name',
+ 'type': 'string'
+ },
+ {
+ 'name': 'type',
+ 'baseName': 'type',
+ 'type': 'string'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return ParameterDefinition.attributeTypeMap;
+ }
+}
+
+export class TokenModel {
+ 'tokenType'?: string;
+ 'accessToken'?: string;
+ 'expiresIn'?: number;
+ 'expiresOn'?: number;
+ 'tokenId'?: string;
+
+ static discriminator: string | undefined = undefined;
+
+ static attributeTypeMap: Array<{ name: string, baseName: string, type: string }> = [
+ {
+ 'name': 'tokenType',
+ 'baseName': 'token_type',
+ 'type': 'string'
+ },
+ {
+ 'name': 'accessToken',
+ 'baseName': 'access_token',
+ 'type': 'string'
+ },
+ {
+ 'name': 'expiresIn',
+ 'baseName': 'expires_in',
+ 'type': 'number'
+ },
+ {
+ 'name': 'expiresOn',
+ 'baseName': 'expires_on',
+ 'type': 'number'
+ },
+ {
+ 'name': 'tokenId',
+ 'baseName': 'token_id',
+ 'type': 'string'
+ }
+ ];
+
+ static getAttributeTypeMap() {
+ return TokenModel.attributeTypeMap;
+ }
+}
+
+
+let enumsMap: { [index: string]: any } = {
+};
+
+let typeMap: { [index: string]: any } = {
+ 'AppMetadata': AppMetadata,
+ 'AppModel': AppModel,
+ 'AppModelParameterDefinition': AppModelParameterDefinition,
+ 'AppRequest': AppRequest,
+ 'AzureFileSpecDefinition': AzureFileSpecDefinition,
+ 'EndpointModel': EndpointModel,
+ 'ParameterDefinition': ParameterDefinition,
+ 'TokenModel': TokenModel,
+};
+
+export interface Authentication {
+ /**
+ * Apply authentication settings to header and query params.
+ */
+ applyToRequest(requestOptions: request.Options): void;
+}
+
+export class HttpBasicAuth implements Authentication {
+ public username: string = '';
+ public password: string = '';
+
+ applyToRequest(requestOptions: request.Options): void {
+ requestOptions.auth = {
+ username: this.username, password: this.password
+ };
+ }
+}
+
+export class ApiKeyAuth implements Authentication {
+ public apiKey: string = '';
+
+ constructor(private location: string, private paramName: string) {
+ }
+
+ applyToRequest(requestOptions: request.Options): void {
+ if (this.location === 'query') {
+ (requestOptions.qs)[this.paramName] = this.apiKey;
+ } else if (this.location === 'header' && requestOptions && requestOptions.headers) {
+ requestOptions.headers[this.paramName] = this.apiKey;
+ }
+ }
+}
+
+export class OAuth implements Authentication {
+ public accessToken: string = '';
+
+ applyToRequest(requestOptions: request.Options): void {
+ if (requestOptions && requestOptions.headers) {
+ requestOptions.headers['Authorization'] = 'Bearer ' + this.accessToken;
+ }
+ }
+}
+
+export class VoidAuth implements Authentication {
+ public username: string = '';
+ public password: string = '';
+
+ applyToRequest(_: request.Options): void {
+ // Do nothing
+ }
+}
+
+export enum AppRouterApiApiKeys {
+}
+
+export class AppRouterApi {
+ protected _basePath = defaultBasePath;
+ protected defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+
+ protected authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(basePath?: string);
+ constructor(username: string, password: string, basePath?: string);
+ constructor(basePathOrUsername: string, password?: string, basePath?: string) {
+ if (password) {
+ this.username = basePathOrUsername;
+ this.password = password;
+ if (basePath) {
+ this.basePath = basePath;
+ }
+ } else {
+ if (basePathOrUsername) {
+ this.basePath = basePathOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set basePath(basePath: string) {
+ this._basePath = basePath;
+ }
+
+ get basePath() {
+ return this._basePath;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this.authentications.default = auth;
+ }
+
+ public setApiKey(key: AppRouterApiApiKeys, value: string) {
+ (this.authentications as any)[AppRouterApiApiKeys[key]].apiKey = value;
+ }
+ set username(username: string) {
+ this.authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this.authentications.basic.password = password;
+ }
+
+ /**
+ * @param name name
+ * @param version version
+ * @param [options] Override http request options.
+ */
+ public appByNameByVersionDelete(name: string, version: string, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/app/{name}/{version}'
+ .replace('{name}', encodeURIComponent(String(name)))
+ .replace('{version}', encodeURIComponent(String(version)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling appByNameByVersionDelete.');
+ }
+
+ // verify required parameter 'version' is not null or undefined
+ if (version === null || version === undefined) {
+ throw new Error('Required parameter version was null or undefined when calling appByNameByVersionDelete.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'DELETE',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param name name
+ * @param version version
+ * @param [options] Override http request options.
+ */
+ public appByNameByVersionGet(name: string, version: string, options: any = {}): Promise<{ response: http.IncomingMessage; body: AppModel; }> {
+ const localVarPath = this.basePath + '/app/{name}/{version}'
+ .replace('{name}', encodeURIComponent(String(name)))
+ .replace('{version}', encodeURIComponent(String(version)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling appByNameByVersionGet.');
+ }
+
+ // verify required parameter 'version' is not null or undefined
+ if (version === null || version === undefined) {
+ throw new Error('Required parameter version was null or undefined when calling appByNameByVersionGet.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body: AppModel; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ body = ObjectSerializer.deserialize(body, 'AppModel');
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param name name
+ * @param version version
+ * @param appRequest appRequest
+ * @param [options] Override http request options.
+ */
+ public appByNameByVersionPatch(name: string, version: string, appRequest?: AppRequest, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/app/{name}/{version}'
+ .replace('{name}', encodeURIComponent(String(name)))
+ .replace('{version}', encodeURIComponent(String(version)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling appByNameByVersionPatch.');
+ }
+
+ // verify required parameter 'version' is not null or undefined
+ if (version === null || version === undefined) {
+ throw new Error('Required parameter version was null or undefined when calling appByNameByVersionPatch.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'PATCH',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ body: ObjectSerializer.serialize(appRequest, 'AppRequest')
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param name name
+ * @param version version
+ * @param [options] Override http request options.
+ */
+ public appByNameByVersionSwaggerJsonGet(name: string, version: string, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/app/{name}/{version}/swagger.json'
+ .replace('{name}', encodeURIComponent(String(name)))
+ .replace('{version}', encodeURIComponent(String(version)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling appByNameByVersionSwaggerJsonGet.');
+ }
+
+ // verify required parameter 'version' is not null or undefined
+ if (version === null || version === undefined) {
+ throw new Error('Required parameter version was null or undefined when calling appByNameByVersionSwaggerJsonGet.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param name name
+ * @param [options] Override http request options.
+ */
+ public appByNameGet(name: string, options: any = {}): Promise<{ response: http.IncomingMessage; body: Array; }> {
+ const localVarPath = this.basePath + '/app/{name}'
+ .replace('{name}', encodeURIComponent(String(name)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling appByNameGet.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body: Array; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ body = ObjectSerializer.deserialize(body, 'Array');
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param [options] Override http request options.
+ */
+ public appGet(options: any = {}): Promise<{ response: http.IncomingMessage; body: Array; }> {
+ const localVarPath = this.basePath + '/app';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body: Array; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ body = ObjectSerializer.deserialize(body, 'Array');
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param _package Zip archive file which contains a spec.yaml
+ * @param [options] Override http request options.
+ */
+ public createApp(_package: Buffer, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/app';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter '_package' is not null or undefined
+ if (_package === null || _package === undefined) {
+ throw new Error('Required parameter _package was null or undefined when calling createApp.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ if (_package !== undefined) {
+ localVarFormParams['package'] = _package;
+ }
+ localVarUseFormData = true;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'POST',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param _package Zip archive file which contains a spec.yaml
+ * @param [options] Override http request options.
+ */
+ public updateApp(_package: Buffer, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/app';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter '_package' is not null or undefined
+ if (_package === null || _package === undefined) {
+ throw new Error('Required parameter _package was null or undefined when calling updateApp.');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ if (_package !== undefined) {
+ localVarFormParams['package'] = _package;
+ }
+ localVarUseFormData = true;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'PATCH',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
+export enum CertificateRouterApiApiKeys {
+}
+
+export class CertificateRouterApi {
+ protected _basePath = defaultBasePath;
+ protected defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+
+ protected authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(basePath?: string);
+ constructor(username: string, password: string, basePath?: string);
+ constructor(basePathOrUsername: string, password?: string, basePath?: string) {
+ if (password) {
+ this.username = basePathOrUsername;
+ this.password = password;
+ if (basePath) {
+ this.basePath = basePath;
+ }
+ } else {
+ if (basePathOrUsername) {
+ this.basePath = basePathOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set basePath(basePath: string) {
+ this._basePath = basePath;
+ }
+
+ get basePath() {
+ return this._basePath;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this.authentications.default = auth;
+ }
+
+ public setApiKey(key: CertificateRouterApiApiKeys, value: string) {
+ (this.authentications as any)[CertificateRouterApiApiKeys[key]].apiKey = value;
+ }
+ set username(username: string) {
+ this.authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this.authentications.basic.password = password;
+ }
+
+ /**
+ * @param [options] Override http request options.
+ */
+ public certificatesRootcaGet(options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/certificates/rootca';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
+
+export enum EndpointRouterApiApiKeys {
+}
+
+export class EndpointRouterApi {
+ protected _url = defaultBasePath;
+ protected _defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+ protected _ignoreSslVerification: boolean = false;
+
+ protected _authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(url?: string);
+ constructor(username: string, password: string, url?: string);
+ constructor(urlOrUsername: string, password?: string, url?: string) {
+ if (password) {
+ this.username = urlOrUsername;
+ this.password = password;
+ if (url) {
+ this.url = url;
+ }
+ } else {
+ if (urlOrUsername) {
+ this.url = urlOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set ignoreSslVerification(ignoreSslVerification: boolean) {
+ this._ignoreSslVerification = ignoreSslVerification;
+ }
+
+ set url(url: string) {
+ this._url = url;
+ }
+
+ get url() {
+ return this._url;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this._authentications.default = auth;
+ }
+
+ public setApiKey(key: EndpointRouterApiApiKeys, value: string) {
+ (this._authentications as any)[EndpointRouterApiApiKeys[key]].apiKey = value;
+ }
+
+ set username(username: string) {
+ this._authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this._authentications.basic.password = password;
+ }
+
+ /**
+ * @param [options] Override http request options.
+ */
+ public endpointsGet(options: request.Options = {}): Promise<{ response: http.IncomingMessage; body: Array; }> {
+ return this.endpointsGetInternal(undefined, options);
+ }
+
+ /**
+ * @param name endpoint name,
+ * @param [options] Override http request options.
+ */
+ public endpointsByNameGet(name: string, options: request.Options = {}): Promise<{ response: http.IncomingMessage; body: Array; }> {
+ // verify required parameter 'name' is not null or undefined
+ if (name === null || name === undefined) {
+ throw new Error('Required parameter name was null or undefined when calling endpointsByNameGet.');
+ }
+ return this.endpointsGetInternal(name, options);
+ }
+
+ private endpointsGetInternal(name?: string, options: request.Options = {}): Promise<{ response: http.IncomingMessage; body: Array; }> {
+ const targetUri = this.url + '/endpoints' + (name ? `/${name}` : '');
+ let requestOptions: request.Options = {
+ method: 'GET',
+ qs: {},
+ headers: {},
+ uri: targetUri,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ agentOptions: {
+ rejectUnauthorized: !this._ignoreSslVerification
+ }
+ };
+ if (Object.keys(options).length) {
+ requestOptions = Object.assign(requestOptions, options);
+ }
+
+ this._authentications.basic.applyToRequest(requestOptions);
+ this._authentications.default.applyToRequest(requestOptions);
+
+ return new Promise<{ response: http.IncomingMessage; body: Array; }>((resolve, reject) => {
+ request(requestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ body = ObjectSerializer.deserialize(body, 'Array');
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
+
+export enum FileRouterApiApiKeys {
+}
+
+export class FileRouterApi {
+ protected _basePath = defaultBasePath;
+ protected defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+
+ protected authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(basePath?: string);
+ constructor(username: string, password: string, basePath?: string);
+ constructor(basePathOrUsername: string, password?: string, basePath?: string) {
+ if (password) {
+ this.username = basePathOrUsername;
+ this.password = password;
+ if (basePath) {
+ this.basePath = basePath;
+ }
+ } else {
+ if (basePathOrUsername) {
+ this.basePath = basePathOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set basePath(basePath: string) {
+ this._basePath = basePath;
+ }
+
+ get basePath() {
+ return this._basePath;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this.authentications.default = auth;
+ }
+
+ public setApiKey(key: FileRouterApiApiKeys, value: string) {
+ (this.authentications as any)[FileRouterApiApiKeys[key]].apiKey = value;
+ }
+ set username(username: string) {
+ this.authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this.authentications.basic.password = password;
+ }
+
+ /**
+ * @param filePath filePath
+ * @param op op
+ * @param [options] Override http request options.
+ */
+ public filesByFilePathGet(filePath: string, op?: string, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/files/{filePath}'
+ .replace('{filePath}', encodeURIComponent(String(filePath)));
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ // verify required parameter 'filePath' is not null or undefined
+ if (filePath === null || filePath === undefined) {
+ throw new Error('Required parameter filePath was null or undefined when calling filesByFilePathGet.');
+ }
+
+ if (op !== undefined) {
+ localVarQueryParameters['op'] = ObjectSerializer.serialize(op, 'string');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
+export enum HealthRouterApiApiKeys {
+}
+
+export class HealthRouterApi {
+ protected _basePath = defaultBasePath;
+ protected defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+
+ protected authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(basePath?: string);
+ constructor(username: string, password: string, basePath?: string);
+ constructor(basePathOrUsername: string, password?: string, basePath?: string) {
+ if (password) {
+ this.username = basePathOrUsername;
+ this.password = password;
+ if (basePath) {
+ this.basePath = basePath;
+ }
+ } else {
+ if (basePathOrUsername) {
+ this.basePath = basePathOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set basePath(basePath: string) {
+ this._basePath = basePath;
+ }
+
+ get basePath() {
+ return this._basePath;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this.authentications.default = auth;
+ }
+
+ public setApiKey(key: HealthRouterApiApiKeys, value: string) {
+ (this.authentications as any)[HealthRouterApiApiKeys[key]].apiKey = value;
+ }
+ set username(username: string) {
+ this.authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this.authentications.basic.password = password;
+ }
+
+ /**
+ * @param query query
+ * @param [options] Override http request options.
+ */
+ public healthGet(query?: string, options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/health';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ if (query !== undefined) {
+ localVarQueryParameters['query'] = ObjectSerializer.serialize(query, 'string');
+ }
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'GET',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * @param [options] Override http request options.
+ */
+ public healthPost(options: any = {}): Promise<{ response: http.IncomingMessage; body?: any; }> {
+ const localVarPath = this.basePath + '/health';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'POST',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
+
+export enum TokenRouterApiApiKeys {
+}
+
+export class TokenRouterApi {
+ protected _basePath = defaultBasePath;
+ protected defaultHeaders: any = {};
+ protected _useQuerystring: boolean = false;
+
+ protected authentications = {
+ 'default': new VoidAuth(),
+ 'basic': new HttpBasicAuth()
+ };
+
+ constructor(basePath?: string);
+ constructor(username: string, password: string, basePath?: string);
+ constructor(basePathOrUsername: string, password?: string, basePath?: string) {
+ if (password) {
+ this.username = basePathOrUsername;
+ this.password = password;
+ if (basePath) {
+ this.basePath = basePath;
+ }
+ } else {
+ if (basePathOrUsername) {
+ this.basePath = basePathOrUsername;
+ }
+ }
+ }
+
+ set useQuerystring(value: boolean) {
+ this._useQuerystring = value;
+ }
+
+ set basePath(basePath: string) {
+ this._basePath = basePath;
+ }
+
+ get basePath() {
+ return this._basePath;
+ }
+
+ public setDefaultAuthentication(auth: Authentication) {
+ this.authentications.default = auth;
+ }
+
+ public setApiKey(key: TokenRouterApiApiKeys, value: string) {
+ (this.authentications as any)[TokenRouterApiApiKeys[key]].apiKey = value;
+ }
+ set username(username: string) {
+ this.authentications.basic.username = username;
+ }
+
+ set password(password: string) {
+ this.authentications.basic.password = password;
+ }
+
+ /**
+ * @param [options] Override http request options.
+ */
+ public tokenPost(options: any = {}): Promise<{ response: http.IncomingMessage; body: TokenModel; }> {
+ const localVarPath = this.basePath + '/token';
+ let localVarQueryParameters: any = {};
+ let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders);
+ let localVarFormParams: any = {};
+
+ localVarHeaderParams = (Object).assign(localVarHeaderParams, options.headers);
+
+ let localVarUseFormData = false;
+
+ let localVarRequestOptions: request.Options = {
+ method: 'POST',
+ qs: localVarQueryParameters,
+ headers: localVarHeaderParams,
+ uri: localVarPath,
+ useQuerystring: this._useQuerystring,
+ json: true,
+ };
+
+ this.authentications.basic.applyToRequest(localVarRequestOptions);
+
+ this.authentications.default.applyToRequest(localVarRequestOptions);
+
+ if (Object.keys(localVarFormParams).length) {
+ if (localVarUseFormData) {
+ (localVarRequestOptions).formData = localVarFormParams;
+ } else {
+ localVarRequestOptions.form = localVarFormParams;
+ }
+ }
+ return new Promise<{ response: http.IncomingMessage; body: TokenModel; }>((resolve, reject) => {
+ request(localVarRequestOptions, (error, response, body) => {
+ if (error) {
+ reject(error);
+ } else {
+ body = ObjectSerializer.deserialize(body, 'TokenModel');
+ if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
+ resolve({ response: response, body: body });
+ } else {
+ reject({ response: response, body: body });
+ }
+ }
+ });
+ });
+ }
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/controller/clusterControllerApi.ts b/extensions/big-data-cluster/src/bigDataCluster/controller/clusterControllerApi.ts
new file mode 100644
index 0000000000..ce90c7904f
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/controller/clusterControllerApi.ts
@@ -0,0 +1,105 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { EndpointRouterApi } from './apiGenerated';
+
+export async function getEndPoints(
+ url: string, username: string, password: string, ignoreSslVerification?: boolean
+): Promise {
+
+ if (!url || !username || !password) {
+ return undefined;
+ }
+
+ url = adjustUrl(url);
+ let endPointApi = new EndpointRouterApi(username, password, url);
+ endPointApi.ignoreSslVerification = !!ignoreSslVerification;
+
+ let controllerResponse: IEndPointsResponse = undefined;
+ let controllerError: IControllerError = undefined;
+ let request = {
+ url: url,
+ username: username,
+ password: password,
+ method: 'endPointsGet'
+ };
+
+ try {
+ let result = await endPointApi.endpointsGet();
+ controllerResponse = {
+ response: result.response as IHttpResponse,
+ endPoints: result.body as IEndPoint[],
+ request
+ };
+ return controllerResponse;
+ } catch (error) {
+ if ('response' in error) {
+ let err: IEndPointsResponse = error as IEndPointsResponse;
+ let errCode = `${err.response.statusCode || ''}`;
+ let errMessage = err.response.statusMessage;
+ let errUrl = err.response.url;
+ controllerError = {
+ address: errUrl,
+ code: errCode,
+ errno: errCode,
+ message: errMessage,
+ name: undefined
+ };
+ } else {
+ controllerError = error as IControllerError;
+ }
+ throw Object.assign(controllerError, { request }) as IControllerError;
+ }
+}
+
+/**
+ * Fixes missing protocol and wrong character for port entered by user
+ */
+function adjustUrl(url: string): string {
+ if (!url) {
+ return undefined;
+ }
+
+ url = url.trim().replace(/ /g, '').replace(/,(\d+)$/, ':$1');
+ if (!url.includes('://')) {
+ url = `https://${url}`;
+ }
+ return url;
+}
+
+export interface IEndPointsRequest {
+ url: string;
+ username: string;
+ password?: string;
+ method?: string;
+}
+
+export interface IEndPointsResponse {
+ request?: IEndPointsRequest;
+ response: IHttpResponse;
+ endPoints: IEndPoint[];
+}
+
+export interface IHttpResponse {
+ method?: string;
+ url?: string;
+ statusCode?: number;
+ statusMessage?: string;
+}
+
+export interface IEndPoint {
+ name?: string;
+ description?: string;
+ endpoint?: string;
+ ip?: string;
+ port?: number;
+}
+
+export interface IControllerError extends Error {
+ code?: string;
+ errno?: string;
+ message: string;
+ request?: any;
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/dialog/addControllerDialog.ts b/extensions/big-data-cluster/src/bigDataCluster/dialog/addControllerDialog.ts
new file mode 100644
index 0000000000..b09d358c9d
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/dialog/addControllerDialog.ts
@@ -0,0 +1,157 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+import * as azdata from 'azdata';
+import * as nls from 'vscode-nls';
+import { IEndPoint, IControllerError, getEndPoints } from '../controller/clusterControllerApi';
+import { ControllerTreeDataProvider } from '../tree/controllerTreeDataProvider';
+import { TreeNode } from '../tree/treeNode';
+import { showErrorMessage } from '../utils';
+
+const localize = nls.loadMessageBundle();
+
+export class AddControllerDialogModel {
+ constructor(
+ public treeDataProvider: ControllerTreeDataProvider,
+ public node?: TreeNode,
+ public prefilledUrl?: string,
+ public prefilledUsername?: string,
+ public prefilledPassword?: string,
+ public prefilledRememberPassword?: boolean
+ ) {
+ this.prefilledUrl = prefilledUrl || (node && node['url']);
+ this.prefilledUsername = prefilledUsername || (node && node['username']);
+ this.prefilledPassword = prefilledPassword || (node && node['password']);
+ this.prefilledRememberPassword = prefilledRememberPassword || (node && node['rememberPassword']);
+ }
+
+ public async onComplete(url: string, username: string, password: string, rememberPassword: boolean): Promise {
+ let response = await getEndPoints(url, username, password, true);
+ if (response && response.request) {
+ let masterInstance: IEndPoint = undefined;
+ if (response.endPoints) {
+ masterInstance = response.endPoints.find(e => e.name && e.name === 'sql-server-master');
+ }
+ this.treeDataProvider.addController(response.request.url, response.request.username,
+ response.request.password, rememberPassword, masterInstance);
+ await this.treeDataProvider.saveControllers();
+ }
+ }
+
+ public async onError(error: IControllerError): Promise {
+ // implement
+ }
+
+ public async onCancel(): Promise {
+ if (this.node) {
+ this.node.refresh();
+ }
+ }
+}
+
+export class AddControllerDialog {
+
+ private dialog: azdata.window.Dialog;
+ private uiModelBuilder: azdata.ModelBuilder;
+
+ private urlInputBox: azdata.InputBoxComponent;
+ private usernameInputBox: azdata.InputBoxComponent;
+ private passwordInputBox: azdata.InputBoxComponent;
+ private rememberPwCheckBox: azdata.CheckBoxComponent;
+
+ constructor(private model: AddControllerDialogModel) {
+ }
+
+ public showDialog(): void {
+ this.createDialog();
+ azdata.window.openDialog(this.dialog);
+ }
+
+ private createDialog(): void {
+ this.dialog = azdata.window.createModelViewDialog(localize('textAddNewController', 'Add New Controller'));
+ this.dialog.registerContent(async view => {
+ this.uiModelBuilder = view.modelBuilder;
+
+ this.urlInputBox = this.uiModelBuilder.inputBox()
+ .withProperties({
+ placeHolder: localize('textUrlLower', 'url'),
+ value: this.model.prefilledUrl
+ }).component();
+ this.usernameInputBox = this.uiModelBuilder.inputBox()
+ .withProperties({
+ placeHolder: localize('textUsernameLower', 'username'),
+ value: this.model.prefilledUsername
+ }).component();
+ this.passwordInputBox = this.uiModelBuilder.inputBox()
+ .withProperties({
+ placeHolder: localize('textPasswordLower', 'password'),
+ inputType: 'password',
+ value: this.model.prefilledPassword
+ })
+ .component();
+ this.rememberPwCheckBox = this.uiModelBuilder.checkBox()
+ .withProperties({
+ label: localize('textRememberPassword', 'Remember Password'),
+ checked: this.model.prefilledRememberPassword
+ }).component();
+
+ let formModel = this.uiModelBuilder.formContainer()
+ .withFormItems([{
+ components: [{
+ component: this.urlInputBox,
+ title: localize('textUrlCapital', 'URL'),
+ required: true
+ }, {
+ component: this.usernameInputBox,
+ title: localize('textUsernameCapital', 'Username'),
+ required: true
+ }, {
+ component: this.passwordInputBox,
+ title: localize('textPasswordCapital', 'Password'),
+ required: true
+ }, {
+ component: this.rememberPwCheckBox,
+ title: ''
+ }
+ ],
+ title: ''
+ }]).withLayout({ width: '100%' }).component();
+
+ await view.initializeModel(formModel);
+ });
+
+ this.dialog.registerCloseValidator(async () => await this.validate());
+ this.dialog.cancelButton.onClick(async () => await this.cancel());
+ this.dialog.okButton.label = localize('textAdd', 'Add');
+ this.dialog.cancelButton.label = localize('textCancel', 'Cancel');
+ }
+
+ private async validate(): Promise {
+ let url = this.urlInputBox && this.urlInputBox.value;
+ let username = this.usernameInputBox && this.usernameInputBox.value;
+ let password = this.passwordInputBox && this.passwordInputBox.value;
+ let rememberPassword = this.passwordInputBox && !!this.rememberPwCheckBox.checked;
+
+ try {
+ await this.model.onComplete(url, username, password, rememberPassword);
+ return true;
+ } catch (error) {
+ showErrorMessage(error);
+ if (this.model && this.model.onError) {
+ await this.model.onError(error as IControllerError);
+ }
+ return false;
+ }
+ }
+
+ private async cancel(): Promise {
+ if (this.model && this.model.onCancel) {
+ await this.model.onCancel();
+ }
+ }
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/tree/addControllerTreeNode.ts b/extensions/big-data-cluster/src/bigDataCluster/tree/addControllerTreeNode.ts
new file mode 100644
index 0000000000..73397636a4
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/tree/addControllerTreeNode.ts
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as nls from 'vscode-nls';
+import * as azdata from 'azdata';
+import * as vscode from 'vscode';
+import { TreeNode } from './treeNode';
+import { BdcItemType } from '../constants';
+
+const localize = nls.loadMessageBundle();
+
+export class AddControllerNode extends TreeNode {
+ private readonly nodeType: string;
+
+ constructor() {
+ super(localize('textBigDataClusterControllerWithDots', 'Add Big Data Cluster Controller...'));
+ this.nodeType = BdcItemType.addController;
+ }
+
+ public async getChildren(): Promise {
+ return [];
+ }
+
+ public getTreeItem(): vscode.TreeItem {
+ let item = new vscode.TreeItem(this.label, vscode.TreeItemCollapsibleState.None);
+ item.command = {
+ title: localize('textConnectToController', 'Connect to Controller'),
+ command: 'bigDataClusters.command.addController',
+ arguments: [this]
+ };
+ item.contextValue = this.nodeType;
+ return item;
+ }
+
+ public getNodeInfo(): azdata.NodeInfo {
+ return {
+ label: this.label,
+ isLeaf: this.isLeaf,
+ errorMessage: undefined,
+ metadata: undefined,
+ nodePath: this.nodePath,
+ nodeStatus: undefined,
+ nodeType: this.nodeType,
+ iconType: this.nodeType,
+ nodeSubType: undefined
+ };
+ }
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeChangeHandler.ts b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeChangeHandler.ts
new file mode 100644
index 0000000000..2fc7e30472
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeChangeHandler.ts
@@ -0,0 +1,12 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import { TreeNode } from './treeNode';
+
+export interface IControllerTreeChangeHandler {
+ notifyNodeChanged(node?: TreeNode): void;
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeDataProvider.ts b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeDataProvider.ts
new file mode 100644
index 0000000000..759efc4adc
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeDataProvider.ts
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+import * as azdata from 'azdata';
+import { TreeNode } from './treeNode';
+import { IControllerTreeChangeHandler } from './controllerTreeChangeHandler';
+import { AddControllerNode } from './addControllerTreeNode';
+import { ControllerRootNode, ControllerNode } from './controllerTreeNode';
+import { IEndPoint } from '../controller/clusterControllerApi';
+import { showErrorMessage } from '../utils';
+
+const ConfigNamespace = 'clusterControllers';
+const CredentialNamespace = 'clusterControllerCredentials';
+
+export class ControllerTreeDataProvider implements vscode.TreeDataProvider, IControllerTreeChangeHandler {
+
+ private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter();
+ public readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event;
+ private root: ControllerRootNode;
+ private credentialProvider: azdata.CredentialProvider;
+
+ constructor() {
+ this.root = new ControllerRootNode(this);
+ this.loadSavedControllers();
+ }
+
+ public async getChildren(element?: TreeNode): Promise {
+ if (element) {
+ return element.getChildren();
+ }
+
+ if (this.root.hasChildren) {
+ return this.root.getChildren();
+ } else {
+ return [new AddControllerNode()];
+ }
+ }
+
+ public getTreeItem(element: TreeNode): vscode.TreeItem | Thenable {
+ return element.getTreeItem();
+ }
+
+ public addController(
+ url: string,
+ username: string,
+ password: string,
+ rememberPassword: boolean,
+ masterInstance?: IEndPoint
+ ): void {
+ this.root.addControllerNode(url, username, password, rememberPassword, masterInstance);
+ this.notifyNodeChanged();
+ }
+
+ public deleteController(url: string, username: string): ControllerNode {
+ let deleted = this.root.deleteControllerNode(url, username);
+ if (deleted) {
+ this.notifyNodeChanged();
+ }
+ return deleted;
+ }
+
+ public notifyNodeChanged(node?: TreeNode): void {
+ this._onDidChangeTreeData.fire(node);
+ }
+
+ public async loadSavedControllers(): Promise {
+ let config = vscode.workspace.getConfiguration(ConfigNamespace);
+ if (config && config.controllers) {
+ let controllers = config.controllers;
+ this.root.clearChildren();
+ for (let c of controllers) {
+ let password = undefined;
+ if (c.rememberPassword) {
+ password = await this.getPassword(c.url, c.username);
+ }
+ this.root.addChild(new ControllerNode(
+ c.url, c.username, password, c.rememberPassword,
+ undefined, this.root, this, undefined
+ ));
+ }
+ this.notifyNodeChanged();
+ }
+ }
+
+ public async saveControllers(): Promise {
+ let controllers = this.root.children.map(e => {
+ let controller = e as ControllerNode;
+ return {
+ url: controller.url,
+ username: controller.username,
+ password: controller.password,
+ rememberPassword: !!controller.rememberPassword
+ };
+ });
+
+ let controllersWithoutPassword = controllers.map(e => {
+ return {
+ url: e.url,
+ username: e.username,
+ rememberPassword: e.rememberPassword
+ };
+ });
+
+ try {
+ await vscode.workspace.getConfiguration(ConfigNamespace).update('controllers', controllersWithoutPassword, true);
+ } catch (error) {
+ showErrorMessage(error);
+ }
+
+ for (let e of controllers) {
+ if (e.rememberPassword) {
+ await this.savePassword(e.url, e.username, e.password);
+ } else {
+ await this.deletePassword(e.url, e.username);
+ }
+ }
+ }
+
+ private async savePassword(url: string, username: string, password: string): Promise {
+ let provider = await this.getCredentialProvider();
+ let id = this.createId(url, username);
+ let result = await provider.saveCredential(id, password);
+ return result;
+ }
+
+ private async deletePassword(url: string, username: string): Promise {
+ let provider = await this.getCredentialProvider();
+ let id = this.createId(url, username);
+ let result = await provider.deleteCredential(id);
+ return result;
+ }
+
+ private async getPassword(url: string, username: string): Promise {
+ let provider = await this.getCredentialProvider();
+ let id = this.createId(url, username);
+ let credential = await provider.readCredential(id);
+ return credential ? credential.password : undefined;
+ }
+
+ private async getCredentialProvider(): Promise {
+ if (!this.credentialProvider) {
+ this.credentialProvider = await azdata.credentials.getProvider(CredentialNamespace);
+ }
+ return this.credentialProvider;
+ }
+
+ private createId(url: string, username: string): string {
+ return `${url}::${username}`;
+ }
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeNode.ts b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeNode.ts
new file mode 100644
index 0000000000..bf76064b1d
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/tree/controllerTreeNode.ts
@@ -0,0 +1,392 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+import * as azdata from 'azdata';
+import * as nls from 'vscode-nls';
+import { IControllerTreeChangeHandler } from './controllerTreeChangeHandler';
+import { TreeNode } from './treeNode';
+import { IconPath, BdcItemType } from '../constants';
+import { IEndPoint, IControllerError, getEndPoints } from '../controller/clusterControllerApi';
+import { showErrorMessage } from '../utils';
+
+const localize = nls.loadMessageBundle();
+
+export abstract class ControllerTreeNode extends TreeNode {
+
+ constructor(
+ label: string,
+ parent: ControllerTreeNode,
+ private _treeChangeHandler: IControllerTreeChangeHandler,
+ private _description?: string,
+ private _nodeType?: string,
+ private _iconPath?: { dark: string, light: string }
+ ) {
+ super(label, parent);
+ this._description = this._description || this.label;
+ }
+
+ public async getChildren(): Promise {
+ return this.children as ControllerTreeNode[];
+ }
+
+ public refresh(): void {
+ super.refresh();
+ this.treeChangeHandler.notifyNodeChanged(this);
+ }
+
+ public getTreeItem(): vscode.TreeItem {
+ let item: vscode.TreeItem = {};
+ item.id = this.id;
+ item.label = this.label;
+ item.collapsibleState = this.isLeaf ?
+ vscode.TreeItemCollapsibleState.None :
+ vscode.TreeItemCollapsibleState.Collapsed;
+ item.iconPath = this._iconPath;
+ item.contextValue = this._nodeType;
+ item.tooltip = this._description;
+ item.iconPath = this._iconPath;
+ return item;
+ }
+
+ public getNodeInfo(): azdata.NodeInfo {
+ return {
+ label: this.label,
+ isLeaf: this.isLeaf,
+ errorMessage: undefined,
+ metadata: undefined,
+ nodePath: this.nodePath,
+ nodeStatus: undefined,
+ nodeType: this._nodeType,
+ iconType: this._nodeType,
+ nodeSubType: undefined
+ };
+ }
+
+ public get description(): string {
+ return this._description;
+ }
+
+ public set description(description: string) {
+ this._description = description;
+ }
+
+ public get nodeType(): string {
+ return this._nodeType;
+ }
+
+ public set nodeType(nodeType: string) {
+ this._nodeType = nodeType;
+ }
+
+ public set iconPath(iconPath: { dark: string, light: string }) {
+ this._iconPath = iconPath;
+ }
+
+ public get iconPath(): { dark: string, light: string } {
+ return this._iconPath;
+ }
+
+ public set treeChangeHandler(treeChangeHandler: IControllerTreeChangeHandler) {
+ this._treeChangeHandler = treeChangeHandler;
+ }
+
+ public get treeChangeHandler(): IControllerTreeChangeHandler {
+ return this._treeChangeHandler;
+ }
+}
+
+export class ControllerRootNode extends ControllerTreeNode {
+
+ private _masterNodeFactory: SqlMasterNodeFactory;
+
+ constructor(treeChangeHandler: IControllerTreeChangeHandler) {
+ super('root', undefined, treeChangeHandler, undefined, BdcItemType.controllerRoot);
+ this._masterNodeFactory = new SqlMasterNodeFactory();
+ }
+
+ public async getChildren(): Promise {
+ return this.children as ControllerNode[];
+ }
+
+ public addControllerNode(url: string, username: string, password: string, rememberPassword: boolean, masterInstance?: IEndPoint): void {
+ let controllerNode = this.getExistingControllerNode(url, username);
+ if (controllerNode) {
+ controllerNode.password = password;
+ controllerNode.rememberPassword = rememberPassword;
+ controllerNode.clearChildren();
+ } else {
+ controllerNode = new ControllerNode(url, username, password, rememberPassword, undefined, this, this.treeChangeHandler, undefined);
+ this.addChild(controllerNode);
+ }
+
+ if (masterInstance) {
+ controllerNode.addSqlMasterNode(masterInstance.endpoint, masterInstance.description);
+ }
+ }
+
+ public deleteControllerNode(url: string, username: string): ControllerNode {
+ if (!url || !username) {
+ return undefined;
+ }
+ let nodes = this.children as ControllerNode[];
+ let index = nodes.findIndex(e => e.url === url && e.username === username);
+ let deleted = undefined;
+ if (index >= 0) {
+ deleted = nodes.splice(index, 1);
+ }
+ return deleted;
+ }
+
+ private getExistingControllerNode(url: string, username: string): ControllerNode {
+ if (!url || !username) {
+ return undefined;
+ }
+ let nodes = this.children as ControllerNode[];
+ return nodes.find(e => e.url === url && e.username === username);
+ }
+
+ public get sqlMasterNodeFactory(): SqlMasterNodeFactory {
+ return this._masterNodeFactory;
+ }
+}
+
+export class ControllerNode extends ControllerTreeNode {
+
+ constructor(
+ private _url: string,
+ private _username: string,
+ private _password: string,
+ private _rememberPassword: boolean,
+ label: string,
+ parent: ControllerTreeNode,
+ treeChangeHandler: IControllerTreeChangeHandler,
+ description?: string,
+ ) {
+ super(label, parent, treeChangeHandler, description, BdcItemType.controller, IconPath.controllerNode);
+ this.label = label;
+ this.description = description;
+
+ }
+
+ public async getChildren(): Promise {
+ if (this.children && this.children.length > 0) {
+ this.clearChildren();
+ }
+
+ if (!this._password) {
+ vscode.commands.executeCommand('bigDataClusters.command.addController', this);
+ return this.children as ControllerTreeNode[];
+ }
+
+ try {
+ let response = await getEndPoints(this._url, this._username, this._password, true);
+ if (response && response.endPoints) {
+ let master = response.endPoints.find(e => e.name && e.name === 'sql-server-master');
+ this.addSqlMasterNode(master.endpoint, master.description);
+ }
+ return this.children as ControllerTreeNode[];
+ } catch (error) {
+ showErrorMessage(error);
+ return this.children as ControllerTreeNode[];
+ }
+ }
+
+ private static toIpAndPort(url: string): string {
+ if (!url) {
+ return;
+ }
+ return url.trim().replace(/ /g, '').replace(/^.+\:\/\//, '').replace(/:(\d+)$/, ',$1');
+ }
+
+ public addSqlMasterNode(endPointAddress: string, description: string): void {
+ let epFolder = this.getEndPointFolderNode();
+ let node = (this.root as ControllerRootNode).sqlMasterNodeFactory
+ .getSqlMasterNode(endPointAddress, epFolder, undefined, this.treeChangeHandler, description);
+ epFolder.addChild(node);
+ }
+
+ private getEndPointFolderNode(): FolderNode {
+ let label = localize('textSqlServers', 'SQL Servers');
+ let epFolderNode = this.children.find(e => e instanceof FolderNode && e.label === label);
+ if (!epFolderNode) {
+ epFolderNode = new FolderNode(label, this, this.treeChangeHandler);
+ this.addChild(epFolderNode);
+ }
+ return epFolderNode as FolderNode;
+ }
+
+ public getTreeItem(): vscode.TreeItem {
+ let item: vscode.TreeItem = super.getTreeItem();
+ item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
+ return item;
+ }
+
+ public get url() {
+ return this._url;
+ }
+
+ public set url(url: string) {
+ this._url = url;
+ }
+
+ public get username() {
+ return this._username;
+ }
+
+ public set username(username: string) {
+ this._username = username;
+ }
+
+ public get password() {
+ return this._password;
+ }
+
+ public set password(pw: string) {
+ this._password = pw;
+ }
+
+ public get rememberPassword() {
+ return this._rememberPassword;
+ }
+
+ public set rememberPassword(rememberPassword: boolean) {
+ this._rememberPassword = rememberPassword;
+ }
+
+ public set label(label: string) {
+ super.label = label || `controller: ${ControllerNode.toIpAndPort(this._url)} (${this._username})`;
+ }
+
+ public get label(): string {
+ return super.label;
+ }
+
+ public set description(description: string) {
+ super.description = description || super.label;
+ }
+
+ public get description(): string {
+ return super.description;
+ }
+}
+
+export class FolderNode extends ControllerTreeNode {
+ constructor(
+ label: string,
+ parent: ControllerTreeNode,
+ treeChangeHandler: IControllerTreeChangeHandler
+ ) {
+ super(label, parent, treeChangeHandler, label, BdcItemType.folder, IconPath.folderNode);
+ }
+}
+
+export class SqlMasterNode extends ControllerTreeNode {
+ private static readonly _role: string = 'sql-server-master';
+ private _username: string;
+ private _password: string;
+
+ constructor(
+ private _endPointAddress: string,
+ parent: ControllerTreeNode,
+ label: string,
+ treeChangeHandler: IControllerTreeChangeHandler,
+ description?: string,
+ ) {
+ super(label, parent, treeChangeHandler, description, BdcItemType.sqlMaster, IconPath.sqlMasterNode);
+ this._username = 'sa';
+ this.label = label;
+ this.description = description;
+ }
+
+ private getControllerPassword(): string {
+ if (!this._password) {
+ let current: TreeNode = this;
+ while (current && !(current instanceof ControllerNode)) {
+ current = current.parent;
+ }
+ this._password = current && current instanceof ControllerNode ? current.password : undefined;
+ }
+ return this._password;
+ }
+
+ public getTreeItem(): vscode.TreeItem {
+ let item = super.getTreeItem();
+ let connectionProfile: azdata.IConnectionProfile = {
+ id: this.id,
+ connectionName: this.id,
+ serverName: this._endPointAddress,
+ databaseName: '',
+ userName: this._username,
+ password: this.getControllerPassword(),
+ authenticationType: 'SqlLogin',
+ savePassword: false,
+ groupFullName: '',
+ groupId: '',
+ providerName: 'MSSQL',
+ saveProfile: false,
+ options: {}
+ };
+ return Object.assign(item, { payload: connectionProfile, childProvider: 'MSSQL' });
+ }
+
+ public get role() {
+ return SqlMasterNode._role;
+ }
+
+ public get endPointAddress() {
+ return this._endPointAddress;
+ }
+
+ public set endPointAddress(endPointAddress: string) {
+ this._endPointAddress = endPointAddress;
+ }
+
+ public set label(label: string) {
+ super.label = label || `master: ${this._endPointAddress} (${this._username})`;
+ }
+
+ public get label(): string {
+ return super.label;
+ }
+
+ public set description(description: string) {
+ super.description = description || super.label;
+ }
+
+ public get description(): string {
+ return super.description;
+ }
+}
+
+export class SqlMasterNodeFactory {
+ private registry: {} = {};
+
+ public getSqlMasterNode(
+ endPointAddress: string,
+ parent: ControllerTreeNode,
+ label: string,
+ treeChangeHandler: IControllerTreeChangeHandler,
+ description?: string
+ ): SqlMasterNode {
+ let id = this.createRegistryId(endPointAddress, 'sa');
+ if (!this.registry[id]) {
+ this.registry[id] = new SqlMasterNode(endPointAddress, parent, label, treeChangeHandler, description);
+ } else {
+ let node = this.registry[id] as SqlMasterNode;
+ node.parent = parent;
+ node.label = label;
+ node.treeChangeHandler = treeChangeHandler;
+ description = description;
+ }
+ return this.registry[id] as SqlMasterNode;
+ }
+
+ private createRegistryId(endPointAddress: string, username: string): string {
+ return `${endPointAddress}::${username}`;
+ }
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/tree/treeNode.ts b/extensions/big-data-cluster/src/bigDataCluster/tree/treeNode.ts
new file mode 100644
index 0000000000..fa6177e32b
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/tree/treeNode.ts
@@ -0,0 +1,195 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as azdata from 'azdata';
+import * as vscode from 'vscode';
+import { generateGuid } from '../utils';
+
+export abstract class TreeNode {
+
+ private _id: string;
+ private _children: TreeNode[];
+ private _isLeaf: boolean;
+
+ constructor(private _label: string, private _parent?: TreeNode) {
+ this.resetId();
+ }
+
+ public resetId(): void {
+ this._id = (this._label || '_') + `::${generateGuid()}`;
+ }
+
+ public get id(): string {
+ return this._id;
+ }
+
+ public set label(label: string) {
+ if (!this._label) {
+ this._label = label;
+ this.resetId();
+ } else {
+ this._label = label;
+ }
+ }
+
+ public get label(): string {
+ return this._label;
+ }
+
+ public set parent(parent: TreeNode) {
+ this._parent = parent;
+ }
+
+ public get parent(): TreeNode {
+ return this._parent;
+ }
+
+ public get children(): TreeNode[] {
+ if (!this._children) {
+ this._children = [];
+ }
+ return this._children;
+ }
+
+ public get hasChildren(): boolean {
+ return this.children && this.children.length > 0;
+ }
+
+ public set isLeaf(isLeaf: boolean) {
+ this._isLeaf = isLeaf;
+ }
+
+ public get isLeaf(): boolean {
+ return this._isLeaf;
+ }
+
+ public get root(): TreeNode {
+ return TreeNode.getRoot(this);
+ }
+
+ public equals(node: TreeNode): boolean {
+ if (!node) {
+ return undefined;
+ }
+ return this.nodePath === node.nodePath;
+ }
+
+ public refresh(): void {
+ this.resetId();
+ }
+
+ public static getRoot(node: TreeNode): TreeNode {
+ if (!node) {
+ return undefined;
+ }
+ let current: TreeNode = node;
+ while (current.parent) {
+ current = current.parent;
+ }
+ return current;
+ }
+
+ public get nodePath(): string {
+ return TreeNode.getNodePath(this);
+ }
+
+ public static getNodePath(node: TreeNode): string {
+ if (!node) {
+ return undefined;
+ }
+
+ let current: TreeNode = node;
+ let path = current._id;
+ while (current.parent) {
+ current = current.parent;
+ path = `${current._id}/${path}`;
+ }
+ return path;
+ }
+
+ public async findNode(condition: (node: TreeNode) => boolean, expandIfNeeded?: boolean): Promise {
+ return TreeNode.findNode(this, condition, expandIfNeeded);
+ }
+
+ public static async findNode(node: TreeNode, condition: (node: TreeNode) => boolean, expandIfNeeded?: boolean): Promise {
+ if (!node || !condition) {
+ return undefined;
+ }
+ let result: TreeNode = undefined;
+ let nodesToCheck: TreeNode[] = [node];
+ while (nodesToCheck.length > 0) {
+ let current = nodesToCheck.shift();
+ if (condition(current)) {
+ result = current;
+ break;
+ }
+ if (current.hasChildren) {
+ nodesToCheck = nodesToCheck.concat(current.children);
+ } else if (expandIfNeeded) {
+ let children = await current.getChildren();
+ if (children && children.length > 0) {
+ nodesToCheck = nodesToCheck.concat(children);
+ }
+ }
+ }
+ return result;
+ }
+
+ public async filterNode(condition: (node: TreeNode) => boolean, expandIfNeeded?: boolean): Promise {
+ return TreeNode.filterNode(this, condition, expandIfNeeded);
+ }
+
+ public static async filterNode(node: TreeNode, condition: (node: TreeNode) => boolean, expandIfNeeded?: boolean): Promise {
+ if (!node || !condition) {
+ return undefined;
+ }
+ let result: TreeNode[] = [];
+ let nodesToCheck: TreeNode[] = [node];
+ while (nodesToCheck.length > 0) {
+ let current = nodesToCheck.shift();
+ if (condition(current)) {
+ result.push(current);
+ }
+ if (current.hasChildren) {
+ nodesToCheck = nodesToCheck.concat(current.children);
+ } else if (expandIfNeeded) {
+ let children = await current.getChildren();
+ if (children && children.length > 0) {
+ nodesToCheck = nodesToCheck.concat(children);
+ }
+ }
+ }
+ return result;
+ }
+
+ public async findNodeByPath(path: string, expandIfNeeded?: boolean): Promise {
+ return TreeNode.findNodeByPath(this, path, expandIfNeeded);
+ }
+
+ public static async findNodeByPath(node: TreeNode, path: string, expandIfNeeded?: boolean): Promise {
+ return TreeNode.findNode(node, node => {
+ return node.nodePath && (node.nodePath === path || node.nodePath.startsWith(path));
+ }, expandIfNeeded);
+ }
+
+ public addChild(node: TreeNode): void {
+ if (!this._children) {
+ this._children = [];
+ }
+ this._children.push(node);
+ }
+
+ public clearChildren(): void {
+ if (this._children) {
+ this._children = [];
+ }
+ }
+
+ public abstract async getChildren(): Promise;
+ public abstract getTreeItem(): vscode.TreeItem;
+ public abstract getNodeInfo(): azdata.NodeInfo;
+}
diff --git a/extensions/big-data-cluster/src/bigDataCluster/utils.ts b/extensions/big-data-cluster/src/bigDataCluster/utils.ts
new file mode 100644
index 0000000000..2c7f3acdda
--- /dev/null
+++ b/extensions/big-data-cluster/src/bigDataCluster/utils.ts
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+
+export function generateGuid(): string {
+ let hexValues: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
+ let oct: string = '';
+ let tmp: number;
+ for (let a: number = 0; a < 4; a++) {
+ tmp = (4294967296 * Math.random()) | 0;
+ oct += hexValues[tmp & 0xF] +
+ hexValues[tmp >> 4 & 0xF] +
+ hexValues[tmp >> 8 & 0xF] +
+ hexValues[tmp >> 12 & 0xF] +
+ hexValues[tmp >> 16 & 0xF] +
+ hexValues[tmp >> 20 & 0xF] +
+ hexValues[tmp >> 24 & 0xF] +
+ hexValues[tmp >> 28 & 0xF];
+ }
+ let clockSequenceHi: string = hexValues[8 + (Math.random() * 4) | 0];
+ return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12);
+}
+
+export function showErrorMessage(error: any): void {
+ if (error) {
+ let text: string = undefined;
+ if (typeof error === 'string') {
+ text = error as string;
+ } else if (typeof error === 'object' && error !== null) {
+ let message = error.message;
+ let code = error.code || error.errno;
+ text = (code ? `${code} ` : '') + message;
+ } else {
+ text = `${error}`;
+ }
+ vscode.window.showErrorMessage(text);
+ }
+}
diff --git a/extensions/big-data-cluster/src/config/config.ts b/extensions/big-data-cluster/src/config/config.ts
deleted file mode 100644
index 05e440ced8..0000000000
--- a/extensions/big-data-cluster/src/config/config.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * 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 { 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';
-
-export async function addPathToConfig(configKey: string, value: string): Promise {
- await setConfigValue(configKey, value);
-}
-
-async function setConfigValue(configKey: string, value: any): Promise {
- await atAllConfigScopes(addValueToConfigAtScope, configKey, value);
-}
-
-async function addValueToConfigAtScope(configKey: string, value: any, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean): Promise {
- if (!createIfNotExist) {
- if (!valueAtScope || !(valueAtScope[configKey])) {
- return;
- }
- }
-
- let newValue: any = {};
- if (valueAtScope) {
- newValue = Object.assign({}, valueAtScope);
- }
- newValue[configKey] = value;
- await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
-}
-
-async function addValueToConfigArray(configKey: string, value: string): Promise {
- await atAllConfigScopes(addValueToConfigArrayAtScope, configKey, value);
-}
-
-async function addValueToConfigArrayAtScope(configKey: string, value: string, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean): Promise {
- if (!createIfNotExist) {
- if (!valueAtScope || !(valueAtScope[configKey])) {
- return;
- }
- }
-
- let newValue: any = {};
- if (valueAtScope) {
- newValue = Object.assign({}, valueAtScope);
- }
- const arrayEntry: string[] = newValue[configKey] || [];
- arrayEntry.push(value);
- newValue[configKey] = arrayEntry;
- await vscode.workspace.getConfiguration().update(EXTENSION_CONFIG_KEY, newValue, scope);
-}
-
-type ConfigUpdater = (configKey: string, value: T, scope: vscode.ConfigurationTarget, valueAtScope: any, createIfNotExist: boolean) => Promise;
-
-async function atAllConfigScopes(fn: ConfigUpdater, configKey: string, value: T): Promise {
- const config = vscode.workspace.getConfiguration().inspect(EXTENSION_CONFIG_KEY)!;
- await fn(configKey, value, vscode.ConfigurationTarget.Global, config.globalValue, true);
- await fn(configKey, value, vscode.ConfigurationTarget.Workspace, config.workspaceValue, false);
- await fn(configKey, value, vscode.ConfigurationTarget.WorkspaceFolder, config.workspaceFolderValue, false);
-}
-
-// Functions for working with the list of known kubeconfigs
-
-export function getKnownKubeconfigs(): string[] {
- const kkcConfig = vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KNOWN_KUBECONFIGS_KEY];
- if (!kkcConfig || !kkcConfig.length) {
- return [];
- }
- return kkcConfig as string[];
-}
-
-export async function addKnownKubeconfig(kubeconfigPath: string) {
- await addValueToConfigArray(KNOWN_KUBECONFIGS_KEY, kubeconfigPath);
-}
-
-// Functions for working with the active kubeconfig setting
-
-export async function setActiveKubeconfig(kubeconfig: string): Promise {
- await addPathToConfig(KUBECONFIG_PATH_KEY, kubeconfig);
-}
-
-export function getActiveKubeconfig(): string {
- return vscode.workspace.getConfiguration(EXTENSION_CONFIG_KEY)[KUBECONFIG_PATH_KEY];
-}
-
-// Functions for working with tool paths
-
-export function getToolPath(host: Host, shell: Shell, tool: string): string | undefined {
- const baseKey = toolPathBaseKey(tool);
- return getPathSetting(host, shell, baseKey);
-}
-
-function getPathSetting(host: Host, shell: Shell, baseKey: string): string | undefined {
- const os = shell.platform();
- const osOverridePath = host.getConfiguration(EXTENSION_CONFIG_KEY)[osOverrideKey(os, baseKey)];
- return osOverridePath || host.getConfiguration(EXTENSION_CONFIG_KEY)[baseKey];
-}
-
-export function toolPathBaseKey(tool: string): string {
- return `mssql-bdc.${tool}-path`;
-}
-
-function osOverrideKey(os: Platform, baseKey: string): string {
- const osKey = osKeyString(os);
- return osKey ? `${baseKey}.${osKey}` : baseKey; // The 'else' clause should never happen so don't worry that this would result in double-checking a missing base key
-}
-
-function osKeyString(os: Platform): string | null {
- switch (os) {
- case Platform.Windows: return 'windows';
- case Platform.MacOS: return 'mac';
- case Platform.Linux: return 'linux';
- default: return null;
- }
-}
-
diff --git a/extensions/big-data-cluster/src/data/kubeConfigParser.ts b/extensions/big-data-cluster/src/data/kubeConfigParser.ts
deleted file mode 100644
index 022b1d981a..0000000000
--- a/extensions/big-data-cluster/src/data/kubeConfigParser.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { ClusterInfo } from '../interfaces';
-
-export interface IKubeConfigParser {
- parse(configPath: string): ClusterInfo[];
-}
-
-export class TestKubeConfigParser implements IKubeConfigParser {
- parse(configPath: string): ClusterInfo[] {
- let clusters = [];
- for (let i = 0; i < 18; i++) {
- let name;
- if (i % 2 === 0) {
- name = `kubernetes cluster ${i}`;
- }
- else {
- name = 'cluster dev ' + i;
- }
- clusters.push(
- {
- displayName: name,
- name: `kub-dev-xxxx-cluster-${i}`,
- user: 'root'
- }
- );
- }
- return clusters;
- }
-}
-
diff --git a/extensions/big-data-cluster/src/extension.ts b/extensions/big-data-cluster/src/extension.ts
new file mode 100644
index 0000000000..a5b937db2d
--- /dev/null
+++ b/extensions/big-data-cluster/src/extension.ts
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import * as vscode from 'vscode';
+import * as nls from 'vscode-nls';
+import { ControllerTreeDataProvider } from './bigDataCluster/tree/controllerTreeDataProvider';
+import { IconPath } from './bigDataCluster/constants';
+import { TreeNode } from './bigDataCluster/tree/treeNode';
+import { AddControllerDialogModel, AddControllerDialog } from './bigDataCluster/dialog/addControllerDialog';
+import { ControllerNode } from './bigDataCluster/tree/controllerTreeNode';
+
+const localize = nls.loadMessageBundle();
+
+export function activate(extensionContext: vscode.ExtensionContext) {
+ IconPath.setExtensionContext(extensionContext);
+ let treeDataProvider = new ControllerTreeDataProvider();
+
+ registerTreeDataProvider(treeDataProvider);
+ registerCommands(treeDataProvider);
+}
+
+export function deactivate() {
+}
+
+function registerTreeDataProvider(treeDataProvider: ControllerTreeDataProvider): void {
+ vscode.window.registerTreeDataProvider('sqlBigDataCluster', treeDataProvider);
+}
+
+function registerCommands(treeDataProvider: ControllerTreeDataProvider): void {
+ vscode.commands.registerCommand('bigDataClusters.command.addController', (node?: TreeNode) => {
+ addBdcController(treeDataProvider, node);
+ });
+
+ vscode.commands.registerCommand('bigDataClusters.command.deleteController', (node: TreeNode) => {
+ deleteBdcController(treeDataProvider, node);
+ });
+
+ vscode.commands.registerCommand('bigDataClusters.command.refreshController', (node: TreeNode) => {
+ if (!node) {
+ return;
+ }
+ treeDataProvider.notifyNodeChanged(node);
+ });
+}
+
+function addBdcController(treeDataProvider: ControllerTreeDataProvider, node?: TreeNode): void {
+ let model = new AddControllerDialogModel(treeDataProvider, node);
+ let dialog = new AddControllerDialog(model);
+ dialog.showDialog();
+}
+
+async function deleteBdcController(treeDataProvider: ControllerTreeDataProvider, node: TreeNode): Promise {
+ if (!node && !(node instanceof ControllerNode)) {
+ return;
+ }
+
+ let controllerNode = node as ControllerNode;
+
+ let choices: { [id: string]: boolean } = {};
+ choices[localize('textYes', 'Yes')] = true;
+ choices[localize('textNo', 'No')] = false;
+
+ let options = {
+ ignoreFocusOut: false,
+ placeHolder: localize('textConfirmDeleteController', 'Are you sure you want to delete \'{0}\'?', controllerNode.label)
+ };
+
+ let result = await vscode.window.showQuickPick(Object.keys(choices), options);
+ let remove: boolean = !!(result && choices[result]);
+ if (remove) {
+ deleteControllerInternal(treeDataProvider, controllerNode);
+ }
+ return remove;
+}
+
+function deleteControllerInternal(treeDataProvider: ControllerTreeDataProvider, controllerNode: ControllerNode): void {
+ let deleted = treeDataProvider.deleteController(controllerNode.url, controllerNode.username);
+ if (deleted) {
+ treeDataProvider.saveControllers();
+ }
+}
diff --git a/extensions/big-data-cluster/src/installer/download.ts b/extensions/big-data-cluster/src/installer/download.ts
deleted file mode 100644
index f80aba6827..0000000000
--- a/extensions/big-data-cluster/src/installer/download.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import * as path from 'path';
-import * as stream from 'stream';
-import * as tmp from 'tmp';
-
-import { succeeded, Errorable } from '../interfaces';
-
-type DownloadFunc =
- (url: string, destination?: string, options?: any)
- => Promise & stream.Duplex; // Stream has additional events - see https://www.npmjs.com/package/download
-
-let download: DownloadFunc;
-
-function ensureDownloadFunc() {
- if (!download) {
- const home = process.env['HOME'];
- download = require('download');
- if (home) {
- process.env['HOME'] = home;
- }
- }
-}
-
-export async function toTempFile(sourceUrl: string): Promise> {
- const tempFileObj = tmp.fileSync({ prefix: 'mssql-bdc-autoinstall-' });
- const downloadResult = await to(sourceUrl, tempFileObj.name);
- if (succeeded(downloadResult)) {
- return { succeeded: true, result: tempFileObj.name };
- }
- return { succeeded: false, error: downloadResult.error };
-}
-
-export async function to(sourceUrl: string, destinationFile: string): Promise> {
- ensureDownloadFunc();
- try {
- await download(sourceUrl, path.dirname(destinationFile), { filename: path.basename(destinationFile) });
- return { succeeded: true, result: null };
- } catch (e) {
- return { succeeded: false, error: [e.message] };
- }
-}
diff --git a/extensions/big-data-cluster/src/installer/installer.ts b/extensions/big-data-cluster/src/installer/installer.ts
deleted file mode 100644
index 62b0ad37c9..0000000000
--- a/extensions/big-data-cluster/src/installer/installer.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-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';
-
-export async function installKubectl(shell: Shell): Promise> {
- const tool = 'kubectl';
- const binFile = (shell.isUnix()) ? 'kubectl' : 'kubectl.exe';
- const os = platformUrlString(shell.platform());
-
- const version = await getStableKubectlVersion();
- if (failed(version)) {
- return { succeeded: false, error: version.error };
- }
-
- const installFolder = getInstallFolder(shell, tool);
- mkdirp.sync(installFolder);
-
- const kubectlUrl = `https://storage.googleapis.com/kubernetes-release/release/${version.result.trim()}/bin/${os}/amd64/${binFile}`;
- const downloadFile = path.join(installFolder, binFile);
- const downloadResult = await download.to(kubectlUrl, downloadFile);
- if (failed(downloadResult)) {
- return { succeeded: false, error: [localize('downloadKubectlFailed', 'Failed to download kubectl: {0}', downloadResult.error[0])] };
- }
-
- if (shell.isUnix()) {
- fs.chmodSync(downloadFile, '0777');
- }
-
- await addPathToConfig(toolPathBaseKey(tool), downloadFile);
- return { succeeded: true, result: null };
-}
-
-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: [localize('kubectlVersionCheckFailed', 'Failed to establish kubectl stable version: {0}', downloadResult.error[0])] };
- }
- const version = fs.readFileSync(downloadResult.result, 'utf-8');
- fs.unlinkSync(downloadResult.result);
- return { succeeded: true, result: version };
-}
-
-export function getInstallFolder(shell: Shell, tool: string): string {
- return path.join(shell.home(), `.mssql-bdc/tools/${tool}`);
-}
-
-function platformUrlString(platform: Platform, supported?: Platform[]): string | null {
- if (supported && supported.indexOf(platform) < 0) {
- return null;
- }
- switch (platform) {
- case Platform.Windows: return 'windows';
- case Platform.MacOS: return 'darwin';
- case Platform.Linux: return 'linux';
- default: return null;
- }
-}
-
-
diff --git a/extensions/big-data-cluster/src/interfaces.ts b/extensions/big-data-cluster/src/interfaces.ts
deleted file mode 100644
index a4f9657374..0000000000
--- a/extensions/big-data-cluster/src/interfaces.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-export interface ClusterInfo {
- name: string;
- displayName: string;
- user: string;
-}
-
-export enum TargetClusterType {
- ExistingKubernetesCluster,
- NewAksCluster
-}
-
-export interface Succeeded {
- readonly succeeded: true;
- readonly result: T;
-}
-
-export interface Failed {
- readonly succeeded: false;
- readonly error: string[];
-}
-
-export type Errorable = Succeeded | Failed;
-
-export function succeeded(e: Errorable): e is Succeeded {
- return e.succeeded;
-}
-
-export function failed(e: Errorable): e is Failed {
- return !e.succeeded;
-}
-export interface ClusterPorts {
- sql: string;
- knox: string;
- controller: string;
- proxy: string;
- grafana: string;
- kibana: string;
-}
-
-export interface ContainerRegistryInfo {
- registry: string;
- repository: string;
- imageTag: string;
-}
-
-export interface TargetClusterTypeInfo {
- enabled: boolean;
- type: TargetClusterType;
- name: string;
- fullName: string;
- description: string;
- iconPath: {
- dark: string,
- light: string
- };
-}
-
-export interface ToolInfo {
- name: string;
- description: string;
- version: string;
- status: ToolInstallationStatus;
-}
-
-export enum ToolInstallationStatus {
- Installed,
- NotInstalled,
- Installing,
- FailedToInstall
-}
-
-export enum ClusterType {
- Unknown = 0,
- AKS,
- Minikube,
- Kubernetes,
- Other
-}
-
-export interface ClusterProfile {
- name: string;
- sqlServerMasterConfiguration: SQLServerMasterConfiguration;
- computePoolConfiguration: PoolConfiguration;
- dataPoolConfiguration: PoolConfiguration;
- storagePoolConfiguration: PoolConfiguration;
- sparkPoolConfiguration: PoolConfiguration;
-}
-
-export interface PoolConfiguration {
- type: ClusterPoolType;
- scale: number;
- maxScale?: number;
- hardwareLabel?: string;
-}
-
-export interface SQLServerMasterConfiguration extends PoolConfiguration {
- engineOnly: boolean;
-}
-
-export enum ClusterPoolType {
- SQL,
- Compute,
- Data,
- Storage,
- Spark
-}
-
-export interface ClusterResourceSummary {
- hardwareLabels: HardwareLabel[];
-}
-
-export interface HardwareLabel {
- name: string;
- totalNodes: number;
- totalCores: number;
- totalMemoryInGB: number;
- totalDisks: number;
-}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/kubectl/binutil.ts b/extensions/big-data-cluster/src/kubectl/binutil.ts
deleted file mode 100644
index 85d1195ed2..0000000000
--- a/extensions/big-data-cluster/src/kubectl/binutil.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * 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';
-
-export interface BinCheckContext {
- readonly host: Host;
- readonly fs: FS;
- readonly shell: Shell;
- readonly installDependenciesCallback: () => void;
- binFound: boolean;
- binPath: string;
-}
-
-interface FindBinaryResult {
- err: number | null;
- output: string;
-}
-
-async function findBinary(shell: Shell, binName: string): Promise {
- let cmd = `which ${binName}`;
-
- if (shell.isWindows()) {
- cmd = `where.exe ${binName}.exe`;
- }
-
- const opts = {
- async: true,
- env: {
- HOME: process.env.HOME,
- PATH: process.env.PATH
- }
- };
-
- const execResult = await shell.execCore(cmd, opts);
- if (execResult.code) {
- return { err: execResult.code, output: execResult.stderr };
- }
-
- return { err: null, output: execResult.stdout };
-}
-
-export function execPath(shell: Shell, basePath: string): string {
- let bin = basePath;
- if (shell.isWindows() && bin && !(bin.endsWith('.exe'))) {
- bin = bin + '.exe';
- }
- return bin;
-}
-
-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, installDependenciesAction, learnMoreAction).then(
- (str) => {
- switch (str) {
- case learnMoreAction:
- host.showInformationMessage(localize('moreInfoMsg', 'Add {0} directory to path, or set "mssql-bdc.{0}-path" config to {0} binary.', binName));
- break;
- case installDependenciesAction:
- installDependencies();
- break;
- }
-
- }
- );
- break;
- case 'configuredFileMissing':
- host.showErrorMessage(message, installDependenciesAction).then(
- (str) => {
- if (str === installDependenciesAction) {
- installDependencies();
- }
- }
- );
- break;
- }
-}
-
-export async function checkForBinary(context: BinCheckContext, bin: string | undefined, binName: string, inferFailedMessage: string, configuredFileMissingMessage: string, alertOnFail: boolean): Promise {
- if (!bin) {
- const fb = await findBinary(context.shell, binName);
-
- if (fb.err || fb.output.length === 0) {
- if (alertOnFail) {
- alertNoBin(context.host, binName, 'inferFailed', inferFailedMessage, context.installDependenciesCallback);
- }
- return false;
- }
-
- context.binFound = true;
-
- return true;
- }
-
- if (context.shell.isWindows) {
- context.binFound = context.fs.existsSync(bin);
- } else {
- const sr = await context.shell.exec(`ls ${bin}`);
- context.binFound = (!!sr && sr.code === 0);
- }
- if (context.binFound) {
- context.binPath = bin;
- } else {
- if (alertOnFail) {
- alertNoBin(context.host, binName, 'configuredFileMissing', configuredFileMissingMessage, context.installDependenciesCallback);
- }
- }
-
- return context.binFound;
-}
diff --git a/extensions/big-data-cluster/src/kubectl/compatibility.ts b/extensions/big-data-cluster/src/kubectl/compatibility.ts
deleted file mode 100644
index 8cea1dba11..0000000000
--- a/extensions/big-data-cluster/src/kubectl/compatibility.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import { Errorable, failed } from '../interfaces';
-
-interface CompatibilityGuaranteed {
- readonly guaranteed: true;
-}
-
-interface CompatibilityNotGuaranteed {
- readonly guaranteed: false;
- readonly didCheck: boolean;
- readonly clientVersion: string;
- readonly serverVersion: string;
-}
-
-export type Compatibility = CompatibilityGuaranteed | CompatibilityNotGuaranteed;
-
-export function isGuaranteedCompatible(c: Compatibility): c is CompatibilityGuaranteed {
- return c.guaranteed;
-}
-
-export interface Version {
- readonly major: string;
- readonly minor: string;
- readonly gitVersion: string;
-}
-
-export async function check(kubectlLoadJSON: (cmd: string) => Promise>): Promise {
- const version = await kubectlLoadJSON('version -o json');
- if (failed(version)) {
- return {
- guaranteed: false,
- didCheck: false,
- clientVersion: '',
- serverVersion: ''
- };
- }
-
- const clientVersion: Version = version.result.clientVersion;
- const serverVersion: Version = version.result.serverVersion;
-
- if (isCompatible(clientVersion, serverVersion)) {
- return { guaranteed: true };
- }
-
- return {
- guaranteed: false,
- didCheck: true,
- clientVersion: clientVersion.gitVersion,
- serverVersion: serverVersion.gitVersion
- };
-}
-
-function isCompatible(clientVersion: Version, serverVersion: Version): boolean {
- if (clientVersion.major === serverVersion.major) {
- const clientMinor = Number.parseInt(clientVersion.minor);
- const serverMinor = Number.parseInt(serverVersion.minor);
- if (Number.isInteger(clientMinor) && Number.isInteger(serverMinor) && Math.abs(clientMinor - serverMinor) <= 1) {
- return true;
- }
- }
- return false;
-}
diff --git a/extensions/big-data-cluster/src/kubectl/host.ts b/extensions/big-data-cluster/src/kubectl/host.ts
deleted file mode 100644
index de9eb5fbde..0000000000
--- a/extensions/big-data-cluster/src/kubectl/host.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * 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';
-
-export interface Host {
- showErrorMessage(message: string, ...items: string[]): Thenable;
- showWarningMessage(message: string, ...items: string[]): Thenable;
- showInformationMessage(message: string, ...items: string[]): Thenable;
- getConfiguration(key: string): any;
- onDidChangeConfiguration(listener: (ch: vscode.ConfigurationChangeEvent) => any): vscode.Disposable;
-}
-
-export const host: Host = {
- showErrorMessage: showErrorMessage,
- showWarningMessage: showWarningMessage,
- showInformationMessage: showInformationMessage,
- getConfiguration: getConfiguration,
- onDidChangeConfiguration: onDidChangeConfiguration,
-};
-
-function showErrorMessage(message: string, ...items: string[]): Thenable {
- return vscode.window.showErrorMessage(message, ...items);
-}
-
-function showWarningMessage(message: string, ...items: string[]): Thenable {
- return vscode.window.showWarningMessage(message, ...items);
-}
-
-function showInformationMessage(message: string, ...items: string[]): Thenable {
- return vscode.window.showInformationMessage(message, ...items);
-}
-
-function getConfiguration(key: string): any {
- return vscode.workspace.getConfiguration(key);
-}
-
-function onDidChangeConfiguration(listener: (e: vscode.ConfigurationChangeEvent) => any): vscode.Disposable {
- return vscode.workspace.onDidChangeConfiguration(listener);
-}
diff --git a/extensions/big-data-cluster/src/kubectl/kubectl.ts b/extensions/big-data-cluster/src/kubectl/kubectl.ts
deleted file mode 100644
index 26d793d851..0000000000
--- a/extensions/big-data-cluster/src/kubectl/kubectl.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * 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';
-import * as binutil from './binutil';
-import { Errorable } from '../interfaces';
-import * as compatibility from './compatibility';
-import { getToolPath } from '../config/config';
-
-export interface Kubectl {
- checkPresent(errorMessageMode: CheckPresentMessageMode): Promise;
- asJson(command: string): Promise>;
- invokeAsync(command: string, stdin?: string): Promise;
- getContext(): Context;
-}
-
-interface Context {
- readonly host: Host;
- readonly fs: FS;
- readonly shell: Shell;
- readonly installDependenciesCallback: () => void;
- binFound: boolean;
- binPath: string;
-}
-
-class KubectlImpl implements Kubectl {
- constructor(host: Host, fs: FS, shell: Shell, installDependenciesCallback: () => void, kubectlFound: boolean) {
- this.context = { host: host, fs: fs, shell: shell, installDependenciesCallback: installDependenciesCallback, binFound: kubectlFound, binPath: 'kubectl' };
- }
-
- readonly context: Context;
-
- checkPresent(errorMessageMode: CheckPresentMessageMode): Promise {
- return checkPresent(this.context, errorMessageMode);
- }
- asJson(command: string): Promise> {
- return asJson(this.context, command);
- }
- invokeAsync(command: string, stdin?: string): Promise {
- return invokeAsync(this.context, command, stdin);
- }
-
- getContext(): Context {
- return this.context;
- }
-}
-
-export function create(host: Host, fs: FS, shell: Shell, installDependenciesCallback: () => void): Kubectl {
- return new KubectlImpl(host, fs, shell, installDependenciesCallback, false);
-}
-
-export enum CheckPresentMessageMode {
- Command,
- Activation,
- Silent,
-}
-
-async function checkPresent(context: Context, errorMessageMode: CheckPresentMessageMode): Promise {
- if (context.binFound) {
- return true;
- }
-
- return await checkForKubectlInternal(context, errorMessageMode);
-}
-
-async function checkForKubectlInternal(context: Context, errorMessageMode: CheckPresentMessageMode): Promise {
- const binName = 'kubectl';
- const bin = getToolPath(context.host, context.shell, binName);
-
- const contextMessage = getCheckKubectlContextMessage(errorMessageMode);
- 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 localize('kubernetesRequired', ' SQL Server Big data cluster requires kubernetes.');
- } else if (errorMessageMode === CheckPresentMessageMode.Command) {
- return localize('cannotExecuteCmd', ' Cannot execute command.');
- }
- return '';
-}
-
-async function invokeAsync(context: Context, command: string, stdin?: string): Promise {
- if (await checkPresent(context, CheckPresentMessageMode.Command)) {
- const bin = baseKubectlPath(context);
- const cmd = `${bin} ${command}`;
- const sr = await context.shell.exec(cmd, stdin);
- if (sr && sr.code !== 0) {
- checkPossibleIncompatibility(context);
- }
- return sr;
- } else {
- return { code: -1, stdout: '', stderr: '' };
- }
-}
-
-// TODO: invalidate this when the context changes or if we know kubectl has changed (e.g. config)
-let checkedCompatibility = false; // We don't want to spam the user (or CPU!) repeatedly running the version check
-
-async function checkPossibleIncompatibility(context: Context): Promise {
- if (checkedCompatibility) {
- return;
- }
- checkedCompatibility = true;
- const compat = await compatibility.check((cmd) => asJson(context, cmd));
- if (!compatibility.isGuaranteedCompatible(compat) && compat.didCheck) {
- const versionAlert = localize('kubectlVersionIncompatible', 'kubectl version ${0} may be incompatible with cluster Kubernetes version {1}', compat.clientVersion, compat.serverVersion);
- context.host.showWarningMessage(versionAlert);
- }
-}
-
-
-export function baseKubectlPath(context: Context): string {
- let bin = getToolPath(context.host, context.shell, 'kubectl');
- if (!bin) {
- bin = 'kubectl';
- }
- return bin;
-}
-
-async function asJson(context: Context, command: string): Promise> {
- const shellResult = await invokeAsync(context, command);
- if (!shellResult) {
- return { succeeded: false, error: [localize('cannotRunCommand', 'Unable to run command ({0})', command)] };
- }
-
- if (shellResult.code === 0) {
- return { succeeded: true, result: JSON.parse(shellResult.stdout.trim()) as T };
-
- }
- return { succeeded: false, error: [shellResult.stderr] };
-}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts b/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts
deleted file mode 100644
index c2bf441860..0000000000
--- a/extensions/big-data-cluster/src/kubectl/kubectlUtils.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * 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 * as nls from 'vscode-nls';
-const localize = nls.loadMessageBundle();
-
-import { Kubectl } from './kubectl';
-import { failed, ClusterType } from '../interfaces';
-
-export interface KubectlContext {
- readonly clusterName: string;
- readonly contextName: string;
- readonly userName: string;
- readonly active: boolean;
-}
-
-interface Kubeconfig {
- readonly apiVersion: string;
- readonly 'current-context': string;
- readonly clusters: {
- readonly name: string;
- readonly cluster: {
- readonly server: string;
- readonly 'certificate-authority'?: string;
- readonly 'certificate-authority-data'?: string;
- };
- }[] | undefined;
- readonly contexts: {
- readonly name: string;
- readonly context: {
- readonly cluster: string;
- readonly user: string;
- readonly namespace?: string;
- };
- }[] | undefined;
- readonly users: {
- readonly name: string;
- readonly user: {};
- }[] | undefined;
-}
-
-export interface ClusterConfig {
- readonly server: string;
- readonly certificateAuthority: string | undefined;
-}
-
-
-
-async function getKubeconfig(kubectl: Kubectl): Promise {
- const shellResult = await kubectl.asJson('config view -o json');
- if (failed(shellResult)) {
- vscode.window.showErrorMessage(shellResult.error[0]);
- return null;
- }
- return shellResult.result;
-}
-
-export async function getCurrentClusterConfig(kubectl: Kubectl): Promise {
- const kubeConfig = await getKubeconfig(kubectl);
- if (!kubeConfig || !kubeConfig.clusters || !kubeConfig.contexts) {
- return undefined;
- }
- 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']
- };
-}
-
-export async function getContexts(kubectl: Kubectl): Promise {
- const kubectlConfig = await getKubeconfig(kubectl);
- if (!kubectlConfig) {
- return [];
- }
- const currentContext = kubectlConfig['current-context'];
- const contexts = kubectlConfig.contexts || [];
- return contexts.map((c) => {
- return {
- clusterName: c.context.cluster,
- contextName: c.name,
- userName: c.context.user,
- active: c.name === currentContext
- };
- });
-}
-
-export async function setContext(kubectl: Kubectl, targetContext: string): Promise {
- const shellResult = await kubectl.invokeAsync(`config use-context ${targetContext}`);
- if (!shellResult || shellResult.code !== 0) {
- // TODO: Update error handling for now.
- 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 = '';
-
- const ctxsr = await kubectl.invokeAsync('config current-context');
- if (ctxsr && ctxsr.code === 0) {
- latestContextName = ctxsr.stdout.trim();
- } else {
- return ClusterType.Other;
- }
-
- const cisr = await kubectl.invokeAsync('cluster-info');
- if (!cisr || cisr.code !== 0) {
- return ClusterType.Unknown;
- }
- const masterInfos = cisr.stdout.split('\n')
- .filter((s) => s.indexOf('master is running at') >= 0);
-
- if (masterInfos.length === 0) {
- return ClusterType.Other;
- }
-
- const masterInfo = masterInfos[0];
- if (masterInfo.indexOf('azmk8s.io') >= 0 || masterInfo.indexOf('azure.com') >= 0) {
- return ClusterType.AKS;
- }
-
- if (latestContextName) {
- const gcsr = await kubectl.invokeAsync(`config get-contexts ${latestContextName}`);
- if (gcsr && gcsr.code === 0) {
- if (gcsr.stdout.indexOf('minikube') >= 0) {
- return ClusterType.Minikube;
- }
- }
- }
-
- return ClusterType.Other;
-}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/kubectl/sqlServerBigDataClusterChannel.ts b/extensions/big-data-cluster/src/kubectl/sqlServerBigDataClusterChannel.ts
deleted file mode 100644
index dd93751c49..0000000000
--- a/extensions/big-data-cluster/src/kubectl/sqlServerBigDataClusterChannel.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * 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 * 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(outputChannelName);
-
- showOutput(message: any, title?: string): void {
- if (title) {
- const simplifiedTime = (new Date()).toISOString().replace(/z|t/gi, ' ').trim(); // YYYY-MM-DD HH:mm:ss.sss
- const hightlightingTitle = `[${title} ${simplifiedTime}]`;
- this.channel.appendLine(hightlightingTitle);
- }
- this.channel.appendLine(message);
- this.channel.show();
- }
-}
-
-export const sqlserverbigdataclusterchannel: ISqlServerBigDataClusterChannel = new SqlServerBigDataCluster();
diff --git a/extensions/big-data-cluster/src/main.ts b/extensions/big-data-cluster/src/main.ts
deleted file mode 100644
index 4d3a864182..0000000000
--- a/extensions/big-data-cluster/src/main.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'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 { shell, Shell } from './utility/shell';
-import { CheckPresentMessageMode, create as kubectlCreate } from './kubectl/kubectl';
-import { installKubectl } from './installer/installer';
-import { Errorable, failed } from './interfaces';
-
-const kubectl = kubectlCreate(host, fs, shell, installDependencies);
-export let controller: MainController;
-
-export function activate(context: vscode.ExtensionContext) {
- controller = new MainController(context, kubectl);
- controller.activate();
-}
-
-// this method is called when your extension is deactivated
-export function deactivate(): void {
- if (controller) {
- controller.deactivate();
- }
-}
-
-export async function installDependencies() {
- const gotKubectl = await kubectl.checkPresent(CheckPresentMessageMode.Silent);
-
-
- const installPromises = [
- installDependency('kubectl', gotKubectl, installKubectl)
- ];
-
- await Promise.all(installPromises);
-
- sqlserverbigdataclusterchannel.showOutput(localize('done', 'Done'));
-}
-
-async function installDependency(name: string, alreadyGot: boolean, installFunc: (shell: Shell) => Promise>): Promise {
- if (alreadyGot) {
- sqlserverbigdataclusterchannel.showOutput(localize('dependencyInstalled', '{0} already installed...', name));
- } else {
- sqlserverbigdataclusterchannel.showOutput(localize('installingDependency', 'Installing {0}...', name));
- const result = await installFunc(shell);
- if (failed(result)) {
- 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/mainController.ts b/extensions/big-data-cluster/src/mainController.ts
deleted file mode 100644
index 02ca5c882c..0000000000
--- a/extensions/big-data-cluster/src/mainController.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as vscode from 'vscode';
-import { CreateClusterWizard } from './wizards/create-cluster/createClusterWizard';
-import { Kubectl } from './kubectl/kubectl';
-/**
- * The main controller class that initializes the extension
- */
-export class MainController {
- protected _context: vscode.ExtensionContext;
- protected _kubectl: Kubectl;
-
- public constructor(context: vscode.ExtensionContext, kubectl: Kubectl) {
- this._context = context;
- this._kubectl = kubectl;
- }
-
- /**
- * Activates the extension
- */
- public activate(): void {
- vscode.commands.registerCommand('mssql.cluster.create', () => {
- let wizard = new CreateClusterWizard(this._context, this._kubectl);
- wizard.open();
- });
- }
-
- /**
- * Deactivates the extension
- */
- public deactivate(): void { }
-}
diff --git a/extensions/big-data-cluster/src/scripting/scripting.ts b/extensions/big-data-cluster/src/scripting/scripting.ts
deleted file mode 100644
index c21e39991e..0000000000
--- a/extensions/big-data-cluster/src/scripting/scripting.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-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';
-
-export interface Scriptable {
- getScriptProperties(): Promise>;
- getTargetKubectlContext(): KubectlContext;
-}
-
-export interface ScriptingDictionary {
- [name: string]: V;
-}
-
-const deployFilePrefix: string = 'mssql-bdc-deploy';
-export class ScriptGenerator {
-
- private _shell: Shell;
- private _kubectl: Kubectl;
-
- private _kubectlPath: string;
- constructor(_kubectl: Kubectl) {
- this._kubectl = _kubectl;
- this._shell = this._kubectl.getContext().shell;
- this._kubectlPath = baseKubectlPath(this._kubectl.getContext());
- }
-
- public async generateDeploymentScript(scriptable: Scriptable): Promise {
- let targetClusterName = scriptable.getTargetKubectlContext().clusterName;
- let targetContextName = scriptable.getTargetKubectlContext().contextName;
-
- let timestamp = new Date().getTime();
- let deployFolder = this.getDeploymentFolder(this._shell);
- let deployFileSuffix = this._shell.isWindows() ? `.bat` : `.sh`;
- let deployFileName = `${deployFilePrefix}-${targetClusterName}-${timestamp}${deployFileSuffix}`;
- let deployFilePath = path.join(deployFolder, deployFileName);
-
- 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 += 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.
- let deployCommand = `mssqlctl create cluster ${targetClusterName}\n`;
-
- let deployContent = envVars + kubeContextcommand + deployCommand;
-
- mkdirp.sync(deployFolder);
- await fs.writeFile(deployFilePath, deployContent, handleError);
- }
-
- public getDeploymentFolder(shell: Shell): string {
- return path.join(shell.home(), `.mssql-bdc/deployment`);
- }
-}
-
-const handleError = (err: NodeJS.ErrnoException) => {
- if (err) {
- vscode.window.showErrorMessage(err.message);
- }
-};
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/typings/ref.d.ts b/extensions/big-data-cluster/src/typings/refs.d.ts
similarity index 93%
rename from extensions/big-data-cluster/src/typings/ref.d.ts
rename to extensions/big-data-cluster/src/typings/refs.d.ts
index 4d46be908b..d79b8a564b 100644
--- a/extensions/big-data-cluster/src/typings/ref.d.ts
+++ b/extensions/big-data-cluster/src/typings/refs.d.ts
@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-///
///
///
+///
///
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/utility/fs.ts b/extensions/big-data-cluster/src/utility/fs.ts
deleted file mode 100644
index 9ba7b63fe1..0000000000
--- a/extensions/big-data-cluster/src/utility/fs.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-import * as sysfs from 'fs';
-
-export interface FS {
- existsSync(path: string): boolean;
- readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
- readFileSync(filename: string, encoding: string): string;
- readFileToBufferSync(filename: string): Buffer;
- writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
- writeFileSync(filename: string, data: any): void;
- dirSync(path: string): string[];
- unlinkAsync(path: string): Promise;
- existsAsync(path: string): Promise;
- openAsync(path: string, flags: string): Promise;
- statSync(path: string): sysfs.Stats;
-}
-
-export const fs: FS = {
- existsSync: (path) => sysfs.existsSync(path),
- readFile: (filename, encoding, callback) => sysfs.readFile(filename, encoding, callback),
- readFileSync: (filename, encoding) => sysfs.readFileSync(filename, encoding),
- readFileToBufferSync: (filename) => sysfs.readFileSync(filename),
- writeFile: (filename, data, callback) => sysfs.writeFile(filename, data, callback),
- writeFileSync: (filename, data) => sysfs.writeFileSync(filename, data),
- dirSync: (path) => sysfs.readdirSync(path),
-
- unlinkAsync: (path) => {
- return new Promise((resolve, reject) => {
- sysfs.unlink(path, (error) => {
- if (error) {
- reject();
- return;
- }
-
- resolve();
- });
- });
- },
-
- existsAsync: (path) => {
- return new Promise((resolve) => {
- sysfs.exists(path, (exists) => {
- resolve(exists);
- });
- });
- },
-
- openAsync: (path, flags) => {
- return new Promise((resolve, reject) => {
- sysfs.open(path, flags, (error, _fd) => {
- if (error) {
- reject();
- return;
- }
-
- resolve();
- });
- });
- },
-
- statSync: (path) => sysfs.statSync(path)
-};
diff --git a/extensions/big-data-cluster/src/utility/shell.ts b/extensions/big-data-cluster/src/utility/shell.ts
deleted file mode 100644
index e27193e2bc..0000000000
--- a/extensions/big-data-cluster/src/utility/shell.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-'use strict';
-
-import * as vscode from 'vscode';
-import * as shelljs from 'shelljs';
-import * as path from 'path';
-import { getActiveKubeconfig, getToolPath } from '../config/config';
-import { host } from '../kubectl/host';
-
-export enum Platform {
- Windows,
- MacOS,
- Linux,
- Unsupported,
-}
-
-export interface ExecCallback extends shelljs.ExecCallback { }
-
-export interface Shell {
- isWindows(): boolean;
- isUnix(): boolean;
- platform(): Platform;
- home(): string;
- combinePath(basePath: string, relativePath: string): string;
- fileUri(filePath: string): vscode.Uri;
- execOpts(): any;
- exec(cmd: string, stdin?: string): Promise;
- execCore(cmd: string, opts: any, stdin?: string): Promise;
- unquotedPath(path: string): string;
- which(bin: string): string | null;
- cat(path: string): string;
- ls(path: string): string[];
-}
-
-export const shell: Shell = {
- isWindows: isWindows,
- isUnix: isUnix,
- platform: platform,
- home: home,
- combinePath: combinePath,
- fileUri: fileUri,
- execOpts: execOpts,
- exec: exec,
- execCore: execCore,
- unquotedPath: unquotedPath,
- which: which,
- cat: cat,
- ls: ls,
-};
-
-const WINDOWS: string = 'win32';
-
-export interface ShellResult {
- readonly code: number;
- readonly stdout: string;
- readonly stderr: string;
-}
-
-export type ShellHandler = (code: number, stdout: string, stderr: string) => void;
-
-function isWindows(): boolean {
- return (process.platform === WINDOWS);
-}
-
-function isUnix(): boolean {
- return !isWindows();
-}
-
-function platform(): Platform {
- switch (process.platform) {
- case 'win32': return Platform.Windows;
- case 'darwin': return Platform.MacOS;
- case 'linux': return Platform.Linux;
- default: return Platform.Unsupported;
- }
-}
-
-function concatIfBoth(s1: string | undefined, s2: string | undefined): string | undefined {
- return s1 && s2 ? s1.concat(s2) : undefined;
-}
-
-function home(): string {
- return process.env['HOME'] ||
- concatIfBoth(process.env['HOMEDRIVE'], process.env['HOMEPATH']) ||
- process.env['USERPROFILE'] ||
- '';
-}
-
-function combinePath(basePath: string, relativePath: string) {
- let separator = '/';
- if (isWindows()) {
- relativePath = relativePath.replace(/\//g, '\\');
- separator = '\\';
- }
- return basePath + separator + relativePath;
-}
-
-function isWindowsFilePath(filePath: string) {
- return filePath[1] === ':' && filePath[2] === '\\';
-}
-
-function fileUri(filePath: string): vscode.Uri {
- if (isWindowsFilePath(filePath)) {
- return vscode.Uri.parse('file:///' + filePath.replace(/\\/g, '/'));
- }
- return vscode.Uri.parse('file://' + filePath);
-}
-
-function execOpts(): any {
- let env = process.env;
- if (isWindows()) {
- env = Object.assign({}, env, { HOME: home() });
- }
- env = shellEnvironment(env);
- const opts = {
- cwd: vscode.workspace.rootPath,
- env: env,
- async: true
- };
- return opts;
-}
-
-async function exec(cmd: string, stdin?: string): Promise {
- try {
- return await execCore(cmd, execOpts(), stdin);
- } catch (ex) {
- vscode.window.showErrorMessage(ex);
- return undefined;
- }
-}
-
-function execCore(cmd: string, opts: any, stdin?: string): Promise {
- return new Promise((resolve) => {
- const proc = shelljs.exec(cmd, opts, (code, stdout, stderr) => resolve({ code: code, stdout: stdout, stderr: stderr }));
- if (stdin) {
- proc.stdin.end(stdin);
- }
- });
-}
-
-function unquotedPath(path: string): string {
- if (isWindows() && path && path.length > 1 && path.startsWith('"') && path.endsWith('"')) {
- return path.substring(1, path.length - 1);
- }
- return path;
-}
-
-export function shellEnvironment(baseEnvironment: any): any {
- const env = Object.assign({}, baseEnvironment);
- const pathVariable = pathVariableName(env);
- for (const tool of ['kubectl']) {
- const toolPath = getToolPath(host, shell, tool);
- if (toolPath) {
- const toolDirectory = path.dirname(toolPath);
- const currentPath = env[pathVariable];
- env[pathVariable] = toolDirectory + (currentPath ? `${pathEntrySeparator()}${currentPath}` : '');
- }
- }
-
- const kubeconfig = getActiveKubeconfig();
- if (kubeconfig) {
- env['KUBECONFIG'] = kubeconfig;
- }
-
- return env;
-}
-
-function pathVariableName(env: any): string {
- if (isWindows()) {
- for (const v of Object.keys(env)) {
- if (v.toLowerCase() === 'path') {
- return v;
- }
- }
- }
- return 'PATH';
-}
-
-function pathEntrySeparator() {
- return isWindows() ? ';' : ':';
-}
-
-function which(bin: string): string | null {
- return shelljs.which(bin);
-}
-
-function cat(path: string): string {
- return shelljs.cat(path);
-}
-
-function ls(path: string): string[] {
- return shelljs.ls(path);
-}
-
-export function shellMessage(sr: ShellResult | undefined, invocationFailureMessage: string): string {
- if (!sr) {
- return invocationFailureMessage;
- }
- return sr.code === 0 ? sr.stdout : sr.stderr;
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/createClusterModel.ts b/extensions/big-data-cluster/src/wizards/create-cluster/createClusterModel.ts
deleted file mode 100644
index c0c9ed1ed5..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/createClusterModel.ts
+++ /dev/null
@@ -1,328 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { TargetClusterType, ClusterPorts, ClusterType, ContainerRegistryInfo, TargetClusterTypeInfo, ToolInfo, ToolInstallationStatus, ClusterProfile, PoolConfiguration, SQLServerMasterConfiguration, ClusterPoolType, ClusterResourceSummary } from '../../interfaces';
-import { getContexts, KubectlContext, setContext, inferCurrentClusterType } from '../../kubectl/kubectlUtils';
-import { Kubectl } from '../../kubectl/kubectl';
-import { Scriptable, ScriptingDictionary } from '../../scripting/scripting';
-import * as nls from 'vscode-nls';
-import * as os from 'os';
-import * as path from 'path';
-
-const localize = nls.loadMessageBundle();
-
-export class CreateClusterModel implements Scriptable {
-
- private _tmp_tools_installed: boolean = false;
- private scriptingProperties: ScriptingDictionary = {};
- constructor(private _kubectl: Kubectl) {
- }
-
- public async loadClusters(): Promise {
- return await getContexts(this._kubectl);
- }
-
- public async changeKubernetesContext(targetContext: string): Promise {
- await setContext(this._kubectl, targetContext);
- }
-
- public getDefaultPorts(): Thenable {
- let promise = new Promise(resolve => {
- resolve({
- sql: '31433',
- knox: '30443',
- controller: '30888',
- proxy: '30909',
- grafana: '30119',
- kibana: '30999'
- });
- });
- return promise;
- }
-
- public getDefaultContainerRegistryInfo(): Thenable {
- let promise = new Promise(resolve => {
- resolve({
- registry: 'private-repo.microsoft.com',
- repository: 'mssql-private-preview',
- imageTag: 'latest'
- });
- });
- return promise;
- }
-
- public getAllTargetClusterTypeInfo(): Thenable {
- let promise = new Promise(resolve => {
- let aksCluster: TargetClusterTypeInfo = {
- enabled: false,
- type: TargetClusterType.NewAksCluster,
- name: localize('bdc-create.AKSClusterCardText', 'New AKS Cluster'),
- fullName: localize('bdc-create.AKSClusterFullName', 'New Azure Kubernetes Service cluster'),
- description: localize('bdc-create.AKSClusterDescription',
- 'This option configures new Azure Kubernetes Service (AKS) for SQL Server big data cluster deployments. AKS makes it simple to create, configure and manage a cluster of virutal machines that are preconfigured with a Kubernetes cluster to run containerized applications.'),
- iconPath: {
- dark: 'images/aks.svg',
- light: 'images/aks.svg'
- }
- };
-
- let existingCluster: TargetClusterTypeInfo = {
- enabled: true,
- type: TargetClusterType.ExistingKubernetesCluster,
- name: localize('bdc-create.ExistingClusterCardText', 'Existing Cluster'),
- fullName: localize('bdc-create.ExistingClusterFullName', 'Existing Kubernetes cluster'),
- description: localize('bdc-create.ExistingClusterDescription', 'This option assumes you already have a Kubernetes cluster installed, Once a prerequisite check is done, ensure the correct cluster context is selected.'),
- iconPath: {
- dark: 'images/kubernetes.svg',
- light: 'images/kubernetes.svg'
- }
- };
- resolve([aksCluster, existingCluster]);
- });
- return promise;
- }
-
- public getRequiredToolStatus(): Thenable {
- let kubeCtl = {
- name: 'kubectl',
- description: 'Tool used for managing the Kubernetes cluster',
- version: '',
- status: ToolInstallationStatus.Installed
- };
- let mssqlCtl = {
- name: 'mssqlctl',
- description: 'Command-line tool for installing and managing the SQL Server big data cluster',
- version: '',
- status: ToolInstallationStatus.Installed
- };
- let azureCli = {
- name: 'Azure CLI',
- description: 'Tool used for managing Azure services',
- version: '',
- status: this._tmp_tools_installed ? ToolInstallationStatus.Installed : ToolInstallationStatus.NotInstalled
- };
- let promise = new Promise(resolve => {
- setTimeout(() => {
- let tools = this.targetClusterType === TargetClusterType.ExistingKubernetesCluster ? [kubeCtl, mssqlCtl] : [kubeCtl, mssqlCtl, azureCli];
- resolve(tools);
- }, 1000);
- });
- return promise;
- }
-
- public installTool(tool: ToolInfo): Thenable {
- let promise = new Promise(resolve => {
- setTimeout(() => {
- tool.status = ToolInstallationStatus.Installed;
- this._tmp_tools_installed = true;
- resolve();
- }, 1000);
- });
- return promise;
- }
-
- public getDefaultKubeConfigPath(): string {
- return path.join(os.homedir(), '.kube', 'config');
- }
-
- public clusterName: string;
-
- public targetClusterType: TargetClusterType;
-
- public selectedCluster: KubectlContext;
-
- public adminUserName: string;
-
- public adminPassword: string;
-
- public sqlPort: string;
-
- public knoxPort: string;
-
- public controllerPort: string;
-
- public proxyPort: string;
-
- public grafanaPort: string;
-
- public kibanaPort: string;
-
- public containerRegistry: string;
-
- public containerRepository: string;
-
- public containerImageTag: string;
-
- public containerRegistryUserName: string;
-
- public containerRegistryPassword: string;
-
- public profile: ClusterProfile;
-
- public async getTargetClusterPlatform(targetContextName: string): Promise {
- await setContext(this._kubectl, targetContextName);
- let clusterType = await inferCurrentClusterType(this._kubectl);
-
- switch (clusterType) {
- case ClusterType.AKS:
- return 'aks';
- case ClusterType.Minikube:
- return 'minikube';
- case ClusterType.Other:
- default:
- return 'kubernetes';
- }
- }
-
- public async getScriptProperties(): Promise> {
-
- // Cluster settings
- this.scriptingProperties['CLUSTER_NAME'] = this.selectedCluster.clusterName;
- this.scriptingProperties['CLUSTER_PLATFORM'] = await this.getTargetClusterPlatform(this.selectedCluster.contextName);
-
- // Default pool count for now. TODO: Update from user input
- this.scriptingProperties['CLUSTER_DATA_POOL_REPLICAS'] = '1';
- this.scriptingProperties['CLUSTER_COMPUTE_POOL_REPLICAS'] = '2';
- this.scriptingProperties['CLUSTER_STORAGE_POOL_REPLICAS'] = '3';
-
- // SQL Server settings
- this.scriptingProperties['CONTROLLER_USERNAME'] = this.adminUserName;
- this.scriptingProperties['CONTROLLER_PASSWORD'] = this.adminPassword;
- this.scriptingProperties['KNOX_PASSWORD'] = this.adminPassword;
- this.scriptingProperties['MSSQL_SA_PASSWORD'] = this.adminPassword;
-
- // docker settings
- this.scriptingProperties['DOCKER_REPOSITORY'] = this.containerRepository;
- this.scriptingProperties['DOCKER_REGISTRY'] = this.containerRegistry;
- this.scriptingProperties['DOCKER_PASSWORD'] = this.containerRegistryPassword;
- this.scriptingProperties['DOCKER_USERNAME'] = this.containerRegistryUserName;
- this.scriptingProperties['DOCKER_IMAGE_TAG'] = this.containerImageTag;
-
- // port settings
- this.scriptingProperties['MASTER_SQL_PORT'] = this.sqlPort;
- this.scriptingProperties['KNOX_PORT'] = this.knoxPort;
- this.scriptingProperties['GRAFANA_PORT'] = this.grafanaPort;
- this.scriptingProperties['KIBANA_PORT'] = this.kibanaPort;
-
- return this.scriptingProperties;
- }
-
- public getTargetKubectlContext(): KubectlContext {
- return this.selectedCluster;
- }
-
- public getClusterResource(): Thenable {
- let promise = new Promise(resolve => {
- setTimeout(() => {
- let resoureSummary: ClusterResourceSummary = {
- hardwareLabels: [
- {
- name: '',
- totalNodes: 10,
- totalCores: 22,
- totalDisks: 128,
- totalMemoryInGB: 77
- },
- {
- name: '#data',
- totalNodes: 4,
- totalCores: 22,
- totalDisks: 200,
- totalMemoryInGB: 100
- },
- {
- name: '#compute',
- totalNodes: 12,
- totalCores: 124,
- totalDisks: 24,
- totalMemoryInGB: 100
- },
- {
- name: '#premium',
- totalNodes: 10,
- totalCores: 100,
- totalDisks: 200,
- totalMemoryInGB: 770
- }
- ]
- };
- resolve(resoureSummary);
- }, 1000);
- });
- return promise;
- }
-
- public getProfiles(): Thenable {
- let promise = new Promise(resolve => {
- setTimeout(() => {
- let profiles: ClusterProfile[] = [];
- profiles.push({
- name: 'Basic',
- sqlServerMasterConfiguration: this.createSQLPoolConfiguration(1, 1),
- computePoolConfiguration: this.createComputePoolConfiguration(2),
- dataPoolConfiguration: this.createDataPoolConfiguration(2),
- storagePoolConfiguration: this.createStoragePoolConfiguration(2),
- sparkPoolConfiguration: this.createSparkPoolConfiguration(2)
- });
- profiles.push({
- name: 'Standard',
- sqlServerMasterConfiguration: this.createSQLPoolConfiguration(3, 9),
- computePoolConfiguration: this.createComputePoolConfiguration(5),
- dataPoolConfiguration: this.createDataPoolConfiguration(5),
- storagePoolConfiguration: this.createStoragePoolConfiguration(5),
- sparkPoolConfiguration: this.createSparkPoolConfiguration(5)
- });
- profiles.push({
- name: 'Premium',
- sqlServerMasterConfiguration: this.createSQLPoolConfiguration(5, 9),
- computePoolConfiguration: this.createComputePoolConfiguration(7),
- dataPoolConfiguration: this.createDataPoolConfiguration(7),
- storagePoolConfiguration: this.createStoragePoolConfiguration(7),
- sparkPoolConfiguration: this.createSparkPoolConfiguration(7)
- });
- resolve(profiles);
- }, 1000);
- });
- return promise;
- }
-
- private createSQLPoolConfiguration(scale: number, maxScale: number): SQLServerMasterConfiguration {
- return {
- type: ClusterPoolType.SQL,
- engineOnly: false,
- scale: scale,
- maxScale: maxScale
- };
- }
-
- private createComputePoolConfiguration(scale: number): PoolConfiguration {
- return {
- type: ClusterPoolType.Compute,
- scale: scale
- };
- }
-
- private createDataPoolConfiguration(scale: number): PoolConfiguration {
- return {
- type: ClusterPoolType.Data,
- scale: scale
- };
- }
-
- private createStoragePoolConfiguration(scale: number): PoolConfiguration {
- return {
- type: ClusterPoolType.Storage,
- scale: scale
- };
- }
-
- private createSparkPoolConfiguration(scale: number): PoolConfiguration {
- return {
- type: ClusterPoolType.Spark,
- scale: scale
- };
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/createClusterWizard.ts b/extensions/big-data-cluster/src/wizards/create-cluster/createClusterWizard.ts
deleted file mode 100644
index e31cc25648..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/createClusterWizard.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { CreateClusterModel } from './createClusterModel';
-import { SelectExistingClusterPage } from './pages/selectExistingClusterPage';
-import { SummaryPage } from './pages/summaryPage';
-import { SettingsPage } from './pages/settingsPage';
-import { ClusterProfilePage } from './pages/clusterProfilePage';
-import { ExtensionContext } from 'vscode';
-import { WizardBase } from '../wizardBase';
-import * as nls from 'vscode-nls';
-import { Kubectl } from '../../kubectl/kubectl';
-import { SelectTargetClusterTypePage } from './pages/selectTargetClusterTypePage';
-import { ScriptGenerator } from '../../scripting/scripting';
-const localize = nls.loadMessageBundle();
-
-export class CreateClusterWizard extends WizardBase {
- private scripter: ScriptGenerator;
- constructor(context: ExtensionContext, kubectl: Kubectl) {
- let model = new CreateClusterModel(kubectl);
- super(model, context, localize('bdc-create.wizardTitle', 'Create a big data cluster'));
- this.scripter = new ScriptGenerator(kubectl);
- }
-
- protected initialize(): void {
- let settingsPage = new SettingsPage(this);
- let clusterProfilePage = new ClusterProfilePage(this);
- let selectTargetClusterPage = new SelectExistingClusterPage(this);
- let summaryPage = new SummaryPage(this);
- let targetClusterTypePage = new SelectTargetClusterTypePage(this);
- this.setPages([targetClusterTypePage, selectTargetClusterPage, settingsPage, clusterProfilePage, summaryPage]);
-
- this.wizardObject.generateScriptButton.label = localize('bdc-create.generateScriptsButtonText', 'Generate Scripts');
- this.wizardObject.generateScriptButton.hidden = false;
- this.wizardObject.doneButton.label = localize('bdc-create.createClusterButtonText', 'Create');
-
- this.registerDisposable(this.wizardObject.generateScriptButton.onClick(async () => {
- this.wizardObject.generateScriptButton.enabled = false;
- this.scripter.generateDeploymentScript(this.model).then(() => {
- this.wizardObject.generateScriptButton.enabled = true;
- //TODO: Add error handling.
- });
- }));
- }
-
- protected onCancel(): void {
- }
-
- protected onOk(): void {
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/pages/clusterProfilePage.ts b/extensions/big-data-cluster/src/wizards/create-cluster/pages/clusterProfilePage.ts
deleted file mode 100644
index ae8d384e1f..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/pages/clusterProfilePage.ts
+++ /dev/null
@@ -1,389 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import * as azdata from 'azdata';
-import { WizardPageBase } from '../../wizardPageBase';
-import { CreateClusterWizard } from '../createClusterWizard';
-import * as nls from 'vscode-nls';
-import { ClusterProfile, PoolConfiguration, ClusterPoolType, SQLServerMasterConfiguration, ClusterResourceSummary } from '../../../interfaces';
-
-
-const localize = nls.loadMessageBundle();
-const LabelWidth = '200px';
-const InputWidth = '300px';
-
-export class ClusterProfilePage extends WizardPageBase {
- private view: azdata.ModelView;
- private clusterProfiles: ClusterProfile[];
- private poolList: azdata.FlexContainer;
- private detailContainer: azdata.FlexContainer;
- private clusterResourceView: azdata.GroupContainer;
- private poolListMap = {};
- private clusterResourceContainer: azdata.FlexContainer;
- private clusterResourceLoadingComponent: azdata.LoadingComponent;
- private clusterResource: ClusterResourceSummary;
-
-
- constructor(wizard: CreateClusterWizard) {
- super(localize('bdc-create.clusterProfilePageTitle', 'Select a cluster profile'),
- localize('bdc-create.clusterProfilePageDescription', 'Select your requirement and we will provide you a pre-defined default scaling. You can later go to cluster configuration and customize it.'),
- wizard);
- }
-
- public onEnter(): void {
- this.updatePoolList();
- this.clusterResourceLoadingComponent.loading = true;
- this.wizard.model.getClusterResource().then((resource) => {
- this.clusterResource = resource;
- this.initializeClusterResourceView();
- });
- this.wizard.wizardObject.registerNavigationValidator(() => {
- return true;
- });
- }
-
- protected initialize(view: azdata.ModelView): Thenable {
- this.view = view;
- let fetchProfilePromise = this.wizard.model.getProfiles().then(p => { this.clusterProfiles = p; });
- return Promise.all([fetchProfilePromise]).then(() => {
- this.wizard.model.profile = this.clusterProfiles[0];
- this.clusterResourceView = this.view.modelBuilder.groupContainer().withLayout({
- header: localize('bdc-create.TargetClusterOverview', 'Target cluster scale overview'),
- collapsed: true,
- collapsible: true
- }).component();
-
- this.clusterResourceContainer = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
- this.clusterResourceLoadingComponent = this.view.modelBuilder.loadingComponent().withItem(this.clusterResourceContainer).component();
- this.clusterResourceView.addItem(this.clusterResourceLoadingComponent);
-
- let profileLabel = view.modelBuilder.text().withProperties({ value: localize('bdc-create.clusterProfileLabel', 'Deployment profile') }).component();
- let profileDropdown = view.modelBuilder.dropDown().withProperties({
- values: this.clusterProfiles.map(profile => profile.name),
- width: '300px'
- }).component();
- let dropdownRow = this.view.modelBuilder.flexContainer().withItems([profileLabel, profileDropdown], { CSSStyles: { 'margin-right': '30px' } }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
- let poolContainer = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', width: '100%', height: '100%' }).component();
- this.poolList = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: '300px', height: '100%' }).component();
- poolContainer.addItem(this.poolList, {
- CSSStyles: {
- 'border-top-style': 'solid',
- 'border-top-width': '2px',
- 'border-right-style': 'solid',
- 'border-right-width': '2px',
- 'border-color': 'lightgray'
- }
- });
-
- this.detailContainer = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: '760px', height: '100%' }).component();
- poolContainer.addItem(this.detailContainer, {
- CSSStyles: {
- 'border-top-style': 'solid',
- 'border-top-width': '2px',
- 'border-color': 'lightgray'
- }
- });
-
- this.wizard.registerDisposable(profileDropdown.onValueChanged(() => {
- let profiles = this.clusterProfiles.filter(p => profileDropdown.value === p.name);
- if (profiles && profiles.length === 1) {
- this.wizard.model.profile = profiles[0];
- this.updatePoolList();
- this.clearPoolDetail();
- }
- }));
-
- this.initializePoolList();
-
- let pageContainer = this.view.modelBuilder.flexContainer().withLayout({
- flexFlow: 'column',
- height: '800px'
- }).component();
- pageContainer.addItem(this.clusterResourceView, {
- flex: '0 0 auto',
- CSSStyles: {
- 'margin-bottom': '20px',
- 'padding-bottom': '5px',
- 'padding-top': '5px'
- }
- });
- pageContainer.addItem(dropdownRow, {
- flex: '0 0 auto',
- CSSStyles: { 'margin-bottom': '10px' }
- });
- pageContainer.addItem(poolContainer, {
- flex: '1 1 auto',
- CSSStyles: {
- 'display': 'flex'
- }
- });
- let formBuilder = view.modelBuilder.formContainer();
- let form = formBuilder.withFormItems([{
- title: '',
- component: pageContainer
- }], {
- horizontal: false,
- componentWidth: '100%'
- }).component();
-
- return view.initializeModel(form);
- });
- }
-
- private initializeClusterResourceView(): void {
- this.clusterResourceContainer.clearItems();
- let text = this.view.modelBuilder.text().withProperties({ value: localize('bdc-create.HardwareProfileText', 'Hardware profile') }).component();
- let height = (this.clusterResource.hardwareLabels.length * 25) + 30;
- let labelColumn: azdata.TableColumn = {
- value: localize('bdc-create.HardwareLabelColumnName', 'Label'),
- width: 100
- };
- let totalNodesColumn: azdata.TableColumn = {
- value: localize('bdc-create.TotalNodesColumnName', 'Nodes'),
- width: 50
- };
- let totalCoresColumn: azdata.TableColumn = {
- value: localize('bdc-create.TotalCoresColumnName', 'Cores'),
- width: 50
- };
- let totalMemoryColumn: azdata.TableColumn = {
- value: localize('bdc-create.TotalMemoryColumnName', 'Memory'),
- width: 50
- };
- let totalDisksColumn: azdata.TableColumn = {
- value: localize('bdc-create.TotalDisksColumnName', 'Disks'),
- width: 50
- };
-
- let table = this.view.modelBuilder.table().withProperties({
- height: `${height}px`,
- data: this.clusterResource.hardwareLabels.map(label => [label.name, label.totalNodes, label.totalCores, label.totalMemoryInGB, label.totalDisks]),
- columns: [labelColumn, totalNodesColumn, totalCoresColumn, totalMemoryColumn, totalDisksColumn],
- width: '300px'
-
- }).component();
- this.clusterResourceContainer.addItems([text, table]);
- this.clusterResourceLoadingComponent.loading = false;
- }
-
- private initializePoolList(): void {
- let pools = [this.wizard.model.profile.sqlServerMasterConfiguration,
- this.wizard.model.profile.computePoolConfiguration,
- this.wizard.model.profile.dataPoolConfiguration,
- this.wizard.model.profile.sparkPoolConfiguration,
- this.wizard.model.profile.storagePoolConfiguration];
- pools.forEach(pool => {
- let poolSummaryButton = this.view.modelBuilder.divContainer().withProperties({ clickable: true }).component();
- let container = this.view.modelBuilder.flexContainer().component();
- this.wizard.registerDisposable(poolSummaryButton.onDidClick(() => {
- this.clearPoolDetail();
- let currentPool: PoolConfiguration;
- switch (pool.type) {
- case ClusterPoolType.SQL:
- currentPool = this.wizard.model.profile.sqlServerMasterConfiguration;
- break;
- case ClusterPoolType.Compute:
- currentPool = this.wizard.model.profile.computePoolConfiguration;
- break;
- case ClusterPoolType.Data:
- currentPool = this.wizard.model.profile.dataPoolConfiguration;
- break;
- case ClusterPoolType.Storage:
- currentPool = this.wizard.model.profile.storagePoolConfiguration;
- break;
- case ClusterPoolType.Spark:
- currentPool = this.wizard.model.profile.sparkPoolConfiguration;
- break;
- default:
- break;
- }
- if (currentPool) {
- this.detailContainer.addItem(this.createPoolConfigurationPart(currentPool), { CSSStyles: { 'margin-left': '10px' } });
- }
- }));
-
- let text = this.view.modelBuilder.text().component();
- this.poolListMap[pool.type] = text;
- text.width = '250px';
- let chrevron = this.view.modelBuilder.text().withProperties({ value: '>' }).component();
- chrevron.width = '30px';
- container.addItem(text);
- container.addItem(chrevron, {
- CSSStyles: {
- 'font-size': '20px',
- 'line-height': '0px'
- }
- });
- poolSummaryButton.addItem(container);
- this.poolList.addItem(poolSummaryButton, {
- CSSStyles: {
- 'border-bottom-style': 'solid',
- 'border-bottom-width': '1px',
- 'border-color': 'lightgray',
- 'cursor': 'pointer'
- }
- });
- });
- }
-
- private createPoolConfigurationPart(configuration: PoolConfiguration): azdata.Component {
- let container = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
- switch (configuration.type) {
- case ClusterPoolType.SQL:
- this.createSQLConfigurationPart(container, configuration as SQLServerMasterConfiguration);
- break;
- default:
- this.createDefaultPoolConfigurationPart(container, configuration);
- break;
- }
- return container;
- }
-
- private createSQLConfigurationPart(container: azdata.FlexContainer, configuration: SQLServerMasterConfiguration): void {
- this.createDefaultPoolConfigurationPart(container, configuration);
- this.addFeatureSetRow(container, configuration);
- }
-
- private createDefaultPoolConfigurationPart(container: azdata.FlexContainer, configuration: PoolConfiguration): void {
- this.addPoolNameLabel(container, this.getPoolDisplayName(configuration.type));
- this.addPoolDescriptionLabel(container, this.getPoolDescription(configuration.type));
- this.addScaleRow(container, configuration);
- this.addHardwareLabelRow(container, configuration);
- }
-
- private addPoolNameLabel(container: azdata.FlexContainer, text: string): void {
- let poolNameLabel = this.view.modelBuilder.text().withProperties({ value: text }).component();
- container.addItem(poolNameLabel, {
- flex: '0 0 auto', CSSStyles: {
- 'font-size': '13px',
- 'font-weight': 'bold'
- }
- });
- }
-
- private addPoolDescriptionLabel(container: azdata.FlexContainer, text: string): void {
- let label = this.view.modelBuilder.text().withProperties({ value: text }).component();
- container.addItem(label, {
- flex: '0 0 auto',
- CSSStyles: {
- 'margin-bottom': '20px'
- }
- });
- }
-
- private addScaleRow(container: azdata.FlexContainer, configuration: PoolConfiguration): void {
- let label = this.view.modelBuilder.text().withProperties({ value: localize('bdc-create.ScaleLabel', 'Scale') }).component();
- label.width = LabelWidth;
- let input = this.view.modelBuilder.inputBox().withProperties({
- inputType: 'number',
- value: configuration.scale.toString(),
- min: 1,
- max: configuration.maxScale
- }).component();
-
- this.wizard.registerDisposable(input.onTextChanged(() => {
- configuration.scale = Number(input.value);
- this.updatePoolList();
- }));
- input.width = InputWidth;
- let row = this.createRow([label, input]);
- container.addItem(row);
- }
-
- private addHardwareLabelRow(container: azdata.FlexContainer, configuration: PoolConfiguration): void {
- let label = this.view.modelBuilder.text().withProperties({ value: localize('bdc-create.HardwareProfileLabel', 'Hardware profile label') }).component();
- label.width = LabelWidth;
- let optionalValues = this.clusterResource.hardwareLabels.map(label => label.name);
- configuration.hardwareLabel = configuration.hardwareLabel ? configuration.hardwareLabel : optionalValues[0];
- let input = this.view.modelBuilder.dropDown().withProperties({ value: configuration.hardwareLabel, values: optionalValues }).component();
- this.wizard.registerDisposable(input.onValueChanged(() => {
- configuration.hardwareLabel = input.value.toString();
- }));
- input.width = InputWidth;
- let row = this.createRow([label, input]);
- container.addItem(row);
- }
-
- private addFeatureSetRow(container: azdata.FlexContainer, configuration: SQLServerMasterConfiguration): void {
- const radioGroupName = 'featureset';
- let label = this.view.modelBuilder.text().withProperties({ value: localize('bdc-create.FeatureSetLabel', 'Feature set') }).component();
- label.width = LabelWidth;
- let engineOnlyOption = this.view.modelBuilder.radioButton().withProperties({ label: localize('bdc-create.EngineOnlyText', 'Engine only'), name: radioGroupName, checked: configuration.engineOnly }).component();
- let engineWithFeaturesOption = this.view.modelBuilder.radioButton().withProperties({ label: localize('bdc-create.EngineWithFeaturesText', 'Engine with optional features'), name: radioGroupName, checked: !configuration.engineOnly }).component();
- let optionContainer = this.view.modelBuilder.divContainer().component();
- optionContainer.width = InputWidth;
- optionContainer.addItems([engineOnlyOption, engineWithFeaturesOption]);
- container.addItem(this.createRow([label, optionContainer]));
- this.wizard.registerDisposable(engineOnlyOption.onDidClick(() => {
- configuration.engineOnly = true;
- }));
- this.wizard.registerDisposable(engineWithFeaturesOption.onDidClick(() => {
- configuration.engineOnly = false;
- }));
- }
-
- private createRow(items: azdata.Component[]): azdata.FlexContainer {
- return this.view.modelBuilder.flexContainer().withItems(items, {
- CSSStyles: {
- 'margin-right': '5px'
- }
- }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
- }
-
- private getPoolDisplayName(poolType: ClusterPoolType): string {
- switch (poolType) {
- case ClusterPoolType.SQL:
- return localize('bdc-create.SQLServerMasterDisplayName', 'SQL Server master');
- case ClusterPoolType.Compute:
- return localize('bdc-create.ComputePoolDisplayName', 'Compute pool');
- case ClusterPoolType.Data:
- return localize('bdc-create.DataPoolDisplayName', 'Data pool');
- case ClusterPoolType.Storage:
- return localize('bdc-create.StoragePoolDisplayName', 'Storage pool');
- case ClusterPoolType.Spark:
- return localize('bdc-create.SparkPoolDisplayName', 'Spark pool');
- default:
- throw new Error('unknown pool type');
- }
- }
-
- private getPoolDescription(poolType: ClusterPoolType): string {
- switch (poolType) {
- case ClusterPoolType.SQL:
- return localize('bdc-create.SQLServerMasterDescription', 'The SQL Server instance provides an externally accessible TDS endpoint for the cluster');
- case ClusterPoolType.Compute:
- return localize('bdc-create.ComputePoolDescription', 'TODO: Add description');
- case ClusterPoolType.Data:
- return localize('bdc-create.DataPoolDescription', 'TODO: Add description');
- case ClusterPoolType.Storage:
- return localize('bdc-create.StoragePoolDescription', 'TODO: Add description');
- case ClusterPoolType.Spark:
- return localize('bdc-create.SparkPoolDescription', 'TODO: Add description');
- default:
- throw new Error('unknown pool type');
- }
- }
-
- private updatePoolList(): void {
- let pools = [this.wizard.model.profile.sqlServerMasterConfiguration,
- this.wizard.model.profile.computePoolConfiguration,
- this.wizard.model.profile.dataPoolConfiguration,
- this.wizard.model.profile.sparkPoolConfiguration,
- this.wizard.model.profile.storagePoolConfiguration];
- pools.forEach(pool => {
- let text = this.poolListMap[pool.type] as azdata.TextComponent;
- if (text) {
- text.value = localize({
- key: 'bdc-create.poolLabelTemplate',
- comment: ['{0} is the pool name, {1} is the scale number']
- }, '{0} ({1})', this.getPoolDisplayName(pool.type), pool.scale);
- }
- });
- }
-
- private clearPoolDetail(): void {
- this.detailContainer.clearItems();
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectExistingClusterPage.ts b/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectExistingClusterPage.ts
deleted file mode 100644
index e996439d13..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectExistingClusterPage.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as azdata from 'azdata';
-import * as vscode from 'vscode';
-import * as os from 'os';
-import * as fs from 'fs';
-import { WizardPageBase } from '../../wizardPageBase';
-import { CreateClusterWizard } from '../createClusterWizard';
-import { setActiveKubeconfig } from '../../../config/config';
-
-import * as nls from 'vscode-nls';
-
-const localize = nls.loadMessageBundle();
-const ClusterRadioButtonGroupName = 'cluster';
-
-export class SelectExistingClusterPage extends WizardPageBase {
- private existingClusterControl: azdata.FlexContainer;
- private clusterContextsLabel: azdata.TextComponent;
- private errorLoadingClustersLabel: azdata.TextComponent;
- private clusterContextList: azdata.DivContainer;
- private clusterContextLoadingComponent: azdata.LoadingComponent;
- private configFileInput: azdata.InputBoxComponent;
- private browseFileButton: azdata.ButtonComponent;
- private loadDefaultKubeConfigFile: boolean = true;
- private view: azdata.ModelView;
-
- constructor(wizard: CreateClusterWizard) {
- super(localize('bdc-create.selectTargetClusterPageTitle', 'Where do you want to deploy this SQL Server big data cluster?'),
- localize('bdc-create.selectTargetClusterPageDescription', 'Select the kubeconfig file and then select a cluster context from the list'),
- wizard);
- }
-
- protected initialize(view: azdata.ModelView): Thenable {
- this.view = view;
- this.initExistingClusterControl();
- let formBuilder = view.modelBuilder.formContainer().withFormItems(
- [
- {
- component: this.existingClusterControl,
- title: ''
- }
- ],
- {
- horizontal: false
- }
- ).withLayout({ width: '100%', height: '100%' });
-
- let form = formBuilder.component();
- return view.initializeModel(form);
- }
-
- public onEnter() {
- if (this.loadDefaultKubeConfigFile) {
- let defaultKubeConfigPath = this.wizard.model.getDefaultKubeConfigPath();
- if (fs.existsSync(defaultKubeConfigPath)) {
- this.loadClusterContexts(defaultKubeConfigPath);
- }
- this.loadDefaultKubeConfigFile = false;
- }
-
- this.wizard.wizardObject.registerNavigationValidator((e) => {
- if (e.lastPage > e.newPage) {
- this.wizard.wizardObject.message = null;
- return true;
- }
- let clusterSelected = this.wizard.model.selectedCluster !== undefined;
- if (!clusterSelected) {
- this.wizard.wizardObject.message = {
- text: localize('bdc-create.ClusterContextNotSelectedMessage', 'Please select a cluster context.'),
- level: azdata.window.MessageLevel.Error
- };
- }
- return clusterSelected;
- });
- }
-
- private initExistingClusterControl(): void {
- let self = this;
- const labelWidth = '150px';
- let configFileLabel = this.view.modelBuilder.text().withProperties({ value: localize('bdc-create.kubeConfigFileLabelText', 'Kube config file path') }).component();
- configFileLabel.width = labelWidth;
- this.configFileInput = this.view.modelBuilder.inputBox().withProperties({ width: '300px' }).component();
- this.configFileInput.enabled = false;
- this.browseFileButton = this.view.modelBuilder.button().withProperties({ label: localize('bdc-browseText', 'Browse'), width: '100px' }).component();
- let configFileContainer = this.view.modelBuilder.flexContainer()
- .withLayout({ flexFlow: 'row', alignItems: 'baseline' })
- .withItems([configFileLabel, this.configFileInput, this.browseFileButton], { CSSStyles: { 'margin-right': '10px' } }).component();
- this.clusterContextsLabel = this.view.modelBuilder.text().withProperties({ value: localize('bdc-clusterContextsLabelText', 'Cluster Contexts') }).component();
- this.clusterContextsLabel.width = labelWidth;
- this.errorLoadingClustersLabel = this.view.modelBuilder.text().withProperties({ value: localize('bdc-errorLoadingClustersText', 'No cluster information is found in the config file or an error ocurred while loading the config file') }).component();
- this.clusterContextList = this.view.modelBuilder.divContainer().component();
- this.clusterContextLoadingComponent = this.view.modelBuilder.loadingComponent().withItem(this.clusterContextList).component();
- this.existingClusterControl = this.view.modelBuilder.divContainer().component();
- let clusterContextContainer = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'start' }).component();
- clusterContextContainer.addItem(this.clusterContextsLabel, { flex: '0 0 auto' });
- clusterContextContainer.addItem(this.clusterContextLoadingComponent, { flex: '0 0 auto', CSSStyles: { 'width': '400px', 'margin-left': '10px', 'margin-top': '10px' } });
-
- this.existingClusterControl.addItem(configFileContainer, { CSSStyles: { 'margin-top': '0px' } });
- this.existingClusterControl.addItem(clusterContextContainer, {
- CSSStyles: { 'margin- top': '10px' }
- });
-
- this.wizard.registerDisposable(this.browseFileButton.onDidClick(async () => {
- let fileUris = await vscode.window.showOpenDialog(
- {
- canSelectFiles: true,
- canSelectFolders: false,
- canSelectMany: false,
- defaultUri: vscode.Uri.file(os.homedir()),
- openLabel: localize('bdc-selectKubeConfigFileText', 'Select'),
- filters: {
- 'KubeConfig Files': ['*'],
- }
- }
- );
-
- if (!fileUris || fileUris.length === 0) {
- return;
- }
- self.clusterContextList.clearItems();
-
- let fileUri = fileUris[0];
-
- self.loadClusterContexts(fileUri.fsPath);
- }));
- }
-
- private async loadClusterContexts(configPath: string): Promise {
- this.clusterContextLoadingComponent.loading = true;
- let self = this;
- this.configFileInput.value = configPath;
- await setActiveKubeconfig(configPath);
-
- let clusters = await this.wizard.model.loadClusters();
- if (clusters.length !== 0) {
- let options = clusters.map(cluster => {
- let option = this.view.modelBuilder.radioButton().withProperties({
- label: cluster.contextName,
- checked: cluster.active,
- name: ClusterRadioButtonGroupName
- }).component();
-
- if (cluster.active) {
- self.wizard.model.selectedCluster = cluster;
- self.wizard.wizardObject.message = null;
- }
-
- this.wizard.registerDisposable(option.onDidClick(() => {
- self.wizard.model.selectedCluster = cluster;
- self.wizard.wizardObject.message = null;
- }));
- return option;
- });
- self.clusterContextList.addItems(options);
- } else {
- self.clusterContextList.addItem(this.errorLoadingClustersLabel);
- }
- this.clusterContextLoadingComponent.loading = false;
- }
-}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectTargetClusterTypePage.ts b/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectTargetClusterTypePage.ts
deleted file mode 100644
index 0ae97e0067..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/pages/selectTargetClusterTypePage.ts
+++ /dev/null
@@ -1,259 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as azdata from 'azdata';
-import { WizardPageBase } from '../../wizardPageBase';
-import { TargetClusterTypeInfo, ToolInstallationStatus, ToolInfo } from '../../../interfaces';
-import * as nls from 'vscode-nls';
-import { CreateClusterWizard } from '../createClusterWizard';
-
-const localize = nls.loadMessageBundle();
-
-const InstallToolsButtonText = localize('bdc-create.InstallToolsText', 'Install Tools');
-const InstallingButtonText = localize('bdc-create.InstallingButtonText', 'Installing...');
-
-export class SelectTargetClusterTypePage extends WizardPageBase {
- private cards: azdata.CardComponent[];
- private toolsTable: azdata.TableComponent;
- private formBuilder: azdata.FormBuilder;
- private form: azdata.FormContainer;
- private installToolsButton: azdata.window.Button;
- private toolsLoadingWrapper: azdata.LoadingComponent;
- private refreshToolsButton: azdata.window.Button;
- private targetDescriptionText: azdata.TextComponent;
- private targetDescriptionGroup: azdata.FormComponent;
- private isValid: boolean = false;
- private isLoading: boolean = false;
- private requiredTools: ToolInfo[];
-
- constructor(wizard: CreateClusterWizard) {
- super(localize('bdc-create.selectTargetClusterTypePageTitle', 'What is your target cluster environment?'),
- localize('bdc-create.selectTargetClusterTypePageDescription', 'Choose the target environment and then install the required tools for it.'),
- wizard);
- this.installToolsButton = azdata.window.createButton(InstallToolsButtonText);
- this.installToolsButton.hidden = true;
- this.wizard.registerDisposable(this.installToolsButton.onClick(async () => {
- this.wizard.wizardObject.message = null;
- this.installToolsButton.label = InstallingButtonText;
- this.installToolsButton.enabled = false;
- this.refreshToolsButton.enabled = false;
- if (this.requiredTools) {
- for (let i = 0; i < this.requiredTools.length; i++) {
- let tool = this.requiredTools[i];
- if (tool.status === ToolInstallationStatus.NotInstalled) {
- tool.status = ToolInstallationStatus.Installing;
- this.updateToolStatusTable();
- await this.wizard.model.installTool(tool);
- }
- }
- }
-
- this.installToolsButton.label = InstallToolsButtonText;
- this.updateRequiredToolStatus();
- }));
- this.wizard.addButton(this.installToolsButton);
-
- this.refreshToolsButton = azdata.window.createButton(localize('bdc-create.RefreshToolsButtonText', 'Refresh Status'));
- this.refreshToolsButton.hidden = true;
- this.wizard.registerDisposable(this.refreshToolsButton.onClick(() => {
- this.updateRequiredToolStatus();
- }));
- this.wizard.addButton(this.refreshToolsButton);
- }
-
- protected initialize(view: azdata.ModelView): Thenable {
- let self = this;
- self.registerNavigationValidator();
- return self.wizard.model.getAllTargetClusterTypeInfo().then((clusterTypes) => {
- self.cards = [];
-
- clusterTypes.forEach(clusterType => {
- let card = self.createCard(view, clusterType);
- self.cards.push(card);
- });
- let cardsContainer = view.modelBuilder.flexContainer().withItems(self.cards, { flex: '0 0 auto', CSSStyles: { 'margin-bottom': '20px' } }).withLayout({ flexFlow: 'row', alignItems: 'left' }).component();
-
- self.targetDescriptionText = view.modelBuilder.text().component();
-
- let toolColumn: azdata.TableColumn = {
- value: localize('bdc-create.toolNameColumnHeader', 'Tool'),
- width: 100
- };
- let descriptionColumn: azdata.TableColumn = {
- value: localize('bdc-create.toolDescriptionColumnHeader', 'Description'),
- width: 500
- };
- let versionColumn: azdata.TableColumn = {
- value: localize('bdc-create.toolVersionColumnHeader', 'Version'),
- width: 200
- };
- let statusColumn: azdata.TableColumn = {
- value: localize('bdc-create.toolStatusColumnHeader', 'Status'),
- width: 200
- };
-
- self.toolsTable = view.modelBuilder.table().withProperties({
- height: 150,
- data: [],
- columns: [toolColumn, descriptionColumn, versionColumn, statusColumn],
- width: 1000
- }).component();
-
- self.toolsLoadingWrapper = view.modelBuilder.loadingComponent().withItem(self.toolsTable).component();
- self.formBuilder = view.modelBuilder.formContainer().withFormItems(
- [
- {
- component: cardsContainer,
- title: localize('bdc-create.PickTargetEnvironmentText', 'Pick target environment')
- }
- ],
- {
- horizontal: false
- }
- );
-
- self.form = self.formBuilder.withLayout({ width: '100%' }).component();
- return view.initializeModel(self.form);
- });
- }
-
- public onEnter(): void {
- this.installToolsButton.hidden = false;
- this.refreshToolsButton.hidden = false;
- this.refreshToolsButton.enabled = true;
- this.installToolsButton.enabled = false;
- this.registerNavigationValidator();
- }
-
- private registerNavigationValidator(): void {
- this.wizard.wizardObject.registerNavigationValidator(() => {
- if (this.isLoading) {
- let messageText = localize('bdc-create.ToolsRefreshingText', 'Please wait while the required tools status is being refreshed.');
- let messageLevel = azdata.window.MessageLevel.Information;
- this.wizard.wizardObject.message = {
- level: messageLevel,
- text: messageText
- };
- return false;
- }
- if (!this.isValid) {
- let messageText = this.cards.filter(c => { return c.selected; }).length === 0 ?
- localize('bdc-create.TargetClusterTypeNotSelectedText', 'Please select a target cluster type.') :
- localize('bdc-create.MissingToolsText', 'Please install the required tools.');
- this.wizard.wizardObject.message = {
- level: azdata.window.MessageLevel.Error,
- text: messageText
- };
- }
- return this.isValid;
- });
- }
-
- public onLeave(): void {
- this.installToolsButton.hidden = true;
- this.refreshToolsButton.hidden = true;
- }
-
- private createCard(view: azdata.ModelView, targetClusterTypeInfo: TargetClusterTypeInfo): azdata.CardComponent {
- let self = this;
- let descriptions = targetClusterTypeInfo.enabled ? [] : [localize('bdc-create.ComingSoonText', '(Coming Soon)')];
- let card = view.modelBuilder.card().withProperties({
- cardType: azdata.CardType.VerticalButton,
- iconPath: {
- dark: self.wizard.context.asAbsolutePath(targetClusterTypeInfo.iconPath.dark),
- light: self.wizard.context.asAbsolutePath(targetClusterTypeInfo.iconPath.light)
- },
- label: targetClusterTypeInfo.name,
- descriptions: descriptions
- }).component();
-
- card.enabled = targetClusterTypeInfo.enabled;
-
- self.wizard.registerDisposable(card.onCardSelectedChanged(() => {
- self.onCardSelected(card, targetClusterTypeInfo);
- }));
- return card;
- }
-
- private onCardSelected(card: azdata.CardComponent, targetClusterTypeInfo: TargetClusterTypeInfo): void {
- let self = this;
- if (card.selected) {
- self.wizard.wizardObject.message = null;
- self.wizard.model.targetClusterType = targetClusterTypeInfo.type;
- self.cards.forEach(c => {
- if (c !== card) {
- c.selected = false;
- }
- });
-
- self.targetDescriptionText.value = targetClusterTypeInfo.description;
-
- if (self.form.items.length === 1) {
- self.formBuilder.addFormItem({
- title: localize('bdc-create.RequiredToolsText', 'Required tools'),
- component: self.toolsLoadingWrapper
- });
- } else {
- self.formBuilder.removeFormItem(self.targetDescriptionGroup);
- }
-
- self.targetDescriptionGroup = {
- title: targetClusterTypeInfo.fullName,
- component: self.targetDescriptionText
- };
- self.formBuilder.insertFormItem(self.targetDescriptionGroup, 1);
-
- self.updateRequiredToolStatus();
- } else {
- if (self.cards.filter(c => { return c !== card && c.selected; }).length === 0) {
- card.selected = true;
- }
- }
- }
-
- private updateRequiredToolStatus(): Thenable {
- this.isLoading = true;
- this.installToolsButton.hidden = false;
- this.refreshToolsButton.hidden = false;
- this.toolsLoadingWrapper.loading = true;
- this.refreshToolsButton.enabled = false;
- this.installToolsButton.enabled = false;
- return this.wizard.model.getRequiredToolStatus().then(tools => {
- this.requiredTools = tools;
- this.isLoading = false;
- this.toolsLoadingWrapper.loading = false;
- this.refreshToolsButton.enabled = true;
- this.installToolsButton.enabled = tools.filter(tool => tool.status !== ToolInstallationStatus.Installed).length !== 0;
- this.isValid = !this.installToolsButton.enabled;
- this.wizard.wizardObject.message = null;
- this.updateToolStatusTable();
- });
- }
-
- private getStatusText(status: ToolInstallationStatus): string {
- switch (status) {
- case ToolInstallationStatus.Installed:
- return '✔️ ' + localize('bdc-create.InstalledText', 'Installed');
- case ToolInstallationStatus.NotInstalled:
- return '❌ ' + localize('bdc-create.NotInstalledText', 'Not Installed');
- case ToolInstallationStatus.Installing:
- return '⌛ ' + localize('bdc-create.InstallingText', 'Installing...');
- case ToolInstallationStatus.FailedToInstall:
- return '❌ ' + localize('bdc-create.FailedToInstallText', 'Install Failed');
- default:
- return 'unknown status';
- }
- }
-
- private updateToolStatusTable(): void {
- if (this.requiredTools) {
- let tableData = this.requiredTools.map(tool => {
- return [tool.name, tool.description, tool.version, this.getStatusText(tool.status)];
- });
- this.toolsTable.data = tableData;
- }
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/pages/settingsPage.ts b/extensions/big-data-cluster/src/wizards/create-cluster/pages/settingsPage.ts
deleted file mode 100644
index e6dd775666..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/pages/settingsPage.ts
+++ /dev/null
@@ -1,278 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as azdata from 'azdata';
-import { WizardPageBase } from '../../wizardPageBase';
-import * as nls from 'vscode-nls';
-import { ClusterPorts, ContainerRegistryInfo } from '../../../interfaces';
-import { CreateClusterWizard } from '../createClusterWizard';
-
-const localize = nls.loadMessageBundle();
-const UserNameInputWidth = '300px';
-const PortInputWidth = '100px';
-const RestoreDefaultValuesText = localize('bdc-create.RestoreDefaultValuesText', 'Restore Default Values');
-
-export class SettingsPage extends WizardPageBase {
- private acceptEulaCheckbox: azdata.CheckBoxComponent;
-
- constructor(wizard: CreateClusterWizard) {
- super(localize('bdc-create.settingsPageTitle', 'Settings'),
- localize('bdc-create.settingsPageDescription', 'Configure the settings required for deploying SQL Server big data cluster'),
- wizard);
- }
-
- public onEnter(): void {
- this.wizard.wizardObject.registerNavigationValidator((e) => {
- if (e.lastPage > e.newPage) {
- this.wizard.wizardObject.message = null;
- return true;
- }
- if (!this.acceptEulaCheckbox.checked) {
- this.wizard.wizardObject.message = {
- text: localize('bdc-create.EulaNotAccepted', 'You need to accept the terms of services and privacy policy in order to proceed'),
- level: azdata.window.MessageLevel.Error
- };
- } else {
- this.wizard.wizardObject.message = null;
- }
- return this.acceptEulaCheckbox.checked;
- });
- }
-
- protected initialize(view: azdata.ModelView): Thenable {
- let clusterPorts: ClusterPorts;
- let containerRegistryInfo: ContainerRegistryInfo;
-
- let clusterPortsPromise = this.wizard.model.getDefaultPorts().then(ports => {
- clusterPorts = ports;
- });
-
- let containerRegistryPromise = this.wizard.model.getDefaultContainerRegistryInfo().then(containerRegistry => {
- containerRegistryInfo = containerRegistry;
- });
- return Promise.all([clusterPortsPromise, containerRegistryPromise]).then(() => {
- let formBuilder = view.modelBuilder.formContainer();
-
- // User settings
- let clusterNameInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.ClusterName', 'Cluster name'),
- inputWidth: UserNameInputWidth,
- isRequiredField: true
- }, (input) => {
- this.wizard.model.clusterName = input.value;
- });
-
- let adminUserNameInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.AdminUsernameText', 'Admin username'),
- isRequiredField: true,
- inputWidth: UserNameInputWidth
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.adminUserName = inputBox.value;
- });
- let adminPasswordInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.AdminUserPasswordText', 'Password'),
- isRequiredField: true,
- inputType: 'password',
- inputWidth: UserNameInputWidth
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.adminPassword = inputBox.value;
- });
-
- // Port settings
- let sqlPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.SQLPortText', 'SQL Server master'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.sql
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.sqlPort = inputBox.value;
- });
- let knoxPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.KnoxPortText', 'Knox'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.knox
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.knoxPort = inputBox.value;
- });
- let controllerPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.ControllerPortText', 'Controller'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.controller
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.controllerPort = inputBox.value;
- });
- let proxyPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.ProxyPortText', 'Proxy'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.proxy
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.proxyPort = inputBox.value;
- });
- let grafanaPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.GrafanaPortText', 'Grafana dashboard'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.grafana
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.grafanaPort = inputBox.value;
- });
- let kibanaPortInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.KibanaPortText', 'Kibana dashboard'),
- isRequiredField: true,
- inputWidth: PortInputWidth,
- initialValue: clusterPorts.kibana
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.kibanaPort = inputBox.value;
- });
- let restorePortSettingsButton = view.modelBuilder.button().withProperties({
- label: RestoreDefaultValuesText,
- width: 200
- }).component();
- this.wizard.registerDisposable(restorePortSettingsButton.onDidClick(() => {
- sqlPortInput.input.value = clusterPorts.sql;
- knoxPortInput.input.value = clusterPorts.knox;
- controllerPortInput.input.value = clusterPorts.controller;
- proxyPortInput.input.value = clusterPorts.proxy;
- grafanaPortInput.input.value = clusterPorts.grafana;
- kibanaPortInput.input.value = clusterPorts.kibana;
- }));
-
- // Container Registry Settings
- const registryUserNamePasswordHintText = localize('bdc-create.RegistryUserNamePasswordHintText', 'only required for private registries');
- let registryInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.RegistryText', 'Registry'),
- isRequiredField: true,
- inputWidth: UserNameInputWidth,
- initialValue: containerRegistryInfo.registry
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.containerRegistry = inputBox.value;
- });
-
- let repositoryInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.RepositoryText', 'Repository'),
- isRequiredField: true,
- inputWidth: UserNameInputWidth,
- initialValue: containerRegistryInfo.repository
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.containerRepository = inputBox.value;
- });
-
- let imageTagInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.ImageTagText', 'Image tag'),
- isRequiredField: true,
- inputWidth: UserNameInputWidth,
- initialValue: containerRegistryInfo.imageTag
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.containerRegistry = inputBox.value;
- });
-
- let registryUserNameInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.RegistryUserNameText', 'Username'),
- isRequiredField: false,
- inputWidth: UserNameInputWidth,
- placeHolder: registryUserNamePasswordHintText
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.containerRegistryUserName = inputBox.value;
- });
-
- let registryPasswordInput = this.createInputWithLabel(view, {
- label: localize('bdc-create.RegistryPasswordText', 'Password'),
- isRequiredField: false,
- inputWidth: UserNameInputWidth,
- placeHolder: registryUserNamePasswordHintText,
- inputType: 'password'
- }, (inputBox: azdata.InputBoxComponent) => {
- this.wizard.model.containerRegistryPassword = inputBox.value;
- });
- let restoreContainerSettingsButton = view.modelBuilder.button().withProperties({
- label: RestoreDefaultValuesText,
- width: 200
- }).component();
- this.wizard.registerDisposable(restoreContainerSettingsButton.onDidClick(() => {
- registryInput.input.value = containerRegistryInfo.registry;
- repositoryInput.input.value = containerRegistryInfo.repository;
- imageTagInput.input.value = containerRegistryInfo.imageTag;
- }));
-
- let basicSettingsGroup = view.modelBuilder.groupContainer().withItems([clusterNameInput.row, adminUserNameInput.row, adminPasswordInput.row]).withLayout({ header: localize('bdc-create.BasicSettingsText', 'Basic Settings'), collapsible: true }).component();
- let containerSettingsGroup = view.modelBuilder.groupContainer().withItems([registryInput.row, repositoryInput.row, imageTagInput.row, registryUserNameInput.row, registryPasswordInput.row, restoreContainerSettingsButton]).withLayout({ header: localize('bdc-create.ContainerRegistrySettings', 'Container Registry Settings'), collapsible: true }).component();
- let portSettingsGroup = view.modelBuilder.groupContainer().withItems([sqlPortInput.row, knoxPortInput.row, controllerPortInput.row, proxyPortInput.row, grafanaPortInput.row, kibanaPortInput.row, restorePortSettingsButton]).withLayout({ header: localize('bdc-create.PortSettings', 'Port Settings (Optional)'), collapsible: true, collapsed: true }).component();
-
- this.acceptEulaCheckbox = view.modelBuilder.checkBox().component();
- this.acceptEulaCheckbox.checked = false;
-
- let eulaLink: azdata.LinkArea = {
- text: localize('bdc-create.LicenseTerms', 'license terms'),
- url: 'https://go.microsoft.com/fwlink/?LinkId=2002534'
- };
- let privacyPolicyLink: azdata.LinkArea = {
- text: localize('bdc-create.PrivacyPolicyText', 'privacy policy'),
- url: 'https://go.microsoft.com/fwlink/?LinkId=853010'
- };
-
- let checkboxText = view.modelBuilder.text().withProperties({
- value: localize({
- key: 'bdc-create.AcceptTermsText',
- comment: ['{0} is the place holder for license terms, {1} is the place holder for privacy policy']
- }, 'I accept the {0} and {1}.'),
- links: [eulaLink, privacyPolicyLink]
- }).component();
-
- let eulaContainer = this.createRow(view, [this.acceptEulaCheckbox, checkboxText]);
-
- let form = formBuilder.withFormItems([
- {
- title: '',
- component: eulaContainer
- }, {
- title: '',
- component: basicSettingsGroup
- }, {
- title: '',
- component: containerSettingsGroup
- }, {
- title: '',
- component: portSettingsGroup
- }]).component();
- return view.initializeModel(form);
- });
- }
-
- private createInputWithLabel(view: azdata.ModelView, options: {
- label: string,
- isRequiredField: boolean,
- inputWidth: string,
- inputType?: string,
- initialValue?: string,
- placeHolder?: string
- }, textChangedHandler: (inputBox: azdata.InputBoxComponent) => void): { row: azdata.FlexContainer, input: azdata.InputBoxComponent } {
- let inputType = !!options.inputType ? options.inputType : 'text';
- let input = view.modelBuilder.inputBox().withProperties({
- required: options.isRequiredField,
- inputType: inputType
- }).component();
- let text = view.modelBuilder.text().withProperties({ value: options.label }).component();
- input.width = options.inputWidth;
- text.width = '150px';
- input.placeHolder = options.placeHolder;
- this.wizard.registerDisposable(input.onTextChanged(() => {
- textChangedHandler(input);
- }));
- input.value = options.initialValue;
- let row = this.createRow(view, [text, input]);
- return {
- input: input,
- row: row
- };
- }
-
- private createRow(view: azdata.ModelView, items: azdata.Component[]): azdata.FlexContainer {
- return view.modelBuilder.flexContainer().withItems(items, { CSSStyles: { 'margin-right': '5px' } }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/create-cluster/pages/summaryPage.ts b/extensions/big-data-cluster/src/wizards/create-cluster/pages/summaryPage.ts
deleted file mode 100644
index df1821ac58..0000000000
--- a/extensions/big-data-cluster/src/wizards/create-cluster/pages/summaryPage.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import * as azdata from 'azdata';
-import { WizardPageBase } from '../../wizardPageBase';
-import { CreateClusterWizard } from '../createClusterWizard';
-import * as nls from 'vscode-nls';
-
-const localize = nls.loadMessageBundle();
-const LabelWidth = '250px';
-
-export class SummaryPage extends WizardPageBase {
- private view: azdata.ModelView;
- private targetTypeText: azdata.TextComponent;
- private targetClusterContextText: azdata.TextComponent;
- private clusterNameText: azdata.TextComponent;
- private clusterAdminUsernameText: azdata.TextComponent;
- private acceptEulaText: azdata.TextComponent;
- private deploymentProfileText: azdata.TextComponent;
- private sqlServerMasterScaleText: azdata.TextComponent;
- private storagePoolScaleText: azdata.TextComponent;
- private computePoolScaleText: azdata.TextComponent;
- private dataPoolScaleText: azdata.TextComponent;
- private sparkPoolScaleText: azdata.TextComponent;
-
- constructor(wizard: CreateClusterWizard) {
- super(localize('bdc-create.summaryPageTitle', 'Summary'), '', wizard);
- }
-
- protected initialize(view: azdata.ModelView): Thenable {
- this.view = view;
- let targetClusterInfoGroup = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
- let bdcClusterInfoGroup = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
- this.targetTypeText = this.view.modelBuilder.text().component();
- this.targetClusterContextText = this.view.modelBuilder.text().component();
- this.clusterNameText = this.view.modelBuilder.text().component();
- this.clusterAdminUsernameText = this.view.modelBuilder.text().component();
- this.acceptEulaText = this.view.modelBuilder.text().component();
- this.deploymentProfileText = this.view.modelBuilder.text().component();
- this.sqlServerMasterScaleText = this.view.modelBuilder.text().component();
- this.storagePoolScaleText = this.view.modelBuilder.text().component();
- this.computePoolScaleText = this.view.modelBuilder.text().component();
- this.dataPoolScaleText = this.view.modelBuilder.text().component();
- this.sparkPoolScaleText = this.view.modelBuilder.text().component();
- targetClusterInfoGroup.addItem(this.createRow(localize('bdc-create.TargetClusterTypeText', 'Cluster type'), this.targetTypeText));
- targetClusterInfoGroup.addItem(this.createRow(localize('bdc-create.ClusterContextText', 'Cluster context'), this.targetClusterContextText));
-
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.ClusterNameText', 'Cluster name'), this.clusterNameText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.ClusterAdminUsernameText', 'Cluster Admin username'), this.clusterAdminUsernameText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.AcceptEulaText', 'Accept license agreement'), this.acceptEulaText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.DeploymentProfileText', 'Deployment profile'), this.deploymentProfileText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.SqlServerMasterScaleText', 'SQL Server master scale'), this.sqlServerMasterScaleText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.ComputePoolScaleText', 'Compute pool scale'), this.computePoolScaleText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.DataPoolScaleText', 'Data pool scale'), this.dataPoolScaleText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.StoragePoolScaleText', 'Storage pool scale'), this.storagePoolScaleText));
- bdcClusterInfoGroup.addItem(this.createRow(localize('bdc-create.SparkPoolScaleText', 'Spark pool scale'), this.sparkPoolScaleText));
-
- let formBuilder = view.modelBuilder.formContainer();
- let form = formBuilder.withFormItems([{
- title: localize('bdc-create.TargetClusterGroupTitle', 'TARGET CLUSTER'),
- component: targetClusterInfoGroup
- }, {
- title: localize('bdc-create.BigDataClusterGroupTitle', 'SQL SERVER BIG DATA CLUSTER'),
- component: bdcClusterInfoGroup
- }]).component();
-
- return view.initializeModel(form);
- }
-
- public onEnter(): void {
- this.wizard.model.getAllTargetClusterTypeInfo().then((clusterTypes) => {
- let selectedClusterType = clusterTypes.filter(clusterType => clusterType.type === this.wizard.model.targetClusterType)[0];
- this.targetTypeText.value = selectedClusterType.fullName;
- this.targetClusterContextText.value = this.wizard.model.selectedCluster.contextName;
- this.clusterNameText.value = this.wizard.model.clusterName;
- this.clusterAdminUsernameText.value = this.wizard.model.adminUserName;
- this.acceptEulaText.value = localize('bdc-create.YesText', 'Yes');
- this.deploymentProfileText.value = this.wizard.model.profile.name;
- this.sqlServerMasterScaleText.value = this.wizard.model.profile.sqlServerMasterConfiguration.scale.toString();
- this.computePoolScaleText.value = this.wizard.model.profile.computePoolConfiguration.scale.toString();
- this.dataPoolScaleText.value = this.wizard.model.profile.dataPoolConfiguration.scale.toString();
- this.storagePoolScaleText.value = this.wizard.model.profile.storagePoolConfiguration.scale.toString();
- this.sparkPoolScaleText.value = this.wizard.model.profile.sparkPoolConfiguration.scale.toString();
-
- });
- this.wizard.wizardObject.generateScriptButton.hidden = false;
- }
-
- public onLeave(): void {
- this.wizard.wizardObject.generateScriptButton.hidden = true;
- }
-
- private createRow(label: string, textComponent: azdata.TextComponent): azdata.FlexContainer {
- let row = this.view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'baseline' }).component();
- let labelComponent = this.view.modelBuilder.text().withProperties({ value: label }).component();
- labelComponent.width = LabelWidth;
- textComponent.width = LabelWidth;
- row.addItems([labelComponent, textComponent]);
- return row;
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/wizardBase.ts b/extensions/big-data-cluster/src/wizards/wizardBase.ts
deleted file mode 100644
index 724329552d..0000000000
--- a/extensions/big-data-cluster/src/wizards/wizardBase.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as azdata from 'azdata';
-import { ExtensionContext, Disposable } from 'vscode';
-import { WizardPageBase } from './wizardPageBase';
-
-export abstract class WizardBase {
-
- public wizardObject: azdata.window.Wizard;
- private customButtons: azdata.window.Button[];
- private pages: WizardPageBase[];
-
- private toDispose: Disposable[] = [];
-
- constructor(public model: T, public context: ExtensionContext, private title: string) {
- this.customButtons = [];
- }
-
- public open(): Thenable {
- this.wizardObject = azdata.window.createWizard(this.title);
- this.initialize();
- this.wizardObject.customButtons = this.customButtons;
- this.toDispose.push(this.wizardObject.onPageChanged((e) => {
- let previousPage = this.pages[e.lastPage];
- let newPage = this.pages[e.newPage];
- previousPage.onLeave();
- newPage.onEnter();
- }));
-
- this.toDispose.push(this.wizardObject.doneButton.onClick(() => {
- this.onOk();
- this.dispose();
- }));
- this.toDispose.push(this.wizardObject.cancelButton.onClick(() => {
- this.onCancel();
- this.dispose();
- }));
-
- return this.wizardObject.open().then(() => {
- if (this.pages && this.pages.length > 0) {
- this.pages[0].onEnter();
- }
- });
-
- }
-
- protected abstract initialize(): void;
- protected abstract onOk(): void;
- protected abstract onCancel(): void;
-
- public addButton(button: azdata.window.Button) {
- this.customButtons.push(button);
- }
-
- protected setPages(pages: WizardPageBase[]) {
- this.wizardObject.pages = pages.map(p => p.pageObject);
- this.pages = pages;
- }
-
- private dispose() {
- this.toDispose.forEach((disposable: Disposable) => {
- try {
- disposable.dispose();
- }
- catch{ }
- });
- }
-
- public registerDisposable(disposable: Disposable): void {
- this.toDispose.push(disposable);
- }
-}
diff --git a/extensions/big-data-cluster/src/wizards/wizardPageBase.ts b/extensions/big-data-cluster/src/wizards/wizardPageBase.ts
deleted file mode 100644
index 586d8b62ec..0000000000
--- a/extensions/big-data-cluster/src/wizards/wizardPageBase.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the Source EULA. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as azdata from 'azdata';
-
-export abstract class WizardPageBase {
- private _page: azdata.window.WizardPage;
-
- public get pageObject(): azdata.window.WizardPage {
- return this._page;
- }
-
- public get wizard(): T {
- return this._wizard;
- }
-
- constructor(title: string, description: string, private _wizard: T) {
- this._page = azdata.window.createWizardPage(title);
- this._page.description = description;
- this._page.registerContent((view: azdata.ModelView) => {
- return this.initialize(view);
- });
- }
-
- protected abstract initialize(view: azdata.ModelView): Thenable;
-
- public onEnter(): void { }
-
- public onLeave(): void { }
-}
diff --git a/extensions/big-data-cluster/tsconfig.json b/extensions/big-data-cluster/tsconfig.json
index d9fbb41ead..723a00781a 100644
--- a/extensions/big-data-cluster/tsconfig.json
+++ b/extensions/big-data-cluster/tsconfig.json
@@ -1,15 +1,23 @@
{
- "extends": "../shared.tsconfig.json",
+ "compileOnSave": true,
"compilerOptions": {
+ "module": "commonjs",
+ "target": "es6",
"outDir": "./out",
- "strict": false,
- "alwaysStrict": false,
- "noImplicitAny": false,
- "noImplicitReturns": false,
- "noUnusedLocals": false,
- "noUnusedParameters": false
+ "lib": [
+ "es6",
+ "es2015.promise"
+ ],
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "moduleResolution": "node",
+ "declaration": false,
+ "typeRoots": [
+ "./node_modules/@types"
+ ]
},
- "include": [
- "src/**/*"
+ "exclude": [
+ "node_modules"
]
-}
+}
\ No newline at end of file
diff --git a/extensions/big-data-cluster/yarn.lock b/extensions/big-data-cluster/yarn.lock
index 4050ca0812..448db25a99 100644
--- a/extensions/big-data-cluster/yarn.lock
+++ b/extensions/big-data-cluster/yarn.lock
@@ -2,28 +2,71 @@
# yarn lockfile v1
-ansi-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
- integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
+"@types/mocha@^5.2.5":
+ version "5.2.7"
+ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea"
+ integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==
+
+"@types/node@^8.0.24":
+ version "8.10.49"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.49.tgz#f331afc5efed0796798e5591d6e0ece636969b7b"
+ integrity sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==
+
+agent-base@4, agent-base@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
+ integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
+ dependencies:
+ es6-promisify "^5.0.0"
+
+ajv@^6.5.5:
+ version "6.10.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
+ integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
+ dependencies:
+ fast-deep-equal "^2.0.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
+asn1@~0.2.3:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
+ integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
+ dependencies:
+ safer-buffer "~2.1.0"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+ integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+
+aws-sign2@~0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+ integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
+
+aws4@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
+ integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-base64-js@^1.0.2:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
- integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==
-
-bl@^1.0.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
- integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+ integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
- readable-stream "^2.3.5"
- safe-buffer "^5.1.1"
+ tweetnacl "^0.14.3"
brace-expansion@^1.1.7:
version "1.1.11"
@@ -33,93 +76,59 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
-buffer-alloc-unsafe@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
- integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
+browser-stdout@1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
+ integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
-buffer-alloc@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
- integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
+buffer-from@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
+ integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+ integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+
+circular-json@^0.3.1:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
+ integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
+
+combined-stream@^1.0.6, combined-stream@~1.0.6:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
+ integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
- buffer-alloc-unsafe "^1.1.0"
- buffer-fill "^1.0.0"
+ delayed-stream "~1.0.0"
-buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-buffer-fill@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
- integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
-
-buffer@^5.2.1:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6"
- integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
-
-caw@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95"
- integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==
- dependencies:
- get-proxy "^2.0.0"
- isurl "^1.0.0-alpha5"
- tunnel-agent "^0.6.0"
- url-to-options "^1.0.1"
-
-charenc@~0.0.1:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
- integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
-
-commander@~2.8.1:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4"
- integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=
- dependencies:
- graceful-readlink ">= 1.0.0"
+commander@2.15.1:
+ version "2.15.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
+ integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-config-chain@^1.1.11:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-content-disposition@^0.5.2:
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
- integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
- dependencies:
- safe-buffer "5.1.2"
-
-core-util-is@~1.0.0:
+core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-crypt@~0.0.1:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
- integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
+ dependencies:
+ assert-plus "^1.0.0"
-debug@^2.2.0:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+debug@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
@@ -130,185 +139,96 @@ debug@^3.1.0:
dependencies:
ms "^2.1.1"
-decompress-response@^3.2.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+
+diff@3.5.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
+ integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
+
+ecc-jsbn@~0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
+ integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
- mimic-response "^1.0.0"
+ jsbn "~0.1.0"
+ safer-buffer "^2.1.0"
-decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1"
- integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==
+es6-promise@^4.0.3:
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
+ integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+
+es6-promisify@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
+ integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
dependencies:
- file-type "^5.2.0"
- is-stream "^1.1.0"
- tar-stream "^1.5.2"
+ es6-promise "^4.0.3"
-decompress-tarbz2@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b"
- integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==
- dependencies:
- decompress-tar "^4.1.0"
- file-type "^6.1.0"
- is-stream "^1.1.0"
- seek-bzip "^1.0.5"
- unbzip2-stream "^1.0.9"
-
-decompress-targz@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee"
- integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==
- dependencies:
- decompress-tar "^4.1.1"
- file-type "^5.2.0"
- is-stream "^1.1.0"
-
-decompress-unzip@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69"
- integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k=
- dependencies:
- file-type "^3.8.0"
- get-stream "^2.2.0"
- pify "^2.3.0"
- yauzl "^2.4.2"
-
-decompress@^4.0.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d"
- integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=
- dependencies:
- decompress-tar "^4.0.0"
- decompress-tarbz2 "^4.0.0"
- decompress-targz "^4.0.0"
- decompress-unzip "^4.0.1"
- graceful-fs "^4.1.10"
- make-dir "^1.0.0"
- pify "^2.3.0"
- strip-dirs "^2.0.0"
-
-download@^6.2.5:
- version "6.2.5"
- resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714"
- integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==
- dependencies:
- caw "^2.0.0"
- content-disposition "^0.5.2"
- decompress "^4.0.0"
- ext-name "^5.0.0"
- file-type "5.2.0"
- filenamify "^2.0.0"
- get-stream "^3.0.0"
- got "^7.0.0"
- make-dir "^1.0.0"
- p-event "^1.0.0"
- pify "^3.0.0"
-
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-end-of-stream@^1.0.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
- integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
- dependencies:
- once "^1.4.0"
-
-escape-string-regexp@^1.0.2:
+escape-string-regexp@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-ext-list@^2.0.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37"
- integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==
- dependencies:
- mime-db "^1.28.0"
+extend@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+ integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
-ext-name@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6"
- integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==
- dependencies:
- ext-list "^2.0.0"
- sort-keys-length "^1.0.0"
+extsprintf@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+ integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
-fd-slicer@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
- dependencies:
- pend "~1.2.0"
+extsprintf@^1.2.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+ integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
-file-type@5.2.0, file-type@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6"
- integrity sha1-LdvqfHP/42No365J3DOMBYwritY=
+fast-deep-equal@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
+ integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
-file-type@^3.8.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
- integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
-
-file-type@^6.1.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919"
- integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==
-
-filename-reserved-regex@^2.0.0:
+fast-json-stable-stringify@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229"
- integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik=
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+ integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
-filenamify@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9"
- integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+ integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+
+form-data@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
+ integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
- filename-reserved-regex "^2.0.0"
- strip-outer "^1.0.0"
- trim-repeated "^1.0.0"
-
-fs-constants@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
- integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-get-proxy@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93"
- integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
- npm-conf "^1.1.0"
+ assert-plus "^1.0.0"
-get-stream@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
- integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=
- dependencies:
- object-assign "^4.0.1"
- pinkie-promise "^2.0.0"
-
-get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
-glob@^7.0.0:
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
- integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
+glob@7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+ integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
@@ -317,52 +237,70 @@ glob@^7.0.0:
once "^1.3.0"
path-is-absolute "^1.0.0"
-got@^7.0.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
- integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==
+glob@^7.1.2:
+ version "7.1.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
+ integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
dependencies:
- decompress-response "^3.2.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-plain-obj "^1.1.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- isurl "^1.0.0-alpha5"
- lowercase-keys "^1.0.0"
- p-cancelable "^0.3.0"
- p-timeout "^1.1.1"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- url-parse-lax "^1.0.0"
- url-to-options "^1.0.1"
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
-graceful-fs@^4.1.10:
- version "4.1.15"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
- integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
+growl@1.10.5:
+ version "1.10.5"
+ resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
+ integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
-"graceful-readlink@>= 1.0.0":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
- integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
+har-schema@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+ integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-has-symbol-support-x@^1.4.1:
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
- integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-
-has-to-string-tag-x@^1.2.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
- integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
+har-validator@~5.1.0:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
+ integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
dependencies:
- has-symbol-support-x "^1.4.1"
+ ajv "^6.5.5"
+ har-schema "^2.0.0"
-ieee754@^1.1.4:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
- integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+ integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+
+he@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
+ integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
+
+http-proxy-agent@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
+ integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
+ dependencies:
+ agent-base "4"
+ debug "3.1.0"
+
+http-signature@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+ integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+ dependencies:
+ assert-plus "^1.0.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+https-proxy-agent@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
+ integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==
+ dependencies:
+ agent-base "^4.1.0"
+ debug "^3.1.0"
inflight@^1.0.4:
version "1.0.6"
@@ -372,101 +310,69 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@~2.0.3:
+inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-ini@^1.3.4:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
- integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
-
-interpret@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
- integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
-
-is-buffer@~1.1.1:
- version "1.1.6"
- resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
- integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-
-is-natural-number@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
- integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
-
-is-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
- integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
-
-is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
- integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
-
-is-retry-allowed@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
- integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=
-
-is-stream@^1.0.0, is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
- integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
-
-isarray@~1.0.0:
+is-typedarray@~1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+ integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-isurl@^1.0.0-alpha5:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
- integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+ integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+ integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+
+json-schema-traverse@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+ integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+ integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+ integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+
+jsprim@^1.2.2:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+ integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
- has-to-string-tag-x "^1.2.0"
- is-object "^1.0.1"
+ assert-plus "1.0.0"
+ extsprintf "1.3.0"
+ json-schema "0.2.3"
+ verror "1.10.0"
-lodash@^4.16.4:
+lodash@^4.17.4:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
-lowercase-keys@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
- integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
+mime-db@1.40.0:
+ version "1.40.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
+ integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
-make-dir@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
- integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
+mime-types@^2.1.12, mime-types@~2.1.19:
+ version "2.1.24"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
+ integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
dependencies:
- pify "^3.0.0"
+ mime-db "1.40.0"
-md5@^2.1.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
- integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
- dependencies:
- charenc "~0.0.1"
- crypt "~0.0.1"
- is-buffer "~1.1.1"
-
-mime-db@^1.28.0:
- version "1.38.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
- integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
-
-mimic-response@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-minimatch@^3.0.4:
+minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -478,31 +384,29 @@ minimist@0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-mkdirp@~0.5.1:
+mkdirp@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
-mocha-junit-reporter@^1.17.0:
- version "1.18.0"
- resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.18.0.tgz#9209a3fba30025ae3ae5e6bfe7f9c5bc3c2e8ee2"
- integrity sha512-y3XuqKa2+HRYtg0wYyhW/XsLm2Ps+pqf9HaTAt7+MVUAKFJaNAHOrNseTZo9KCxjfIbxUWwckP5qCDDPUmjSWA==
+mocha@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6"
+ integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
dependencies:
- debug "^2.2.0"
- md5 "^2.1.0"
- mkdirp "~0.5.1"
- strip-ansi "^4.0.0"
- xml "^1.0.0"
-
-mocha-multi-reporters@^1.1.7:
- version "1.1.7"
- resolved "https://registry.yarnpkg.com/mocha-multi-reporters/-/mocha-multi-reporters-1.1.7.tgz#cc7f3f4d32f478520941d852abb64d9988587d82"
- integrity sha1-zH8/TTL0eFIJQdhSq7ZNmYhYfYI=
- dependencies:
- debug "^3.1.0"
- lodash "^4.16.4"
+ browser-stdout "1.3.1"
+ commander "2.15.1"
+ debug "3.1.0"
+ diff "3.5.0"
+ escape-string-regexp "1.0.5"
+ glob "7.1.2"
+ growl "1.10.5"
+ he "1.1.1"
+ minimatch "3.0.4"
+ mkdirp "0.5.1"
+ supports-color "5.4.0"
ms@2.0.0:
version "2.0.0"
@@ -510,230 +414,194 @@ ms@2.0.0:
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
- integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+ integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-npm-conf@^1.1.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
- integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
- dependencies:
- config-chain "^1.1.11"
- pify "^3.0.0"
+oauth-sign@~0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
+ integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-object-assign@^4.0.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-once@^1.3.0, once@^1.4.0:
+once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
-p-cancelable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
- integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
-
-p-event@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085"
- integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=
- dependencies:
- p-timeout "^1.1.1"
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
- integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-timeout@^1.1.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
- integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=
- dependencies:
- p-finally "^1.0.0"
-
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-path-parse@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
- integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
+performance-now@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+ integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
+postinstall-build@^5.0.1:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
+ integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
-pify@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
+psl@^1.1.24:
+ version "1.1.32"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.32.tgz#3f132717cf2f9c169724b2b6caf373cf694198db"
+ integrity sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==
-pify@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
- integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+ integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-pinkie-promise@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
- integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
+punycode@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+ integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
+qs@~6.5.2:
+ version "6.5.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
+ integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
+
+querystringify@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
+ integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
+
+request@^2.88.0:
+ version "2.88.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
+ integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
dependencies:
- pinkie "^2.0.0"
+ aws-sign2 "~0.7.0"
+ aws4 "^1.8.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.6"
+ extend "~3.0.2"
+ forever-agent "~0.6.1"
+ form-data "~2.3.2"
+ har-validator "~5.1.0"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.19"
+ oauth-sign "~0.9.0"
+ performance-now "^2.1.0"
+ qs "~6.5.2"
+ safe-buffer "^5.1.2"
+ tough-cookie "~2.4.3"
+ tunnel-agent "^0.6.0"
+ uuid "^3.3.2"
-pinkie@^2.0.0:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
- integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+ integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
-prepend-http@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
- integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
-
-process-nextick-args@~2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
- integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
-
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
-readable-stream@^2.3.0, readable-stream@^2.3.5:
- version "2.3.6"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
- integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-rechoir@^0.6.2:
- version "0.6.2"
- resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
- integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
- dependencies:
- resolve "^1.1.6"
-
-resolve@^1.1.6:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
- integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==
- dependencies:
- path-parse "^1.0.6"
-
-safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-seek-bzip@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc"
- integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=
+safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
+semver@^5.4.1:
+ version "5.7.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
+ integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
+
+should-equal@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3"
+ integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==
dependencies:
- commander "~2.8.1"
+ should-type "^1.4.0"
-shelljs@^0.8.3:
- version "0.8.3"
- resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097"
- integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==
+should-format@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1"
+ integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE=
dependencies:
- glob "^7.0.0"
- interpret "^1.0.0"
- rechoir "^0.6.2"
+ should-type "^1.3.0"
+ should-type-adaptors "^1.0.1"
-sort-keys-length@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188"
- integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=
+should-type-adaptors@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a"
+ integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==
dependencies:
- sort-keys "^1.0.0"
+ should-type "^1.3.0"
+ should-util "^1.0.0"
-sort-keys@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
- integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0=
- dependencies:
- is-plain-obj "^1.0.0"
+should-type@^1.3.0, should-type@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3"
+ integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-strip-ansi@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
- integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
- dependencies:
- ansi-regex "^3.0.0"
-
-strip-dirs@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5"
- integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==
- dependencies:
- is-natural-number "^4.0.1"
-
-strip-outer@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631"
- integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==
- dependencies:
- escape-string-regexp "^1.0.2"
-
-tar-stream@^1.5.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
- integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
- dependencies:
- bl "^1.0.0"
- buffer-alloc "^1.2.0"
- end-of-stream "^1.0.0"
- fs-constants "^1.0.0"
- readable-stream "^2.3.0"
- to-buffer "^1.1.1"
- xtend "^4.0.0"
-
-through@^2.3.8:
- version "2.3.8"
- resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
- integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
-
-timed-out@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
- integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
-
-to-buffer@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
- integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
-
-trim-repeated@^1.0.0:
+should-util@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21"
- integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE=
+ resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063"
+ integrity sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=
+
+should@^13.2.1:
+ version "13.2.3"
+ resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10"
+ integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==
dependencies:
- escape-string-regexp "^1.0.2"
+ should-equal "^2.0.0"
+ should-format "^3.0.3"
+ should-type "^1.4.0"
+ should-type-adaptors "^1.0.1"
+ should-util "^1.0.0"
+
+source-map-support@^0.5.0:
+ version "0.5.12"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
+ integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map@^0.6.0:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+sshpk@^1.7.0:
+ version "1.16.1"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
+ integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ bcrypt-pbkdf "^1.0.0"
+ dashdash "^1.12.0"
+ ecc-jsbn "~0.1.1"
+ getpass "^0.1.1"
+ jsbn "~0.1.0"
+ safer-buffer "^2.0.2"
+ tweetnacl "~0.14.0"
+
+supports-color@5.4.0:
+ version "5.4.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
+ integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==
+ dependencies:
+ has-flag "^3.0.0"
+
+tough-cookie@~2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
+ integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
+ dependencies:
+ psl "^1.1.24"
+ punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
@@ -742,55 +610,76 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
-unbzip2-stream@^1.0.9:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a"
- integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+ integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+
+typemoq@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/typemoq/-/typemoq-2.1.0.tgz#4452ce360d92cf2a1a180f0c29de2803f87af1e8"
+ integrity sha512-DtRNLb7x8yCTv/KHlwes+NI+aGb4Vl1iPC63Hhtcvk1DpxSAZzKWQv0RQFY0jX2Uqj0SDBNl8Na4e6MV6TNDgw==
dependencies:
- buffer "^5.2.1"
- through "^2.3.8"
+ circular-json "^0.3.1"
+ lodash "^4.17.4"
+ postinstall-build "^5.0.1"
-url-parse-lax@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
- integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
+uri-js@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
+ integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
dependencies:
- prepend-http "^1.0.1"
+ punycode "^2.1.0"
-url-to-options@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
- integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
+url-parse@^1.4.4:
+ version "1.4.7"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
+ integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
+ dependencies:
+ querystringify "^2.1.1"
+ requires-port "^1.0.0"
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+uuid@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
+ integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
-vscode-nls@^3.2.1:
- version "3.2.5"
- resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.5.tgz#25520c1955108036dec607c85e00a522f247f1a4"
- integrity sha512-ITtoh3V4AkWXMmp3TB97vsMaHRgHhsSFPsUdzlueSL+dRZbSNTZeOmdQv60kjCV306ghPxhDeoNUEm3+EZMuyw==
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+ integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
+ dependencies:
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
+
+vscode-nls@^4.0.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"
+ integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==
+
+vscode-test@^0.4.1:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8"
+ integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==
+ dependencies:
+ http-proxy-agent "^2.1.0"
+ https-proxy-agent "^2.2.1"
+
+vscode@^1.1.26:
+ version "1.1.35"
+ resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.35.tgz#f8c6beb905738b874d539ddb3784e5feeec71c0a"
+ integrity sha512-xPnxzQU40LOS2yPyzWW+WKpTV6qA3z16TcgpZ9O38UWLA157Zz4GxUx5H7Gd07pxzw0GqvusbF4D+5GBgNxvEQ==
+ dependencies:
+ glob "^7.1.2"
+ mocha "^5.2.0"
+ request "^2.88.0"
+ semver "^5.4.1"
+ source-map-support "^0.5.0"
+ url-parse "^1.4.4"
+ vscode-test "^0.4.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-xml@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
- integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
-
-xtend@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
- integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
-
-yauzl@^2.4.2:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
- integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.1.0"