├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE-MIT ├── README.md ├── TODO.md ├── docker-compose.yml ├── jest.config.js ├── lib ├── es-export-aliases.js ├── es-export-bulk.js ├── es-export-mappings.js ├── es-export-settings.js ├── es-import-aliases.js ├── es-import-bulk.js ├── es-import-mappings.js ├── es-import-settings.js ├── exporter.js ├── helpers.js └── importer.js ├── package-lock.json ├── package.json ├── scripts └── build-readme.js └── tests ├── fixtures ├── docker-compose-cluster.yml ├── docker-compose-kibana.yml ├── import-tests │ ├── aliases.txt │ ├── bulk.txt │ ├── mappings.txt │ └── settings.txt └── working │ └── .placeholder ├── integration ├── __snapshots__ │ └── all.test.js.snap ├── all.test.js └── insert-data.js └── unit ├── __snapshots__ ├── es-export-aliases.test.js.snap ├── es-export-mappings.test.js.snap ├── es-export-settings.test.js.snap ├── es-import-aliases.test.js.snap ├── es-import-mappings.test.js.snap └── es-import-settings.test.js.snap ├── es-export-aliases.test.js ├── es-export-mappings.test.js ├── es-export-settings.test.js ├── es-import-aliases.test.js ├── es-import-mappings.test.js └── es-import-settings.test.js /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | jest: true 5 | }, 6 | extends: 'eslint:recommended', 7 | parserOptions: { 8 | ecmaVersion: 8 9 | }, 10 | rules: { 11 | 'no-console': 'warn' 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _ignore/ 2 | coverage/ 3 | node_modules/ 4 | tests/fixtures/working/*.txt 5 | .DS_Store 6 | .idea/ 7 | .npm-debug.log 8 | .project 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .git* 2 | _ignore/ 3 | coverage/ 4 | test/ 5 | .DS_Store 6 | .gitignore 7 | .npm-debug.log 8 | .project 9 | .travis.yml 10 | TODO.md 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: node_js 3 | node_js: 4 | - "node" 5 | - "8" 6 | 7 | services: 8 | - docker 9 | 10 | before_install: 11 | - docker-compose up -d 12 | - docker ps 13 | - sleep 10 14 | 15 | script: 16 | - npm run build 17 | - npm run test:integration 18 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 skratchdot 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elasticsearch-tools 2 | 3 | A collection of elasticsearch command line tools for doing things like bulk importing/exporting 4 | and exporting/importing mappings. 5 | 6 | It was created because some of the existing import/export tools ran too slow on my machine. Using 7 | the new bulk API seemed to speed things up dramatically. The other tools I used also weren't 8 | exporting \_parent and \_routing fields. 9 | 10 | ## Installation 11 | 12 | ```bash 13 | npm install -g elasticsearch-tools 14 | ``` 15 | 16 | After installing, you will have access to the following command line tools: 17 | 18 | #### Exporting 19 | 20 | - [es-export-bulk](#usage-es-export-bulk) 21 | - [es-export-mappings](#usage-es-export-mappings) 22 | - [es-export-settings](#usage-es-export-settings) 23 | - [es-export-aliases](#usage-es-export-aliases) 24 | 25 | #### Importing 26 | 27 | - [es-import-bulk](#usage-es-import-bulk) 28 | - [es-import-mappings](#usage-es-import-mappings) 29 | - [es-import-settings](#usage-es-import-settings) 30 | - [es-import-aliases](#usage-es-import-aliases) 31 | 32 | ## Usage: es-export-bulk 33 | 34 | ### Options 35 | 36 | ```bash 37 | es-export-bulk --help 38 | 39 | Usage: es-export-bulk [options] 40 | 41 | Options: 42 | 43 | -h, --help output usage information 44 | -v, --version output the version number 45 | -u, --url comma-separated elasticsearch urls to connect to 46 | -f, --file the file to write data to 47 | -m, --max the maximum number of items to export. different than the scroll size 48 | --transformMeta a javascript function that returns an object that is the transformed meta object 49 | --transformSource a javascript function that returns an object that is the transformed source object 50 | --transformMetaInit a javascript function that returns an init object that contains helpers for the transform function 51 | --transformSourceInit a javascript function that returns an init object that contains helpers for the transform function 52 | --index ES OPTION: a comma-separated list of index names to search; use _all or empty string to perform the operation on all indices 53 | --type ES OPTION: a comma-separated list of document types to search; leave empty to perform the operation on all types 54 | --body ES OPTION: the body to send along with this request. 55 | --analyzer ES OPTION: The analyzer to use for the query string 56 | --analyzeWildcard ES OPTION: specify whether wildcard and prefix queries should be analyzed (default: false) 57 | --fields ES OPTION: a comma-separated list of fields to return as part of a hit (default: "*") 58 | --from ES OPTION: starting offset (default: 0) 59 | --q ES OPTION: query in the Lucene query string syntax 60 | --routing ES OPTION: a comma-separated list of specific routing values 61 | --scroll ES OPTION: specify how long a consistent view of the index should be maintained for scrolled search (default: 1m) 62 | --size ES OPTION: number of hits to return during each scan 63 | --sort ES OPTION: a comma-separated list of : pairs 64 | --timeout ES OPTION: explicit operation timeout 65 | --apiVersion ES CLIENT OPTION: the major version of the Elasticsearch nodes you will be connecting to (default: 2.3) 66 | --maxRetries ES CLIENT OPTION: how many times should the client try to connect to other nodes before returning a ConnectionFault error (default: 3) 67 | --requestTimeout ES CLIENT OPTION: milliseconds before an HTTP request will be aborted and retried. This can also be set per request (default: 30000) 68 | --deadTimeout ES CLIENT OPTION: milliseconds that a dead connection will wait before attempting to revive itself (default: 60000) 69 | --pingTimeout ES CLIENT OPTION: milliseconds that a ping request can take before timing out (default: 3000) 70 | --maxSockets ES CLIENT OPTION: maximum number of concurrent requests that can be made to any node (default: 10) 71 | --minSockets ES CLIENT OPTION: minimum number of sockets to keep connected to a node (default: 10) 72 | --selector ES CLIENT OPTION: select a connection from the ConnectionPool using roundRobin (default) or random 73 | ``` 74 | 75 | ### Examples 76 | 77 | #### export 1 hour of data from local db 78 | 79 | ```bash 80 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --body ' 81 | {"query":{"range":{"timestamp":{"gte":"2014-08-13T11:00:00.000Z","lte":"2014-08-13T12:00:00.000Z"}}}} 82 | ' 83 | ``` 84 | 85 | #### export "myIndex" from local db 86 | 87 | ```bash 88 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --index myIndex 89 | ``` 90 | 91 | #### add a key/value to all exported documents 92 | 93 | ```bash 94 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --transformSource 'data.foo = "neat"' 95 | # the return statement is optional 96 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --transformSource 'data.foo = "neat";return data;' 97 | ``` 98 | 99 | #### delete the key "foo" from all exported documents 100 | 101 | ```bash 102 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --transformSource 'delete data.foo' 103 | ``` 104 | 105 | #### don't include \_parent in meta data 106 | 107 | ```bash 108 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --transformMeta 'delete data.index._parent' 109 | ``` 110 | 111 | #### change the index name that we export 112 | 113 | ```bash 114 | es-export-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/data.json --transformMeta 'data.index._index = "newIndex"' 115 | ``` 116 | 117 | ## Usage: es-export-mappings 118 | 119 | ### Options 120 | 121 | ```bash 122 | es-export-mappings --help 123 | 124 | Usage: es-export-mappings [options] 125 | 126 | Options: 127 | 128 | -h, --help output usage information 129 | -v, --version output the version number 130 | -u, --url the elasticsearch url to connect to 131 | -f, --file the file to write data to 132 | --index ES OPTION: String, String[], Boolean — A comma-separated list of index names 133 | --type ES OPTION: String, String[], Boolean — A comma-separated list of document types 134 | --ignoreUnavailable ES OPTION: Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed) 135 | --allowNoIndices ES OPTION: Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified) 136 | --expandWildcards ES OPTION: String — Whether to expand wildcard expression to concrete indices that are open, closed or both. 137 | --local ES OPTION: Boolean — Return local information, do not retrieve the state from master node (default: false) 138 | ``` 139 | 140 | ### Examples 141 | 142 | #### export mappings from local db 143 | 144 | ```bash 145 | es-export-mappings --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.mappings.json 146 | ``` 147 | 148 | ## Usage: es-export-settings 149 | 150 | ### Options 151 | 152 | ```bash 153 | es-export-settings --help 154 | 155 | Usage: es-export-settings [options] 156 | 157 | Options: 158 | 159 | -h, --help output usage information 160 | -v, --version output the version number 161 | -u, --url the elasticsearch url to connect to 162 | -f, --file the file to write data to 163 | --index ES OPTION: String, String[], Boolean — A comma-separated list of index names 164 | --ignoreUnavailable ES OPTION: Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed) 165 | --allowNoIndices ES OPTION: Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified) 166 | --expandWildcards ES OPTION: String — Whether to expand wildcard expression to concrete indices that are open, closed or both. 167 | --local ES OPTION: Boolean — Return local information, do not retrieve the state from master node (default: false) 168 | --name ES OPTION: String, String[], Boolean — The name of the settings that should be included 169 | ``` 170 | 171 | ### Examples 172 | 173 | #### export settings from local db 174 | 175 | ```bash 176 | es-export-settings --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.settings.json 177 | ``` 178 | 179 | ## Usage: es-export-aliases 180 | 181 | ### Options 182 | 183 | ```bash 184 | es-export-aliases --help 185 | 186 | Usage: es-export-aliases [options] 187 | 188 | Options: 189 | 190 | -h, --help output usage information 191 | -v, --version output the version number 192 | -u, --url the elasticsearch url to connect to 193 | -f, --file the file to write data to 194 | --index ES OPTION: String, String[], Boolean — A comma-separated list of index names 195 | --local ES OPTION: Boolean — Return local information, do not retrieve the state from master node (default: false) 196 | --name ES OPTION: String, String[], Boolean — The name of the settings that should be included 197 | ``` 198 | 199 | ### Examples 200 | 201 | #### export aliases from local db 202 | 203 | ```bash 204 | es-export-aliases --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.aliases.json 205 | ``` 206 | 207 | ## Usage: es-import-bulk 208 | 209 | ### Options 210 | 211 | ```bash 212 | es-import-bulk --help 213 | 214 | Usage: es-import-bulk [options] 215 | 216 | Options: 217 | 218 | -v, --version output the version number 219 | -u, --url the elasticsearch url to connect to 220 | -f, --file the file to read data from 221 | -m, --max the max number of lines to process per batch (default: 20,000) (default: 20000) 222 | --requestTimeout ES CLIENT OPTION: milliseconds before an HTTP request will be aborted and retried. This can also be set per request (default: 30000) (default: 30000) 223 | -h, --help output usage information 224 | ``` 225 | 226 | ### Examples 227 | 228 | #### import data to local db from file 229 | 230 | ```bash 231 | es-import-bulk --url http://localhost:9200 --file ~/backups/elasticsearch/prod/rafflev1.json 232 | ``` 233 | 234 | ## Usage: es-import-mappings 235 | 236 | ### Options 237 | 238 | ```bash 239 | es-import-mappings --help 240 | 241 | Usage: es-import-mappings [options] 242 | 243 | Options: 244 | 245 | -v, --version output the version number 246 | -u, --url the elasticsearch url to connect to 247 | -f, --file the file to read data from 248 | --ignoreConflicts ES OPTION: Boolean — Specify whether to ignore conflicts while updating the mapping (default: false) 249 | --timeout ES OPTION: Date, Number — Explicit operation timeout 250 | --masterTimeout ES OPTION: Date, Number — Specify timeout for connection to master 251 | --ignoreUnavailable ES OPTION: Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed) 252 | --allowNoIndices ES OPTION: Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified) 253 | --expandWildcards ES OPTION: String — Whether to expand wildcard expression to concrete indices that are open, closed or both. 254 | -h, --help output usage information 255 | ``` 256 | 257 | ### Examples 258 | 259 | #### import mappings to local db 260 | 261 | ```bash 262 | es-import-mappings --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.mappings.json 263 | ``` 264 | 265 | ## Usage: es-import-settings 266 | 267 | ### Options 268 | 269 | ```bash 270 | es-import-settings --help 271 | 272 | Usage: es-import-settings [options] 273 | 274 | Options: 275 | 276 | -v, --version output the version number 277 | -u, --url the elasticsearch url to connect to 278 | -f, --file the file to read data from 279 | --masterTimeout ES OPTION: Date, Number — Specify timeout for connection to master 280 | --ignoreUnavailable ES OPTION: Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed) 281 | --allowNoIndices ES OPTION: Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified) 282 | --expandWildcards ES OPTION: String — Whether to expand wildcard expression to concrete indices that are open, closed or both. 283 | -h, --help output usage information 284 | ``` 285 | 286 | ### Examples 287 | 288 | #### import settings to local db 289 | 290 | ```bash 291 | es-import-settings --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.settings.json 292 | ``` 293 | 294 | ## Usage: es-import-aliases 295 | 296 | ### Options 297 | 298 | ```bash 299 | es-import-aliases --help 300 | 301 | Usage: es-import-aliases [options] 302 | 303 | Options: 304 | 305 | -v, --version output the version number 306 | -u, --url the elasticsearch url to connect to 307 | -f, --file the file to read data from 308 | --timeout ES OPTION: Date, Number — Explicit operation timeout 309 | --masterTimeout ES OPTION: Date, Number — Specify timeout for connection to master 310 | -h, --help output usage information 311 | ``` 312 | 313 | ### Examples 314 | 315 | #### import aliases to local db 316 | 317 | ```bash 318 | es-import-aliases --url http://localhost:9200 --file ~/backups/elasticsearch/prod/prod.aliases.json 319 | ``` 320 | 321 | ## Other Elasticsearch Tools 322 | 323 | #### Imports / Exports 324 | 325 | - [elasticdump](https://github.com/taskrabbit/elasticsearch-dump) 326 | - [elasticsearch-exporter](https://github.com/mallocator/Elasticsearch-Exporter) 327 | 328 | ## Running tests 329 | 330 | Unit tests can be ran via: 331 | 332 | ```bash 333 | npm run test 334 | ``` 335 | 336 | The integration tests hit an elasticsearch server at: `localhost:20202`. To 337 | start the server, you can install [docker](https://www.docker.com), then run: 338 | 339 | ```bash 340 | docker-compose up 341 | ``` 342 | 343 | One the server is running, you can run the integration tests via: 344 | 345 | ```bash 346 | npm run test:integration 347 | ``` 348 | 349 | ## License 350 | 351 | Copyright (c) 2014 skratchdot 352 | Licensed under the MIT license. 353 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ## Should Do 2 | 3 | - Add more tests 4 | - Add badges to README 5 | - Add more tools 6 | 7 | ## Might Do 8 | 9 | - Allow different inputs/outputs: url, file, stdin, stdout 10 | - One CLI Tool: instead of multiple cli tools, have 1 tool that uses commands: 11 | - instead of `es-export-bulk [options]` use `es-export bulk [options]` 12 | - instead of `es-import-mappings [options]` use `es-import mappings [options]` 13 | - Config folder/file 14 | - setup .es-tool in the home dir, so --url and --file don't need to be passed each time 15 | - potentially allow aliases (prod vs dev, etc) 16 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.2' 2 | services: 3 | elasticsearch: 4 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.2 5 | container_name: elasticsearch 6 | environment: 7 | - cluster.name=docker-cluster 8 | - bootstrap.memory_lock=true 9 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 10 | ulimits: 11 | memlock: 12 | soft: -1 13 | hard: -1 14 | volumes: 15 | - esdata1:/usr/share/elasticsearch/data 16 | ports: 17 | - 20202:9200 18 | networks: 19 | - esnet 20 | elasticsearch2: 21 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.2 22 | container_name: elasticsearch2 23 | environment: 24 | - cluster.name=docker-cluster 25 | - bootstrap.memory_lock=true 26 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 27 | - "discovery.zen.ping.unicast.hosts=elasticsearch" 28 | ulimits: 29 | memlock: 30 | soft: -1 31 | hard: -1 32 | volumes: 33 | - esdata2:/usr/share/elasticsearch/data 34 | networks: 35 | - esnet 36 | 37 | volumes: 38 | esdata1: 39 | driver: local 40 | esdata2: 41 | driver: local 42 | 43 | networks: 44 | esnet: 45 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | collectCoverageFrom: ['scripts/**/*.js', 'lib/**/*.js'], 4 | coverageReporters: ['text', 'text-summary', 'html', 'json', 'lcovonly'] 5 | }; 6 | -------------------------------------------------------------------------------- /lib/es-export-aliases.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./exporter').indicesExport('getAlias', 'aliases', { 4 | index: 'String, String[], Boolean — A comma-separated list of index names', 5 | local: 6 | 'Boolean — Return local information, do not retrieve the state from master node (default: false)', 7 | name: 8 | 'String, String[], Boolean — The name of the settings that should be included' 9 | }); 10 | -------------------------------------------------------------------------------- /lib/es-export-bulk.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var helpers = require('./helpers'); 5 | var fs = require('fs'); 6 | var vm = require('vm'); 7 | var program = require('commander'); 8 | var elasticsearch = require('elasticsearch'); 9 | var appInfo = require('../package.json'); 10 | var ProgressBar = require('progress'); 11 | var bar, key; 12 | 13 | var esOptions = { 14 | index: 15 | 'a comma-separated list of index names to search; use _all or empty string to perform the operation on all indices', 16 | type: 17 | 'a comma-separated list of document types to search; leave empty to perform the operation on all types', 18 | body: 'the body to send along with this request.', 19 | analyzer: 'The analyzer to use for the query string', 20 | analyzeWildcard: 21 | 'specify whether wildcard and prefix queries should be analyzed (default: false)', 22 | fields: 23 | 'a comma-separated list of fields to return as part of a hit (default: "*")', 24 | from: 'starting offset (default: 0)', 25 | q: 'query in the Lucene query string syntax', 26 | routing: 'a comma-separated list of specific routing values', 27 | scroll: 28 | 'specify how long a consistent view of the index should be maintained for scrolled search (default: 1m)', 29 | size: 'number of hits to return during each scan', 30 | sort: 'a comma-separated list of : pairs', 31 | timeout: 'explicit operation timeout' 32 | }; 33 | 34 | var esClientOptions = { 35 | apiVersion: 36 | 'the major version of the Elasticsearch nodes you will be connecting to (default: 2.3)', 37 | maxRetries: 38 | 'how many times should the client try to connect to other nodes before returning a ConnectionFault error (default: 3)', 39 | requestTimeout: 40 | 'milliseconds before an HTTP request will be aborted and retried. This can also be set per request (default: 30000)', 41 | deadTimeout: 42 | 'milliseconds that a dead connection will wait before attempting to revive itself (default: 60000)', 43 | pingTimeout: 44 | 'milliseconds that a ping request can take before timing out (default: 3000)', 45 | maxSockets: 46 | 'maximum number of concurrent requests that can be made to any node (default: 10)', 47 | minSockets: 48 | 'minimum number of sockets to keep connected to a node (default: 10)', 49 | selector: 50 | 'select a connection from the ConnectionPool using roundRobin (default) or random' 51 | }; 52 | 53 | // setup command line options 54 | program 55 | .version(appInfo.version, '-v, --version') 56 | .option('-u, --url ', 'comma-separated elasticsearch urls to connect to') 57 | .option('-f, --file ', 'the file to write data to') 58 | .option( 59 | '-m, --max ', 60 | 'the maximum number of items to export. different than the scroll size', 61 | parseInt 62 | ) 63 | .option( 64 | '--transformMeta ', 65 | 'a javascript function that returns an object that is the transformed meta object' 66 | ) 67 | .option( 68 | '--transformSource ', 69 | 'a javascript function that returns an object that is the transformed source object' 70 | ) 71 | .option( 72 | '--transformMetaInit ', 73 | 'a javascript function that returns an init object that contains helpers for the transform function' 74 | ) 75 | .option( 76 | '--transformSourceInit ', 77 | 'a javascript function that returns an init object that contains helpers for the transform function' 78 | ); 79 | 80 | // add es options 81 | for (key in esOptions) { 82 | if (esOptions.hasOwnProperty(key)) { 83 | program.option( 84 | '--' + key + ' <' + key + '>', 85 | 'ES OPTION: ' + esOptions[key] 86 | ); 87 | } 88 | } 89 | 90 | // add client options 91 | for (key in esClientOptions) { 92 | if (esClientOptions.hasOwnProperty(key)) { 93 | program.option( 94 | '--' + key + ' <' + key + '>', 95 | 'ES CLIENT OPTION: ' + esClientOptions[key] 96 | ); 97 | } 98 | } 99 | 100 | // parse arguments 101 | program.parse(process.argv); 102 | 103 | // validate url and file 104 | helpers.validateUrlAndFile(program); 105 | 106 | // setup a default scroll value 107 | if (!program.scroll) { 108 | program.scroll = '1m'; 109 | } 110 | 111 | // these can be strings or the contents of files 112 | [ 113 | 'transformMeta', 114 | 'transformSource', 115 | 'transformMetaInit', 116 | 'transformSourceInit' 117 | ].forEach(function(key) { 118 | if ( 119 | program.hasOwnProperty(key) && 120 | typeof program[key] === 'string' && 121 | fs.existsSync(program[key]) 122 | ) { 123 | program[key] = fs.readFileSync(program[key], 'utf-8'); 124 | } 125 | }); 126 | 127 | // get init objects 128 | ['transformMetaInit', 'transformSourceInit'].forEach(function(key) { 129 | if (program.hasOwnProperty(key)) { 130 | program[key] = vm.runInNewContext( 131 | '(function () {' + program[key] + ';return {};}());' 132 | ); 133 | } 134 | }); 135 | 136 | // init client 137 | var clientConfig = { 138 | hosts: program.url.split(',') 139 | }; 140 | for (key in esClientOptions) { 141 | if (esClientOptions.hasOwnProperty(key) && program.hasOwnProperty(key)) { 142 | var value = program[key]; 143 | if (isNaN(value) || key == 'apiVersion') { 144 | clientConfig[key] = program[key]; 145 | } else { 146 | clientConfig[key] = parseInt(program[key]); 147 | } 148 | } 149 | } 150 | 151 | var client = new elasticsearch.Client(clientConfig); 152 | var stdout = program.file == '-'; 153 | 154 | // build our search object 155 | var search = { 156 | _source: true 157 | }; 158 | for (key in esOptions) { 159 | if (esOptions.hasOwnProperty(key) && program.hasOwnProperty(key)) { 160 | search[key] = program[key]; 161 | } 162 | } 163 | 164 | // declare our processing functions 165 | var processed = 0; 166 | var barUpdateSize = 100000; 167 | var processResults = function(error, response) { 168 | var content = '', 169 | hitMax = false, 170 | scrollOptions; 171 | if (error && typeof response === 'string') { 172 | console.log( 173 | '\nattempting to parse invalid json returned from elasticsearch server' 174 | ); 175 | response = vm.runInThisContext( 176 | '(function () {return ' + response + ';}());' 177 | ); 178 | if (typeof response !== 'object') { 179 | helpers.exit('attempt to parse invalid json as javascript failed.'); 180 | } 181 | } else if (error) { 182 | helpers.exit(error); 183 | } 184 | if (response.hits.total === 0) { 185 | helpers.exit('no results were returned, so exiting.'); 186 | } 187 | // init progress bar if needed 188 | if (!bar) { 189 | var halfAPercent = Math.round(response.hits.total * 0.005); 190 | if (halfAPercent < barUpdateSize) barUpdateSize = halfAPercent; 191 | bar = new ProgressBar( 192 | 'processing :current of :total [:bar] :percent :elapseds', 193 | { 194 | width: 20, 195 | total: response.hits.total 196 | } 197 | ); 198 | bar.render(); 199 | } 200 | 201 | // process results 202 | response.hits.hits.forEach(function(hit) { 203 | var meta = { index: {} }; 204 | var source = hit._source || {}; 205 | var fields = hit.fields || {}; 206 | // if we passed in a max, stop processing 207 | if (typeof program.max === 'number' && processed >= program.max) { 208 | hitMax = true; 209 | return; 210 | } 211 | // build meta 212 | for (var key in hit) { 213 | if (hit.hasOwnProperty(key) && key !== '_source' && key !== 'fields') { 214 | meta.index[key] = hit[key]; 215 | } 216 | } 217 | for (key in fields) { 218 | if (fields.hasOwnProperty(key)) { 219 | meta.index[key] = fields[key]; 220 | } 221 | } 222 | // transform meta 223 | if (program.transformMeta) { 224 | meta = vm.runInNewContext( 225 | '(function () {' + program.transformMeta + ';return data;}());', 226 | { 227 | init: program.transformMetaInit, 228 | data: meta, 229 | source: source 230 | } 231 | ); 232 | } 233 | 234 | // transform source 235 | if (program.transformSource) { 236 | source = vm.runInNewContext( 237 | '(function () {' + program.transformSource + ';return data;}());', 238 | { 239 | init: program.transformSourceInit, 240 | data: source, 241 | meta: meta 242 | } 243 | ); 244 | } 245 | 246 | if (typeof meta !== 'object' || typeof source !== 'object') { 247 | helpers.exit({ 248 | message: 'an invalid bulk item was created after transforming data', 249 | meta: meta, 250 | source: source 251 | }); 252 | } 253 | delete meta.index._score; // Remove the score, causes errors in ES 2.3 (maybe earlier versions too) 254 | content += JSON.stringify(meta) + '\n' + JSON.stringify(source) + '\n'; 255 | processed++; 256 | if (processed % barUpdateSize == 0) bar.tick(barUpdateSize); 257 | }); 258 | if (stdout) { 259 | process.stdout.write(content); 260 | } else { 261 | fs.appendFileSync(program.file, content, 'utf-8'); 262 | } 263 | // continue to scroll 264 | if (response.hits.total !== processed && !hitMax) { 265 | scrollOptions = { scrollId: response._scroll_id }; 266 | if (program.scroll) { 267 | scrollOptions.scroll = program.scroll; 268 | } 269 | client.scroll(scrollOptions, processResults); 270 | } else { 271 | bar.tick(processed - Math.floor(processed / barUpdateSize) * barUpdateSize); 272 | console.log('Done!'); 273 | process.exit(); 274 | } 275 | }; 276 | 277 | if (!stdout) { 278 | // empty our file 279 | fs.writeFileSync(program.file, '', 'utf-8'); 280 | } 281 | 282 | // perform our search and start scrolling 283 | client.search(search, processResults); 284 | -------------------------------------------------------------------------------- /lib/es-export-mappings.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./exporter').indicesExport('getMapping', 'mappings', { 4 | index: 'String, String[], Boolean — A comma-separated list of index names', 5 | type: 'String, String[], Boolean — A comma-separated list of document types', 6 | ignoreUnavailable: 7 | 'Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)', 8 | allowNoIndices: 9 | 'Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)', 10 | expandWildcards: 11 | 'String — Whether to expand wildcard expression to concrete indices that are open, closed or both.', 12 | local: 13 | 'Boolean — Return local information, do not retrieve the state from master node (default: false)' 14 | }); 15 | -------------------------------------------------------------------------------- /lib/es-export-settings.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./exporter').indicesExport('getSettings', 'settings', { 4 | index: 'String, String[], Boolean — A comma-separated list of index names', 5 | ignoreUnavailable: 6 | 'Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)', 7 | allowNoIndices: 8 | 'Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)', 9 | expandWildcards: 10 | 'String — Whether to expand wildcard expression to concrete indices that are open, closed or both.', 11 | local: 12 | 'Boolean — Return local information, do not retrieve the state from master node (default: false)', 13 | name: 14 | 'String, String[], Boolean — The name of the settings that should be included' 15 | }); 16 | -------------------------------------------------------------------------------- /lib/es-import-aliases.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./importer').indicesImport('putAlias', 'aliases', 'name', { 4 | timeout: 'Date, Number — Explicit operation timeout', 5 | masterTimeout: 'Date, Number — Specify timeout for connection to master' 6 | }); 7 | -------------------------------------------------------------------------------- /lib/es-import-bulk.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var helpers = require('./helpers'); 5 | var fs = require('fs'); 6 | var program = require('commander'); 7 | var elasticsearch = require('elasticsearch'); 8 | var LineByLineReader = require('line-by-line'); 9 | var appInfo = require('../package.json'); 10 | var filesize = require('filesize'); 11 | var ProgressBar = require('progress'); 12 | var bar; 13 | 14 | // instance variables 15 | var isFileDone = false; 16 | var isPaused = false; 17 | var totalLines = 0; 18 | var currentCount = 0; 19 | var currentBatch = ''; 20 | 21 | // setup command line options 22 | program 23 | .version(appInfo.version, '-v, --version') 24 | .option('-u, --url ', 'the elasticsearch url to connect to') 25 | .option('-f, --file ', 'the file to read data from') 26 | .option( 27 | '-m, --max ', 28 | 'the max number of lines to process per batch (default: 20,000)', 29 | helpers.integer, 30 | 20000 31 | ) 32 | .option( 33 | '--requestTimeout ', 34 | 'ES CLIENT OPTION: milliseconds before an HTTP request will be aborted and retried. This can also be set per request (default: 30000)', 35 | helpers.integer, 36 | 30000 37 | ) 38 | .parse(process.argv); 39 | 40 | // validate url and file 41 | helpers.validateUrlAndFile(program); 42 | 43 | // validate max items per batch 44 | if (program.max <= 0 || Number.isNaN(program.max)) { 45 | helpers.exit('You must pass in a valid --max option'); 46 | } 47 | 48 | // validate file exists 49 | if (!fs.existsSync(program.file)) { 50 | helpers.exit('The file you passed in does not exist.'); 51 | } 52 | 53 | // init client 54 | var client = new elasticsearch.Client({ 55 | requestTimeout: program.requestTimeout, 56 | hosts: program.url.split(',') 57 | }); 58 | 59 | // declare our bulk import function 60 | var bulkImport = function(cb) { 61 | client.bulk({ body: currentBatch }, function(err, response) { 62 | if (err) { 63 | helpers.exit(err); 64 | } 65 | if (response.error) { 66 | helpers.exit('When executing bulk query: ' + response.error.toString()); 67 | } 68 | // reset global variables 69 | currentCount = 0; 70 | currentBatch = ''; 71 | // exit or continue processing 72 | if (isFileDone) { 73 | console.log('Complete!'); 74 | process.exit(); 75 | } else { 76 | cb(); 77 | } 78 | }); 79 | }; 80 | 81 | var filestats = fs.statSync(program.file); 82 | console.log('Pre-Processing file of size: ' + filesize(filestats.size)); 83 | var preprocess = new LineByLineReader(program.file, { 84 | encoding: 'utf8', 85 | skipEmptyLines: false 86 | }); 87 | preprocess.on('error', helpers.exit); 88 | preprocess.on('line', function() { 89 | totalLines++; 90 | }); 91 | preprocess.on('end', function() { 92 | var barUpdateSize = 100000; 93 | var halfAPercent = Math.round(totalLines * 0.005); 94 | if (halfAPercent < barUpdateSize) barUpdateSize = halfAPercent; 95 | 96 | bar = new ProgressBar( 97 | 'Processing line :current of :total [:bar] :percent :elapseds', 98 | { 99 | width: 20, 100 | total: totalLines 101 | } 102 | ); 103 | var lr = new LineByLineReader(program.file, { 104 | encoding: 'utf8', 105 | skipEmptyLines: false 106 | }); 107 | var totalLinesProcessed = 0; 108 | console.log( 109 | 'Starting bulk imports with batches of ' + program.max + ' lines.' 110 | ); 111 | bar.render(); 112 | lr.on('error', function(err) { 113 | helpers.exit(err); 114 | }); 115 | lr.on('line', function(line) { 116 | totalLinesProcessed++; 117 | if (totalLinesProcessed % barUpdateSize == 0) bar.tick(barUpdateSize); 118 | currentCount++; 119 | currentBatch += line + '\n'; 120 | if (currentCount >= program.max && currentCount % 2 === 0) { 121 | lr.pause(); 122 | isPaused = true; 123 | bulkImport(function() { 124 | isPaused = false; 125 | lr.resume(); 126 | }); 127 | } 128 | }); 129 | lr.on('end', function() { 130 | isFileDone = true; 131 | bar.tick( 132 | totalLinesProcessed - 133 | Math.floor(totalLinesProcessed / barUpdateSize) * barUpdateSize 134 | ); 135 | if (!isPaused && currentCount > 0) { 136 | bulkImport(); 137 | } 138 | }); 139 | }); 140 | -------------------------------------------------------------------------------- /lib/es-import-mappings.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./importer').indicesImport('putMapping', 'mappings', 'type', { 4 | ignoreConflicts: 5 | 'Boolean — Specify whether to ignore conflicts while updating the mapping (default: false)', 6 | timeout: 'Date, Number — Explicit operation timeout', 7 | masterTimeout: 'Date, Number — Specify timeout for connection to master', 8 | ignoreUnavailable: 9 | 'Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)', 10 | allowNoIndices: 11 | 'Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)', 12 | expandWildcards: 13 | 'String — Whether to expand wildcard expression to concrete indices that are open, closed or both.' 14 | }); 15 | -------------------------------------------------------------------------------- /lib/es-import-settings.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./importer').indicesImport('putSettings', 'settings', null, { 4 | masterTimeout: 'Date, Number — Specify timeout for connection to master', 5 | ignoreUnavailable: 6 | 'Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)', 7 | allowNoIndices: 8 | 'Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)', 9 | expandWildcards: 10 | 'String — Whether to expand wildcard expression to concrete indices that are open, closed or both.' 11 | }); 12 | -------------------------------------------------------------------------------- /lib/exporter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('./helpers'); 4 | var fs = require('fs'); 5 | var program = require('commander'); 6 | var elasticsearch = require('elasticsearch'); 7 | var appInfo = require('../package.json'); 8 | 9 | exports.indicesExport = function(fnName, exportKey, esOptions) { 10 | var key; 11 | // setup command line options 12 | program 13 | .version(appInfo.version, '-v, --version') 14 | .option('-u, --url ', 'the elasticsearch url to connect to') 15 | .option('-f, --file ', 'the file to write data to'); 16 | // add es options 17 | for (key in esOptions) { 18 | if (esOptions.hasOwnProperty(key)) { 19 | program.option( 20 | '--' + key + ' <' + key + '>', 21 | 'ES OPTION: ' + esOptions[key] 22 | ); 23 | } 24 | } 25 | // parse arguments 26 | program.parse(process.argv); 27 | 28 | // validate url and file 29 | helpers.validateUrlAndFile(program); 30 | 31 | // init client 32 | var client = new elasticsearch.Client({ hosts: program.url.split(',') }); 33 | 34 | // build our params object 35 | var params = {}; 36 | for (key in esOptions) { 37 | if (esOptions.hasOwnProperty(key) && program.hasOwnProperty(key)) { 38 | params[key] = program[key]; 39 | } 40 | } 41 | 42 | // empty our file 43 | fs.writeFileSync(program.file, '', 'utf-8'); 44 | 45 | // get mapping, and write to file 46 | client.indices[fnName](params, function(error, response) { 47 | if (error) { 48 | helpers.exit(error); 49 | } 50 | var keys = Object.keys(response); 51 | fs.appendFileSync( 52 | program.file, 53 | JSON.stringify(response, null, ' '), 54 | 'utf-8' 55 | ); 56 | console.log('Exporting ' + exportKey + ' for: ', keys); 57 | console.log('Done!'); 58 | process.exit(); 59 | }); 60 | }; 61 | -------------------------------------------------------------------------------- /lib/helpers.js: -------------------------------------------------------------------------------- 1 | // a few helper functions 2 | 'use strict'; 3 | 4 | exports.exit = function(err) { 5 | var str = JSON.stringify(err).replace(/^error:/i, ''); 6 | console.error('\n error: ' + str); 7 | process.exit(1); 8 | }; 9 | 10 | exports.validateUrlAndFile = function(program) { 11 | ['url', 'file'].forEach(function(key) { 12 | if (typeof program[key] !== 'string') { 13 | exports.exit('You must pass in a valid --' + key + ' option.'); 14 | } 15 | }); 16 | }; 17 | 18 | exports.integer = function(num) { 19 | return parseInt(num, 10); 20 | }; 21 | -------------------------------------------------------------------------------- /lib/importer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('./helpers'); 4 | var fs = require('fs'); 5 | var program = require('commander'); 6 | var elasticsearch = require('elasticsearch'); 7 | var appInfo = require('../package.json'); 8 | var async = require('async'); 9 | 10 | exports.indicesImport = function(fnName, importKey, alsoInclude, esOptions) { 11 | var key; 12 | // setup command line options 13 | program 14 | .version(appInfo.version, '-v, --version') 15 | .option('-u, --url ', 'the elasticsearch url to connect to') 16 | .option('-f, --file ', 'the file to read data from'); 17 | // add es options 18 | for (key in esOptions) { 19 | if (esOptions.hasOwnProperty(key)) { 20 | program.option( 21 | '--' + key + ' <' + key + '>', 22 | 'ES OPTION: ' + esOptions[key] 23 | ); 24 | } 25 | } 26 | // parse arguments 27 | program.parse(process.argv); 28 | 29 | // validate url and file 30 | helpers.validateUrlAndFile(program); 31 | 32 | // init client 33 | var client = new elasticsearch.Client({ hosts: program.url.split(',') }); 34 | 35 | // build our params object 36 | var params = {}; 37 | for (key in esOptions) { 38 | if (esOptions.hasOwnProperty(key) && program.hasOwnProperty(key)) { 39 | params[key] = program[key]; 40 | } 41 | } 42 | 43 | // read file, and create indexes / keyValues 44 | fs.readFile(program.file, 'utf-8', function(err, contents) { 45 | var parsedContent; 46 | if (err) { 47 | helpers.exit(err); 48 | } 49 | try { 50 | parsedContent = JSON.parse(contents); 51 | } catch (err) { 52 | helpers.exit('Cannot parse file: ' + err.toString()); 53 | } 54 | var indexes = Object.keys(parsedContent); 55 | var keyValues = []; 56 | var created = []; 57 | // build our keyValues array 58 | indexes.forEach(function(index) { 59 | var currentObj = parsedContent[index][importKey]; 60 | // loop through properties 61 | Object.keys(currentObj).forEach(function(prop) { 62 | keyValues.push({ 63 | index: index, 64 | prop: prop, 65 | body: currentObj[prop] 66 | }); 67 | }); 68 | }); 69 | console.log('Creating Indexes (if needed):'); 70 | async.eachSeries( 71 | keyValues, 72 | function(mapping, callback) { 73 | var prefix = ' [index="' + mapping.index + '"]'; 74 | if (created.indexOf(mapping.index) >= 0) { 75 | callback(); 76 | } else { 77 | created.push(mapping.index); 78 | client.indices.exists({ index: mapping.index }, function( 79 | error, 80 | response 81 | ) { 82 | if (err) { 83 | callback(err); 84 | } else if (response) { 85 | console.log(prefix + ' - exists'); 86 | callback(); 87 | } else { 88 | console.log(prefix + ' - creating'); 89 | client.indices.create({ index: mapping.index }, callback); 90 | } 91 | }); 92 | } 93 | }, 94 | function(err) { 95 | if (err) { 96 | helpers.exit(err); 97 | } 98 | console.log('Creating ' + importKey + ':'); 99 | async.eachSeries( 100 | keyValues, 101 | function(mapping, callback) { 102 | // put mapping 103 | console.log( 104 | ' [index="' + mapping.index + '", prop="' + mapping.prop + '"]' 105 | ); 106 | params.index = mapping.index; 107 | if (typeof alsoInclude === 'string') { 108 | params[alsoInclude] = mapping.prop; 109 | } 110 | params.body = mapping.body; 111 | client.indices[fnName](params, callback); 112 | }, 113 | function(err) { 114 | if (err) { 115 | helpers.exit(err); 116 | } 117 | console.log('Done!'); 118 | process.exit(); 119 | } 120 | ); 121 | } 122 | ); 123 | }); 124 | }; 125 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elasticsearch-tools", 3 | "version": "5.0.0", 4 | "description": "Elasticsearch command line tools for importing, exporting, etc", 5 | "homepage": "http://github.com/skratchdot/elasticsearch-tools", 6 | "preferGlobal": true, 7 | "bin": { 8 | "es-export-aliases": "./lib/es-export-aliases.js", 9 | "es-export-bulk": "./lib/es-export-bulk.js", 10 | "es-export-mappings": "./lib/es-export-mappings.js", 11 | "es-export-settings": "./lib/es-export-settings.js", 12 | "es-import-aliases": "./lib/es-import-aliases.js", 13 | "es-import-bulk": "./lib/es-import-bulk.js", 14 | "es-import-mappings": "./lib/es-import-mappings.js", 15 | "es-import-settings": "./lib/es-import-settings.js" 16 | }, 17 | "author": "skratchdot", 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/skratchdot/elasticsearch-tools.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/skratchdot/elasticsearch-tools/issues" 25 | }, 26 | "scripts": { 27 | "build": "npm-run-all readme format lint cover", 28 | "cover": "npm run test -- --coverage", 29 | "format": "prettier --write --single-quote ./**/*.js ./*.{js,md}", 30 | "lint": "eslint .", 31 | "readme": "./scripts/build-readme.js", 32 | "test": "jest tests/unit/", 33 | "test:integration": "jest tests/integration/" 34 | }, 35 | "dependencies": { 36 | "commander": "^2.9.0", 37 | "elasticsearch": "^15.1.1", 38 | "filesize": "^3.2.0", 39 | "line-by-line": "^0.1.4", 40 | "prettier": "^1.10.2", 41 | "progress": "^2.0.0" 42 | }, 43 | "devDependencies": { 44 | "async": "^2.6.0", 45 | "eslint": "^5.2.0", 46 | "jest": "^23.4.1", 47 | "npm-run-all": "^4.1.2" 48 | }, 49 | "keywords": [ 50 | "elasticsearch", 51 | "es", 52 | "cli", 53 | "import", 54 | "export", 55 | "dump", 56 | "restore", 57 | "mappings", 58 | "data", 59 | "schema" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /scripts/build-readme.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const fs = require('fs'); 3 | const { execSync } = require('child_process'); 4 | 5 | const filename = `${__dirname}/../README.md`; 6 | let contents = fs.readFileSync(filename, 'utf8'); 7 | 8 | const setSection = (tool, contents) => { 9 | const re = new RegExp( 10 | `([\\S\\s]*?)(\\n## Usage: ${tool}\\n\\n### Options\\n\\n\`\`\`bash\\n)([\\S\\s]*?)(\`\`\`)([\\S\\s]*)` 11 | ); 12 | const output = execSync(`node ${__dirname}/../lib/${tool}.js --help`) 13 | .toString() 14 | .trim(); 15 | const help = `${tool} --help\n\n${output}\n`; 16 | return contents.replace(re, `$1$2${help}$4$5`); 17 | }; 18 | 19 | ['aliases', 'bulk', 'mappings', 'settings'].forEach(key => { 20 | contents = setSection(`es-import-${key}`, contents); 21 | contents = setSection(`es-import-${key}`, contents); 22 | }); 23 | fs.writeFileSync(filename, contents, 'utf8'); 24 | -------------------------------------------------------------------------------- /tests/fixtures/docker-compose-cluster.yml: -------------------------------------------------------------------------------- 1 | version: '2.2' 2 | services: 3 | elasticsearch: 4 | image: docker.elastic.co/elasticsearch/elasticsearch:6.1.2 5 | container_name: elasticsearch 6 | environment: 7 | - cluster.name=docker-cluster 8 | - bootstrap.memory_lock=true 9 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 10 | ulimits: 11 | memlock: 12 | soft: -1 13 | hard: -1 14 | volumes: 15 | - esdata1:/usr/share/elasticsearch/data 16 | ports: 17 | - 9200:9200 18 | networks: 19 | - esnet 20 | elasticsearch2: 21 | image: docker.elastic.co/elasticsearch/elasticsearch:6.1.2 22 | container_name: elasticsearch2 23 | environment: 24 | - cluster.name=docker-cluster 25 | - bootstrap.memory_lock=true 26 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 27 | - "discovery.zen.ping.unicast.hosts=elasticsearch" 28 | ulimits: 29 | memlock: 30 | soft: -1 31 | hard: -1 32 | volumes: 33 | - esdata2:/usr/share/elasticsearch/data 34 | networks: 35 | - esnet 36 | 37 | volumes: 38 | esdata1: 39 | driver: local 40 | esdata2: 41 | driver: local 42 | 43 | networks: 44 | esnet: 45 | -------------------------------------------------------------------------------- /tests/fixtures/docker-compose-kibana.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | kibana: 4 | image: docker.elastic.co/kibana/kibana-oss:6.1.2 5 | links: 6 | - elasticsearch 7 | ports: 8 | - 5601:5601 9 | elasticsearch: 10 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.2 11 | cap_add: 12 | - IPC_LOCK 13 | volumes: 14 | - esdata1:/usr/share/elasticsearch/data 15 | ports: 16 | - 9200:9200 17 | volumes: 18 | esdata1: 19 | driver: local 20 | -------------------------------------------------------------------------------- /tests/fixtures/import-tests/aliases.txt: -------------------------------------------------------------------------------- 1 | { 2 | "test-lib": { 3 | "aliases": {} 4 | } 5 | } -------------------------------------------------------------------------------- /tests/fixtures/import-tests/bulk.txt: -------------------------------------------------------------------------------- 1 | {"index":{"_index":"test-lib","_type":"groups","_id":"14"}} 2 | {"title":"temp-data-a-13","group":"a","value":13} 3 | {"index":{"_index":"test-lib","_type":"groups","_id":"19"}} 4 | {"title":"temp-data-a-18","group":"a","value":18} 5 | {"index":{"_index":"test-lib","_type":"groups","_id":"22"}} 6 | {"title":"temp-data-a-21","group":"a","value":21} 7 | {"index":{"_index":"test-lib","_type":"groups","_id":"24"}} 8 | {"title":"temp-data-a-23","group":"a","value":23} 9 | {"index":{"_index":"test-lib","_type":"groups","_id":"25"}} 10 | {"title":"temp-data-a-24","group":"a","value":24} 11 | {"index":{"_index":"test-lib","_type":"groups","_id":"26"}} 12 | {"title":"temp-data-a-25","group":"a","value":25} 13 | {"index":{"_index":"test-lib","_type":"groups","_id":"29"}} 14 | {"title":"temp-data-a-28","group":"a","value":28} 15 | {"index":{"_index":"test-lib","_type":"groups","_id":"40"}} 16 | {"title":"temp-data-a-39","group":"a","value":39} 17 | {"index":{"_index":"test-lib","_type":"groups","_id":"41"}} 18 | {"title":"temp-data-a-40","group":"a","value":40} 19 | {"index":{"_index":"test-lib","_type":"groups","_id":"44"}} 20 | {"title":"temp-data-a-43","group":"a","value":43} 21 | {"index":{"_index":"test-lib","_type":"groups","_id":"48"}} 22 | {"title":"temp-data-a-47","group":"a","value":47} 23 | {"index":{"_index":"test-lib","_type":"groups","_id":"73"}} 24 | {"title":"temp-data-b-22","group":"b","value":22} 25 | {"index":{"_index":"test-lib","_type":"groups","_id":"79"}} 26 | {"title":"temp-data-b-28","group":"b","value":28} 27 | {"index":{"_index":"test-lib","_type":"groups","_id":"84"}} 28 | {"title":"temp-data-b-33","group":"b","value":33} 29 | {"index":{"_index":"test-lib","_type":"groups","_id":"89"}} 30 | {"title":"temp-data-b-38","group":"b","value":38} 31 | {"index":{"_index":"test-lib","_type":"groups","_id":"92"}} 32 | {"title":"temp-data-b-41","group":"b","value":41} 33 | {"index":{"_index":"test-lib","_type":"groups","_id":"98"}} 34 | {"title":"temp-data-b-47","group":"b","value":47} 35 | {"index":{"_index":"test-lib","_type":"groups","_id":"52"}} 36 | {"title":"temp-data-b-1","group":"b","value":1} 37 | {"index":{"_index":"test-lib","_type":"groups","_id":"60"}} 38 | {"title":"temp-data-b-9","group":"b","value":9} 39 | {"index":{"_index":"test-lib","_type":"groups","_id":"116"}} 40 | {"title":"temp-data-c-15","group":"c","value":15} 41 | {"index":{"_index":"test-lib","_type":"groups","_id":"119"}} 42 | {"title":"temp-data-c-18","group":"c","value":18} 43 | {"index":{"_index":"test-lib","_type":"groups","_id":"120"}} 44 | {"title":"temp-data-c-19","group":"c","value":19} 45 | {"index":{"_index":"test-lib","_type":"groups","_id":"123"}} 46 | {"title":"temp-data-c-22","group":"c","value":22} 47 | {"index":{"_index":"test-lib","_type":"groups","_id":"126"}} 48 | {"title":"temp-data-c-25","group":"c","value":25} 49 | {"index":{"_index":"test-lib","_type":"groups","_id":"99"}} 50 | {"title":"temp-data-b-48","group":"b","value":48} 51 | {"index":{"_index":"test-lib","_type":"groups","_id":"105"}} 52 | {"title":"temp-data-c-4","group":"c","value":4} 53 | {"index":{"_index":"test-lib","_type":"groups","_id":"108"}} 54 | {"title":"temp-data-c-7","group":"c","value":7} 55 | {"index":{"_index":"test-lib","_type":"groups","_id":"110"}} 56 | {"title":"temp-data-c-9","group":"c","value":9} 57 | {"index":{"_index":"test-lib","_type":"groups","_id":"145"}} 58 | {"title":"temp-data-c-44","group":"c","value":44} 59 | {"index":{"_index":"test-lib","_type":"groups","_id":"149"}} 60 | {"title":"temp-data-c-48","group":"c","value":48} 61 | {"index":{"_index":"test-lib","_type":"groups","_id":"166"}} 62 | {"title":"temp-data-d-15","group":"d","value":15} 63 | {"index":{"_index":"test-lib","_type":"groups","_id":"172"}} 64 | {"title":"temp-data-d-21","group":"d","value":21} 65 | {"index":{"_index":"test-lib","_type":"groups","_id":"129"}} 66 | {"title":"temp-data-c-28","group":"c","value":28} 67 | {"index":{"_index":"test-lib","_type":"groups","_id":"130"}} 68 | {"title":"temp-data-c-29","group":"c","value":29} 69 | {"index":{"_index":"test-lib","_type":"groups","_id":"132"}} 70 | {"title":"temp-data-c-31","group":"c","value":31} 71 | {"index":{"_index":"test-lib","_type":"groups","_id":"143"}} 72 | {"title":"temp-data-c-42","group":"c","value":42} 73 | {"index":{"_index":"test-lib","_type":"groups","_id":"144"}} 74 | {"title":"temp-data-c-43","group":"c","value":43} 75 | {"index":{"_index":"test-lib","_type":"groups","_id":"183"}} 76 | {"title":"temp-data-d-32","group":"d","value":32} 77 | {"index":{"_index":"test-lib","_type":"groups","_id":"190"}} 78 | {"title":"temp-data-d-39","group":"d","value":39} 79 | {"index":{"_index":"test-lib","_type":"groups","_id":"5"}} 80 | {"title":"temp-data-a-4","group":"a","value":4} 81 | {"index":{"_index":"test-lib","_type":"groups","_id":"8"}} 82 | {"title":"temp-data-a-7","group":"a","value":7} 83 | {"index":{"_index":"test-lib","_type":"groups","_id":"9"}} 84 | {"title":"temp-data-a-8","group":"a","value":8} 85 | {"index":{"_index":"test-lib","_type":"groups","_id":"10"}} 86 | {"title":"temp-data-a-9","group":"a","value":9} 87 | {"index":{"_index":"test-lib","_type":"groups","_id":"12"}} 88 | {"title":"temp-data-a-11","group":"a","value":11} 89 | {"index":{"_index":"test-lib","_type":"groups","_id":"21"}} 90 | {"title":"temp-data-a-20","group":"a","value":20} 91 | {"index":{"_index":"test-lib","_type":"groups","_id":"30"}} 92 | {"title":"temp-data-a-29","group":"a","value":29} 93 | {"index":{"_index":"test-lib","_type":"groups","_id":"32"}} 94 | {"title":"temp-data-a-31","group":"a","value":31} 95 | {"index":{"_index":"test-lib","_type":"groups","_id":"33"}} 96 | {"title":"temp-data-a-32","group":"a","value":32} 97 | {"index":{"_index":"test-lib","_type":"groups","_id":"34"}} 98 | {"title":"temp-data-a-33","group":"a","value":33} 99 | {"index":{"_index":"test-lib","_type":"groups","_id":"42"}} 100 | {"title":"temp-data-a-41","group":"a","value":41} 101 | {"index":{"_index":"test-lib","_type":"groups","_id":"62"}} 102 | {"title":"temp-data-b-11","group":"b","value":11} 103 | {"index":{"_index":"test-lib","_type":"groups","_id":"65"}} 104 | {"title":"temp-data-b-14","group":"b","value":14} 105 | {"index":{"_index":"test-lib","_type":"groups","_id":"70"}} 106 | {"title":"temp-data-b-19","group":"b","value":19} 107 | {"index":{"_index":"test-lib","_type":"groups","_id":"78"}} 108 | {"title":"temp-data-b-27","group":"b","value":27} 109 | {"index":{"_index":"test-lib","_type":"groups","_id":"59"}} 110 | {"title":"temp-data-b-8","group":"b","value":8} 111 | {"index":{"_index":"test-lib","_type":"groups","_id":"100"}} 112 | {"title":"temp-data-b-49","group":"b","value":49} 113 | {"index":{"_index":"test-lib","_type":"groups","_id":"82"}} 114 | {"title":"temp-data-b-31","group":"b","value":31} 115 | {"index":{"_index":"test-lib","_type":"groups","_id":"87"}} 116 | {"title":"temp-data-b-36","group":"b","value":36} 117 | {"index":{"_index":"test-lib","_type":"groups","_id":"88"}} 118 | {"title":"temp-data-b-37","group":"b","value":37} 119 | {"index":{"_index":"test-lib","_type":"groups","_id":"94"}} 120 | {"title":"temp-data-b-43","group":"b","value":43} 121 | {"index":{"_index":"test-lib","_type":"groups","_id":"96"}} 122 | {"title":"temp-data-b-45","group":"b","value":45} 123 | {"index":{"_index":"test-lib","_type":"groups","_id":"101"}} 124 | {"title":"temp-data-c-0","group":"c","value":0} 125 | {"index":{"_index":"test-lib","_type":"groups","_id":"103"}} 126 | {"title":"temp-data-c-2","group":"c","value":2} 127 | {"index":{"_index":"test-lib","_type":"groups","_id":"104"}} 128 | {"title":"temp-data-c-3","group":"c","value":3} 129 | {"index":{"_index":"test-lib","_type":"groups","_id":"113"}} 130 | {"title":"temp-data-c-12","group":"c","value":12} 131 | {"index":{"_index":"test-lib","_type":"groups","_id":"117"}} 132 | {"title":"temp-data-c-16","group":"c","value":16} 133 | {"index":{"_index":"test-lib","_type":"groups","_id":"127"}} 134 | {"title":"temp-data-c-26","group":"c","value":26} 135 | {"index":{"_index":"test-lib","_type":"groups","_id":"135"}} 136 | {"title":"temp-data-c-34","group":"c","value":34} 137 | {"index":{"_index":"test-lib","_type":"groups","_id":"136"}} 138 | {"title":"temp-data-c-35","group":"c","value":35} 139 | {"index":{"_index":"test-lib","_type":"groups","_id":"137"}} 140 | {"title":"temp-data-c-36","group":"c","value":36} 141 | {"index":{"_index":"test-lib","_type":"groups","_id":"142"}} 142 | {"title":"temp-data-c-41","group":"c","value":41} 143 | {"index":{"_index":"test-lib","_type":"groups","_id":"146"}} 144 | {"title":"temp-data-c-45","group":"c","value":45} 145 | {"index":{"_index":"test-lib","_type":"groups","_id":"157"}} 146 | {"title":"temp-data-d-6","group":"d","value":6} 147 | {"index":{"_index":"test-lib","_type":"groups","_id":"160"}} 148 | {"title":"temp-data-d-9","group":"d","value":9} 149 | {"index":{"_index":"test-lib","_type":"groups","_id":"164"}} 150 | {"title":"temp-data-d-13","group":"d","value":13} 151 | {"index":{"_index":"test-lib","_type":"groups","_id":"168"}} 152 | {"title":"temp-data-d-17","group":"d","value":17} 153 | {"index":{"_index":"test-lib","_type":"groups","_id":"191"}} 154 | {"title":"temp-data-d-40","group":"d","value":40} 155 | {"index":{"_index":"test-lib","_type":"groups","_id":"200"}} 156 | {"title":"temp-data-d-49","group":"d","value":49} 157 | {"index":{"_index":"test-lib","_type":"groups","_id":"15"}} 158 | {"title":"temp-data-a-14","group":"a","value":14} 159 | {"index":{"_index":"test-lib","_type":"groups","_id":"20"}} 160 | {"title":"temp-data-a-19","group":"a","value":19} 161 | {"index":{"_index":"test-lib","_type":"groups","_id":"27"}} 162 | {"title":"temp-data-a-26","group":"a","value":26} 163 | {"index":{"_index":"test-lib","_type":"groups","_id":"35"}} 164 | {"title":"temp-data-a-34","group":"a","value":34} 165 | {"index":{"_index":"test-lib","_type":"groups","_id":"36"}} 166 | {"title":"temp-data-a-35","group":"a","value":35} 167 | {"index":{"_index":"test-lib","_type":"groups","_id":"38"}} 168 | {"title":"temp-data-a-37","group":"a","value":37} 169 | {"index":{"_index":"test-lib","_type":"groups","_id":"43"}} 170 | {"title":"temp-data-a-42","group":"a","value":42} 171 | {"index":{"_index":"test-lib","_type":"groups","_id":"2"}} 172 | {"title":"temp-data-a-1","group":"a","value":1} 173 | {"index":{"_index":"test-lib","_type":"groups","_id":"4"}} 174 | {"title":"temp-data-a-3","group":"a","value":3} 175 | {"index":{"_index":"test-lib","_type":"groups","_id":"6"}} 176 | {"title":"temp-data-a-5","group":"a","value":5} 177 | {"index":{"_index":"test-lib","_type":"groups","_id":"80"}} 178 | {"title":"temp-data-b-29","group":"b","value":29} 179 | {"index":{"_index":"test-lib","_type":"groups","_id":"85"}} 180 | {"title":"temp-data-b-34","group":"b","value":34} 181 | {"index":{"_index":"test-lib","_type":"groups","_id":"93"}} 182 | {"title":"temp-data-b-42","group":"b","value":42} 183 | {"index":{"_index":"test-lib","_type":"groups","_id":"106"}} 184 | {"title":"temp-data-c-5","group":"c","value":5} 185 | {"index":{"_index":"test-lib","_type":"groups","_id":"109"}} 186 | {"title":"temp-data-c-8","group":"c","value":8} 187 | {"index":{"_index":"test-lib","_type":"groups","_id":"51"}} 188 | {"title":"temp-data-b-0","group":"b","value":0} 189 | {"index":{"_index":"test-lib","_type":"groups","_id":"54"}} 190 | {"title":"temp-data-b-3","group":"b","value":3} 191 | {"index":{"_index":"test-lib","_type":"groups","_id":"55"}} 192 | {"title":"temp-data-b-4","group":"b","value":4} 193 | {"index":{"_index":"test-lib","_type":"groups","_id":"57"}} 194 | {"title":"temp-data-b-6","group":"b","value":6} 195 | {"index":{"_index":"test-lib","_type":"groups","_id":"114"}} 196 | {"title":"temp-data-c-13","group":"c","value":13} 197 | {"index":{"_index":"test-lib","_type":"groups","_id":"118"}} 198 | {"title":"temp-data-c-17","group":"c","value":17} 199 | {"index":{"_index":"test-lib","_type":"groups","_id":"131"}} 200 | {"title":"temp-data-c-30","group":"c","value":30} 201 | {"index":{"_index":"test-lib","_type":"groups","_id":"134"}} 202 | {"title":"temp-data-c-33","group":"c","value":33} 203 | {"index":{"_index":"test-lib","_type":"groups","_id":"150"}} 204 | {"title":"temp-data-c-49","group":"c","value":49} 205 | {"index":{"_index":"test-lib","_type":"groups","_id":"161"}} 206 | {"title":"temp-data-d-10","group":"d","value":10} 207 | {"index":{"_index":"test-lib","_type":"groups","_id":"162"}} 208 | {"title":"temp-data-d-11","group":"d","value":11} 209 | {"index":{"_index":"test-lib","_type":"groups","_id":"163"}} 210 | {"title":"temp-data-d-12","group":"d","value":12} 211 | {"index":{"_index":"test-lib","_type":"groups","_id":"159"}} 212 | {"title":"temp-data-d-8","group":"d","value":8} 213 | {"index":{"_index":"test-lib","_type":"groups","_id":"180"}} 214 | {"title":"temp-data-d-29","group":"d","value":29} 215 | {"index":{"_index":"test-lib","_type":"groups","_id":"188"}} 216 | {"title":"temp-data-d-37","group":"d","value":37} 217 | {"index":{"_index":"test-lib","_type":"groups","_id":"198"}} 218 | {"title":"temp-data-d-47","group":"d","value":47} 219 | {"index":{"_index":"test-lib","_type":"groups","_id":"199"}} 220 | {"title":"temp-data-d-48","group":"d","value":48} 221 | {"index":{"_index":"test-lib","_type":"groups","_id":"169"}} 222 | {"title":"temp-data-d-18","group":"d","value":18} 223 | {"index":{"_index":"test-lib","_type":"groups","_id":"170"}} 224 | {"title":"temp-data-d-19","group":"d","value":19} 225 | {"index":{"_index":"test-lib","_type":"groups","_id":"175"}} 226 | {"title":"temp-data-d-24","group":"d","value":24} 227 | {"index":{"_index":"test-lib","_type":"groups","_id":"176"}} 228 | {"title":"temp-data-d-25","group":"d","value":25} 229 | {"index":{"_index":"test-lib","_type":"groups","_id":"178"}} 230 | {"title":"temp-data-d-27","group":"d","value":27} 231 | {"index":{"_index":"test-lib","_type":"groups","_id":"13"}} 232 | {"title":"temp-data-a-12","group":"a","value":12} 233 | {"index":{"_index":"test-lib","_type":"groups","_id":"16"}} 234 | {"title":"temp-data-a-15","group":"a","value":15} 235 | {"index":{"_index":"test-lib","_type":"groups","_id":"18"}} 236 | {"title":"temp-data-a-17","group":"a","value":17} 237 | {"index":{"_index":"test-lib","_type":"groups","_id":"28"}} 238 | {"title":"temp-data-a-27","group":"a","value":27} 239 | {"index":{"_index":"test-lib","_type":"groups","_id":"39"}} 240 | {"title":"temp-data-a-38","group":"a","value":38} 241 | {"index":{"_index":"test-lib","_type":"groups","_id":"46"}} 242 | {"title":"temp-data-a-45","group":"a","value":45} 243 | {"index":{"_index":"test-lib","_type":"groups","_id":"49"}} 244 | {"title":"temp-data-a-48","group":"a","value":48} 245 | {"index":{"_index":"test-lib","_type":"groups","_id":"66"}} 246 | {"title":"temp-data-b-15","group":"b","value":15} 247 | {"index":{"_index":"test-lib","_type":"groups","_id":"1"}} 248 | {"title":"temp-data-a-0","group":"a","value":0} 249 | {"index":{"_index":"test-lib","_type":"groups","_id":"7"}} 250 | {"title":"temp-data-a-6","group":"a","value":6} 251 | {"index":{"_index":"test-lib","_type":"groups","_id":"67"}} 252 | {"title":"temp-data-b-16","group":"b","value":16} 253 | {"index":{"_index":"test-lib","_type":"groups","_id":"71"}} 254 | {"title":"temp-data-b-20","group":"b","value":20} 255 | {"index":{"_index":"test-lib","_type":"groups","_id":"72"}} 256 | {"title":"temp-data-b-21","group":"b","value":21} 257 | {"index":{"_index":"test-lib","_type":"groups","_id":"77"}} 258 | {"title":"temp-data-b-26","group":"b","value":26} 259 | {"index":{"_index":"test-lib","_type":"groups","_id":"81"}} 260 | {"title":"temp-data-b-30","group":"b","value":30} 261 | {"index":{"_index":"test-lib","_type":"groups","_id":"86"}} 262 | {"title":"temp-data-b-35","group":"b","value":35} 263 | {"index":{"_index":"test-lib","_type":"groups","_id":"95"}} 264 | {"title":"temp-data-b-44","group":"b","value":44} 265 | {"index":{"_index":"test-lib","_type":"groups","_id":"97"}} 266 | {"title":"temp-data-b-46","group":"b","value":46} 267 | {"index":{"_index":"test-lib","_type":"groups","_id":"107"}} 268 | {"title":"temp-data-c-6","group":"c","value":6} 269 | {"index":{"_index":"test-lib","_type":"groups","_id":"111"}} 270 | {"title":"temp-data-c-10","group":"c","value":10} 271 | {"index":{"_index":"test-lib","_type":"groups","_id":"112"}} 272 | {"title":"temp-data-c-11","group":"c","value":11} 273 | {"index":{"_index":"test-lib","_type":"groups","_id":"115"}} 274 | {"title":"temp-data-c-14","group":"c","value":14} 275 | {"index":{"_index":"test-lib","_type":"groups","_id":"121"}} 276 | {"title":"temp-data-c-20","group":"c","value":20} 277 | {"index":{"_index":"test-lib","_type":"groups","_id":"124"}} 278 | {"title":"temp-data-c-23","group":"c","value":23} 279 | {"index":{"_index":"test-lib","_type":"groups","_id":"125"}} 280 | {"title":"temp-data-c-24","group":"c","value":24} 281 | {"index":{"_index":"test-lib","_type":"groups","_id":"128"}} 282 | {"title":"temp-data-c-27","group":"c","value":27} 283 | {"index":{"_index":"test-lib","_type":"groups","_id":"138"}} 284 | {"title":"temp-data-c-37","group":"c","value":37} 285 | {"index":{"_index":"test-lib","_type":"groups","_id":"139"}} 286 | {"title":"temp-data-c-38","group":"c","value":38} 287 | {"index":{"_index":"test-lib","_type":"groups","_id":"181"}} 288 | {"title":"temp-data-d-30","group":"d","value":30} 289 | {"index":{"_index":"test-lib","_type":"groups","_id":"185"}} 290 | {"title":"temp-data-d-34","group":"d","value":34} 291 | {"index":{"_index":"test-lib","_type":"groups","_id":"187"}} 292 | {"title":"temp-data-d-36","group":"d","value":36} 293 | {"index":{"_index":"test-lib","_type":"groups","_id":"189"}} 294 | {"title":"temp-data-d-38","group":"d","value":38} 295 | {"index":{"_index":"test-lib","_type":"groups","_id":"140"}} 296 | {"title":"temp-data-c-39","group":"c","value":39} 297 | {"index":{"_index":"test-lib","_type":"groups","_id":"147"}} 298 | {"title":"temp-data-c-46","group":"c","value":46} 299 | {"index":{"_index":"test-lib","_type":"groups","_id":"179"}} 300 | {"title":"temp-data-d-28","group":"d","value":28} 301 | {"index":{"_index":"test-lib","_type":"groups","_id":"155"}} 302 | {"title":"temp-data-d-4","group":"d","value":4} 303 | {"index":{"_index":"test-lib","_type":"groups","_id":"158"}} 304 | {"title":"temp-data-d-7","group":"d","value":7} 305 | {"index":{"_index":"test-lib","_type":"groups","_id":"197"}} 306 | {"title":"temp-data-d-46","group":"d","value":46} 307 | {"index":{"_index":"test-lib","_type":"groups","_id":"11"}} 308 | {"title":"temp-data-a-10","group":"a","value":10} 309 | {"index":{"_index":"test-lib","_type":"groups","_id":"17"}} 310 | {"title":"temp-data-a-16","group":"a","value":16} 311 | {"index":{"_index":"test-lib","_type":"groups","_id":"23"}} 312 | {"title":"temp-data-a-22","group":"a","value":22} 313 | {"index":{"_index":"test-lib","_type":"groups","_id":"31"}} 314 | {"title":"temp-data-a-30","group":"a","value":30} 315 | {"index":{"_index":"test-lib","_type":"groups","_id":"37"}} 316 | {"title":"temp-data-a-36","group":"a","value":36} 317 | {"index":{"_index":"test-lib","_type":"groups","_id":"45"}} 318 | {"title":"temp-data-a-44","group":"a","value":44} 319 | {"index":{"_index":"test-lib","_type":"groups","_id":"47"}} 320 | {"title":"temp-data-a-46","group":"a","value":46} 321 | {"index":{"_index":"test-lib","_type":"groups","_id":"50"}} 322 | {"title":"temp-data-a-49","group":"a","value":49} 323 | {"index":{"_index":"test-lib","_type":"groups","_id":"3"}} 324 | {"title":"temp-data-a-2","group":"a","value":2} 325 | {"index":{"_index":"test-lib","_type":"groups","_id":"53"}} 326 | {"title":"temp-data-b-2","group":"b","value":2} 327 | {"index":{"_index":"test-lib","_type":"groups","_id":"61"}} 328 | {"title":"temp-data-b-10","group":"b","value":10} 329 | {"index":{"_index":"test-lib","_type":"groups","_id":"63"}} 330 | {"title":"temp-data-b-12","group":"b","value":12} 331 | {"index":{"_index":"test-lib","_type":"groups","_id":"64"}} 332 | {"title":"temp-data-b-13","group":"b","value":13} 333 | {"index":{"_index":"test-lib","_type":"groups","_id":"68"}} 334 | {"title":"temp-data-b-17","group":"b","value":17} 335 | {"index":{"_index":"test-lib","_type":"groups","_id":"69"}} 336 | {"title":"temp-data-b-18","group":"b","value":18} 337 | {"index":{"_index":"test-lib","_type":"groups","_id":"74"}} 338 | {"title":"temp-data-b-23","group":"b","value":23} 339 | {"index":{"_index":"test-lib","_type":"groups","_id":"75"}} 340 | {"title":"temp-data-b-24","group":"b","value":24} 341 | {"index":{"_index":"test-lib","_type":"groups","_id":"56"}} 342 | {"title":"temp-data-b-5","group":"b","value":5} 343 | {"index":{"_index":"test-lib","_type":"groups","_id":"58"}} 344 | {"title":"temp-data-b-7","group":"b","value":7} 345 | {"index":{"_index":"test-lib","_type":"groups","_id":"122"}} 346 | {"title":"temp-data-c-21","group":"c","value":21} 347 | {"index":{"_index":"test-lib","_type":"groups","_id":"133"}} 348 | {"title":"temp-data-c-32","group":"c","value":32} 349 | {"index":{"_index":"test-lib","_type":"groups","_id":"141"}} 350 | {"title":"temp-data-c-40","group":"c","value":40} 351 | {"index":{"_index":"test-lib","_type":"groups","_id":"148"}} 352 | {"title":"temp-data-c-47","group":"c","value":47} 353 | {"index":{"_index":"test-lib","_type":"groups","_id":"76"}} 354 | {"title":"temp-data-b-25","group":"b","value":25} 355 | {"index":{"_index":"test-lib","_type":"groups","_id":"83"}} 356 | {"title":"temp-data-b-32","group":"b","value":32} 357 | {"index":{"_index":"test-lib","_type":"groups","_id":"90"}} 358 | {"title":"temp-data-b-39","group":"b","value":39} 359 | {"index":{"_index":"test-lib","_type":"groups","_id":"91"}} 360 | {"title":"temp-data-b-40","group":"b","value":40} 361 | {"index":{"_index":"test-lib","_type":"groups","_id":"102"}} 362 | {"title":"temp-data-c-1","group":"c","value":1} 363 | {"index":{"_index":"test-lib","_type":"groups","_id":"165"}} 364 | {"title":"temp-data-d-14","group":"d","value":14} 365 | {"index":{"_index":"test-lib","_type":"groups","_id":"167"}} 366 | {"title":"temp-data-d-16","group":"d","value":16} 367 | {"index":{"_index":"test-lib","_type":"groups","_id":"171"}} 368 | {"title":"temp-data-d-20","group":"d","value":20} 369 | {"index":{"_index":"test-lib","_type":"groups","_id":"173"}} 370 | {"title":"temp-data-d-22","group":"d","value":22} 371 | {"index":{"_index":"test-lib","_type":"groups","_id":"151"}} 372 | {"title":"temp-data-d-0","group":"d","value":0} 373 | {"index":{"_index":"test-lib","_type":"groups","_id":"152"}} 374 | {"title":"temp-data-d-1","group":"d","value":1} 375 | {"index":{"_index":"test-lib","_type":"groups","_id":"153"}} 376 | {"title":"temp-data-d-2","group":"d","value":2} 377 | {"index":{"_index":"test-lib","_type":"groups","_id":"154"}} 378 | {"title":"temp-data-d-3","group":"d","value":3} 379 | {"index":{"_index":"test-lib","_type":"groups","_id":"156"}} 380 | {"title":"temp-data-d-5","group":"d","value":5} 381 | {"index":{"_index":"test-lib","_type":"groups","_id":"174"}} 382 | {"title":"temp-data-d-23","group":"d","value":23} 383 | {"index":{"_index":"test-lib","_type":"groups","_id":"177"}} 384 | {"title":"temp-data-d-26","group":"d","value":26} 385 | {"index":{"_index":"test-lib","_type":"groups","_id":"182"}} 386 | {"title":"temp-data-d-31","group":"d","value":31} 387 | {"index":{"_index":"test-lib","_type":"groups","_id":"184"}} 388 | {"title":"temp-data-d-33","group":"d","value":33} 389 | {"index":{"_index":"test-lib","_type":"groups","_id":"186"}} 390 | {"title":"temp-data-d-35","group":"d","value":35} 391 | {"index":{"_index":"test-lib","_type":"groups","_id":"192"}} 392 | {"title":"temp-data-d-41","group":"d","value":41} 393 | {"index":{"_index":"test-lib","_type":"groups","_id":"193"}} 394 | {"title":"temp-data-d-42","group":"d","value":42} 395 | {"index":{"_index":"test-lib","_type":"groups","_id":"194"}} 396 | {"title":"temp-data-d-43","group":"d","value":43} 397 | {"index":{"_index":"test-lib","_type":"groups","_id":"195"}} 398 | {"title":"temp-data-d-44","group":"d","value":44} 399 | {"index":{"_index":"test-lib","_type":"groups","_id":"196"}} 400 | {"title":"temp-data-d-45","group":"d","value":45} 401 | -------------------------------------------------------------------------------- /tests/fixtures/import-tests/mappings.txt: -------------------------------------------------------------------------------- 1 | { 2 | "test-lib": { 3 | "mappings": { 4 | "groups": { 5 | "properties": { 6 | "group": { 7 | "type": "text", 8 | "fields": { 9 | "keyword": { 10 | "type": "keyword", 11 | "ignore_above": 256 12 | } 13 | } 14 | }, 15 | "title": { 16 | "type": "text", 17 | "fields": { 18 | "keyword": { 19 | "type": "keyword", 20 | "ignore_above": 256 21 | } 22 | } 23 | }, 24 | "value": { 25 | "type": "long" 26 | } 27 | } 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /tests/fixtures/import-tests/settings.txt: -------------------------------------------------------------------------------- 1 | { 2 | "test-lib": { 3 | "settings": { 4 | "index": { 5 | "number_of_replicas": "2" 6 | } 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/fixtures/working/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skratchdot/elasticsearch-tools/9c3b5827f2e157a74f7f383deaaad251c5b7e213/tests/fixtures/working/.placeholder -------------------------------------------------------------------------------- /tests/integration/__snapshots__/all.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`delete all indices again test all exports 1`] = ` 4 | "Exporting aliases for: [] 5 | Done! 6 | " 7 | `; 8 | 9 | exports[`delete all indices again test all exports 2`] = ` 10 | "Command failed: node ../../lib//es-export-bulk --url http://localhost:20202 --file ../fixtures/working/3-emptyagain-bulk.txt 11 | 12 | error: \\"no results were returned, so exiting.\\" 13 | " 14 | `; 15 | 16 | exports[`delete all indices again test all exports 3`] = ` 17 | "Exporting mappings for: [] 18 | Done! 19 | " 20 | `; 21 | 22 | exports[`delete all indices again test all exports 4`] = ` 23 | "Exporting settings for: [] 24 | Done! 25 | " 26 | `; 27 | 28 | exports[`importing from files client.indices.stats 1`] = ` 29 | Array [ 30 | "test-lib", 31 | ] 32 | `; 33 | 34 | exports[`importing from files test all exports 1`] = ` 35 | "Exporting aliases for: [ 'test-lib' ] 36 | Done! 37 | " 38 | `; 39 | 40 | exports[`importing from files test all exports 2`] = ` 41 | "Done! 42 | " 43 | `; 44 | 45 | exports[`importing from files test all exports 3`] = ` 46 | "Exporting mappings for: [ 'test-lib' ] 47 | Done! 48 | " 49 | `; 50 | 51 | exports[`importing from files test all exports 4`] = ` 52 | "Exporting settings for: [ 'test-lib' ] 53 | Done! 54 | " 55 | `; 56 | 57 | exports[`importing from files test all imports 1`] = ` 58 | "Creating Indexes (if needed): 59 | [index=\\"test-lib\\"] - creating 60 | Creating settings: 61 | [index=\\"test-lib\\", prop=\\"index\\"] 62 | Done! 63 | " 64 | `; 65 | 66 | exports[`importing from files test all imports 2`] = ` 67 | "Creating Indexes (if needed): 68 | Creating aliases: 69 | Done! 70 | " 71 | `; 72 | 73 | exports[`importing from files test all imports 3`] = ` 74 | "Creating Indexes (if needed): 75 | [index=\\"test-lib\\"] - exists 76 | Creating mappings: 77 | [index=\\"test-lib\\", prop=\\"groups\\"] 78 | Done! 79 | " 80 | `; 81 | 82 | exports[`importing from files test all imports 4`] = ` 83 | "Pre-Processing file of size: 21.5 KB 84 | Starting bulk imports with batches of 20000 lines. 85 | Complete! 86 | " 87 | `; 88 | 89 | exports[`insert data with node lib client.indices.stats 1`] = ` 90 | Array [ 91 | "test-lib", 92 | ] 93 | `; 94 | 95 | exports[`insert data with node lib test all exports 1`] = ` 96 | "Exporting aliases for: [ 'test-lib' ] 97 | Done! 98 | " 99 | `; 100 | 101 | exports[`insert data with node lib test all exports 2`] = ` 102 | "Done! 103 | " 104 | `; 105 | 106 | exports[`insert data with node lib test all exports 3`] = ` 107 | "Exporting mappings for: [ 'test-lib' ] 108 | Done! 109 | " 110 | `; 111 | 112 | exports[`insert data with node lib test all exports 4`] = ` 113 | "Exporting settings for: [ 'test-lib' ] 114 | Done! 115 | " 116 | `; 117 | 118 | exports[`with empty db test all exports 1`] = ` 119 | "Exporting aliases for: [] 120 | Done! 121 | " 122 | `; 123 | 124 | exports[`with empty db test all exports 2`] = ` 125 | "Command failed: node ../../lib//es-export-bulk --url http://localhost:20202 --file ../fixtures/working/1-empty-bulk.txt 126 | 127 | error: \\"no results were returned, so exiting.\\" 128 | " 129 | `; 130 | 131 | exports[`with empty db test all exports 3`] = ` 132 | "Exporting mappings for: [] 133 | Done! 134 | " 135 | `; 136 | 137 | exports[`with empty db test all exports 4`] = ` 138 | "Exporting settings for: [] 139 | Done! 140 | " 141 | `; 142 | -------------------------------------------------------------------------------- /tests/integration/all.test.js: -------------------------------------------------------------------------------- 1 | const elasticsearch = require('elasticsearch'); 2 | const { execSync } = require('child_process'); 3 | const insertData = require('./insert-data'); 4 | 5 | const host = 'http://localhost:20202'; 6 | const client = new elasticsearch.Client({ host }); 7 | const commands = ['aliases', 'bulk', 'mappings', 'settings']; 8 | const libdir = `../../lib/`; 9 | const workingdir = `../fixtures/working`; 10 | const importdir = `../fixtures/import-tests/`; 11 | 12 | const run = (type, cmd) => `node ${libdir}/es-${type}-${cmd} --url ${host}`; 13 | 14 | const testAllExports = async (prefix) => { 15 | commands.forEach(command => { 16 | const cmd = `${run('export', command)} --file ${workingdir}/${prefix}-${command}.txt`; 17 | try { 18 | const result = execSync(cmd, { cwd: __dirname }).toString(); 19 | expect(result).toMatchSnapshot(); 20 | } catch (err) { 21 | expect(err.message).toMatchSnapshot(); 22 | } 23 | }); 24 | }; 25 | 26 | beforeAll(async () => { 27 | // eslint-disable-next-line 28 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 300000; 29 | await client.indices.delete({ index: '*' }); 30 | }); 31 | 32 | describe('with empty db', async () => { 33 | test('client.indices.stats', async () => { 34 | const stats = await client.indices.stats(); 35 | expect(stats.indices).toEqual({}); 36 | }); 37 | test('test all exports', async () => { 38 | await testAllExports('1-empty'); 39 | }); 40 | }); 41 | 42 | describe('insert data with node lib', async () => { 43 | test('insert data', async () => { 44 | await insertData(client, 'test-lib', 'groups'); 45 | }); 46 | test('client.indices.stats', async () => { 47 | const stats = await client.indices.stats(); 48 | expect(Object.keys(stats.indices)).toMatchSnapshot(); 49 | }); 50 | test('test all exports', async () => { 51 | await testAllExports('2-somedata'); 52 | }); 53 | }); 54 | 55 | describe('delete all indices again', async () => { 56 | test('delete indices', async () => { 57 | await client.indices.delete({ index: '*' }); 58 | }); 59 | test('client.indices.stats', async () => { 60 | const stats = await client.indices.stats(); 61 | expect(stats.indices).toEqual({}); 62 | }); 63 | test('test all exports', async () => { 64 | await testAllExports('3-emptyagain'); 65 | }); 66 | }); 67 | 68 | describe('importing from files', async () => { 69 | test('test all imports', async () => { 70 | ['settings', 'aliases', 'mappings', 'bulk'].forEach(command => { 71 | const result = execSync(`${run('import', command)} --file ${importdir}/${command}.txt`, { cwd: __dirname }).toString(); 72 | expect(result).toMatchSnapshot(); 73 | }); 74 | }); 75 | test('client.indices.stats', async () => { 76 | const stats = await client.indices.stats(); 77 | expect(Object.keys(stats.indices)).toMatchSnapshot(); 78 | }); 79 | test('test all exports', async () => { 80 | await testAllExports('4-afterimports'); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /tests/integration/insert-data.js: -------------------------------------------------------------------------------- 1 | module.exports = async (client, index, type) => { 2 | // build first index 3 | const data = [ 4 | ['a', 0, 50], 5 | ['b', 0, 50], 6 | ['c', 25, 50], 7 | ['d', 50, 50] 8 | ]; 9 | let currentId = 1; 10 | for (let i = 0; i < data.length; i++) { 11 | const [ group, start, numDocs ] = data[i]; 12 | for (let j = start; j < numDocs; j++) { 13 | await client.index({ 14 | index, 15 | type, 16 | id: currentId++, 17 | refresh: 'true', 18 | body: { 19 | title: `temp-data-${group}-${j}`, 20 | group: group, 21 | value: j 22 | } 23 | }); 24 | } 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-export-aliases.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-export-alises 1`] = ` 4 | Array [ 5 | Array [ 6 | "getAlias", 7 | "aliases", 8 | Object { 9 | "index": "String, String[], Boolean — A comma-separated list of index names", 10 | "local": "Boolean — Return local information, do not retrieve the state from master node (default: false)", 11 | "name": "String, String[], Boolean — The name of the settings that should be included", 12 | }, 13 | ], 14 | ] 15 | `; 16 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-export-mappings.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-export-mappings 1`] = ` 4 | Array [ 5 | Array [ 6 | "getMapping", 7 | "mappings", 8 | Object { 9 | "allowNoIndices": "Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)", 10 | "expandWildcards": "String — Whether to expand wildcard expression to concrete indices that are open, closed or both.", 11 | "ignoreUnavailable": "Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)", 12 | "index": "String, String[], Boolean — A comma-separated list of index names", 13 | "local": "Boolean — Return local information, do not retrieve the state from master node (default: false)", 14 | "type": "String, String[], Boolean — A comma-separated list of document types", 15 | }, 16 | ], 17 | ] 18 | `; 19 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-export-settings.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-export-settings 1`] = ` 4 | Array [ 5 | Array [ 6 | "getSettings", 7 | "settings", 8 | Object { 9 | "allowNoIndices": "Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)", 10 | "expandWildcards": "String — Whether to expand wildcard expression to concrete indices that are open, closed or both.", 11 | "ignoreUnavailable": "Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)", 12 | "index": "String, String[], Boolean — A comma-separated list of index names", 13 | "local": "Boolean — Return local information, do not retrieve the state from master node (default: false)", 14 | "name": "String, String[], Boolean — The name of the settings that should be included", 15 | }, 16 | ], 17 | ] 18 | `; 19 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-import-aliases.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-import-alises 1`] = ` 4 | Array [ 5 | Array [ 6 | "putAlias", 7 | "aliases", 8 | "name", 9 | Object { 10 | "masterTimeout": "Date, Number — Specify timeout for connection to master", 11 | "timeout": "Date, Number — Explicit operation timeout", 12 | }, 13 | ], 14 | ] 15 | `; 16 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-import-mappings.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-import-mappings 1`] = ` 4 | Array [ 5 | Array [ 6 | "putMapping", 7 | "mappings", 8 | "type", 9 | Object { 10 | "allowNoIndices": "Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)", 11 | "expandWildcards": "String — Whether to expand wildcard expression to concrete indices that are open, closed or both.", 12 | "ignoreConflicts": "Boolean — Specify whether to ignore conflicts while updating the mapping (default: false)", 13 | "ignoreUnavailable": "Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)", 14 | "masterTimeout": "Date, Number — Specify timeout for connection to master", 15 | "timeout": "Date, Number — Explicit operation timeout", 16 | }, 17 | ], 18 | ] 19 | `; 20 | -------------------------------------------------------------------------------- /tests/unit/__snapshots__/es-import-settings.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`es-import-settings 1`] = ` 4 | Array [ 5 | Array [ 6 | "putSettings", 7 | "settings", 8 | null, 9 | Object { 10 | "allowNoIndices": "Boolean — Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified)", 11 | "expandWildcards": "String — Whether to expand wildcard expression to concrete indices that are open, closed or both.", 12 | "ignoreUnavailable": "Boolean — Whether specified concrete indices should be ignored when unavailable (missing or closed)", 13 | "masterTimeout": "Date, Number — Specify timeout for connection to master", 14 | }, 15 | ], 16 | ] 17 | `; 18 | -------------------------------------------------------------------------------- /tests/unit/es-export-aliases.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/exporter.js'); 2 | 3 | test('es-export-alises', () => { 4 | const exporterMock = require('../../lib/exporter'); 5 | require('../../lib/es-export-aliases'); 6 | expect(exporterMock.indicesExport.mock.calls).toMatchSnapshot(); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/unit/es-export-mappings.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/exporter.js'); 2 | 3 | test('es-export-mappings', () => { 4 | const exporterMock = require('../../lib/exporter'); 5 | require('../../lib/es-export-mappings'); 6 | expect(exporterMock.indicesExport.mock.calls).toMatchSnapshot(); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/unit/es-export-settings.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/exporter.js'); 2 | 3 | test('es-export-settings', () => { 4 | const exporterMock = require('../../lib/exporter'); 5 | require('../../lib/es-export-settings'); 6 | expect(exporterMock.indicesExport.mock.calls).toMatchSnapshot(); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/unit/es-import-aliases.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/importer.js'); 2 | 3 | test('es-import-alises', () => { 4 | const importerMock = require('../../lib/importer'); 5 | require('../../lib/es-import-aliases'); 6 | expect(importerMock.indicesImport.mock.calls).toMatchSnapshot(); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/unit/es-import-mappings.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/importer.js'); 2 | 3 | test('es-import-mappings', () => { 4 | const importerMock = require('../../lib/importer'); 5 | require('../../lib/es-import-mappings'); 6 | expect(importerMock.indicesImport.mock.calls).toMatchSnapshot(); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/unit/es-import-settings.test.js: -------------------------------------------------------------------------------- 1 | jest.mock('../../lib/importer.js'); 2 | 3 | test('es-import-settings', () => { 4 | const importerMock = require('../../lib/importer'); 5 | require('../../lib/es-import-settings'); 6 | expect(importerMock.indicesImport.mock.calls).toMatchSnapshot(); 7 | }); 8 | --------------------------------------------------------------------------------