'use strict' ; import * as vscode from 'vscode' ; import * as sinon from 'sinon' ; import * as path from 'path' ; import * as fs from 'fs-extra' ; import * as chai from 'chai' ; import * as sinonChai from 'sinon-chai' ; import * as chaiAsPromised from 'chai-as-promised' ; import { UserInputUtilHelper } from './userInputUtilHelper' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { BlockchainEnvironmentExplorerProvider } from '../../extension/explorer/environmentExplorer' ; import { UserInputUtil , IBlockchainQuickPickItem } from '../../extension/commands/UserInputUtil' ; import { FabricEnvironmentRegistry , FabricEnvironmentRegistryEntry , FabricNode , FabricWalletRegistry , FabricWalletRegistryEntry , FabricEnvironment , FabricNodeType , FileConfigurations } from 'ibm-blockchain-platform-common' ; import { ExtensionUtil } from '../../extension/util/ExtensionUtil' ; import { EnvironmentFactory } from '../../extension/fabric/environments/EnvironmentFactory' ; import { ModuleUtilHelper } from './moduleUtilHelper' ; import { FabricEnvironmentTreeItem } from '../../extension/explorer/runtimeOps/disconnectedTree/FabricEnvironmentTreeItem' ; import { ExtensionsInteractionUtilHelper } from './extensionsInteractionUtilHelper' ; import { EnvironmentGroupTreeItem } from '../../extension/explorer/runtimeOps/EnvironmentGroupTreeItem' ; chai . use ( sinonChai ) ; chai . use ( chaiAsPromised ) ; export class EnvironmentHelper { mySandBox : sinon . SinonSandbox ; userInputUtilHelper : UserInputUtilHelper ; moduleUtilHelper : ModuleUtilHelper ; extensionsInteractionUtilHelper : ExtensionsInteractionUtilHelper ; constructor ( sandbox , userInputUtilHelper , moduleUtilHelper , extensionsInteractionUtilHelper ) { this . mySandBox = sandbox ; this . userInputUtilHelper = userInputUtilHelper ; this . moduleUtilHelper = moduleUtilHelper ; this . extensionsInteractionUtilHelper = extensionsInteractionUtilHelper ; } public async createEnvironment ( name , opsType ? , createLocal ? , capability = UserInputUtil . V2_0 ) { let treeItem ; const blockchainEnvironmentExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const treeItems = await blockchainEnvironmentExplorerProvider . getChildren ( ) as EnvironmentGroupTreeItem [ ] ; const allChildren = [ ] ; for ( const item of treeItems ) { const children = await blockchainEnvironmentExplorerProvider . getChildren ( item ) as FabricEnvironmentTreeItem [ ] ; allChildren . push ( ... children ) ; } treeItem = allChildren . find ( ( item ) => { return item . label === name ; } ) ; if ( ! treeItem ) { this . userInputUtilHelper . inputBoxStub . withArgs ( 'Enter a name for the environment' ) . resolves ( name ) ; if ( process . env . OPSTOOLS_FABRIC ) { this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Select a method to add an environment' ) . resolves ( { data : UserInputUtil . ADD_ENVIRONMENT_FROM_OPS_TOOLS } ) ; if ( opsType === 'SaaS' ) { this . userInputUtilHelper . showYesNoQuickPick . withArgs ( 'Are you connecting to an IBM Blockchain Platform service instance on IBM Cloud?' ) . resolves ( UserInputUtil . YES ) ; const callCount = await this . extensionsInteractionUtilHelper . cloudAccountGetIbpResourcesStub . callCount - 1 ; const instances = await this . extensionsInteractionUtilHelper . cloudAccountGetIbpResourcesStub . getCalls ( ) [ callCount ] . returnValue ; const instance = instances . find ( ( _instance ) => _instance . name === 'VSCodeSaasOps' ) ; if ( ! instance ) { throw new Error ( 'Could not find "VSCodeSaasOps" saas instance.' ) ; } this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Select an IBM Blockchain Platform service instance' ) . resolves ( { label : instance . name , description : instance . guid , data : instance } ) ; } else if ( opsType === 'software' ) { this . userInputUtilHelper . showYesNoQuickPick . withArgs ( 'Are you connecting to an IBM Blockchain Platform service instance on IBM Cloud?' ) . resolves ( UserInputUtil . NO ) ; this . userInputUtilHelper . inputBoxStub . withArgs ( 'Enter the URL of the IBM Blockchain Platform Console you want to connect to' ) . resolves ( process . env . MAP_OPSTOOLS_URL ) ; this . userInputUtilHelper . inputBoxStub . withArgs ( 'Enter the API key or the User ID of the IBM Blockchain Platform Console you want to connect to' ) . resolves ( process . env . MAP_OPSTOOLS_KEY ) ; this . userInputUtilHelper . inputBoxStub . withArgs ( 'Enter the API secret or the password of the IBM Blockchain Platform Console you want to connect to' ) . resolves ( process . env . MAP_OPSTOOLS_SECRET ) ; this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Unable to perform certificate verification. Please choose how to proceed' , [ { label : UserInputUtil . CONNECT_NO_CA_CERT_CHAIN , data : UserInputUtil . CONNECT_NO_CA_CERT_CHAIN } , { label : UserInputUtil . CANCEL_NO_CERT_CHAIN , data : UserInputUtil . CANCEL_NO_CERT_CHAIN , description : UserInputUtil . CANCEL_NO_CERT_CHAIN_DESCRIPTION } ] ) . resolves ( { label : UserInputUtil . CONNECT_NO_CA_CERT_CHAIN , data : UserInputUtil . CONNECT_NO_CA_CERT_CHAIN } ) ; } this . userInputUtilHelper . opsToolsNodeQuickPickStub . resolves ( [ ] ) ; } else if ( process . env . TWO_ORG_FABRIC ) { this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Select a method to add an environment' ) . resolves ( { data : UserInputUtil . ADD_ENVIRONMENT_FROM_TEMPLATE } ) ; this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Choose a configuration for a new local network' ) . resolves ( { data : 2 } ) ; this . userInputUtilHelper . selectCapabilitiesStub . withArgs ( 'Select the channel capability version to use for the network' ) . resolves ( capability ) ; } else if ( createLocal ) { this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Select a method to add an environment' ) . resolves ( { data : UserInputUtil . ADD_ENVIRONMENT_FROM_TEMPLATE } ) ; this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Choose a configuration for a new local network' ) . resolves ( { data : 1 } ) ; this . userInputUtilHelper . selectCapabilitiesStub . withArgs ( 'Select the channel capability version to use for the network' ) . resolves ( capability ) ; } else { this . userInputUtilHelper . showQuickPickItemStub . withArgs ( 'Select a method to add an environment' ) . resolves ( { data : UserInputUtil . ADD_ENVIRONMENT_FROM_NODES } ) ; const caUri = vscode . Uri . file ( path . join ( this . userInputUtilHelper . cucumberDir , 'hlfv1' , 'nodes' , 'ca.example.com.json' ) ) ; const ordererUri = vscode . Uri . file ( path . join ( this . userInputUtilHelper . cucumberDir , 'hlfv1' , 'nodes' , 'orderer.example.com.json' ) ) ; const peerUri = vscode . Uri . file ( path . join ( this . userInputUtilHelper . cucumberDir , 'hlfv1' , 'nodes' , 'peer0.org1.example.com.json' ) ) ; const nodes = [ caUri , ordererUri , peerUri ] ; this . userInputUtilHelper . browseStub . withArgs ( 'Select all the Fabric node (JSON) files you want to import' ) . resolves ( nodes ) ; this . userInputUtilHelper . addMoreNodesStub . resolves ( UserInputUtil . DONE_ADDING_NODES ) ; } await vscode . commands . executeCommand ( ExtensionCommands . ADD_ENVIRONMENT ) ; if ( process . env . OPSTOOLS_FABRIC ) { if ( opsType === 'SaaS' ) { this . extensionsInteractionUtilHelper . cloudAccountGetAccessTokenStub . called . should . equal ( true ) ; } else { this . moduleUtilHelper . setPasswordStub . called . should . equal ( true ) ; this . moduleUtilHelper . getPasswordStub . called . should . equal ( true ) ; } this . userInputUtilHelper . opsToolsNodeQuickPickStub . called . should . equal ( true ) ; const call = this . userInputUtilHelper . opsToolsNodeQuickPickStub . getCall ( 0 ) ; return call . args [ 0 ] ; } } else { if ( process . env . OPSTOOLS_FABRIC ) { const env = EnvironmentFactory . getEnvironment ( treeItem . environmentRegistryEntry ) ; const nodes = await env . getNodes ( false , true ) ; const items = new Set < IBlockchainQuickPickItem < FabricNode > > ( ) ; for ( const node of nodes ) { if ( node . type === FabricNodeType . ORDERER ) { items . add ( { label : node . cluster_name , data : node } ) ; } else { items . add ( { label : node . name , data : node } ) ; } } return Array . from ( items ) ; } } return [ ] ; } public async deleteNode ( nodeName , environmentName ) { this . userInputUtilHelper . showConfirmationWarningMessageStub . resolves ( true ) ; const fabricEnvironmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environmentName ) ; this . userInputUtilHelper . showEnvironmentQuickPickStub . resolves ( { label : environmentName , data : fabricEnvironmentRegistryEntry } ) ; const environment = EnvironmentFactory . getEnvironment ( fabricEnvironmentRegistryEntry ) ; const nodes = await environment . getNodes ( ) ; const node = nodes . find ( ( _node ) => { return _node . name === nodeName ; } ) ; this . userInputUtilHelper . showNodesInEnvironmentQuickPickStub . resolves ( [ { label : nodeName , data : node } ] ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_NODE ) ; } public async hideNode ( nodeName , environmentName ) { this . userInputUtilHelper . showConfirmationWarningMessageStub . resolves ( true ) ; const fabricEnvironmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environmentName ) ; this . userInputUtilHelper . showEnvironmentQuickPickStub . resolves ( { label : environmentName , data : fabricEnvironmentRegistryEntry } ) ; const environment = EnvironmentFactory . getEnvironment ( fabricEnvironmentRegistryEntry ) ; const nodes = await environment . getNodes ( ) ; const node = nodes . find ( ( _node ) => { return _node . name === nodeName ; } ) ; this . userInputUtilHelper . showNodesInEnvironmentQuickPickStub . resolves ( [ { label : nodeName , data : node } ] ) ; await vscode . commands . executeCommand ( ExtensionCommands . HIDE_NODE ) ; } public async deleteEnvironment ( environmentName ) { this . userInputUtilHelper . showConfirmationWarningMessageStub . resolves ( true ) ; const fabricEnvironmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environmentName ) ; this . userInputUtilHelper . showEnvironmentQuickPickStub . resolves ( [ { label : environmentName , data : fabricEnvironmentRegistryEntry } ] ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; } public async associateNodeWithIdentitiy ( environmentName , nodeName , identityName , walletName , mspId = 'Org1MSP' ) { const walletReigstryEntry = await FabricWalletRegistry . instance ( ) . get ( walletName , environmentName ) ; this . userInputUtilHelper . showWalletsQuickPickStub . resolves ( { label : walletName , data : walletReigstryEntry } ) ; this . userInputUtilHelper . showIdentitiesQuickPickStub . resolves ( identityName ) ; this . userInputUtilHelper . showQuickPickStub . resolves ( 'Use ID and secret to enroll a new identity' ) ; this . userInputUtilHelper . showYesNoQuickPick . withArgs ( 'Do you want to associate the same identity with another node?' ) . resolves ( UserInputUtil . NO ) ; this . userInputUtilHelper . inputBoxStub . withArgs ( 'Provide a name for the identity' ) . resolves ( identityName ) ; this . userInputUtilHelper . inputBoxStub . withArgs ( 'Enter MSPID' ) . resolves ( mspId ) ; const nodePath = path . join ( this . userInputUtilHelper . cucumberDir , 'tmp' , 'v2' , FileConfigurations . FABRIC_ENVIRONMENTS , environmentName , 'nodes' , `${ nodeName }.json` ) ; const node = await fs . readJson ( nodePath ) ; if ( node . identity && node . wallet ) { return ; } const environmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environmentName ) ; await vscode . commands . executeCommand ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE , environmentRegistryEntry , node ) ; } public async connectToEnvironment ( environment ) { const registryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environment ) ; await vscode . commands . executeCommand ( ExtensionCommands . CONNECT_TO_ENVIRONMENT , registryEntry ) ; } public async editNodeFilters ( nodesToImport , environmentName ) { const environmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( environmentName ) ; this . userInputUtilHelper . showEnvironmentQuickPickStub . resolves ( { label : environmentName , data : environmentRegistryEntry } ) ; this . userInputUtilHelper . opsToolsNodeQuickPickStub . resolves ( nodesToImport ) ; await ExtensionUtil . executeCommandInternal ( ExtensionCommands . EDIT_NODE_FILTERS , undefined , false , UserInputUtil . ADD_ENVIRONMENT_FROM_OPS_TOOLS ) ; const environment = EnvironmentFactory . getEnvironment ( environmentRegistryEntry ) ; const nodes = await environment . getNodes ( ) ; nodes . length . should . equal ( nodesToImport . length ) ; } }