import { Client } from 'elasticsearch' ; import { get } from 'lodash' ; import { LegacyOpenSearchErrorHelpers } from './errors' ; import { GetAuthHeaders , OpenSearchDashboardsRequest , isOpenSearchDashboardsRequest , isRealRequest , } from '../../http' ; import { AuditorFactory } from '../../audit_trail' ; import { filterHeaders , ensureRawRequest } from '../../http/router' ; import { Logger } from '../../logging' ; import { ScopeableRequest } from '../types' ; import { LegacyOpenSearchClientConfig , parseOpenSearchClientConfig , } from './opensearch_client_config' ; import { LegacyScopedClusterClient , ILegacyScopedClusterClient } from './scoped_cluster_client' ; import { LegacyCallAPIOptions , LegacyAPICaller } from './api_types' ; public const noop = ( ) => undefined ; param client param endpoint param clientParams param options const callAPI = async ( client , endpoint , clientParams = { } , options = { wrap401Errors : true } ) => { const clientPath = endpoint . split ( '.' ) ; const api = get ( client , clientPath ) ; if ( ! api ) { throw new Error ( `called with an invalid endpoint: ${ endpoint }` ) ; } const apiContext = clientPath . length === 1 ? client : get ( client , clientPath . slice ( 0 , - 1 ) ) ; try { return await new Promise ( ( resolve , reject ) => { const request = api . call ( apiContext , clientParams ) ; if ( options . signal ) { options . signal . addEventListener ( 'abort' , ( ) => { request . abort ( ) ; reject ( new Error ( 'Request was aborted' ) ) ; } ) ; } return request . then ( resolve , reject ) ; } ) ; } catch ( err ) { if ( ! options . wrap401Errors || err . statusCode !== 401 ) { throw err ; } throw LegacyOpenSearchErrorHelpers . decorateNotAuthorizedError ( err ) ; } } ; /**
 * Represents an OpenSearch cluster API client created by the platform.
 * It allows to call API on behalf of the internal OpenSearch Dashboards user and
 * the actual user that is derived from the request headers (via `asScoped(...)`).
 *
 * See  LegacyClusterClient .
 *
 *  deprecated Use  IClusterClient .
 *  public export type ILegacyClusterClient = Pick < LegacyClusterClient , 'callAsInternalUser' | 'asScoped' > ; /**
 * Represents an OpenSearch cluster API client created by a plugin.
 * It allows to call API on behalf of the internal OpenSearch Dashboards user and
 * the actual user that is derived from the request headers (via `asScoped(...)`).
 *
 * See  LegacyClusterClient .
 *  deprecated Use  ICustomClusterClient .
 *  public export type ILegacyCustomClusterClient = Pick < LegacyClusterClient , 'callAsInternalUser' | 'close' | 'asScoped' > ; deprecated Use  IClusterClient .
 *  public export class LegacyClusterClient implements ILegacyClusterClient { /**
     * Raw OpenSearch JS client that acts on behalf of the OpenSearch Dashboards internal user.
     */ private readonly client : Client ; /**
     * Optional raw OpenSearch JS client that is shared between all the scoped clients created
     * from this cluster client. Every API call is attributed by the wh
     */ private scopedClient ? : Client ; /**
     * Indicates whether this cluster client (and all internal raw OpenSearch JS clients) has been closed.
     */ private isClosed = false ; constructor ( private readonly config , private readonly log , private readonly getAuditorFactory , private readonly getAuthHeaders = noop ) { this . client = new Client ( parseOpenSearchClientConfig ( config , log ) ) ; } /**
     * Calls specified endpoint with provided clientParams on behalf of the
     * OpenSearch Dashboards internal user.
     * See  LegacyAPICaller .
     *
     *  param endpoint param clientParams param options public callAsInternalUser : LegacyAPICaller = async ( endpoint , clientParams = { } , options ? ) => { this . assertIsNotClosed ( ) ; return await ( callAPI . bind ( null , this . client ) as LegacyAPICaller ) ( endpoint , clientParams , options ) ; } ; /**
     * Closes the cluster client. After that client cannot be used and one should
     * create a new client instance to be able to interact with OpenSearch API.
     */ public close ( ) { if ( this . isClosed ) { return ; } this . isClosed = true ; this . client . close ( ) ; if ( this . scopedClient !== undefined ) { this . scopedClient . close ( ) ; } } /**
     * Creates an instance of  ILegacyScopedClusterClient based on the configuration the
     * current cluster client that exposes additional `callAsCurrentUser` method
     * scoped to the provided req. Consumers shouldn't worry about closing
     * scoped client instances, these will be automatically closed as soon as the
     * original cluster client isn't needed anymore and closed.
     *
     *  param request public asScoped ( request ? ) { if ( this . scopedClient === undefined ) { this . scopedClient = new Client ( parseOpenSearchClientConfig ( this . config , this . log , { auth : false , ignoreCertAndKey : ! this . config . ssl || ! this . config . ssl . alwaysPresentCertificate , } ) ) ; } return new LegacyScopedClusterClient ( this . callAsInternalUser , this . callAsCurrentUser , filterHeaders ( this . getHeaders ( request ) , [ 'x-opaque-id' , ... this . config . requestHeadersWhitelist , ] ) , this . getScopedAuditor ( request ) ) ; } private getScopedAuditor ( request ? ) { if ( request && isRealRequest ( request ) ) { const opensearchDashboardsRequest = isOpenSearchDashboardsRequest ( request ) ? request : OpenSearchDashboardsRequest . from ( request ) ; const auditorFactory = this . getAuditorFactory ( ) ; return auditorFactory . asScoped ( opensearchDashboardsRequest ) ; } } /**
     * Calls specified endpoint with provided clientParams on behalf of the
     * user initiated request to the OpenSearch Dashboards server (via HTTP request headers).
     * See  LegacyAPICaller .
     *
     *  param endpoint param clientParams param options private callAsCurrentUser : LegacyAPICaller = async ( endpoint , clientParams = { } , options ? ) => { this . assertIsNotClosed ( ) ; return await ( callAPI . bind ( null , this . scopedClient ! ) as LegacyAPICaller ) ( endpoint , clientParams , options ) ; } ; private assertIsNotClosed ( ) { if ( this . isClosed ) { throw new Error ( 'Cluster client cannot be used after it has been closed.' ) ; } } private getHeaders ( request ? ) { if ( ! isRealRequest ( request ) ) { return request && request . headers ? request . headers : { } ; } const authHeaders = this . getAuthHeaders ( request ) ; const requestHeaders = ensureRawRequest ( request ) . headers ; const requestIdHeaders = isOpenSearchDashboardsRequest ( request ) ? { 'x-opaque-id' : request . id } : { } ; return { ... requestHeaders , ... requestIdHeaders , ... authHeaders } ; } }