Compare commits

...

8 Commits

Author SHA1 Message Date
f1275cf040 Bumped v7.11.0 2021-02-11 08:21:25 +01:00
8bccc50d6d API generation 2021-02-10 17:23:26 +01:00
69953cf9a1 Fix CI (#1399) 2021-02-09 08:17:49 +01:00
db65adcd39 Added Elasticsearch proxy example (#1398)
Co-authored-by: István Zoltán Szabó <istvan.szabo@elastic.co>
2021-02-09 08:17:17 +01:00
b8e67d4cf4 Updated CI conf 2021-02-09 08:17:17 +01:00
c22cacd7c8 Bumped v7.11.0-rc.1 2020-12-16 17:33:21 +01:00
5cfc87b181 API generation 2020-12-16 16:58:19 +01:00
30c8e7ae98 Updated ci configuration 2020-12-16 10:49:30 +01:00
38 changed files with 787 additions and 71 deletions

View File

@ -18,7 +18,7 @@ require_stack_version
if [[ -z $es_node_name ]]; then
# only set these once
set -euo pipefail
export TEST_SUITE=${TEST_SUITE-oss}
export TEST_SUITE=${TEST_SUITE-free}
export RUNSCRIPTS=${RUNSCRIPTS-}
export DETACH=${DETACH-false}
export CLEANUP=${CLEANUP-false}
@ -27,8 +27,7 @@ if [[ -z $es_node_name ]]; then
export elastic_password=changeme
export elasticsearch_image=elasticsearch
export elasticsearch_url=https://elastic:${elastic_password}@${es_node_name}:9200
if [[ $TEST_SUITE != "xpack" ]]; then
export elasticsearch_image=elasticsearch-${TEST_SUITE}
if [[ $TEST_SUITE != "platinum" ]]; then
export elasticsearch_url=http://${es_node_name}:9200
fi
export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost}

View File

@ -4,7 +4,7 @@
# to form a cluster suitable for running the REST API tests.
#
# Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'.
# Export the TEST_SUITE variable, eg. 'oss' or 'xpack' defaults to 'oss'.
# Export the TEST_SUITE variable, eg. 'free' or 'platinum' defaults to 'free'.
# Export the NUMBER_OF_NODES variable to start more than 1 node
# Version 1.2.0
@ -39,7 +39,7 @@ environment=($(cat <<-END
--env repositories.url.allowed_urls=http://snapshot.test*
END
))
if [[ "$TEST_SUITE" == "xpack" ]]; then
if [[ "$TEST_SUITE" == "platinum" ]]; then
environment+=($(cat <<-END
--env ELASTIC_PASSWORD=$elastic_password
--env xpack.license.self_generated.type=trial
@ -64,7 +64,7 @@ END
fi
cert_validation_flags=""
if [[ "$TEST_SUITE" == "xpack" ]]; then
if [[ "$TEST_SUITE" == "platinum" ]]; then
cert_validation_flags="--insecure --cacert /usr/share/elasticsearch/config/certs/ca.crt --resolve ${es_node_name}:443:127.0.0.1"
fi

View File

@ -2,7 +2,7 @@
# parameters are available to this script
# STACK_VERSION -- version e.g Major.Minor.Patch(-Prelease)
# TEST_SUITE -- which test suite to run: oss or xpack
# TEST_SUITE -- which test suite to run: free or platinum
# ELASTICSEARCH_URL -- The url at which elasticsearch is reachable, a default is composed based on STACK_VERSION and TEST_SUITE
# NODE_JS_VERSION -- node js version (defined in test-matrix.yml, a default is hardcoded here)
script_path=$(dirname $(realpath -s $0))

View File

@ -1,6 +1,6 @@
---
STACK_VERSION:
- 7.x-SNAPSHOT
- 7.11.0-SNAPSHOT
NODE_JS_VERSION:
- 14
@ -9,7 +9,7 @@ NODE_JS_VERSION:
- 8
TEST_SUITE:
- oss
- xpack
- free
- platinum
exclude: ~

View File

@ -86,7 +86,7 @@ jobs:
- name: Runs Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.x-SNAPSHOT
stack-version: 7.11.0-SNAPSHOT
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1

View File

@ -71,7 +71,7 @@ npm install @elastic/elasticsearch@<major>
#### Browser
WARNING: There is no official support for the browser environment. It exposes your Elasticsearch instance to everyone, which could lead to security issues.
We recommend that you write a lightweight proxy that uses this client instead.
We recommend that you write a lightweight proxy that uses this client instead, you can see a proxy example [here](./docs/examples/proxy).
## Documentation

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'wait_for_completion_timeout', 'keep_alive', 'typed_keys', 'keep_on_completion', 'batched_reduce_size', 'request_cache', 'analyzer', 'analyze_wildcard', 'default_operator', 'df', 'explain', 'stored_fields', 'docvalue_fields', 'from', 'ignore_unavailable', 'ignore_throttled', 'allow_no_indices', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'search_type', 'size', 'sort', '_source', '_source_excludes', '_source_includes', 'terminate_after', 'stats', 'suggest_field', 'suggest_mode', 'suggest_size', 'suggest_text', 'timeout', 'track_scores', 'track_total_hits', 'allow_partial_search_results', 'version', 'seq_no_primary_term', 'max_concurrent_shard_requests']
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path', waitForCompletionTimeout: 'wait_for_completion_timeout', keepAlive: 'keep_alive', typedKeys: 'typed_keys', keepOnCompletion: 'keep_on_completion', batchedReduceSize: 'batched_reduce_size', requestCache: 'request_cache', analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', storedFields: 'stored_fields', docvalueFields: 'docvalue_fields', ignoreUnavailable: 'ignore_unavailable', ignoreThrottled: 'ignore_throttled', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', terminateAfter: 'terminate_after', suggestField: 'suggest_field', suggestMode: 'suggest_mode', suggestSize: 'suggest_size', suggestText: 'suggest_text', trackScores: 'track_scores', trackTotalHits: 'track_total_hits', allowPartialSearchResults: 'allow_partial_search_results', seqNoPrimaryTerm: 'seq_no_primary_term', maxConcurrentShardRequests: 'max_concurrent_shard_requests' }
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'wait_for_completion_timeout', 'keep_alive', 'typed_keys', 'keep_on_completion', 'batched_reduce_size', 'request_cache', 'analyzer', 'analyze_wildcard', 'default_operator', 'df', 'explain', 'stored_fields', 'docvalue_fields', 'from', 'ignore_unavailable', 'ignore_throttled', 'allow_no_indices', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'search_type', 'size', 'sort', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'terminate_after', 'stats', 'suggest_field', 'suggest_mode', 'suggest_size', 'suggest_text', 'timeout', 'track_scores', 'track_total_hits', 'allow_partial_search_results', 'version', 'seq_no_primary_term', 'max_concurrent_shard_requests']
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path', waitForCompletionTimeout: 'wait_for_completion_timeout', keepAlive: 'keep_alive', typedKeys: 'typed_keys', keepOnCompletion: 'keep_on_completion', batchedReduceSize: 'batched_reduce_size', requestCache: 'request_cache', analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', storedFields: 'stored_fields', docvalueFields: 'docvalue_fields', ignoreUnavailable: 'ignore_unavailable', ignoreThrottled: 'ignore_throttled', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', terminateAfter: 'terminate_after', suggestField: 'suggest_field', suggestMode: 'suggest_mode', suggestSize: 'suggest_size', suggestText: 'suggest_text', trackScores: 'track_scores', trackTotalHits: 'track_total_hits', allowPartialSearchResults: 'allow_partial_search_results', seqNoPrimaryTerm: 'seq_no_primary_term', maxConcurrentShardRequests: 'max_concurrent_shard_requests' }
function AsyncSearchApi (transport, ConfigurationError) {
this.transport = transport

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['wait_for_active_shards', 'refresh', 'routing', 'timeout', 'type', '_source', '_source_excludes', '_source_includes', 'pipeline', 'require_alias', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { waitForActiveShards: 'wait_for_active_shards', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', requireAlias: 'require_alias', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['wait_for_active_shards', 'refresh', 'routing', 'timeout', 'type', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'pipeline', 'require_alias', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { waitForActiveShards: 'wait_for_active_shards', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', requireAlias: 'require_alias', errorTrace: 'error_trace', filterPath: 'filter_path' }
function bulkApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['format', 'local', 'h', 'help', 's', 'v', 'expand_wildcards', 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'bytes', 'master_timeout', 'fields', 'time', 'ts', 'health', 'pri', 'include_unloaded_segments', 'full_id', 'active_only', 'detailed', 'index', 'ignore_unavailable', 'node_id', 'actions', 'parent_task', 'size', 'allow_no_match', 'allow_no_datafeeds', 'allow_no_jobs', 'from']
const snakeCase = { expandWildcards: 'expand_wildcards', errorTrace: 'error_trace', filterPath: 'filter_path', masterTimeout: 'master_timeout', includeUnloadedSegments: 'include_unloaded_segments', fullId: 'full_id', activeOnly: 'active_only', ignoreUnavailable: 'ignore_unavailable', nodeId: 'node_id', parentTask: 'parent_task', allowNoMatch: 'allow_no_match', allowNoDatafeeds: 'allow_no_datafeeds', allowNoJobs: 'allow_no_jobs' }
const acceptedQuerystring = ['format', 'local', 'h', 'help', 's', 'v', 'expand_wildcards', 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'bytes', 'master_timeout', 'fields', 'time', 'ts', 'health', 'pri', 'include_unloaded_segments', 'full_id', 'active_only', 'detailed', 'index', 'ignore_unavailable', 'nodes', 'actions', 'parent_task_id', 'size', 'allow_no_match', 'allow_no_datafeeds', 'allow_no_jobs', 'from']
const snakeCase = { expandWildcards: 'expand_wildcards', errorTrace: 'error_trace', filterPath: 'filter_path', masterTimeout: 'master_timeout', includeUnloadedSegments: 'include_unloaded_segments', fullId: 'full_id', activeOnly: 'active_only', ignoreUnavailable: 'ignore_unavailable', parentTaskId: 'parent_task_id', allowNoMatch: 'allow_no_match', allowNoDatafeeds: 'allow_no_datafeeds', allowNoJobs: 'allow_no_jobs' }
function CatApi (transport, ConfigurationError) {
this.transport = transport

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'default_operator', 'df', 'from', 'ignore_unavailable', 'allow_no_indices', 'conflicts', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'scroll', 'search_type', 'search_timeout', 'size', 'max_docs', 'sort', '_source', '_source_excludes', '_source_includes', 'terminate_after', 'stats', 'version', 'request_cache', 'refresh', 'timeout', 'wait_for_active_shards', 'scroll_size', 'wait_for_completion', 'requests_per_second', 'slices', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', ignoreUnavailable: 'ignore_unavailable', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', searchTimeout: 'search_timeout', maxDocs: 'max_docs', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', terminateAfter: 'terminate_after', requestCache: 'request_cache', waitForActiveShards: 'wait_for_active_shards', scrollSize: 'scroll_size', waitForCompletion: 'wait_for_completion', requestsPerSecond: 'requests_per_second', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'default_operator', 'df', 'from', 'ignore_unavailable', 'allow_no_indices', 'conflicts', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'scroll', 'search_type', 'search_timeout', 'size', 'max_docs', 'sort', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'terminate_after', 'stats', 'version', 'request_cache', 'refresh', 'timeout', 'wait_for_active_shards', 'scroll_size', 'wait_for_completion', 'requests_per_second', 'slices', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', ignoreUnavailable: 'ignore_unavailable', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', searchTimeout: 'search_timeout', maxDocs: 'max_docs', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', terminateAfter: 'terminate_after', requestCache: 'request_cache', waitForActiveShards: 'wait_for_active_shards', scrollSize: 'scroll_size', waitForCompletion: 'wait_for_completion', requestsPerSecond: 'requests_per_second', errorTrace: 'error_trace', filterPath: 'filter_path' }
function deleteByQueryApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_includes', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
function existsApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_includes', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
function existsSourceApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['analyze_wildcard', 'analyzer', 'default_operator', 'df', 'stored_fields', 'lenient', 'preference', 'q', 'routing', '_source', '_source_excludes', '_source_includes', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['analyze_wildcard', 'analyzer', 'default_operator', 'df', 'stored_fields', 'lenient', 'preference', 'q', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', errorTrace: 'error_trace', filterPath: 'filter_path' }
function explainApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_includes', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
function getApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_includes', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'version', 'version_type', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', versionType: 'version_type', errorTrace: 'error_trace', filterPath: 'filter_path' }
function getSourceApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -1548,6 +1548,33 @@ IndicesApi.prototype.getDataStream = function indicesGetDataStreamApi (params, o
return this.transport.request(request, options, callback)
}
IndicesApi.prototype.migrateToDataStream = function indicesMigrateToDataStreamApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
// check required parameters
if (params['name'] == null) {
const err = new this[kConfigurationError]('Missing required parameter: name')
return handleError(err, callback)
}
var { method, body, name, ...querystring } = params
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring)
var path = ''
if (method == null) method = 'POST'
path = '/' + '_data_stream' + '/' + '_migrate' + '/' + encodeURIComponent(name)
// build request object
const request = {
method,
path,
body: body || '',
querystring
}
return this.transport.request(request, options, callback)
}
IndicesApi.prototype.promoteDataStream = function indicesPromoteDataStreamApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
@ -1662,6 +1689,7 @@ Object.defineProperties(IndicesApi.prototype, {
data_streams_stats: { get () { return this.dataStreamsStats } },
delete_data_stream: { get () { return this.deleteDataStream } },
get_data_stream: { get () { return this.getDataStream } },
migrate_to_data_stream: { get () { return this.migrateToDataStream } },
promote_data_stream: { get () { return this.promoteDataStream } },
reload_search_analyzers: { get () { return this.reloadSearchAnalyzers } }
})

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_includes', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['stored_fields', 'preference', 'realtime', 'refresh', 'routing', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { storedFields: 'stored_fields', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', errorTrace: 'error_trace', filterPath: 'filter_path' }
function mgetApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -176,17 +176,27 @@ RollupApi.prototype.rollup = function rollupRollupApi (params, options, callback
const err = new this[kConfigurationError]('Missing required parameter: index')
return handleError(err, callback)
}
if (params['rollup_index'] == null && params['rollupIndex'] == null) {
const err = new this[kConfigurationError]('Missing required parameter: rollup_index or rollupIndex')
return handleError(err, callback)
}
if (params['body'] == null) {
const err = new this[kConfigurationError]('Missing required parameter: body')
return handleError(err, callback)
}
var { method, body, index, ...querystring } = params
// check required url components
if ((params['rollup_index'] != null || params['rollupIndex'] != null) && (params['index'] == null)) {
const err = new this[kConfigurationError]('Missing required parameter of the url: index')
return handleError(err, callback)
}
var { method, body, index, rollupIndex, rollup_index, ...querystring } = params
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring)
var path = ''
if (method == null) method = 'POST'
path = '/' + encodeURIComponent(index) + '/' + '_rollup'
path = '/' + encodeURIComponent(index) + '/' + '_rollup' + '/' + encodeURIComponent(rollup_index || rollupIndex)
// build request object
const request = {

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'ccs_minimize_roundtrips', 'default_operator', 'df', 'explain', 'stored_fields', 'docvalue_fields', 'from', 'ignore_unavailable', 'ignore_throttled', 'allow_no_indices', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'scroll', 'search_type', 'size', 'sort', '_source', '_source_excludes', '_source_includes', 'terminate_after', 'stats', 'suggest_field', 'suggest_mode', 'suggest_size', 'suggest_text', 'timeout', 'track_scores', 'track_total_hits', 'allow_partial_search_results', 'typed_keys', 'version', 'seq_no_primary_term', 'request_cache', 'batched_reduce_size', 'max_concurrent_shard_requests', 'pre_filter_shard_size', 'rest_total_hits_as_int', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', ccsMinimizeRoundtrips: 'ccs_minimize_roundtrips', defaultOperator: 'default_operator', storedFields: 'stored_fields', docvalueFields: 'docvalue_fields', ignoreUnavailable: 'ignore_unavailable', ignoreThrottled: 'ignore_throttled', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', terminateAfter: 'terminate_after', suggestField: 'suggest_field', suggestMode: 'suggest_mode', suggestSize: 'suggest_size', suggestText: 'suggest_text', trackScores: 'track_scores', trackTotalHits: 'track_total_hits', allowPartialSearchResults: 'allow_partial_search_results', typedKeys: 'typed_keys', seqNoPrimaryTerm: 'seq_no_primary_term', requestCache: 'request_cache', batchedReduceSize: 'batched_reduce_size', maxConcurrentShardRequests: 'max_concurrent_shard_requests', preFilterShardSize: 'pre_filter_shard_size', restTotalHitsAsInt: 'rest_total_hits_as_int', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'ccs_minimize_roundtrips', 'default_operator', 'df', 'explain', 'stored_fields', 'docvalue_fields', 'from', 'ignore_unavailable', 'ignore_throttled', 'allow_no_indices', 'expand_wildcards', 'lenient', 'preference', 'q', 'routing', 'scroll', 'search_type', 'size', 'sort', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'terminate_after', 'stats', 'suggest_field', 'suggest_mode', 'suggest_size', 'suggest_text', 'timeout', 'track_scores', 'track_total_hits', 'allow_partial_search_results', 'typed_keys', 'version', 'seq_no_primary_term', 'request_cache', 'batched_reduce_size', 'max_concurrent_shard_requests', 'pre_filter_shard_size', 'rest_total_hits_as_int', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', ccsMinimizeRoundtrips: 'ccs_minimize_roundtrips', defaultOperator: 'default_operator', storedFields: 'stored_fields', docvalueFields: 'docvalue_fields', ignoreUnavailable: 'ignore_unavailable', ignoreThrottled: 'ignore_throttled', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', terminateAfter: 'terminate_after', suggestField: 'suggest_field', suggestMode: 'suggest_mode', suggestSize: 'suggest_size', suggestText: 'suggest_text', trackScores: 'track_scores', trackTotalHits: 'track_total_hits', allowPartialSearchResults: 'allow_partial_search_results', typedKeys: 'typed_keys', seqNoPrimaryTerm: 'seq_no_primary_term', requestCache: 'request_cache', batchedReduceSize: 'batched_reduce_size', maxConcurrentShardRequests: 'max_concurrent_shard_requests', preFilterShardSize: 'pre_filter_shard_size', restTotalHitsAsInt: 'rest_total_hits_as_int', errorTrace: 'error_trace', filterPath: 'filter_path' }
function searchApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['wait_for_active_shards', '_source', '_source_excludes', '_source_includes', 'lang', 'refresh', 'retry_on_conflict', 'routing', 'timeout', 'if_seq_no', 'if_primary_term', 'require_alias', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { waitForActiveShards: 'wait_for_active_shards', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', retryOnConflict: 'retry_on_conflict', ifSeqNo: 'if_seq_no', ifPrimaryTerm: 'if_primary_term', requireAlias: 'require_alias', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['wait_for_active_shards', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'lang', 'refresh', 'retry_on_conflict', 'routing', 'timeout', 'if_seq_no', 'if_primary_term', 'require_alias', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { waitForActiveShards: 'wait_for_active_shards', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', retryOnConflict: 'retry_on_conflict', ifSeqNo: 'if_seq_no', ifPrimaryTerm: 'if_primary_term', requireAlias: 'require_alias', errorTrace: 'error_trace', filterPath: 'filter_path' }
function updateApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

View File

@ -23,8 +23,8 @@
/* eslint no-unused-vars: 0 */
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils')
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'default_operator', 'df', 'from', 'ignore_unavailable', 'allow_no_indices', 'conflicts', 'expand_wildcards', 'lenient', 'pipeline', 'preference', 'q', 'routing', 'scroll', 'search_type', 'search_timeout', 'size', 'max_docs', 'sort', '_source', '_source_excludes', '_source_includes', 'terminate_after', 'stats', 'version', 'version_type', 'request_cache', 'refresh', 'timeout', 'wait_for_active_shards', 'scroll_size', 'wait_for_completion', 'requests_per_second', 'slices', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', ignoreUnavailable: 'ignore_unavailable', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', searchTimeout: 'search_timeout', maxDocs: 'max_docs', _sourceExcludes: '_source_excludes', _sourceIncludes: '_source_includes', terminateAfter: 'terminate_after', versionType: 'version_type', requestCache: 'request_cache', waitForActiveShards: 'wait_for_active_shards', scrollSize: 'scroll_size', waitForCompletion: 'wait_for_completion', requestsPerSecond: 'requests_per_second', errorTrace: 'error_trace', filterPath: 'filter_path' }
const acceptedQuerystring = ['analyzer', 'analyze_wildcard', 'default_operator', 'df', 'from', 'ignore_unavailable', 'allow_no_indices', 'conflicts', 'expand_wildcards', 'lenient', 'pipeline', 'preference', 'q', 'routing', 'scroll', 'search_type', 'search_timeout', 'size', 'max_docs', 'sort', '_source', '_source_excludes', '_source_exclude', '_source_includes', '_source_include', 'terminate_after', 'stats', 'version', 'version_type', 'request_cache', 'refresh', 'timeout', 'wait_for_active_shards', 'scroll_size', 'wait_for_completion', 'requests_per_second', 'slices', 'pretty', 'human', 'error_trace', 'source', 'filter_path']
const snakeCase = { analyzeWildcard: 'analyze_wildcard', defaultOperator: 'default_operator', ignoreUnavailable: 'ignore_unavailable', allowNoIndices: 'allow_no_indices', expandWildcards: 'expand_wildcards', searchType: 'search_type', searchTimeout: 'search_timeout', maxDocs: 'max_docs', _sourceExcludes: '_source_excludes', _sourceExclude: '_source_exclude', _sourceIncludes: '_source_includes', _sourceInclude: '_source_include', terminateAfter: 'terminate_after', versionType: 'version_type', requestCache: 'request_cache', waitForActiveShards: 'wait_for_active_shards', scrollSize: 'scroll_size', waitForCompletion: 'wait_for_completion', requestsPerSecond: 'requests_per_second', errorTrace: 'error_trace', filterPath: 'filter_path' }
function updateByQueryApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)

