elasticdump
Version:
import and export tools for elasticsearch
130 lines (110 loc) • 4.18 kB
JavaScript
const jsonParser = require('../../jsonparser.js')
const aws4signer = require('../../aws4signer')
const req = require('../../request')
const status = require('http-status')
const semver = require('semver')
class Base {
applyProxy (url, proxyHost, proxyPort) { return req.applyProxy(url, proxyHost, proxyPort) }
applySSL (props) { return req.applySSL(props, this) }
handleError (err, response) {
if (err) return err
if (response.statusCode !== 200) {
err = new Error(response.body)
err.statusCode = response.statusCode
err.name = status[`${response.statusCode}_NAME`]
if (!err.message) {
err.message = status[`${response.statusCode}_MESSAGE`]
}
return err
}
}
paramsToString (paramsObj, prefix = '?') {
return paramsObj ? `${prefix}${Object.keys(paramsObj).map(key => `${key}=${paramsObj[key]}`).join('&')}` : ''
}
setSearchBody () {
if (!this.searchBody) {
if (this.ESversion >= 5) {
this.searchBody = { query: { match_all: {} }, stored_fields: ['*'], _source: true }
} else {
this.searchBody = { query: { match_all: {} }, fields: ['*'], _source: true }
}
}
}
/**
* @returns {{version: string, distribution: string, distributionVersion: string}}
*/
_parseVersion (response) {
// Skip `this.handleError` if server is AOSS
// They didn't implement `GET /` and will return 404 here, but we can hard-code
// the version info by `server` in response header
if (this.parent.options.openSearchServerless || response.headers.server === 'aoss-amazon') {
return {
version: this.parent.options['force-os-version'],
distribution: 'opensearch-serverless',
// See https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-overview.html
// "Currently, serverless collections run OpenSearch version 2.0.x", as of May 13, 2025
distributionVersion: '2.0.0',
isOpenSearch: true
}
}
const err = this.handleError(null, response)
if (err) {
throw err
}
const parsed = jsonParser.parse(response.body)
if (!parsed.version) {
// Fallback version
this.parent.emit('debug', 'unable to detect version, using default: 5.0.0')
return {
version: '5.0.0',
distribution: 'elasticsearch',
distributionVersion: '5.0.0'
}
}
if (parsed.version.distribution === 'opensearch') {
return {
version: this.parent.options['force-os-version'],
distribution: 'opensearch',
distributionVersion: parsed.version.number,
isOpenSearch: true
}
}
return {
version: parsed.version.number,
distribution: parsed.version.build_flavor === 'serverless' ? 'elasticsearch-serverless' : 'elasticserach',
distributionVersion: parsed.version.number
}
}
version (prefix, callback) {
if (this.ESversion) {
return callback()
}
const esRequest = {
url: `${this.base.host}/`,
method: 'GET'
}
aws4signer(esRequest, this.parent).then(() => {
this.baseRequest(esRequest, (err, response) => {
if (err) {
return callback(err, [])
}
const parsed = this._parseVersion(response)
this.parent.emit('debug', `detected ${prefix} distribution = ${parsed.distribution}, ESversion = ${parsed.version}, distribution version = ${parsed.distributionVersion}`)
// No need to check elasticsearch-serverless. Those are at least >= v8
if (this.parent.options.searchAfter && parsed.distribution === 'elasticsearch') {
if (!semver.gte(this.ESFullversion, '7.17.0')) {
return callback(new Error('searchAfter requires Elasticsearch 7.17.0 or higher'))
}
}
this.ESFullversion = parsed.version
this.ESversion = this.ESFullversion.split('.')[0]
this.ESDistribution = parsed.distribution
this.DistributionVersion = parsed.distributionVersion
this.IsOpenSearch = !!parsed.isOpenSearch
this.setSearchBody()
callback()
})
}).catch(callback)
}
}
module.exports = Base