import { SubscriptionClient , SubscriptionModels } from '@azure/arm-subscriptions' ; import { Environment } from '@azure/ms-rest-azure-env' ; import { ApplicationTokenCredentials , loginWithServicePrincipalSecret } from '@azure/ms-rest-nodeauth' ; import { Event , EventEmitter } from 'vscode' ; import * as types from '../index' ; import { AzureAccount , AzureLoginStatus , AzureResourceFilter , AzureSession , AzureSubscription } from './@types/azure-account.api' ; import { nonNullProp , nonNullValue } from './utils/nonNull' ; export class TestAzureAccount implements AzureAccount , types . TestAzureAccount { public status : AzureLoginStatus = 'LoggedOut' ; public onStatusChanged : Event < AzureLoginStatus > ; public sessions : AzureSession [ ] = [ ] ; public onSessionsChanged : Event < void > ; public subscriptions : AzureSubscription [ ] = [ ] ; public onSubscriptionsChanged : Event < void > ; public filters : AzureResourceFilter [ ] = [ ] ; public onFiltersChanged : Event < void > ; private readonly _onStatusChangedEmitter : EventEmitter < AzureLoginStatus > ; private readonly _onFiltersChangedEmitter : EventEmitter < void > ; private readonly _onSessionsChangedEmitter : EventEmitter < void > ; private readonly _onSubscriptionsChangedEmitter : EventEmitter < void > ; public constructor ( vscode ) { this . _onStatusChangedEmitter = new vscode . EventEmitter < AzureLoginStatus > ( ) ; this . onStatusChanged = this . _onStatusChangedEmitter . event ; this . _onFiltersChangedEmitter = new vscode . EventEmitter < void > ( ) ; this . onFiltersChanged = this . _onFiltersChangedEmitter . event ; this . _onSessionsChangedEmitter = new vscode . EventEmitter < void > ( ) ; this . onSessionsChanged = this . _onSessionsChangedEmitter . event ; this . _onSubscriptionsChangedEmitter = new vscode . EventEmitter < void > ( ) ; this . onSubscriptionsChanged = this . _onSubscriptionsChangedEmitter . event ; } public async signIn ( ) { type servicePrincipalCredentials = ApplicationTokenCredentials & { environment : Environment ; } ; const clientId = process . env . SERVICE_PRINCIPAL_CLIENT_ID ; const secret = process . env . SERVICE_PRINCIPAL_SECRET ; const domain = process . env . SERVICE_PRINCIPAL_DOMAIN ; if ( ! clientId || ! secret || ! domain ) { throw new Error ( 'TestAzureAccount cannot be used without the following environment variables: SERVICE_PRINCIPAL_CLIENT_ID, SERVICE_PRINCIPAL_SECRET, SERVICE_PRINCIPAL_DOMAIN' ) ; } this . changeStatus ( 'LoggingIn' ) ; const credentials = < servicePrincipalCredentials > ( await loginWithServicePrincipalSecret ( clientId , secret , domain ) ) ; const subscriptionClient = new SubscriptionClient ( credentials ) ; const subscriptions = await subscriptionClient . subscriptions . list ( ) ; const tenants = await subscriptionClient . tenants . list ( ) ; const tenantId = nonNullProp ( nonNullValue ( tenants [ 0 ] ) , 'id' ) ; const session = { environment : credentials . environment , userId : '' , tenantId : tenantId , credentials2 : credentials } ; const testAzureSubscription = { session : session , subscription : nonNullValue ( subscriptions [ 0 ] ) } ; this . subscriptions . push ( testAzureSubscription ) ; this . changeStatus ( 'LoggedIn' ) ; this . changeFilter ( testAzureSubscription ) ; } public signOut ( ) { this . changeStatus ( 'LoggedOut' ) ; this . changeFilter ( ) ; this . subscriptions = [ ] ; } public getSubscriptionContext ( ) { this . verifySubscription ( ) ; const info = this . subscriptions [ 0 ] ; return { credentials : info . session . credentials2 , subscriptionDisplayName : nonNullProp ( info . subscription , 'displayName' ) , subscriptionId : nonNullProp ( info . subscription , 'subscriptionId' ) , subscriptionPath : nonNullProp ( info . subscription , 'id' ) , tenantId : info . session . tenantId , userId : info . session . userId , environment : info . session . environment , isCustomCloud : false } ; } public async waitForLogin ( ) { return true ; } public async waitForSubscriptions ( ) { return true ; } public async waitForFilters ( ) { return true ; } private changeStatus ( newStatus ) { this . status = newStatus ; this . _onStatusChangedEmitter . fire ( this . status ) ; } private changeFilter ( newFilter ? ) { if ( newFilter ) { this . filters . push ( newFilter ) ; } else { this . filters = [ ] ; } this . _onFiltersChangedEmitter . fire ( ) ; } private verifySubscription ( ) { if ( this . subscriptions . length === 0 ) { const noSubscription = 'No subscription found.  Invoke TestAzureAccount.signIn().' ; throw new Error ( noSubscription ) ; } } }