import Boom from '@hapi/boom' ; import { NODES_INFO_PRIVILEGES } from '../../../common/constants' ; import { isPopulatedObject } from '../../../common/shared_imports' ; import { RouteDependencies } from '../../types' ; import { addBasePath } from '../index' ; import { wrapError , wrapEsError } from './error_utils' ; const NODE_ROLES = 'roles' ; interface NodesAttributes { roles : string [ ] ; } type Nodes = Record < string , NodesAttributes > ; export const isNodes = ( arg ) : arg is Nodes => { return ( isPopulatedObject ( arg ) && Object . values ( arg ) . every ( ( node ) => isPopulatedObject ( node , [ NODE_ROLES ] ) && Array . isArray ( node . roles ) ) ) ; } ; export function registerTransformNodesRoutes ( { router , license } ) { apiGroup api apiName apiDescription router . get < undefined , undefined , undefined > ( { path : addBasePath ( 'transforms/_nodes' ) , validate : false , } , license . guardApiRoute < undefined , undefined , undefined > ( async ( ctx , req , res ) => { try { if ( license . getStatus ( ) . isSecurityEnabled === true ) { const { body : { has_all_requested : hasAllPrivileges } , } = await ctx . core . elasticsearch . client . asCurrentUser . security . hasPrivileges ( { body : { cluster : NODES_INFO_PRIVILEGES , } , } ) ; if ( ! hasAllPrivileges ) { return res . customError ( wrapError ( new Boom . Boom ( 'Forbidden' , { statusCode : 403 } ) ) ) ; } } const { body : { nodes } , } = await ctx . core . elasticsearch . client . asInternalUser . nodes . info ( { filter_path : `nodes.*.${ NODE_ROLES }` , } ) ; let count = 0 ; if ( isNodes ( nodes ) ) { for ( const { roles } of Object . values ( nodes ) ) { if ( roles . includes ( 'transform' ) ) { count ++ ; } } } return res . ok ( { body : { count } } ) ; } catch ( e ) { return res . customError ( wrapError ( wrapEsError ( e ) ) ) ; } } ) ) ; }