import * as Either from 'fp-ts/lib/Either' ; import * as Option from 'fp-ts/lib/Option' ; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey' ; import { AliasAction , isLeftTypeof } from '../actions' ; import { AllActionStates , State } from '../state' ; import type { ResponseType } from '../next' ; import { disableUnknownTypeMappingFields } from '../core' ; import { createInitialProgress , incrementProcessedProgress , logProgress , setProgressTotal , } from './progress' ; import { delayRetryState , resetRetryState } from './retry_state' ; import { extractTransformFailuresReason , extractUnknownDocFailureReason } from './extract_errors' ; import type { ExcludeRetryableEsError } from './types' ; import { getAliases , indexBelongsToLaterVersion , indexVersion , mergeMigrationMappingPropertyHashes , throwBadControlState , throwBadResponse , } from './helpers' ; import { createBatches } from './create_batches' ; const FATAL_REASON_REQUEST_ENTITY_TOO_LARGE = `While indexing a batch of saved objects, Elasticsearch returned a 413 Request Entity Too Large exception. Ensure that the Kibana configuration option 'migrations.maxBatchSizeBytes' is set to a value that is lower than or equal to the Elasticsearch 'http.max_content_length' configuration option.` ; const fatalReasonDocumentExceedsMaxBatchSizeBytes = ( { _id , docSizeBytes , maxBatchSizeBytes , } ) => `The document with _id "${ _id }" is ${ docSizeBytes } bytes which exceeds the configured maximum batch size of ${ maxBatchSizeBytes } bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.` ; export const model = ( currentState , resW ) : State => { let stateP = currentState ; if ( Either . isLeft < unknown , unknown > ( resW ) && isLeftTypeof ( resW . left , 'retryable_es_client_error' ) ) { return delayRetryState ( stateP , resW . left . message , stateP . retryAttempts ) ; } else { stateP = resetRetryState ( stateP ) ; } if ( stateP . controlState === 'INIT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const indices = res . right ; const aliases = getAliases ( indices ) ; if ( aliases [ stateP . currentAlias ] != null && aliases [ stateP . versionAlias ] != null && aliases [ stateP . currentAlias ] === aliases [ stateP . versionAlias ] ) { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_OPEN_PIT' , sourceIndex : Option . none , targetIndex : `${ stateP . indexPrefix }_${ stateP . kibanaVersion }_001` , targetIndexMappings : mergeMigrationMappingPropertyHashes ( stateP . targetIndexMappings , indices [ aliases [ stateP . currentAlias ] ] . mappings ) , versionIndexReadyActions : Option . none , } ; } else if ( indexBelongsToLaterVersion ( aliases [ stateP . currentAlias ] , stateP . kibanaVersion ) ) { return { ... stateP , controlState : 'FATAL' , reason : `The ${ stateP . currentAlias } alias is pointing to a newer version of Kibana: v${ indexVersion ( aliases [ stateP . currentAlias ] ) }` , } ; } else if ( aliases [ stateP . currentAlias ] != null ) { const source = aliases [ stateP . currentAlias ] ; return { ... stateP , controlState : 'WAIT_FOR_YELLOW_SOURCE' , sourceIndex : Option . some ( source ) as Option . Some < string > , sourceIndexMappings : indices [ source ] . mappings , } ; } else if ( indices [ stateP . legacyIndex ] != null ) { let legacyVersion = '' ; if ( stateP . indexPrefix === '.kibana' ) { legacyVersion = 'pre6.5.0' ; } else if ( stateP . indexPrefix === '.kibana_task_manager' ) { legacyVersion = 'pre7.4.0' ; } else { legacyVersion = 'pre' + stateP . kibanaVersion ; } const legacyReindexTarget = `${ stateP . indexPrefix }_${ legacyVersion }_001` ; const target = stateP . versionIndex ; return { ... stateP , controlState : 'LEGACY_SET_WRITE_BLOCK' , sourceIndex : Option . some ( legacyReindexTarget ) as Option . Some < string > , targetIndex : target , targetIndexMappings : disableUnknownTypeMappingFields ( stateP . targetIndexMappings , indices [ stateP . legacyIndex ] . mappings ) , legacyReindexTargetMappings : indices [ stateP . legacyIndex ] . mappings , legacyPreMigrationDoneActions : [ { remove_index : { index : stateP . legacyIndex } } , { add : { index : legacyReindexTarget , alias : stateP . currentAlias , } , } , ] , versionIndexReadyActions : Option . some < AliasAction [ ] > ( [ { remove : { index : legacyReindexTarget , alias : stateP . currentAlias , must_exist : true , } , } , { add : { index : target , alias : stateP . currentAlias } } , { add : { index : target , alias : stateP . versionAlias } } , { remove_index : { index : stateP . tempIndex } } , ] ) , } ; } else { const target = stateP . versionIndex ; return { ... stateP , controlState : 'CREATE_NEW_TARGET' , sourceIndex : Option . none as Option . None , targetIndex : target , versionIndexReadyActions : Option . some ( [ { add : { index : target , alias : stateP . currentAlias } } , { add : { index : target , alias : stateP . versionAlias } } , ] ) as Option . Some < AliasAction [ ] > , } ; } } else { return throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'LEGACY_SET_WRITE_BLOCK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'LEGACY_CREATE_REINDEX_TARGET' } ; } else if ( Either . isLeft ( res ) ) { if ( isLeftTypeof ( res . left , 'index_not_found_exception' ) ) { return { ... stateP , controlState : 'LEGACY_CREATE_REINDEX_TARGET' } ; } else { return throwBadResponse ( stateP , res ) ; } } else { return throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'LEGACY_CREATE_REINDEX_TARGET' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'LEGACY_REINDEX' , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'LEGACY_REINDEX' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'LEGACY_REINDEX_WAIT_FOR_TASK' , legacyReindexTaskId : res . right . taskId , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'LEGACY_REINDEX_WAIT_FOR_TASK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'LEGACY_DELETE' , } ; } else { const left = res . left ; if ( ( isLeftTypeof ( left , 'index_not_found_exception' ) && left . index === stateP . legacyIndex ) || isLeftTypeof ( left , 'target_index_had_write_block' ) ) { return { ... stateP , controlState : 'LEGACY_DELETE' } ; } else if ( isLeftTypeof ( left , 'wait_for_task_completion_timeout' ) ) { return delayRetryState ( stateP , left . message , Number . MAX_SAFE_INTEGER ) ; } else if ( isLeftTypeof ( left , 'index_not_found_exception' ) || isLeftTypeof ( left , 'incompatible_mapping_exception' ) ) { throwBadResponse ( stateP , left as never ) ; } else { throwBadResponse ( stateP , left ) ; } } } else if ( stateP . controlState === 'LEGACY_DELETE' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'SET_SOURCE_WRITE_BLOCK' } ; } else if ( Either . isLeft ( res ) ) { const left = res . left ; if ( isLeftTypeof ( left , 'remove_index_not_a_concrete_index' ) || ( isLeftTypeof ( left , 'index_not_found_exception' ) && left . index === stateP . legacyIndex ) ) { return { ... stateP , controlState : 'SET_SOURCE_WRITE_BLOCK' } ; } else if ( isLeftTypeof ( left , 'index_not_found_exception' ) || isLeftTypeof ( left , 'alias_not_found_exception' ) ) { throwBadResponse ( stateP , left as never ) ; } else { throwBadResponse ( stateP , left ) ; } } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'WAIT_FOR_YELLOW_SOURCE' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'CHECK_UNKNOWN_DOCUMENTS' , } ; } else { return throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'CHECK_UNKNOWN_DOCUMENTS' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const source = stateP . sourceIndex ; const target = stateP . versionIndex ; return { ... stateP , controlState : 'SET_SOURCE_WRITE_BLOCK' , sourceIndex : source , targetIndex : target , targetIndexMappings : disableUnknownTypeMappingFields ( stateP . targetIndexMappings , stateP . sourceIndexMappings ) , versionIndexReadyActions : Option . some < AliasAction [ ] > ( [ { remove : { index : source . value , alias : stateP . currentAlias , must_exist : true } } , { add : { index : target , alias : stateP . currentAlias } } , { add : { index : target , alias : stateP . versionAlias } } , { remove_index : { index : stateP . tempIndex } } , ] ) , } ; } else { if ( isLeftTypeof ( res . left , 'unknown_docs_found' ) ) { return { ... stateP , controlState : 'FATAL' , reason : extractUnknownDocFailureReason ( res . left . unknownDocs , stateP . sourceIndex . value ) , } ; } else { return throwBadResponse ( stateP , res . left ) ; } } } else if ( stateP . controlState === 'SET_SOURCE_WRITE_BLOCK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'CALCULATE_EXCLUDE_FILTERS' , } ; } else if ( isLeftTypeof ( res . left , 'index_not_found_exception' ) ) { return throwBadResponse ( stateP , res . left as never ) ; } else { return throwBadResponse ( stateP , res . left ) ; } } else if ( stateP . controlState === 'CALCULATE_EXCLUDE_FILTERS' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const unusedTypesQuery = { bool : { filter : [ stateP . unusedTypesQuery , res . right . excludeFilter ] , } , } ; return { ... stateP , controlState : 'CREATE_REINDEX_TEMP' , unusedTypesQuery , logs : [ ... stateP . logs , ... Object . entries ( res . right . errorsByType ) . map ( ( [ soType , error ] ) => ( { level : 'warning' as const , message : `Ignoring excludeOnUpgrade hook on type [${ soType }] that failed with error: "${ error . toString ( ) }"` , } ) ) , ] , } ; } else { return throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'CREATE_REINDEX_TEMP' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_OPEN_PIT' } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'REINDEX_SOURCE_TO_TEMP_OPEN_PIT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_READ' , sourceIndexPitId : res . right . pitId , lastHitSortValue : undefined , corruptDocumentIds : [ ] , transformErrors : [ ] , progress : createInitialProgress ( ) , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'REINDEX_SOURCE_TO_TEMP_READ' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const progress = setProgressTotal ( stateP . progress , res . right . totalHits ) ; const logs = logProgress ( stateP . logs , progress ) ; if ( res . right . outdatedDocuments . length > 0 ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_TRANSFORM' , outdatedDocuments : res . right . outdatedDocuments , lastHitSortValue : res . right . lastHitSortValue , progress , logs , } ; } else { if ( stateP . corruptDocumentIds . length > 0 || stateP . transformErrors . length > 0 ) { const transformFailureReason = extractTransformFailuresReason ( stateP . corruptDocumentIds , stateP . transformErrors ) ; return { ... stateP , controlState : 'FATAL' , reason : transformFailureReason , } ; } else { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT' , logs , } ; } } } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const { sourceIndexPitId , ... state } = stateP ; return { ... state , controlState : 'SET_TEMP_WRITE_BLOCK' , sourceIndex : stateP . sourceIndex as Option . Some < string > , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'REINDEX_SOURCE_TO_TEMP_TRANSFORM' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; const progress = incrementProcessedProgress ( stateP . progress , stateP . outdatedDocuments . length ) ; if ( Either . isRight ( res ) ) { if ( stateP . corruptDocumentIds . length === 0 && stateP . transformErrors . length === 0 ) { const batches = createBatches ( res . right . processedDocs , stateP . tempIndex , stateP . maxBatchSizeBytes ) ; if ( Either . isRight ( batches ) ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK' , transformedDocBatches : batches . right , currentBatch : 0 , progress , } ; } else { return { ... stateP , controlState : 'FATAL' , reason : fatalReasonDocumentExceedsMaxBatchSizeBytes ( { _id : batches . left . document . _id , docSizeBytes : batches . left . docSizeBytes , maxBatchSizeBytes : batches . left . maxBatchSizeBytes , } ) , } ; } } else { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_READ' , progress , } ; } } else { const left = res . left ; if ( isLeftTypeof ( left , 'documents_transform_failed' ) ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_READ' , corruptDocumentIds : [ ... stateP . corruptDocumentIds , ... left . corruptDocumentIds ] , transformErrors : [ ... stateP . transformErrors , ... left . transformErrors ] , progress , } ; } else { throwBadResponse ( stateP , res as never ) ; } } } else if ( stateP . controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { if ( stateP . currentBatch + 1 < stateP . transformedDocBatches . length ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK' , currentBatch : stateP . currentBatch + 1 , } ; } else { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_READ' , corruptDocumentIds : [ ] , transformErrors : [ ] , } ; } } else { if ( isLeftTypeof ( res . left , 'target_index_had_write_block' ) || isLeftTypeof ( res . left , 'index_not_found_exception' ) ) { return { ... stateP , controlState : 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT' , } ; } else if ( isLeftTypeof ( res . left , 'request_entity_too_large_exception' ) ) { return { ... stateP , controlState : 'FATAL' , reason : FATAL_REASON_REQUEST_ENTITY_TOO_LARGE , } ; } throwBadResponse ( stateP , res . left ) ; } } else if ( stateP . controlState === 'SET_TEMP_WRITE_BLOCK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'CLONE_TEMP_TO_TARGET' , } ; } else { const left = res . left ; if ( isLeftTypeof ( left , 'index_not_found_exception' ) ) { return { ... stateP , controlState : 'CLONE_TEMP_TO_TARGET' , } ; } else { throwBadResponse ( stateP , left ) ; } } } else if ( stateP . controlState === 'CLONE_TEMP_TO_TARGET' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'REFRESH_TARGET' , } ; } else { const left = res . left ; if ( isLeftTypeof ( left , 'index_not_found_exception' ) ) { return { ... stateP , controlState : 'REFRESH_TARGET' , } ; } else { throwBadResponse ( stateP , left ) ; } } } else if ( stateP . controlState === 'REFRESH_TARGET' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_OPEN_PIT' , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'OUTDATED_DOCUMENTS_SEARCH_OPEN_PIT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_READ' , pitId : res . right . pitId , lastHitSortValue : undefined , progress : createInitialProgress ( ) , hasTransformedDocs : false , corruptDocumentIds : [ ] , transformErrors : [ ] , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'OUTDATED_DOCUMENTS_SEARCH_READ' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { if ( res . right . outdatedDocuments . length > 0 ) { const progress = setProgressTotal ( stateP . progress , res . right . totalHits ) ; const logs = logProgress ( stateP . logs , progress ) ; return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_TRANSFORM' , outdatedDocuments : res . right . outdatedDocuments , lastHitSortValue : res . right . lastHitSortValue , progress , logs , } ; } else { if ( stateP . corruptDocumentIds . length > 0 || stateP . transformErrors . length > 0 ) { const transformFailureReason = extractTransformFailuresReason ( stateP . corruptDocumentIds , stateP . transformErrors ) ; return { ... stateP , controlState : 'FATAL' , reason : transformFailureReason , } ; } else { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_CLOSE_PIT' , } ; } } } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'OUTDATED_DOCUMENTS_TRANSFORM' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; const progress = incrementProcessedProgress ( stateP . progress , stateP . outdatedDocuments . length ) ; if ( Either . isRight ( res ) ) { if ( stateP . corruptDocumentIds . length === 0 && stateP . transformErrors . length === 0 ) { const batches = createBatches ( res . right . processedDocs , stateP . targetIndex , stateP . maxBatchSizeBytes ) ; if ( Either . isRight ( batches ) ) { return { ... stateP , controlState : 'TRANSFORMED_DOCUMENTS_BULK_INDEX' , transformedDocBatches : batches . right , currentBatch : 0 , hasTransformedDocs : true , progress , } ; } else { return { ... stateP , controlState : 'FATAL' , reason : fatalReasonDocumentExceedsMaxBatchSizeBytes ( { _id : batches . left . document . _id , docSizeBytes : batches . left . docSizeBytes , maxBatchSizeBytes : batches . left . maxBatchSizeBytes , } ) , } ; } } else { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_READ' , progress , } ; } } else { if ( isLeftTypeof ( res . left , 'documents_transform_failed' ) ) { return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_READ' , corruptDocumentIds : [ ... stateP . corruptDocumentIds , ... res . left . corruptDocumentIds ] , transformErrors : [ ... stateP . transformErrors , ... res . left . transformErrors ] , hasTransformedDocs : false , progress , } ; } else { throwBadResponse ( stateP , res as never ) ; } } } else if ( stateP . controlState === 'TRANSFORMED_DOCUMENTS_BULK_INDEX' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { if ( stateP . currentBatch + 1 < stateP . transformedDocBatches . length ) { return { ... stateP , controlState : 'TRANSFORMED_DOCUMENTS_BULK_INDEX' , currentBatch : stateP . currentBatch + 1 , } ; } return { ... stateP , controlState : 'OUTDATED_DOCUMENTS_SEARCH_READ' , corruptDocumentIds : [ ] , transformErrors : [ ] , hasTransformedDocs : true , } ; } else { if ( isLeftTypeof ( res . left , 'request_entity_too_large_exception' ) ) { return { ... stateP , controlState : 'FATAL' , reason : FATAL_REASON_REQUEST_ENTITY_TOO_LARGE , } ; } else if ( isLeftTypeof ( res . left , 'target_index_had_write_block' ) || isLeftTypeof ( res . left , 'index_not_found_exception' ) ) { throwBadResponse ( stateP , res . left as never ) ; } else { throwBadResponse ( stateP , res . left ) ; } } } else if ( stateP . controlState === 'UPDATE_TARGET_MAPPINGS' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'UPDATE_TARGET_MAPPINGS_WAIT_FOR_TASK' , updateTargetMappingsTaskId : res . right . taskId , } ; } else { throwBadResponse ( stateP , res as never ) ; } } else if ( stateP . controlState === 'OUTDATED_DOCUMENTS_REFRESH' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'UPDATE_TARGET_MAPPINGS' , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'OUTDATED_DOCUMENTS_SEARCH_CLOSE_PIT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const { pitId , hasTransformedDocs , ... state } = stateP ; if ( hasTransformedDocs ) { return { ... state , controlState : 'OUTDATED_DOCUMENTS_REFRESH' , } ; } return { ... state , controlState : 'UPDATE_TARGET_MAPPINGS' , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'UPDATE_TARGET_MAPPINGS_WAIT_FOR_TASK' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { if ( Option . isSome ( stateP . versionIndexReadyActions ) ) { return { ... stateP , controlState : 'MARK_VERSION_INDEX_READY' , versionIndexReadyActions : stateP . versionIndexReadyActions , } ; } else { return { ... stateP , controlState : 'DONE' , } ; } } else { const left = res . left ; if ( isLeftTypeof ( left , 'wait_for_task_completion_timeout' ) ) { return delayRetryState ( stateP , res . left . message , Number . MAX_SAFE_INTEGER ) ; } else { throwBadResponse ( stateP , left ) ; } } } else if ( stateP . controlState === 'CREATE_NEW_TARGET' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'MARK_VERSION_INDEX_READY' , } ; } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'MARK_VERSION_INDEX_READY' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { return { ... stateP , controlState : 'DONE' } ; } else { const left = res . left ; if ( isLeftTypeof ( left , 'alias_not_found_exception' ) ) { return { ... stateP , controlState : 'MARK_VERSION_INDEX_READY_CONFLICT' } ; } else if ( isLeftTypeof ( left , 'index_not_found_exception' ) ) { if ( left . index === stateP . tempIndex ) { return { ... stateP , controlState : 'MARK_VERSION_INDEX_READY_CONFLICT' } ; } else { throwBadResponse ( stateP , left as never ) ; } } else if ( isLeftTypeof ( left , 'remove_index_not_a_concrete_index' ) ) { throwBadResponse ( stateP , left as never ) ; } else { throwBadResponse ( stateP , left ) ; } } } else if ( stateP . controlState === 'MARK_VERSION_INDEX_READY_CONFLICT' ) { const res = resW as ExcludeRetryableEsError < ResponseType < typeof stateP . controlState > > ; if ( Either . isRight ( res ) ) { const indices = res . right ; const aliases = getAliases ( indices ) ; if ( aliases [ stateP . currentAlias ] != null && aliases [ stateP . versionAlias ] != null && aliases [ stateP . currentAlias ] === aliases [ stateP . versionAlias ] ) { return { ... stateP , controlState : 'DONE' } ; } else { const conflictingKibanaVersion = indexVersion ( aliases [ stateP . currentAlias ] ) ?? aliases [ stateP . currentAlias ] ; return { ... stateP , controlState : 'FATAL' , reason : `Multiple versions of Kibana are attempting a migration in parallel. Another Kibana instance on version ${ conflictingKibanaVersion } completed this migration (this instance is running ${ stateP . kibanaVersion }). Ensure that all Kibana instances are running on same version and try again.` , } ; } } else { throwBadResponse ( stateP , res ) ; } } else if ( stateP . controlState === 'DONE' || stateP . controlState === 'FATAL' ) { throwBadControlState ( stateP as never ) ; } else { return throwBadControlState ( stateP ) ; } } ;