1
api/kibana.d.ts vendored
View File

@ -229,6 +229,7 @@ interface KibanaClient {
getSettings<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesGetSettings, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
getTemplate<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesGetTemplate, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
getUpgrade<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesGetUpgrade, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
migrateToDataStream<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesMigrateToDataStream, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
open<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesOpen, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
promoteDataStream<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesPromoteDataStream, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
putAlias<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesPutAlias<TRequestBody>, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>

View File

@ -45,6 +45,8 @@ export interface AsyncSearchStatus extends Generic {
export interface AsyncSearchSubmit<T = RequestBody> extends Generic {
index?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
wait_for_completion_timeout?: string;
keep_on_completion?: boolean;
keep_alive?: string;
@ -108,6 +110,8 @@ export interface AutoscalingPutAutoscalingPolicy<T = RequestBody> extends Generi
export interface Bulk<T = RequestNDBody> extends Generic {
index?: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
wait_for_active_shards?: string;
refresh?: 'wait_for' | boolean;
routing?: string;
@ -359,10 +363,10 @@ export interface CatSnapshots extends Generic {
export interface CatTasks extends Generic {
format?: string;
node_id?: string | string[];
nodes?: string | string[];
actions?: string | string[];
detailed?: boolean;
parent_task?: number;
parent_task_id?: string;
h?: string | string[];
help?: boolean;
s?: string | string[];
@ -647,6 +651,8 @@ export interface Delete extends Generic {
export interface DeleteByQuery<T = RequestBody> extends Generic {
index: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
default_operator?: 'AND' | 'OR';
@ -737,6 +743,8 @@ export interface Exists extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
preference?: string;
realtime?: boolean;
@ -753,6 +761,8 @@ export interface ExistsSource extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
preference?: string;
realtime?: boolean;
refresh?: boolean;
@ -768,6 +778,8 @@ export interface Explain<T = RequestBody> extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
analyze_wildcard?: boolean;
analyzer?: string;
default_operator?: 'AND' | 'OR';
@ -797,6 +809,8 @@ export interface Get extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
preference?: string;
realtime?: boolean;
@ -824,6 +838,8 @@ export interface GetSource extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
preference?: string;
realtime?: boolean;
refresh?: boolean;
@ -1158,6 +1174,10 @@ export interface IndicesGetUpgrade extends Generic {
expand_wildcards?: 'open' | 'closed' | 'hidden' | 'none' | 'all';
}
export interface IndicesMigrateToDataStream extends Generic {
name: string;
}
export interface IndicesOpen extends Generic {
index: string | string[];
timeout?: string;
@ -1429,6 +1449,8 @@ export interface LicensePostStartTrial extends Generic {
export interface Mget<T = RequestBody> extends Generic {
index?: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
preference?: string;
realtime?: boolean;
@ -2034,6 +2056,7 @@ export interface RollupPutJob<T = RequestBody> extends Generic {
export interface RollupRollup<T = RequestBody> extends Generic {
index: string;
rollup_index: string;
body: T;
}
@ -2069,6 +2092,8 @@ export interface Scroll<T = RequestBody> extends Generic {
export interface Search<T = RequestBody> extends Generic {
index?: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
ccs_minimize_roundtrips?: boolean;
@ -2525,6 +2550,8 @@ export interface Update<T = RequestBody> extends Generic {
id: string;
index: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
wait_for_active_shards?: string;
_source?: string | string[];
_source_excludes?: string | string[];
@ -2543,6 +2570,8 @@ export interface Update<T = RequestBody> extends Generic {
export interface UpdateByQuery<T = RequestBody> extends Generic {
index: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
default_operator?: 'AND' | 'OR';

51
docs/examples/proxy/.gitignore vendored Normal file
View File

@ -0,0 +1,51 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# coverage output
coverage.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# mac files
.DS_Store
# vim swap files
*.swp
#Jetbrains editor folder
.idea
.vercel

View File

@ -0,0 +1,65 @@
# Elasticsearch proxy example
This folder contains an example of how to build a lightweight proxy
between your frontend code and Elasticsearch if you don't
have a more sophisticated backend in place yet.
> **IMPORTANT:** This is not a production ready code and it is only for demonstration purposes,
> we make no guarantees on it's security and stability.
This project is designed to be deployed on [Vercel](https://vercel.com/), a cloud platform
for static sites and Serverless Functions. You can use other functions providers,
such as [Google Cloud functions](https://cloud.google.com/functions).
## Project structure
The project comes with four endpoints:
- `/api/search`: runs a search, requires `'read'` permission
- `/api/autocomplete`: runs an autocomplete suggestion, requires `'read'` permission
- `/api/index`: indexes or updates a document, requires `'write'` permission
- `/api/delete`: deletes a document, requires `'write'` permission
Inside `utils/authorize.js` you can find the authorization logic for the endpoints.
In each endpoint you should configure the `INDEX` variable.
## How to use
Create an account on Vercel, then create a deployment on Elastic Cloud. If you
don't have an account on Elastic Cloud, you can create one with a free 14-day trial
of the [Elasticsearch Service](https://www.elastic.co/elasticsearch/service).
### Configure Elasticsearch
Once you have created a deployment on Elastic Cloud copy the generated Cloud Id and the credentials.
Then open `utils/prepare-elasticsearch.js` and fill your credentials. The script generates
an [Api Key](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html)
that you can use for authenticating your request. Based on the configuration of the Api Key, you will be able
to perform different operation on the specified indices or index pattern.
### Configure Vercel
Install the [Vercel CLI](https://vercel.com/docs/cli) to bootstrap the project,
or read the [quickstart](https://vercel.com/docs) documentation.
If you are using the CLI, bootstrap the project by running `vercel`. Test the project locally
with `vercel dev`, and deploy it with `vercel deploy`.
Configure the `ELASTIC_CLOUD_ID` [environment varible](https://vercel.com/docs/environment-variables) as well.
The Api Key is passed from the frontend app via a `Authorization` header as `Bearer` token and is
used to authorize the API calls to the endpoints as well.
Additional configuration, such as CORS, can be added to [`vercel.json`](https://vercel.com/docs/configuration).
## Authentication
If you are using Elasticsearch only for search purposes, such as a search box, you can create
an Api Key with `read` permissions and store it in your frontend app. Then you can send it
via `Authorization` header to the proxy and run your searches.
If you need to ingest data as well, it's more secure to have a strong authentication in your application.
For such cases, use an external authentication service, such as [Auth0](https://auth0.com/)
or [Magic Link](https://magic.link/). Then create a different Api Key with `read` and `write`
permissions for authenticated users, that will not be stored in the frontend app.
## License
This software is licensed under the [Apache 2 license](../../LICENSE).

View File

@ -0,0 +1,105 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// IMPORTANT: this is not a production ready code & purely for demonstration purposes,
// we make no guarantees on it's security and stability
// NOTE: to make this endpoint work, you should create an ApiKey with 'read' permissions
'use strict'
const { Client } = require('@elastic/elasticsearch')
const authorize = require('../utils/authorize')
const INDEX = '<index-name>'
const client = new Client({
cloud: {
id: process.env.ELASTIC_CLOUD_ID
}
})
module.exports = async (req, res) => {
const [err, token] = authorize(req)
if (err) {
res.status(401)
res.json(err)
return
}
if (typeof req.query.q !== 'string') {
res.status(400)
res.json({
error: 'Bad Request',
message: 'Missing parameter "query.q"',
statusCode: 400
})
return
}
if (req.query.q.length < 3) {
res.status(400)
res.json({
error: 'Bad Request',
message: 'The length of "query.q" should be at least 3',
statusCode: 400
})
return
}
try {
const response = await client.search({
index: INDEX,
// You could directly send from the browser
// the Elasticsearch's query DSL, but it will
// expose you to the risk that a malicious user
// could overload your cluster by crafting
// expensive queries.
body: {
_source: ['id', 'url', 'name'], // the fields you want to show in the autocompletion
size: 0,
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
suggest: {
suggestions: {
prefix: req.query.q,
completion: {
field: 'suggest',
size: 5
}
}
}
}
}, {
headers: {
Authorization: `ApiKey ${token}`
}
})
// It might be useful to configure http control caching headers
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
// res.setHeader('stale-while-revalidate', '30')
res.json(response.body)
} catch (err) {
res.status(err.statusCode || 500)
res.json({
error: err.name,
message: err.message,
statusCode: err.statusCode || 500
})
}
}

View File

@ -0,0 +1,74 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// IMPORTANT: this is not a production ready code & purely for demonstration purposes,
// we make no guarantees on it's security and stability
// NOTE: to make this endpoint work, you should create an ApiKey with 'write' permissions
'use strict'
const { Client } = require('@elastic/elasticsearch')
const authorize = require('../utils/authorize')
const INDEX = '<index-name>'
const client = new Client({
cloud: {
id: process.env.ELASTIC_CLOUD_ID
}
})
module.exports = async (req, res) => {
const [err, token] = authorize(req)
if (err) {
res.status(401)
res.json(err)
return
}
if (typeof req.query.id !== 'string' && req.query.id.length === 0) {
res.status(400)
res.json({
error: 'Bad Request',
message: 'Missing document id',
statusCode: 400
})
return
}
try {
const response = await client.delete({
index: INDEX,
id: req.query.id
}, {
headers: {
Authorization: `ApiKey ${token}`
}
})
res.json(response.body)
} catch (err) {
res.status(err.statusCode || 500)
res.json({
error: err.name,
message: err.message,
statusCode: err.statusCode || 500
})
}
}

View File

@ -0,0 +1,76 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// IMPORTANT: this is not a production ready code & purely for demonstration purposes,
// we make no guarantees on it's security and stability
// NOTE: to make this endpoint work, you should create an ApiKey with 'write' permissions
'use strict'
const { Client } = require('@elastic/elasticsearch')
const authorize = require('../utils/authorize')
const INDEX = '<index-name>'
const client = new Client({
cloud: {
id: process.env.ELASTIC_CLOUD_ID
}
})
module.exports = async (req, res) => {
const [err, token] = authorize(req)
if (err) {
res.status(401)
res.json(err)
return
}
if (typeof req.body !== 'object') {
res.status(400)
res.json({
error: 'Bad Request',
message: 'The document should be an object',
statusCode: 400
})
return
}
try {
const response = await client.index({
index: INDEX,
id: req.query.id,
body: req.body
}, {
headers: {
Authorization: `ApiKey ${token}`
}
})
res.status(response.statusCode)
res.json(response.body)
} catch (err) {
res.status(err.statusCode || 500)
res.json({
error: err.name,
message: err.message,
statusCode: err.statusCode || 500
})
}
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// IMPORTANT: this is not a production ready code & purely for demonstration purposes,
// we make no guarantees on it's security and stability
// NOTE: to make this endpoint work, you should create an ApiKey with 'read' permissions
'use strict'
const { Client } = require('@elastic/elasticsearch')
const authorize = require('../utils/authorize')
const INDEX = '<index-name>'
const client = new Client({
cloud: {
id: process.env.ELASTIC_CLOUD_ID
}
})
module.exports = async (req, res) => {
const [err, token] = authorize(req)
if (err) {
res.status(401)
res.json(err)
return
}
if (typeof req.body.text !== 'string') {
res.status(400)
res.json({
error: 'Bad Request',
message: 'Missing parameter "body.text"',
statusCode: 400
})
return
}
try {
const response = await client.search({
index: INDEX,
// You could directly send from the browser
// the Elasticsearch's query DSL, but it will
// expose you to the risk that a malicious user
// could overload your cluster by crafting
// expensive queries.
body: {
query: {
match: { field: req.body.text }
}
}
}, {
headers: {
Authorization: `ApiKey ${token}`
}
})
// It might be useful to configure http control caching headers
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
// res.setHeader('stale-while-revalidate', '30')
res.json(response.body)
} catch (err) {
res.status(err.statusCode || 500)
res.json({
error: err.name,
message: err.message,
statusCode: err.statusCode || 500
})
}
}

View File

@ -0,0 +1,19 @@
{
"name": "proxy-example",
"version": "1.0.0",
"private": true,
"description": "",
"main": "index.js",
"scripts": {
"test": "standard"
},
"keywords": [],
"author": "Tomas Della Vedova",
"license": "Apache-2.0",
"dependencies": {
"@elastic/elasticsearch": "^7.10.0"
},
"devDependencies": {
"standard": "^16.0.3"
}
}

View File

@ -0,0 +1,54 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// IMPORTANT: this is not a production ready code & purely for demonstration purposes,
// we make no guarantees on it's security and stability
'use strict'
module.exports = (req) => {
const auth = req.headers.authorization
if (typeof auth !== 'string') {
return [{
error: 'Unauthorized',
message: 'Missing authorization header',
statusCode: 401
}, null]
}
const [type, token] = req.headers.authorization.split(' ')
if (type !== 'Bearer') {
return [{
error: 'Unauthorized',
message: 'Bad authorization type',
statusCode: 401
}, null]
}
if (token.length === 0) {
return [{
error: 'Unauthorized',
message: 'Bad authorization token',
statusCode: 401
}, null]
}
return [null, token]
}

View File

@ -0,0 +1,68 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
'use strict'
const { Client } = require('@elastic/elasticsearch')
// Your Cloud Id
const cloudId = ''
// Your admin username
const username = ''
// Your admin password
const password = ''
// The indices or index patterns you will need to access
const indexNames = ['my-index-name-or-pattern']
// see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-privileges.html#privileges-list-indices
const privileges = ['read']
async function generateApiKeys (opts) {
const client = new Client({
cloud: {
id: cloudId
},
auth: {
username,
password
}
})
const { body } = await client.security.createApiKey({
body: {
name: 'elasticsearch-proxy',
role_descriptors: {
'elasticsearch-proxy-users': {
index: [{
names: indexNames,
privileges
}]
}
}
}
})
return Buffer.from(`${body.id}:${body.api_key}`).toString('base64')
}
generateApiKeys()
.then(console.log)
.catch(err => {
console.error(err)
process.exit(1)
})

View File

@ -0,0 +1,13 @@
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
{ "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
]
}
]
}

View File

@ -90,4 +90,5 @@ using.
WARNING: There is no official support for the browser environment. It exposes
your {es} instance to everyone, which could lead to security issues. We
recommend you to write a lightweight proxy that uses this client instead.
recommend you to write a lightweight proxy that uses this client instead,
you can see a proxy example https://github.com/elastic/elasticsearch-js/tree/master/docs/examples/proxy[here].

View File

@ -354,7 +354,7 @@ _Default:_ `5`
[discrete]
=== autoscaling.deleteAutoscalingPolicy
*Stability:* experimental
[source,ts]
----
client.autoscaling.deleteAutoscalingPolicy({
@ -371,7 +371,7 @@ link:{ref}/autoscaling-delete-autoscaling-policy.html[Documentation] +
[discrete]
=== autoscaling.getAutoscalingCapacity
*Stability:* experimental
[source,ts]
----
client.autoscaling.getAutoscalingCapacity()
@ -381,7 +381,7 @@ link:{ref}/autoscaling-get-autoscaling-capacity.html[Documentation] +
[discrete]
=== autoscaling.getAutoscalingPolicy
*Stability:* experimental
[source,ts]
----
client.autoscaling.getAutoscalingPolicy({
@ -398,7 +398,7 @@ link:{ref}/autoscaling-get-autoscaling-policy.html[Documentation] +
[discrete]
=== autoscaling.putAutoscalingPolicy
*Stability:* experimental
[source,ts]
----
client.autoscaling.putAutoscalingPolicy({
@ -1470,10 +1470,10 @@ link:{ref}/cat-snapshots.html[Documentation] +
----
client.cat.tasks({
format: string,
node_id: string | string[],
nodes: string | string[],
actions: string | string[],
detailed: boolean,
parent_task: number,
parent_task_id: string,
h: string | string[],
help: boolean,
s: string | string[],
@ -1487,7 +1487,7 @@ link:{ref}/tasks.html[Documentation] +
|`format`
|`string` - a short version of the Accept header, e.g. json, yaml
|`node_id` or `nodeId`
|`nodes`
|`string \| string[]` - A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes
|`actions`
@ -1496,8 +1496,8 @@ link:{ref}/tasks.html[Documentation] +
|`detailed`
|`boolean` - Return detailed task information (default: false)
|`parent_task` or `parentTask`
|`number` - Return tasks with specified parent task id. Set to -1 to return all.
|`parent_task_id` or `parentTaskId`
|`string` - Return tasks with specified parent task id (node_id:task_number). Set to -1 to return all.
|`h`
|`string \| string[]` - Comma-separated list of column names to display
@ -2957,7 +2957,7 @@ link:{ref}/enrich-stats-api.html[Documentation] +
[discrete]
=== eql.delete
*Stability:* beta
[source,ts]
----
client.eql.delete({
@ -2974,7 +2974,7 @@ link:{ref}/eql-search-api.html[Documentation] +
[discrete]
=== eql.get
*Stability:* beta
[source,ts]
----
client.eql.get({
@ -3000,7 +3000,7 @@ _Default:_ `5d`
[discrete]
=== eql.search
*Stability:* beta
[source,ts]
----
client.eql.search({
@ -4812,6 +4812,23 @@ _Default:_ `open`
|===
[discrete]
=== indices.migrateToDataStream
[source,ts]
----
client.indices.migrateToDataStream({
name: string
})
----
link:{ref}/data-streams.html[Documentation] +
[cols=2*]
|===
|`name`
|`string` - The name of the alias to migrate
|===
[discrete]
=== indices.open
@ -8482,6 +8499,7 @@ link:{ref}/rollup-put-job.html[Documentation] +
----
client.rollup.rollup({
index: string,
rollup_index: string,
body: object
})
----
@ -8491,6 +8509,9 @@ link:{ref}/rollup-api.html[Documentation] +
|`index`
|`string` - The index to roll up
|`rollup_index` or `rollupIndex`
|`string` - The name of the rollup index to create
|`body`
|`object` - The rollup configuration

8
index.d.ts vendored
View File

@ -1045,6 +1045,14 @@ declare class Client {
getUpgrade<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getUpgrade<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesGetUpgrade, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getUpgrade<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesGetUpgrade, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrate_to_data_stream<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesMigrateToDataStream, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
migrate_to_data_stream<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrate_to_data_stream<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesMigrateToDataStream, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrate_to_data_stream<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesMigrateToDataStream, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrateToDataStream<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesMigrateToDataStream, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
migrateToDataStream<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrateToDataStream<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesMigrateToDataStream, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
migrateToDataStream<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesMigrateToDataStream, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
open<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.IndicesOpen, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
open<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
open<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.IndicesOpen, callback: callbackFn<TResponse, TContext>): TransportRequestCallback

View File

@ -11,7 +11,7 @@
"./": "./"
},
"homepage": "http://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
"version": "7.7.1",
"version": "7.11.0",
"keywords": [
"elasticsearch",
"elastic",

View File

@ -43,9 +43,10 @@ const MAX_API_TIME = 1000 * 90
const MAX_FILE_TIME = 1000 * 30
const MAX_TEST_TIME = 1000 * 3
const ossSkips = {
const freeSkips = {
'cat.indices/10_basic.yml': ['Test cat indices output for closed index (pre 7.2.0)'],
'cluster.health/10_basic.yml': ['cluster health with closed index (pre 7.2.0)'],
// TODO: remove this once 'arbitrary_key' is implemented
// https://github.com/elastic/elasticsearch/pull/41492
'indices.split/30_copy_settings.yml': ['*'],
@ -56,12 +57,18 @@ const ossSkips = {
// which triggers a retry and the node to be marked as dead
'search.aggregation/240_max_buckets.yml': ['*']
}
const xPackBlackList = {
// file path: test name
const platinumBlackList = {
// this two test cases are broken, we should
// return on those in the future.
'analytics/top_metrics.yml': [
'sort by keyword field fails',
'sort by string script fails'
],
'cat.aliases/10_basic.yml': ['Empty cluster'],
'index/10_with_id.yml': ['Index with ID'],
'indices.get_alias/10_basic.yml': ['Get alias against closed indices'],
'indices.get_alias/20_empty.yml': ['Check empty aliases when getting all aliases via /_alias'],
'text_structure/find_structure.yml': ['*'],
// https://github.com/elastic/elasticsearch/pull/39400
'ml/jobs_crud.yml': ['Test put job with id that is already taken'],
// object keys must me strings, and `0.0.toString()` is `0`
@ -82,6 +89,7 @@ const xPackBlackList = {
'monitoring/bulk/20_privileges.yml': ['*'],
'license/20_put_license.yml': ['*'],
'snapshot/10_basic.yml': ['*'],
'snapshot/20_operator_privileges_disabled.yml': ['*'],
// the body is correct, but the regex is failing
'sql/sql.yml': ['Getting textual representation'],
// we are setting two certificates in the docker config
@ -155,9 +163,9 @@ async function start ({ client, isXPack }) {
log(`Checking out sha ${sha}...`)
await withSHA(sha)
log(`Testing ${isXPack ? 'XPack' : 'oss'} api...`)
log(`Testing ${isXPack ? 'Platinum' : 'Free'} api...`)
const junit = createJunitReporter()
const junitTestSuites = junit.testsuites(`Integration test for ${isXPack ? 'XPack' : 'oss'} api`)
const junitTestSuites = junit.testsuites(`Integration test for ${isXPack ? 'Platinum' : 'Free'} api`)
const stats = {
total: 0,
@ -248,7 +256,7 @@ async function start ({ client, isXPack }) {
junitTestCase.end()
junitTestSuite.end()
junitTestSuites.end()
generateJunitXmlReport(junit, isXPack ? 'xpack' : 'oss')
generateJunitXmlReport(junit, isXPack ? 'platinum' : 'free')
console.error(err)
process.exit(1)
}
@ -276,7 +284,7 @@ async function start ({ client, isXPack }) {
}
}
junitTestSuites.end()
generateJunitXmlReport(junit, isXPack ? 'xpack' : 'oss')
generateJunitXmlReport(junit, isXPack ? 'platinum' : 'free')
log(`Total testing time: ${ms(now() - totalTime)}`)
log(`Test stats:
- Total: ${stats.total}
@ -419,26 +427,26 @@ if (require.main === module) {
}
const shouldSkip = (isXPack, file, name) => {
var list = Object.keys(ossSkips)
var list = Object.keys(freeSkips)
for (var i = 0; i < list.length; i++) {
const ossTest = ossSkips[list[i]]
for (var j = 0; j < ossTest.length; j++) {
if (file.endsWith(list[i]) && (name === ossTest[j] || ossTest[j] === '*')) {
const freeTest = freeSkips[list[i]]
for (var j = 0; j < freeTest.length; j++) {
if (file.endsWith(list[i]) && (name === freeTest[j] || freeTest[j] === '*')) {
const testName = file.slice(file.indexOf(`${sep}elasticsearch${sep}`)) + ' / ' + name
log(`Skipping test ${testName} because is blacklisted in the oss test`)
log(`Skipping test ${testName} because is blacklisted in the free test`)
return true
}
}
}
if (file.includes('x-pack') || isXPack) {
list = Object.keys(xPackBlackList)
list = Object.keys(platinumBlackList)
for (i = 0; i < list.length; i++) {
const platTest = xPackBlackList[list[i]]
const platTest = platinumBlackList[list[i]]
for (j = 0; j < platTest.length; j++) {
if (file.endsWith(list[i]) && (name === platTest[j] || platTest[j] === '*')) {
const testName = file.slice(file.indexOf(`${sep}elasticsearch${sep}`)) + ' / ' + name
log(`Skipping test ${testName} because is blacklisted in the XPack test`)
log(`Skipping test ${testName} because is blacklisted in the platinum test`)
return true
}
}