import { ListNodesRouteResponse , DataTierRole } from '../../../../common/types' ; import { RouteDependencies } from '../../../types' ; import { addBasePath } from '../../../services' ; interface Settings { nodes : { [ nodeId ] : { attributes : Record < string , string > ; roles : string [ ] ; settings : { node : { data ? : string ; } ; } ; } ; } ; } export function convertSettingsIntoLists ( settings , disallowedNodeAttributes ) { return Object . entries ( settings . nodes ) . reduce ( ( accum , [ nodeId , nodeSettings ] ) => { const attributes = nodeSettings . attributes || { } ; for ( const [ key , value ] of Object . entries ( attributes ) ) { const isNodeAttributeAllowed = ! disallowedNodeAttributes . includes ( key ) ; if ( isNodeAttributeAllowed ) { const attributeString = `${ key }:${ value }` ; accum . nodesByAttributes [ attributeString ] = accum . nodesByAttributes [ attributeString ] ?? [ ] ; accum . nodesByAttributes [ attributeString ] . push ( nodeId ) ; } } const dataRoles = nodeSettings . roles . filter ( ( r ) => r . startsWith ( 'data' ) ) as DataTierRole [ ] ; for ( const role of dataRoles ) { accum . nodesByRoles [ role as DataTierRole ] = accum . nodesByRoles [ role ] ?? [ ] ; accum . nodesByRoles [ role as DataTierRole ] ! . push ( nodeId ) ; } if ( nodeSettings . settings ?. node ?. data === 'true' ) { accum . isUsingDeprecatedDataRoleConfig = true ; } return accum ; } , { nodesByAttributes : { } , nodesByRoles : { } , isUsingDeprecatedDataRoleConfig : false , } as ListNodesRouteResponse ) ; } export function registerListRoute ( { router , config , license , lib : { handleEsError } , } ) { const { filteredNodeAttributes } = config ; const NODE_ATTRS_KEYS_TO_IGNORE = [ 'ml.enabled' , 'ml.machine_memory' , 'ml.max_open_jobs' , 'ml.max_jvm_size' , 'transform.node' , 'xpack.installed' , ] ; const disallowedNodeAttributes = [ ... NODE_ATTRS_KEYS_TO_IGNORE , ... filteredNodeAttributes ] ; router . get ( { path : addBasePath ( '/nodes/list' ) , validate : false } , license . guardApiRoute ( async ( context , request , response ) => { try { const settingsResponse = await context . core . elasticsearch . client . asCurrentUser . transport . request ( { method : 'GET' , path : '/_nodes/settings' , querystring : { format : 'json' , } , } ) ; const body = convertSettingsIntoLists ( settingsResponse . body as Settings , disallowedNodeAttributes ) ; return response . ok ( { body } ) ; } catch ( error ) { return handleEsError ( { error , response } ) ; } } ) ) ; }