Skip to content

Instantly share code, notes, and snippets.

@Aschen
Created March 7, 2022 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Aschen/a21094ba4472ce273f1ec393f1b36404 to your computer and use it in GitHub Desktop.
Save Aschen/a21094ba4472ce273f1ec393f1b36404 to your computer and use it in GitHub Desktop.
Migrate Elasticsearch stored scripts

Migrate Elasticsearch stored scripts

This is a standalone migration script to export and imports Elasticsearch Stored Scripts.

Usage

Export scripts from your ES cluster:

node migrate.js export http://localhost:9200

This will create a es-stored-scripts.json file containing the scripts.

Then you can import them:

node migrate.js import http://localhost:9200
const fs = require('fs');
// Embedded "min-req-promise" package
const http = require('http');
const https = require('https');
const URL = require('url');
const client = (url) => /^https/.test(url) ? https : http;
const httpRequest = (url, method, options = {}) => new Promise((resolve, reject) => {
const u = URL.parse(url);
const req = client(url).request(Object.assign({}, options, {
method,
hostname: u.hostname,
port: u.port,
path: u.path,
}), res => {
let buffer = new Buffer.alloc(0);
res.on('data', chunk => {
buffer = Buffer.concat([buffer, chunk]);
});
res.on('end',() => {
if (options.responseEncoding
|| !res.headers['content-type']
|| /^(text|application\/json)/.test(res.headers['content-type'])
) {
let charset = 'utf-8';
if (options.responseEncoding) {
charset = options.responseEncoding;
}
else if (res.headers['content-type']) {
const match = /;\s*charset=(.*)/.exec(res.headers['content-type']);
if (match) {
charset = match[1];
}
}
charset = charset.toLowerCase()
.replace(/^iso-?8859(-1)?$/, 'latin1');
if ([
'ascii',
'base64',
'binary',
'hex',
'ucs2',
'ucs-2',
'utf16le',
'utf-16le',
'utf8',
'utf-8',
'latin1'
].indexOf(charset) < 0) {
// unsupported charset, fallback to utf-8
charset = 'utf-8';
}
res.body = buffer.toString(charset);
}
else {
// assume binary content
res.body = buffer;
}
resolve(res);
});
res.on('error', reject);
res.on('timeout', () => reject(req));
});
req.on('error', reject);
req.write(options.body || '');
req.end();
});
const httpGet = (url, options = {}) => httpRequest(url, 'GET', options);
const httpPut = (url, options = {}) => httpRequest(url, 'PUT', options);
// End "min-req-promise" package
const action = process.argv[2];
const target = process.argv[3];
async function exportScripts (target) {
console.log(`Export scripts from ${target} to "es-stored-scripts.json"`);
const response = await httpGet(`${target}/_cluster/state/metadata?pretty&filter_path=**.stored_scripts`);
const scripts = JSON.parse(response.body).metadata.stored_scripts;
fs.writeFileSync('es-stored-scripts.json', JSON.stringify(scripts, null, 2));
}
async function importScripts (target) {
console.log(`Import scripts from "es-stored-scripts.json" to ${target}`);
const scripts = JSON.parse(fs.readFileSync('es-stored-scripts.json'));
for (const [name, script] of Object.entries(scripts)) {
await httpPut(`${target}/_scripts/${name}`, {
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ script })
});
}
}
if (action === 'export') {
exportScripts(target);
}
else {
importScripts(target);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment