diff --git a/docs/developer/architecture/security/feature-registration.asciidoc b/docs/developer/architecture/security/feature-registration.asciidoc index 8c80c2e5f2ffb..4e0c220477faf 100644 --- a/docs/developer/architecture/security/feature-registration.asciidoc +++ b/docs/developer/architecture/security/feature-registration.asciidoc @@ -198,7 +198,10 @@ server.route({ === Example 3: Discover Discover takes advantage of subfeature privileges to allow fine-grained access control. In this example, -a single "Create Short URLs" subfeature privilege is defined, which allows users to grant access to this feature without having to grant the `all` privilege to Discover. In other words, you can grant `read` access to Discover, and also grant the ability to create short URLs. +two subfeature privileges are defined: "Create Short URLs", and "Generate PDF Reports". These allow users to grant access to this feature without having to grant the `all` privilege to Discover. In other words, you can grant `read` access to Discover, and also grant the ability to create short URLs or generate PDF reports. + +Notice the "Generate PDF Reports" subfeature privilege has an additional `minimumPrivilege` option. Kibana will only offer this subfeature privilege if the +license requirement is satisfied. ["source","javascript"] ----------- @@ -259,6 +262,28 @@ public setup(core, { features }) { }, ], }, + { + groupType: 'independent', + privileges: [ + { + id: 'pdf_generate', + name: i18n.translate( + 'xpack.features.ossFeatures.discoverGeneratePDFReportsPrivilegeName', + { + defaultMessage: 'Generate PDF Reports', + } + ), + minimumLicense: 'platinum', + includeIn: 'all', + savedObject: { + all: [], + read: [], + }, + api: ['generatePDFReports'], + ui: ['generatePDFReports'], + }, + ], + }, ], }, ], diff --git a/docs/getting-started/quick-start-guide.asciidoc b/docs/getting-started/quick-start-guide.asciidoc index f239b7ae6ca88..ccb6e931d69e3 100644 --- a/docs/getting-started/quick-start-guide.asciidoc +++ b/docs/getting-started/quick-start-guide.asciidoc @@ -140,4 +140,4 @@ For more information, refer to <>. If you are you ready to add your own data, refer to <>. -If you want to ingest your data, refer to {ingest-guide}/ingest-management-getting-started.html[Quick start: Get logs and metrics into the Elastic Stack]. +If you want to ingest your data, refer to {ingest-guide}/fleet-quick-start.html[Quick start: Get logs and metrics into the Elastic Stack]. diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc index 03a728a15351e..0af953ec2cb09 100644 --- a/docs/setup/connect-to-elasticsearch.asciidoc +++ b/docs/setup/connect-to-elasticsearch.asciidoc @@ -37,7 +37,7 @@ ship with dashboards and visualizations, so you can quickly get insights into your data. To get started, refer to -{ingest-guide}/ingest-management-getting-started.html[Quick start: Get logs and metrics into the Elastic Stack]. +{ingest-guide}/fleet-quick-start.html[Quick start: Get logs and metrics into the Elastic Stack]. [role="screenshot"] image::images/add-data-fleet.png[Add data using Fleet] diff --git a/docs/user/security/authentication/index.asciidoc b/docs/user/security/authentication/index.asciidoc index bd37351e9b60a..c88fa9750b3e4 100644 --- a/docs/user/security/authentication/index.asciidoc +++ b/docs/user/security/authentication/index.asciidoc @@ -116,6 +116,7 @@ You can also configure both PKI and basic authentication for the same {kib} inst [source,yaml] -------------------------------------------------------------------------------- +server.ssl.clientAuthentication: optional xpack.security.authc.providers: pki.pki1: order: 0 diff --git a/package.json b/package.json index 1a19b322bf655..2a0c292435403 100644 --- a/package.json +++ b/package.json @@ -723,7 +723,7 @@ "less": "npm:@elastic/less@2.7.3-kibana", "license-checker": "^16.0.0", "listr": "^0.14.1", - "lmdb-store": "^0.6.10", + "lmdb-store": "^0.8.11", "load-grunt-config": "^3.0.1", "loader-utils": "^1.2.3", "log-symbols": "^2.2.0", diff --git a/packages/kbn-optimizer/src/node/cache.ts b/packages/kbn-optimizer/src/node/cache.ts index 1ce3b9eeeafd0..dc96bf47fafcf 100644 --- a/packages/kbn-optimizer/src/node/cache.ts +++ b/packages/kbn-optimizer/src/node/cache.ts @@ -19,7 +19,6 @@ import Path from 'path'; -// @ts-expect-error no types available import * as LmdbStore from 'lmdb-store'; import { REPO_ROOT, UPSTREAM_BRANCH } from '@kbn/dev-utils'; @@ -37,25 +36,11 @@ const MINUTE = 1000 * 60; const HOUR = MINUTE * 60; const DAY = HOUR * 24; -interface Lmdb { - get(key: string): T | undefined; - put(key: string, value: T, version?: number, ifVersion?: number): Promise; - remove(key: string, ifVersion?: number): Promise; - openDB(options: { name: string; encoding: 'msgpack' | 'string' | 'json' | 'binary' }): Lmdb; - getRange(options?: { - start?: T; - end?: T; - reverse?: boolean; - limit?: number; - versions?: boolean; - }): Iterable<{ key: string; value: T }>; -} - export class Cache { - private readonly codes: Lmdb; - private readonly atimes: Lmdb; - private readonly mtimes: Lmdb; - private readonly sourceMaps: Lmdb; + private readonly codes: LmdbStore.RootDatabase; + private readonly atimes: LmdbStore.Database; + private readonly mtimes: LmdbStore.Database; + private readonly sourceMaps: LmdbStore.Database; private readonly prefix: string; constructor(config: { prefix: string }) { @@ -64,19 +49,23 @@ export class Cache { this.codes = LmdbStore.open({ name: 'codes', path: CACHE_DIR, + // @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18 maxReaders: 500, }); + // @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18 this.atimes = this.codes.openDB({ name: 'atimes', encoding: 'string', }); + // @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18 this.mtimes = this.codes.openDB({ name: 'mtimes', encoding: 'string', }); + // @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18 this.sourceMaps = this.codes.openDB({ name: 'sourceMaps', encoding: 'msgpack', @@ -92,7 +81,7 @@ export class Cache { } getMtime(path: string) { - return this.mtimes.get(this.getKey(path)); + return this.safeGet(this.mtimes, this.getKey(path)); } getCode(path: string) { @@ -103,11 +92,11 @@ export class Cache { // touched in a long time (currently 30 days) this.atimes.put(key, GLOBAL_ATIME).catch(reportError); - return this.codes.get(key); + return this.safeGet(this.codes, key); } getSourceMap(path: string) { - return this.sourceMaps.get(this.getKey(path)); + return this.safeGet(this.sourceMaps, this.getKey(path)); } update(path: string, file: { mtime: string; code: string; map: any }) { @@ -125,17 +114,27 @@ export class Cache { return `${this.prefix}${path}`; } + private safeGet(db: LmdbStore.Database, key: string) { + try { + return db.get(key) as V | undefined; + } catch (error) { + // get errors indicate that a key value is corrupt in some way, so remove it + db.removeSync(key); + } + } + private async pruneOldKeys() { try { const ATIME_LIMIT = Date.now() - 30 * DAY; const BATCH_SIZE = 1000; - const validKeys: string[] = []; - const invalidKeys: string[] = []; + const validKeys: LmdbStore.Key[] = []; + const invalidKeys: LmdbStore.Key[] = []; + // @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18 for (const { key, value } of this.atimes.getRange()) { - const atime = parseInt(value, 10); - if (atime < ATIME_LIMIT) { + const atime = parseInt(`${value}`, 10); + if (Number.isNaN(atime) || atime < ATIME_LIMIT) { invalidKeys.push(key); } else { validKeys.push(key); diff --git a/packages/kbn-plugin-helpers/src/cli.ts b/packages/kbn-plugin-helpers/src/cli.ts index 21b6559f63650..81db3b0bbebc0 100644 --- a/packages/kbn-plugin-helpers/src/cli.ts +++ b/packages/kbn-plugin-helpers/src/cli.ts @@ -90,6 +90,7 @@ export function runCli() { await Tasks.initTargets(context); await Tasks.optimize(context); + await Tasks.writePublicAssets(context); await Tasks.writeServerFiles(context); await Tasks.yarnInstall(context); diff --git a/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts b/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts index 5c1ecc4ee4ee4..a9f8ed045f6e3 100644 --- a/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts +++ b/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts @@ -77,7 +77,8 @@ it('builds a generated plugin into a viable archive', async () => { │ info initialized, 0 bundles cached │ info starting worker [1 bundle] │ succ 1 bundles compiled successfully after