import { schema , TypeOf } from '@kbn/config-schema' ; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey' ; import { SnapshotRestore , SnapshotRestoreShardEs } from '../../../common/types' ; import { serializeRestoreSettings } from '../../../common/lib' ; import { deserializeRestoreShard } from '../../lib' ; import { RouteDependencies } from '../../types' ; import { addBasePath } from '../helpers' ; import { restoreSettingsSchema } from './validate_schemas' ; export function registerRestoreRoutes ( { router , license , lib : { handleEsError } , } ) { router . get ( { path : addBasePath ( 'restores' ) , validate : false } , license . guardApiRoute ( async ( ctx , req , res ) => { const { client : clusterClient } = ctx . core . elasticsearch ; try { const snapshotRestores = [ ] ; const { body : recoveryByIndexName } = await clusterClient . asCurrentUser . indices . recovery ( { human : true , } ) ; Object . keys ( recoveryByIndexName ) . forEach ( ( index ) => { const recovery = recoveryByIndexName [ index ] ; let latestActivityTimeInMillis = 0 ; let latestEndTimeInMillis = null ; const snapshotShards = ( recovery . shards || [ ] ) . filter ( ( shard ) => shard . type === 'SNAPSHOT' ) . sort ( ( a , b ) => a . id - b . id ) . map ( ( shard ) => { const deserializedShard = deserializeRestoreShard ( shard as SnapshotRestoreShardEs ) ; const { startTimeInMillis , stopTimeInMillis } = deserializedShard ; latestActivityTimeInMillis = Math . max ( startTimeInMillis || 0 , stopTimeInMillis || 0 , latestActivityTimeInMillis ) ; if ( stopTimeInMillis === undefined ) { latestEndTimeInMillis = null ; } else if ( latestEndTimeInMillis === null || stopTimeInMillis > latestEndTimeInMillis ) { latestEndTimeInMillis = stopTimeInMillis ; } return deserializedShard ; } ) ; if ( snapshotShards . length > 0 ) { snapshotRestores . push ( { index , latestActivityTimeInMillis , shards : snapshotShards , isComplete : latestEndTimeInMillis !== null , } ) ; } } ) ; snapshotRestores . sort ( ( a , b ) => b . latestActivityTimeInMillis - a . latestActivityTimeInMillis ) ; return res . ok ( { body : snapshotRestores } ) ; } catch ( e ) { return handleEsError ( { error : e , response : res } ) ; } } ) ) ; const restoreParamsSchema = schema . object ( { repository : schema . string ( ) , snapshot : schema . string ( ) , } ) ; router . post ( { path : addBasePath ( 'restore/{repository}/{snapshot}' ) , validate : { body : restoreSettingsSchema , params : restoreParamsSchema } , } , license . guardApiRoute ( async ( ctx , req , res ) => { const { client : clusterClient } = ctx . core . elasticsearch ; const { repository , snapshot } = req . params as TypeOf < typeof restoreParamsSchema > ; const restoreSettings = req . body as TypeOf < typeof restoreSettingsSchema > ; try { const response = await clusterClient . asCurrentUser . snapshot . restore ( { repository , snapshot , body : serializeRestoreSettings ( restoreSettings ) as estypes . SnapshotRestoreRequest [ 'body' ] , } ) ; return res . ok ( { body : response . body } ) ; } catch ( e ) { return handleEsError ( { error : e , response : res } ) ; } } ) ) ; }