diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage
new file mode 100644
index 0000000000000..d9ec1861c9979
--- /dev/null
+++ b/.ci/Jenkinsfile_coverage
@@ -0,0 +1,112 @@
+#!/bin/groovy
+
+library 'kibana-pipeline-library'
+kibanaLibrary.load() // load from the Jenkins instance
+
+stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a little bit
+ timeout(time: 180, unit: 'MINUTES') {
+ timestamps {
+ ansiColor('xterm') {
+ catchError {
+ withEnv([
+ 'CODE_COVERAGE=1', // Needed for multiple ci scripts, such as remote.ts, test/scripts/*.sh, schema.js, etc.
+ ]) {
+ parallel([
+ 'kibana-intake-agent': {
+ withEnv([
+ 'NODE_ENV=test' // Needed for jest tests only
+ ]) {
+ kibanaPipeline.legacyJobRunner('kibana-intake')()
+ }
+ },
+ 'x-pack-intake-agent': {
+ withEnv([
+ 'NODE_ENV=test' // Needed for jest tests only
+ ]) {
+ kibanaPipeline.legacyJobRunner('x-pack-intake')()
+ }
+ },
+ 'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [
+ 'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1),
+ 'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2),
+ 'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3),
+ 'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4),
+ 'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5),
+ 'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6),
+ 'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7),
+ 'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8),
+ 'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9),
+ 'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10),
+ 'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11),
+ 'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12),
+ ]),
+ 'kibana-xpack-agent-1': kibanaPipeline.withWorkers('kibana-xpack-tests-1', { kibanaPipeline.buildXpack() }, [
+ 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1),
+ 'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2),
+ ]),
+ 'kibana-xpack-agent-2': kibanaPipeline.withWorkers('kibana-xpack-tests-2', { kibanaPipeline.buildXpack() }, [
+ 'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3),
+ 'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4),
+ ]),
+
+ 'kibana-xpack-agent-3': kibanaPipeline.withWorkers('kibana-xpack-tests-3', { kibanaPipeline.buildXpack() }, [
+ 'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5),
+ 'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6),
+ 'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7),
+ 'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8),
+ 'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9),
+ 'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10),
+ ]),
+ ])
+ kibanaPipeline.jobRunner('tests-l', false) {
+ kibanaPipeline.downloadCoverageArtifacts()
+ kibanaPipeline.bash(
+ '''
+ # bootstrap from x-pack folder
+ source src/dev/ci_setup/setup_env.sh
+ cd x-pack
+ yarn kbn bootstrap --prefer-offline
+ cd ..
+ # extract archives
+ mkdir -p /tmp/extracted_coverage
+ echo extracting intakes
+ tar -xzf /tmp/downloaded_coverage/coverage/kibana-intake/kibana-coverage.tar.gz -C /tmp/extracted_coverage
+ tar -xzf /tmp/downloaded_coverage/coverage/x-pack-intake/kibana-coverage.tar.gz -C /tmp/extracted_coverage
+ echo extracting kibana-oss-tests
+ tar -xzf /tmp/downloaded_coverage/coverage/kibana-oss-tests/kibana-coverage.tar.gz -C /tmp/extracted_coverage
+ echo extracting kibana-xpack-tests
+ for i in {1..3}; do
+ tar -xzf /tmp/downloaded_coverage/coverage/kibana-xpack-tests-${i}/kibana-coverage.tar.gz -C /tmp/extracted_coverage
+ done
+ # replace path in json files to have valid html report
+ pwd=$(pwd)
+ du -sh /tmp/extracted_coverage/target/kibana-coverage/
+ echo replacing path in json files
+ for i in {1..9}; do
+ sed -i "s|/dev/shm/workspace/kibana|$pwd|g" /tmp/extracted_coverage/target/kibana-coverage/functional/${i}*.json &
+ done
+ wait
+ # merge oss & x-pack reports
+ echo merging coverage reports
+ yarn nyc report --temp-dir /tmp/extracted_coverage/target/kibana-coverage/jest --report-dir target/kibana-coverage/jest-combined --reporter=html --reporter=json-summary
+ yarn nyc report --temp-dir /tmp/extracted_coverage/target/kibana-coverage/functional --report-dir target/kibana-coverage/functional-combined --reporter=html --reporter=json-summary
+ echo copy mocha reports
+ mkdir -p target/kibana-coverage/mocha-combined
+ cp -r /tmp/extracted_coverage/target/kibana-coverage/mocha target/kibana-coverage/mocha-combined
+ ''',
+ "run `yarn kbn bootstrap && merge coverage`"
+ )
+ sh 'tar -czf kibana-jest-coverage.tar.gz target/kibana-coverage/jest-combined/*'
+ kibanaPipeline.uploadCoverageArtifacts("coverage/jest-combined", 'kibana-jest-coverage.tar.gz')
+ sh 'tar -czf kibana-functional-coverage.tar.gz target/kibana-coverage/functional-combined/*'
+ kibanaPipeline.uploadCoverageArtifacts("coverage/functional-combined", 'kibana-functional-coverage.tar.gz')
+ sh 'tar -czf kibana-mocha-coverage.tar.gz target/kibana-coverage/mocha-combined/*'
+ kibanaPipeline.uploadCoverageArtifacts("coverage/mocha-combined", 'kibana-mocha-coverage.tar.gz')
+ }
+ }
+ }
+ kibanaPipeline.sendMail()
+ }
+ }
+ }
+}
diff --git a/.ci/Jenkinsfile_flaky b/.ci/Jenkinsfile_flaky
index 669395564db44..f702405aad69e 100644
--- a/.ci/Jenkinsfile_flaky
+++ b/.ci/Jenkinsfile_flaky
@@ -99,7 +99,7 @@ def getWorkerMap(agentNumber, numberOfExecutions, worker, workerFailures, maxWor
def numberOfWorkers = Math.min(numberOfExecutions, maxWorkerProcesses)
for(def i = 1; i <= numberOfWorkers; i++) {
- def workerExecutions = numberOfExecutions/numberOfWorkers + (i <= numberOfExecutions%numberOfWorkers ? 1 : 0)
+ def workerExecutions = floor(numberOfExecutions/numberOfWorkers + (i <= numberOfExecutions%numberOfWorkers ? 1 : 0))
workerMap["agent-${agentNumber}-worker-${i}"] = { workerNumber ->
for(def j = 0; j < workerExecutions; j++) {
diff --git a/.ci/es-snapshots/Jenkinsfile_build_es b/.ci/es-snapshots/Jenkinsfile_build_es
new file mode 100644
index 0000000000000..ad0ad54275e12
--- /dev/null
+++ b/.ci/es-snapshots/Jenkinsfile_build_es
@@ -0,0 +1,162 @@
+#!/bin/groovy
+
+// This job effectively has two SCM configurations:
+// one for kibana, used to check out this Jenkinsfile (which means it's the job's main SCM configuration), as well as kick-off the downstream verification job
+// one for elasticsearch, used to check out the elasticsearch source before building it
+
+// There are two parameters that drive which branch is checked out for each of these, but they will typically be the same
+// 'branch_specifier' is for kibana / the job itself
+// ES_BRANCH is for elasticsearch
+
+library 'kibana-pipeline-library'
+kibanaLibrary.load()
+
+def ES_BRANCH = params.ES_BRANCH
+
+if (!ES_BRANCH) {
+ error "Parameter 'ES_BRANCH' must be specified."
+}
+
+currentBuild.displayName += " - ${ES_BRANCH}"
+currentBuild.description = "ES: ${ES_BRANCH}
Kibana: ${params.branch_specifier}"
+
+def PROMOTE_WITHOUT_VERIFY = !!params.PROMOTE_WITHOUT_VERIFICATION
+
+timeout(time: 120, unit: 'MINUTES') {
+ timestamps {
+ ansiColor('xterm') {
+ node('linux && immutable') {
+ catchError {
+ def VERSION
+ def SNAPSHOT_ID
+ def DESTINATION
+
+ def scmVars = checkoutEs(ES_BRANCH)
+ def GIT_COMMIT = scmVars.GIT_COMMIT
+ def GIT_COMMIT_SHORT = sh(script: "git rev-parse --short ${GIT_COMMIT}", returnStdout: true).trim()
+
+ buildArchives('to-archive')
+
+ dir('to-archive') {
+ def now = new Date()
+ def date = now.format("yyyyMMdd-HHmmss")
+
+ def filesRaw = sh(script: "ls -1", returnStdout: true).trim()
+ def files = filesRaw
+ .split("\n")
+ .collect { filename ->
+ // Filename examples
+ // elasticsearch-oss-8.0.0-SNAPSHOT-linux-x86_64.tar.gz
+ // elasticsearch-8.0.0-SNAPSHOT-linux-x86_64.tar.gz
+ def parts = filename.replace("elasticsearch-oss", "oss").split("-")
+
+ VERSION = VERSION ?: parts[1]
+ SNAPSHOT_ID = SNAPSHOT_ID ?: "${date}_${GIT_COMMIT_SHORT}"
+ DESTINATION = DESTINATION ?: "${VERSION}/archives/${SNAPSHOT_ID}"
+
+ return [
+ filename: filename,
+ checksum: filename + '.sha512',
+ url: "https://storage.googleapis.com/kibana-ci-es-snapshots-daily/${DESTINATION}/${filename}".toString(),
+ version: parts[1],
+ platform: parts[3],
+ architecture: parts[4].split('\\.')[0],
+ license: parts[0] == 'oss' ? 'oss' : 'default',
+ ]
+ }
+
+ sh 'find * -exec bash -c "shasum -a 512 {} > {}.sha512" \\;'
+
+ def manifest = [
+ bucket: "kibana-ci-es-snapshots-daily/${DESTINATION}".toString(),
+ branch: ES_BRANCH,
+ sha: GIT_COMMIT,
+ sha_short: GIT_COMMIT_SHORT,
+ version: VERSION,
+ generated: now.format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")),
+ archives: files,
+ ]
+ def manifestJson = toJSON(manifest).toString()
+ writeFile file: 'manifest.json', text: manifestJson
+
+ upload(DESTINATION, '*.*')
+
+ sh "cp manifest.json manifest-latest.json"
+ upload(VERSION, 'manifest-latest.json')
+ }
+
+ if (PROMOTE_WITHOUT_VERIFY) {
+ esSnapshots.promote(VERSION, SNAPSHOT_ID)
+
+ emailext(
+ to: 'build-kibana@elastic.co',
+ subject: "ES snapshot promoted without verification: ${params.ES_BRANCH}",
+ body: '${SCRIPT,template="groovy-html.template"}',
+ mimeType: 'text/html',
+ )
+ } else {
+ build(
+ propagate: false,
+ wait: false,
+ job: 'elasticsearch+snapshots+verify',
+ parameters: [
+ string(name: 'branch_specifier', value: branch_specifier),
+ string(name: 'SNAPSHOT_VERSION', value: VERSION),
+ string(name: 'SNAPSHOT_ID', value: SNAPSHOT_ID),
+ ]
+ )
+ }
+ }
+
+ kibanaPipeline.sendMail()
+ }
+ }
+ }
+}
+
+def checkoutEs(branch) {
+ retryWithDelay(8, 15) {
+ return checkout([
+ $class: 'GitSCM',
+ branches: [[name: branch]],
+ doGenerateSubmoduleConfigurations: false,
+ extensions: [],
+ submoduleCfg: [],
+ userRemoteConfigs: [[
+ credentialsId: 'f6c7695a-671e-4f4f-a331-acdce44ff9ba',
+ url: 'git@github.com:elastic/elasticsearch',
+ ]],
+ ])
+ }
+}
+
+def upload(destination, pattern) {
+ return googleStorageUpload(
+ credentialsId: 'kibana-ci-gcs-plugin',
+ bucket: "gs://kibana-ci-es-snapshots-daily/${destination}",
+ pattern: pattern,
+ sharedPublicly: false,
+ showInline: false,
+ )
+}
+
+def buildArchives(destination) {
+ def props = readProperties file: '.ci/java-versions.properties'
+ withEnv([
+ // Select the correct JDK for this branch
+ "PATH=/var/lib/jenkins/.java/${props.ES_BUILD_JAVA}/bin:${env.PATH}",
+
+ // These Jenkins env vars trigger some automation in the elasticsearch repo that we don't want
+ "BUILD_NUMBER=",
+ "JENKINS_URL=",
+ "BUILD_URL=",
+ "JOB_NAME=",
+ "NODE_NAME=",
+ ]) {
+ sh """
+ ./gradlew -p distribution/archives assemble --parallel
+ mkdir -p ${destination}
+ find distribution/archives -type f \\( -name 'elasticsearch-*-*-*-*.tar.gz' -o -name 'elasticsearch-*-*-*-*.zip' \\) -not -path *no-jdk* -exec cp {} ${destination} \\;
+ """
+ }
+}
diff --git a/.ci/es-snapshots/Jenkinsfile_trigger_build_es b/.ci/es-snapshots/Jenkinsfile_trigger_build_es
new file mode 100644
index 0000000000000..186917e967824
--- /dev/null
+++ b/.ci/es-snapshots/Jenkinsfile_trigger_build_es
@@ -0,0 +1,19 @@
+#!/bin/groovy
+
+if (!params.branches_yaml) {
+ error "'branches_yaml' parameter must be specified"
+}
+
+def branches = readYaml text: params.branches_yaml
+
+branches.each { branch ->
+ build(
+ propagate: false,
+ wait: false,
+ job: 'elasticsearch+snapshots+build',
+ parameters: [
+ string(name: 'branch_specifier', value: branch),
+ string(name: 'ES_BRANCH', value: branch),
+ ]
+ )
+}
diff --git a/.ci/es-snapshots/Jenkinsfile_verify_es b/.ci/es-snapshots/Jenkinsfile_verify_es
new file mode 100644
index 0000000000000..3d5ec75fa0e72
--- /dev/null
+++ b/.ci/es-snapshots/Jenkinsfile_verify_es
@@ -0,0 +1,72 @@
+#!/bin/groovy
+
+library 'kibana-pipeline-library'
+kibanaLibrary.load()
+
+def SNAPSHOT_VERSION = params.SNAPSHOT_VERSION
+def SNAPSHOT_ID = params.SNAPSHOT_ID
+
+if (!SNAPSHOT_VERSION) {
+ error "Parameter SNAPSHOT_VERSION must be specified"
+}
+
+if (!SNAPSHOT_ID) {
+ error "Parameter SNAPSHOT_ID must be specified"
+}
+
+currentBuild.displayName += " - ${SNAPSHOT_VERSION}"
+currentBuild.description = "ES: ${SNAPSHOT_VERSION}
Kibana: ${params.branch_specifier}"
+
+def SNAPSHOT_MANIFEST = "https://storage.googleapis.com/kibana-ci-es-snapshots-daily/${SNAPSHOT_VERSION}/archives/${SNAPSHOT_ID}/manifest.json"
+
+timeout(time: 120, unit: 'MINUTES') {
+ timestamps {
+ ansiColor('xterm') {
+ catchError {
+ withEnv(["ES_SNAPSHOT_MANIFEST=${SNAPSHOT_MANIFEST}"]) {
+ parallel([
+ // TODO we just need to run integration tests from intake?
+ 'kibana-intake-agent': kibanaPipeline.legacyJobRunner('kibana-intake'),
+ 'x-pack-intake-agent': kibanaPipeline.legacyJobRunner('x-pack-intake'),
+ 'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [
+ 'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1),
+ 'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2),
+ 'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3),
+ 'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4),
+ 'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5),
+ 'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6),
+ 'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7),
+ 'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8),
+ 'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9),
+ 'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10),
+ 'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11),
+ 'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12),
+ ]),
+ 'kibana-xpack-agent': kibanaPipeline.withWorkers('kibana-xpack-tests', { kibanaPipeline.buildXpack() }, [
+ 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1),
+ 'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2),
+ 'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3),
+ 'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4),
+ 'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5),
+ 'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6),
+ 'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7),
+ 'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8),
+ 'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9),
+ 'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10),
+ ]),
+ ])
+ }
+
+ promoteSnapshot(SNAPSHOT_VERSION, SNAPSHOT_ID)
+ }
+
+ kibanaPipeline.sendMail()
+ }
+ }
+}
+
+def promoteSnapshot(snapshotVersion, snapshotId) {
+ node('linux && immutable') {
+ esSnapshots.promote(snapshotVersion, snapshotId)
+ }
+}
diff --git a/.eslintrc.js b/.eslintrc.js
index 03a674993ab50..bdab4e0cebbe5 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -82,13 +82,6 @@ module.exports = {
'react-hooks/exhaustive-deps': 'off',
},
},
- {
- files: ['src/legacy/core_plugins/kibana/**/*.{js,ts,tsx}'],
- rules: {
- 'react-hooks/rules-of-hooks': 'off',
- 'react-hooks/exhaustive-deps': 'off',
- },
- },
{
files: ['src/legacy/core_plugins/tile_map/**/*.{js,ts,tsx}'],
rules: {
@@ -101,24 +94,12 @@ module.exports = {
'react-hooks/exhaustive-deps': 'off',
},
},
- {
- files: ['src/legacy/core_plugins/vis_type_metric/**/*.{js,ts,tsx}'],
- rules: {
- 'jsx-a11y/click-events-have-key-events': 'off',
- },
- },
{
files: ['src/legacy/core_plugins/vis_type_table/**/*.{js,ts,tsx}'],
rules: {
'react-hooks/exhaustive-deps': 'off',
},
},
- {
- files: ['src/legacy/core_plugins/vis_type_vega/**/*.{js,ts,tsx}'],
- rules: {
- 'react-hooks/exhaustive-deps': 'off',
- },
- },
{
files: ['src/legacy/ui/public/vis/**/*.{js,ts,tsx}'],
rules: {
@@ -177,12 +158,6 @@ module.exports = {
'react-hooks/exhaustive-deps': 'off',
},
},
- {
- files: ['x-pack/legacy/plugins/monitoring/**/*.{js,ts,tsx}'],
- rules: {
- 'jsx-a11y/click-events-have-key-events': 'off',
- },
- },
{
files: ['x-pack/legacy/plugins/snapshot_restore/**/*.{js,ts,tsx}'],
rules: {
@@ -253,6 +228,7 @@ module.exports = {
'!x-pack/test/**/*',
'(src|x-pack)/plugins/**/(public|server)/**/*',
'src/core/(public|server)/**/*',
+ 'examples/**/*',
],
from: [
'src/core/public/**/*',
@@ -289,11 +265,15 @@ module.exports = {
'x-pack/legacy/plugins/**/*',
'!x-pack/legacy/plugins/*/server/**/*',
'!x-pack/legacy/plugins/*/index.{js,ts,tsx}',
+
+ 'examples/**/*',
+ '!examples/**/server/**/*',
],
from: [
'src/core/server',
'src/core/server/**/*',
'(src|x-pack)/plugins/*/server/**/*',
+ 'examples/**/server/**/*',
],
errorMessage:
'Server modules cannot be imported into client modules or shared modules.',
@@ -729,15 +709,13 @@ module.exports = {
'no-unreachable': 'error',
'no-unsafe-finally': 'error',
'no-useless-call': 'error',
- // This will be turned on after bug fixes are mostly complete
- // 'no-useless-catch': 'warn',
+ 'no-useless-catch': 'error',
'no-useless-concat': 'error',
'no-useless-computed-key': 'error',
// This will be turned on after bug fixes are mostly complete
// 'no-useless-escape': 'warn',
'no-useless-rename': 'error',
- // This will be turned on after bug fixes are mostly complete
- // 'no-useless-return': 'warn',
+ 'no-useless-return': 'error',
// This will be turned on after bug fixers are mostly complete
// 'no-void': 'warn',
'one-var-declaration-per-line': 'error',
@@ -745,14 +723,13 @@ module.exports = {
'prefer-promise-reject-errors': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
- // This style will be turned on after most bugs are fixed
- // 'prefer-template': 'warn',
+ 'prefer-template': 'error',
'react/boolean-prop-naming': 'error',
'react/button-has-type': 'error',
+ 'react/display-name': 'error',
'react/forbid-dom-props': 'error',
'react/no-access-state-in-setstate': 'error',
- // This style will be turned on after most bugs are fixed
- // 'react/no-children-prop': 'warn',
+ 'react/no-children-prop': 'error',
'react/no-danger-with-children': 'error',
'react/no-deprecated': 'error',
'react/no-did-mount-set-state': 'error',
@@ -814,21 +791,6 @@ module.exports = {
},
},
- /**
- * Monitoring overrides
- */
- {
- files: ['x-pack/legacy/plugins/monitoring/**/*.js'],
- rules: {
- 'no-unused-vars': ['error', { args: 'all', argsIgnorePattern: '^_' }],
- 'no-else-return': 'error',
- },
- },
- {
- files: ['x-pack/legacy/plugins/monitoring/public/**/*.js'],
- env: { browser: true },
- },
-
/**
* Canvas overrides
*/
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 1137fb99f81a7..a0a22446ba31d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -14,6 +14,7 @@
/src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app
/src/legacy/core_plugins/kibana/public/home/ @elastic/kibana-app
/src/legacy/core_plugins/kibana/public/dev_tools/ @elastic/kibana-app
+/src/legacy/core_plugins/metrics/ @elastic/kibana-app
/src/plugins/home/ @elastic/kibana-app
/src/plugins/kibana_legacy/ @elastic/kibana-app
/src/plugins/timelion/ @elastic/kibana-app
@@ -30,6 +31,7 @@
/src/plugins/visualizations/ @elastic/kibana-app-arch
/x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch
/src/legacy/core_plugins/data/ @elastic/kibana-app-arch
+/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js @elastic/kibana-app-arch
/src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch
/src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch
/src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch
@@ -146,6 +148,3 @@
/x-pack/legacy/plugins/searchprofiler/ @elastic/es-ui
/x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui
/x-pack/legacy/plugins/watcher/ @elastic/es-ui
-
-# Kibana TSVB external contractors
-/src/legacy/core_plugins/metrics/ @elastic/kibana-tsvb-external
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 06e08c85dafec..6ae3db559b61b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -190,6 +190,19 @@ These snapshots are built on a nightly basis which expire after a couple weeks.
yarn es snapshot
```
+##### Keeping data between snapshots
+
+If you want to keep the data inside your Elasticsearch between usages of this command,
+you should use the following command, to keep your data folder outside the downloaded snapshot
+folder:
+
+```bash
+yarn es snapshot -E path.data=../data
+```
+
+The same parameter can be used with the source and archive command shown in the following
+paragraphs.
+
#### Source
By default, it will reference an [elasticsearch](https://github.com/elastic/elasticsearch) checkout which is a sibling to the Kibana directory named `elasticsearch`. If you wish to use a checkout in another location you can provide that by supplying `--source-path`
diff --git a/docs/apm/settings.asciidoc b/docs/apm/settings.asciidoc
index 2fc8748f13b09..37122fc9c635d 100644
--- a/docs/apm/settings.asciidoc
+++ b/docs/apm/settings.asciidoc
@@ -3,8 +3,16 @@
[[apm-settings-in-kibana]]
=== APM settings in Kibana
-You do not need to configure any settings to use APM. It is enabled by default.
-If you'd like to change any of the default values,
-copy and paste the relevant settings below into your `kibana.yml` configuration file.
+You do not need to configure any settings to use the APM app. It is enabled by default.
+
+[float]
+[[apm-indices-settings]]
+==== APM Indices
+
+include::./../settings/apm-settings.asciidoc[tag=apm-indices-settings]
+
+[float]
+[[general-apm-settings]]
+==== General APM settings
include::./../settings/apm-settings.asciidoc[tag=general-apm-settings]
diff --git a/docs/apm/troubleshooting.asciidoc b/docs/apm/troubleshooting.asciidoc
index ec0863b09d653..22279b69b70fe 100644
--- a/docs/apm/troubleshooting.asciidoc
+++ b/docs/apm/troubleshooting.asciidoc
@@ -17,6 +17,7 @@ This section can help with any of the following:
There are a number of factors that could be at play here.
One important thing to double-check first is your index template.
+*Index template*
An APM index template must exist for the APM app to work correctly.
By default, this index template is created by APM Server on startup.
However, this only happens if `setup.template.enabled` is `true` in `apm-server.yml`.
@@ -34,14 +35,21 @@ GET /_template/apm-{version}
--------------------------------------------------
// CONSOLE
+*Using Logstash, Kafka, etc.*
If you're not outputting data directly from APM Server to Elasticsearch (perhaps you're using Logstash or Kafka),
then the index template will not be set up automatically. Instead, you'll need to
-{apm-server-ref}/_manually_loading_template_configuration.html#load-template-manually-alternate[load the template manually].
+{apm-server-ref}/_manually_loading_template_configuration.html[load the template manually].
-Finally, this problem can also occur if you've changed the index name that you write APM data to.
-The default index pattern can be found {apm-server-ref}/elasticsearch-output.html#index-option-es[here].
-If you change this setting, you must also configure the `setup.template.name` and `setup.template.pattern` options.
+*Using a custom index names*
+This problem can also occur if you've customized the index name that you write APM data to.
+The default index name that APM writes events to can be found
+{apm-server-ref}/elasticsearch-output.html#index-option-es[here].
+If you change the default, you must also configure the `setup.template.name` and `setup.template.pattern` options.
See {apm-server-ref}/configuration-template.html[Load the Elasticsearch index template].
+If the Elasticsearch index template has already been successfully loaded to the index,
+you can customize the indices that the APM app uses to display data.
+Navigate to *APM* > *Settings* > *Indices*, and change all `apm_oss.*Pattern` values to
+include the new index pattern. For example: `customIndexName-*`.
==== Unknown route
diff --git a/docs/developer/plugin/development-uiexports.asciidoc b/docs/developer/plugin/development-uiexports.asciidoc
index 6368446f7fb43..18d326cbfb9c0 100644
--- a/docs/developer/plugin/development-uiexports.asciidoc
+++ b/docs/developer/plugin/development-uiexports.asciidoc
@@ -9,8 +9,8 @@ An aggregate list of available UiExport types:
| hacks | Any module that should be included in every application
| visTypes | Modules that register providers with the `ui/registry/vis_types` registry.
| inspectorViews | Modules that register custom inspector views via the `viewRegistry` in `ui/inspector`.
-| chromeNavControls | Modules that register providers with the `ui/registry/chrome_nav_controls` registry.
-| navbarExtensions | Modules that register providers with the `ui/registry/navbar_extensions` registry.
-| docViews | Modules that register providers with the `ui/registry/doc_views` registry.
+| chromeNavControls | Modules that register providers with the `ui/registry/chrome_header_nav_controls` registry.
+| navbarExtensions | Modules that register providers with the setup contract of the `navigation` plugin.
+| docViews | Modules that register providers with the setup contract method `addDocView` of the `discover` plugin.
| app | Adds an application to the system. This uiExport type is defined as an object of metadata rather than just a module id.
|=======================================================================
diff --git a/docs/development/core/public/kibana-plugin-public.savedobjectsclient.find.md b/docs/development/core/public/kibana-plugin-public.savedobjectsclient.find.md
index 1ce18834f5319..a4fa3f17d0d94 100644
--- a/docs/development/core/public/kibana-plugin-public.savedobjectsclient.find.md
+++ b/docs/development/core/public/kibana-plugin-public.savedobjectsclient.find.md
@@ -9,5 +9,5 @@ Search for objects
Signature:
```typescript
-find: (options: Pick) => Promise>;
+find: (options: Pick) => Promise>;
```
diff --git a/docs/development/core/public/kibana-plugin-public.savedobjectsclient.md b/docs/development/core/public/kibana-plugin-public.savedobjectsclient.md
index 3b916db972673..88485aa71f7c5 100644
--- a/docs/development/core/public/kibana-plugin-public.savedobjectsclient.md
+++ b/docs/development/core/public/kibana-plugin-public.savedobjectsclient.md
@@ -24,7 +24,7 @@ The constructor for this class is marked as internal. Third-party code should no
| [bulkGet](./kibana-plugin-public.savedobjectsclient.bulkget.md) | | (objects?: {
id: string;
type: string;
}[]) => Promise<SavedObjectsBatchResponse<SavedObjectAttributes>>
| Returns an array of objects by id |
| [create](./kibana-plugin-public.savedobjectsclient.create.md) | | <T extends SavedObjectAttributes>(type: string, attributes: T, options?: SavedObjectsCreateOptions) => Promise<SimpleSavedObject<T>>
| Persists an object |
| [delete](./kibana-plugin-public.savedobjectsclient.delete.md) | | (type: string, id: string) => Promise<{}>
| Deletes an object |
-| [find](./kibana-plugin-public.savedobjectsclient.find.md) | | <T extends SavedObjectAttributes>(options: Pick<SavedObjectFindOptionsServer, "search" | "filter" | "type" | "page" | "fields" | "searchFields" | "defaultSearchOperator" | "hasReference" | "sortField" | "perPage">) => Promise<SavedObjectsFindResponsePublic<T>>
| Search for objects |
+| [find](./kibana-plugin-public.savedobjectsclient.find.md) | | <T extends SavedObjectAttributes>(options: Pick<SavedObjectFindOptionsServer, "search" | "filter" | "type" | "page" | "perPage" | "sortField" | "fields" | "searchFields" | "hasReference" | "defaultSearchOperator">) => Promise<SavedObjectsFindResponsePublic<T>>
| Search for objects |
| [get](./kibana-plugin-public.savedobjectsclient.get.md) | | <T extends SavedObjectAttributes>(type: string, id: string) => Promise<SimpleSavedObject<T>>
| Fetches a single object |
## Methods
diff --git a/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md b/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md
index ed7d028a1ec8a..bb1f481c9ef4f 100644
--- a/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md
+++ b/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md
@@ -9,14 +9,14 @@ Creates an instance of [IScopedClusterClient](./kibana-plugin-server.iscopedclus
Signature:
```typescript
-asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): IScopedClusterClient;
+asScoped(request?: ScopeableRequest): IScopedClusterClient;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
-| request | KibanaRequest | LegacyRequest | FakeRequest
| Request the IScopedClusterClient
instance will be scoped to. Supports request optionality, Legacy.Request & FakeRequest for BWC with LegacyPlatform |
+| request | ScopeableRequest
| Request the IScopedClusterClient
instance will be scoped to. Supports request optionality, Legacy.Request & FakeRequest for BWC with LegacyPlatform |
Returns:
diff --git a/docs/development/core/server/kibana-plugin-server.clusterclient.md b/docs/development/core/server/kibana-plugin-server.clusterclient.md
index 5fdda7ef3e499..d547b846e65b7 100644
--- a/docs/development/core/server/kibana-plugin-server.clusterclient.md
+++ b/docs/development/core/server/kibana-plugin-server.clusterclient.md
@@ -4,7 +4,7 @@
## ClusterClient class
-Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`).
+Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`).
See [ClusterClient](./kibana-plugin-server.clusterclient.md).
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient.md
new file mode 100644
index 0000000000000..415423f555266
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient.md
@@ -0,0 +1,22 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) > [adminClient](./kibana-plugin-server.elasticsearchservicesetup.adminclient.md)
+
+## ElasticsearchServiceSetup.adminClient property
+
+A client for the `admin` cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
+
+Signature:
+
+```typescript
+readonly adminClient: IClusterClient;
+```
+
+## Example
+
+
+```js
+const client = core.elasticsearch.adminClient;
+
+```
+
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md
deleted file mode 100644
index b5bfc68d3ca0c..0000000000000
--- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) > [adminClient$](./kibana-plugin-server.elasticsearchservicesetup.adminclient_.md)
-
-## ElasticsearchServiceSetup.adminClient$ property
-
-Observable of clients for the `admin` cluster. Observable emits when Elasticsearch config changes on the Kibana server. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
-
-
-```js
-const client = await elasticsearch.adminClient$.pipe(take(1)).toPromise();
-
-```
-
-Signature:
-
-```typescript
-readonly adminClient$: Observable;
-```
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md
index 3d26f2d4cec88..797f402cc2580 100644
--- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md
+++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md
@@ -9,7 +9,7 @@ Create application specific Elasticsearch cluster API client with customized con
Signature:
```typescript
-readonly createClient: (type: string, clientConfig?: Partial) => IClusterClient;
+readonly createClient: (type: string, clientConfig?: Partial) => ICustomClusterClient;
```
## Example
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient.md
new file mode 100644
index 0000000000000..e9845dce6915d
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient.md
@@ -0,0 +1,22 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) > [dataClient](./kibana-plugin-server.elasticsearchservicesetup.dataclient.md)
+
+## ElasticsearchServiceSetup.dataClient property
+
+A client for the `data` cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
+
+Signature:
+
+```typescript
+readonly dataClient: IClusterClient;
+```
+
+## Example
+
+
+```js
+const client = core.elasticsearch.dataClient;
+
+```
+
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md
deleted file mode 100644
index 9411f2f6b8694..0000000000000
--- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) > [dataClient$](./kibana-plugin-server.elasticsearchservicesetup.dataclient_.md)
-
-## ElasticsearchServiceSetup.dataClient$ property
-
-Observable of clients for the `data` cluster. Observable emits when Elasticsearch config changes on the Kibana server. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
-
-
-```js
-const client = await elasticsearch.dataClient$.pipe(take(1)).toPromise();
-
-```
-
-Signature:
-
-```typescript
-readonly dataClient$: Observable;
-```
diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md
index e3d151cdc0d8b..2de3f6e6d1bbc 100644
--- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md
+++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md
@@ -15,17 +15,7 @@ export interface ElasticsearchServiceSetup
| Property | Type | Description |
| --- | --- | --- |
-| [adminClient$](./kibana-plugin-server.elasticsearchservicesetup.adminclient_.md) | Observable<IClusterClient>
| Observable of clients for the admin
cluster. Observable emits when Elasticsearch config changes on the Kibana server. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
-```js
-const client = await elasticsearch.adminClient$.pipe(take(1)).toPromise();
-
-```
- |
-| [createClient](./kibana-plugin-server.elasticsearchservicesetup.createclient.md) | (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => IClusterClient
| Create application specific Elasticsearch cluster API client with customized config. See [IClusterClient](./kibana-plugin-server.iclusterclient.md). |
-| [dataClient$](./kibana-plugin-server.elasticsearchservicesetup.dataclient_.md) | Observable<IClusterClient>
| Observable of clients for the data
cluster. Observable emits when Elasticsearch config changes on the Kibana server. See [IClusterClient](./kibana-plugin-server.iclusterclient.md).
-```js
-const client = await elasticsearch.dataClient$.pipe(take(1)).toPromise();
-
-```
- |
+| [adminClient](./kibana-plugin-server.elasticsearchservicesetup.adminclient.md) | IClusterClient
| A client for the admin
cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-server.iclusterclient.md). |
+| [createClient](./kibana-plugin-server.elasticsearchservicesetup.createclient.md) | (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient
| Create application specific Elasticsearch cluster API client with customized config. See [IClusterClient](./kibana-plugin-server.iclusterclient.md). |
+| [dataClient](./kibana-plugin-server.elasticsearchservicesetup.dataclient.md) | IClusterClient
| A client for the data
cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-server.iclusterclient.md). |
diff --git a/docs/development/core/server/kibana-plugin-server.iclusterclient.md b/docs/development/core/server/kibana-plugin-server.iclusterclient.md
index 834afa6db5157..e7435a9d91a74 100644
--- a/docs/development/core/server/kibana-plugin-server.iclusterclient.md
+++ b/docs/development/core/server/kibana-plugin-server.iclusterclient.md
@@ -4,12 +4,12 @@
## IClusterClient type
-Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`).
+Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`).
See [ClusterClient](./kibana-plugin-server.clusterclient.md).
Signature:
```typescript
-export declare type IClusterClient = Pick;
+export declare type IClusterClient = Pick;
```
diff --git a/docs/development/core/server/kibana-plugin-server.icustomclusterclient.md b/docs/development/core/server/kibana-plugin-server.icustomclusterclient.md
new file mode 100644
index 0000000000000..bc9ea71bc2389
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.icustomclusterclient.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ICustomClusterClient](./kibana-plugin-server.icustomclusterclient.md)
+
+## ICustomClusterClient type
+
+Represents an Elasticsearch cluster API client created by a plugin.. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`).
+
+See [ClusterClient](./kibana-plugin-server.clusterclient.md).
+
+Signature:
+
+```typescript
+export declare type ICustomClusterClient = Pick;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md
index 5e7f84c55244d..3f01048846fe1 100644
--- a/docs/development/core/server/kibana-plugin-server.md
+++ b/docs/development/core/server/kibana-plugin-server.md
@@ -17,7 +17,7 @@ The plugin integrates with the core system via lifecycle events: `setup`
| Class | Description |
| --- | --- |
| [BasePath](./kibana-plugin-server.basepath.md) | Access or manipulate the Kibana base path |
-| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
+| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
| [CspConfig](./kibana-plugin-server.cspconfig.md) | CSP configuration for use in Kibana. |
| [ElasticsearchErrorHelpers](./kibana-plugin-server.elasticsearcherrorhelpers.md) | Helpers for working with errors returned from the Elasticsearch service.Since the internal data of errors are subject to change, consumers of the Elasticsearch service should always use these helpers to classify errors instead of checking error internals such as body.error.header[WWW-Authenticate]
|
| [KibanaRequest](./kibana-plugin-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. |
@@ -175,8 +175,9 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [Headers](./kibana-plugin-server.headers.md) | Http request headers to read. |
| [HttpResponsePayload](./kibana-plugin-server.httpresponsepayload.md) | Data send to the client as a response payload. |
| [IBasePath](./kibana-plugin-server.ibasepath.md) | Access or manipulate the Kibana base path[BasePath](./kibana-plugin-server.basepath.md) |
-| [IClusterClient](./kibana-plugin-server.iclusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
+| [IClusterClient](./kibana-plugin-server.iclusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
| [IContextProvider](./kibana-plugin-server.icontextprovider.md) | A function that returns a context value for a specific key of given context type. |
+| [ICustomClusterClient](./kibana-plugin-server.icustomclusterclient.md) | Represents an Elasticsearch cluster API client created by a plugin.. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
| [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Return authentication status for a request. |
| [ISavedObjectsRepository](./kibana-plugin-server.isavedobjectsrepository.md) | See [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) |
| [IScopedClusterClient](./kibana-plugin-server.iscopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient
but exposes additional callAsCurrentUser
method that doesn't use credentials of the Kibana internal user (as callAsInternalUser
does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). |
@@ -213,6 +214,7 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [SavedObjectsClientContract](./kibana-plugin-server.savedobjectsclientcontract.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing plugin state.\#\# SavedObjectsClient errorsSince the SavedObjectsClient has its hands in everything we are a little paranoid about the way we present errors back to to application code. Ideally, all errors will be either:1. Caused by bad implementation (ie. undefined is not a function) and as such unpredictable 2. An error that has been classified and decorated appropriately by the decorators in [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md)Type 1 errors are inevitable, but since all expected/handle-able errors should be Type 2 the isXYZError()
helpers exposed at SavedObjectsErrorHelpers
should be used to understand and manage error responses from the SavedObjectsClient
.Type 2 errors are decorated versions of the source error, so if the elasticsearch client threw an error it will be decorated based on its type. That means that rather than looking for error.body.error.type
or doing substring checks on error.body.error.reason
, just use the helpers to understand the meaning of the error:\`\`\`js if (SavedObjectsErrorHelpers.isNotFoundError(error)) { // handle 404 }if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) { // 401 handling should be automatic, but in case you wanted to know }// always rethrow the error unless you handle it throw error; \`\`\`\#\#\# 404s from missing indexFrom the perspective of application code and APIs the SavedObjectsClient is a black box that persists objects. One of the internal details that users have no control over is that we use an elasticsearch index for persistance and that index might be missing.At the time of writing we are in the process of transitioning away from the operating assumption that the SavedObjects index is always available. Part of this transition is handling errors resulting from an index missing. These used to trigger a 500 error in most cases, and in others cause 404s with different error messages.From my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The object the request/call was targeting could not be found. This is why \#14141 takes special care to ensure that 404 errors are generic and don't distinguish between index missing or document missing.\#\#\# 503s from missing indexUnlike all other methods, create requests are supposed to succeed even when the Kibana index does not exist because it will be automatically created by elasticsearch. When that is not the case it is because Elasticsearch's action.auto_create_index
setting prevents it from being created automatically so we throw a special 503 with the intention of informing the user that their Elasticsearch settings need to be updated.See [SavedObjectsClient](./kibana-plugin-server.savedobjectsclient.md) See [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) |
| [SavedObjectsClientFactory](./kibana-plugin-server.savedobjectsclientfactory.md) | Describes the factory used to create instances of the Saved Objects Client. |
| [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | Describes the factory used to create instances of Saved Objects Client Wrappers. |
+| [ScopeableRequest](./kibana-plugin-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.See [KibanaRequest](./kibana-plugin-server.kibanarequest.md). |
| [SharedGlobalConfig](./kibana-plugin-server.sharedglobalconfig.md) | |
| [UiSettingsType](./kibana-plugin-server.uisettingstype.md) | UI element type to represent the settings. |
diff --git a/docs/development/core/server/kibana-plugin-server.scopeablerequest.md b/docs/development/core/server/kibana-plugin-server.scopeablerequest.md
new file mode 100644
index 0000000000000..5a9443376996d
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.scopeablerequest.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ScopeableRequest](./kibana-plugin-server.scopeablerequest.md)
+
+## ScopeableRequest type
+
+A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.
+
+See [KibanaRequest](./kibana-plugin-server.kibanarequest.md).
+
+Signature:
+
+```typescript
+export declare type ScopeableRequest = KibanaRequest | LegacyRequest | FakeRequest;
+```
diff --git a/docs/limitations.asciidoc b/docs/limitations.asciidoc
index 9bcba3b65d660..818cc766bf6a9 100644
--- a/docs/limitations.asciidoc
+++ b/docs/limitations.asciidoc
@@ -19,4 +19,4 @@ These {stack} features also have limitations that affect {kib}:
include::limitations/nested-objects.asciidoc[]
-include::limitations/export-data.asciidoc[]
+include::limitations/export-data.asciidoc[]
\ No newline at end of file
diff --git a/docs/management/index-patterns.asciidoc b/docs/management/index-patterns.asciidoc
index 8d9ef515108ed..8e687f641c92b 100644
--- a/docs/management/index-patterns.asciidoc
+++ b/docs/management/index-patterns.asciidoc
@@ -1,17 +1,22 @@
[[index-patterns]]
-== Index patterns
+== Creating an index pattern
-To visualize and explore data in {kib}, you must create an index pattern.
-An index pattern tells {kib} which {es} indices contain the data that you want to work with.
-An index pattern can match a single index, multiple indices, and a rollup index.
+To explore and visualize data in {kib}, you must create an index pattern.
+An index pattern tells {kib} which {es} indices contain the data that
+you want to work with.
+Once you create an index pattern, you're ready to:
+
+* Interactively explore your data in <>.
+* Analyze your data in charts, tables, gauges, tag clouds, and more in <>.
+* Show off your data in a <