Skip to content

Commit c0a16e4

Browse files
committed
Merge remote-tracking branch 'origin/master' into HEAD
2 parents cc902e2 + a8913d3 commit c0a16e4

File tree

236 files changed

+14581
-11061
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

236 files changed

+14581
-11061
lines changed

.github/workflows/project-assigner.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
uses: elastic/github-actions/[email protected]
1212
id: project_assigner
1313
with:
14-
issue-mappings: '[{"label": "Team:AppArch", "projectNumber": 37, "columnName": "To triage"}, {"label": "Feature:Lens", "projectNumber": 32, "columnName": "Long-term goals"}, {"label": "Feature:Canvas", "projectNumber": 38, "columnName": "Inbox"}, {"label": "Feature:Dashboard", "projectNumber": 68, "columnName": "Inbox"}, {"label": "Feature:Drilldowns", "projectNumber": 68, "columnName": "Inbox"}]'
14+
issue-mappings: '[{"label": "Feature:Lens", "projectNumber": 32, "columnName": "Long-term goals"}, {"label": "Feature:Canvas", "projectNumber": 38, "columnName": "Inbox"}, {"label": "Feature:Dashboard", "projectNumber": 68, "columnName": "Inbox"}, {"label": "Feature:Drilldowns", "projectNumber": 68, "columnName": "Inbox"}]'
1515
ghToken: ${{ secrets.PROJECT_ASSIGNER_TOKEN }}
1616

1717

docs/discover/kuery.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ To match multiple fields:
147147
machine.os*:windows 10
148148
-------------------
149149

150-
This sytax is handy when you have text and keyword
150+
This syntax is handy when you have text and keyword
151151
versions of a field. The query checks machine.os and machine.os.keyword
152152
for the term
153153
`windows 10`.

docs/migration/migrate_8_0.asciidoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ for example, `logstash-*`.
3636
=== Settings changes
3737

3838
// tag::notable-breaking-changes[]
39+
[float]
40+
==== Multitenancy by changing `kibana.index` is no longer supported
41+
*Details:* `kibana.index`, `xpack.reporting.index` and `xpack.task_manager.index` can no longer be specified.
42+
43+
*Impact:* Users who relied on changing these settings to achieve multitenancy should use *Spaces*, cross-cluster replication, or cross-cluster search instead. To migrate to *Spaces*, users are encouraged to use saved object management to export their saved objects from a tenant into the default tenant in a space. Improvements are planned to improve on this workflow. See https://github.com/elastic/kibana/issues/82020 for more details.
44+
3945
[float]
4046
==== Legacy browsers are now rejected by default
4147
*Details:* `csp.strict` is now enabled by default, so Kibana will fail to load for older, legacy browsers that do not enforce basic Content Security Policy protections - notably Internet Explorer 11.

docs/user/alerting/action-types.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ a| <<jira-action-type, Jira>>
2323

2424
| Create an incident in Jira.
2525

26+
a| <<teams-action-type, Microsoft Teams>>
27+
28+
| Send a message to a Microsoft Teams channel.
2629

2730
a| <<pagerduty-action-type, PagerDuty>>
2831

@@ -65,6 +68,7 @@ include::action-types/email.asciidoc[]
6568
include::action-types/resilient.asciidoc[]
6669
include::action-types/index.asciidoc[]
6770
include::action-types/jira.asciidoc[]
71+
include::action-types/teams.asciidoc[]
6872
include::action-types/pagerduty.asciidoc[]
6973
include::action-types/server-log.asciidoc[]
7074
include::action-types/servicenow.asciidoc[]
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
[role="xpack"]
2+
[[teams-action-type]]
3+
=== Microsoft Teams action
4+
5+
The Microsoft Teams action type uses https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook[Incoming Webhooks].
6+
7+
[float]
8+
[[teams-connector-configuration]]
9+
==== Connector configuration
10+
11+
Microsoft Teams connectors have the following configuration properties:
12+
13+
Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action.
14+
Webhook URL:: The URL of the incoming webhook. See https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook#add-an-incoming-webhook-to-a-teams-channel[Add Incoming Webhooks] for instructions on generating this URL. If you are using the <<action-settings, `xpack.actions.allowedHosts`>> setting, make sure the hostname is added to the allowed hosts.
15+
16+
[float]
17+
[[Preconfigured-teams-configuration]]
18+
==== Preconfigured action type
19+
20+
[source,text]
21+
--
22+
my-teams:
23+
name: preconfigured-teams-action-type
24+
actionTypeId: .teams
25+
config:
26+
webhookUrl: 'https://outlook.office.com/webhook/abcd@0123456/IncomingWebhook/abcdefgh/ijklmnopqrstuvwxyz'
27+
--
28+
29+
`config` defines the action type specific to the configuration.
30+
`config` contains
31+
`webhookUrl`, a string that corresponds to *Webhook URL*.
32+
33+
34+
[float]
35+
[[teams-action-configuration]]
36+
==== Action configuration
37+
38+
Microsoft Teams actions have the following properties:
39+
40+
Message:: The message text, converted to the `text` field in the Webhook JSON payload. Currently only the text field is supported. Markdown, images, and other advanced formatting are not yet supported.
41+
42+
[[configuring-teams]]
43+
==== Configuring Microsoft Teams Accounts
44+
45+
You need a https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook[Microsoft Teams webhook URL] to
46+
configure a Microsoft Teams action. To create a webhook
47+
URL, add the **Incoming Webhook App** through the Microsoft Teams console:
48+
49+
. Log in to http://teams.microsoft.com[teams.microsoft.com] as a team administrator.
50+
. Navigate to the Apps directory, search for and select the *Incoming Webhook* app.
51+
. Choose _Add to team_ and select a team and channel for the app.
52+
. Enter a name for your webhook and (optionally) upload a custom icon.
53+
+
54+
image::images/teams-add-webhook-integration.png[]
55+
. Click *Create*.
56+
. Copy the generated webhook URL so you can paste it into your Teams connector form.
57+
+
58+
image::images/teams-copy-webhook-url.png[]
238 KB
Loading
49.2 KB
Loading

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@
723723
"less": "npm:@elastic/[email protected]",
724724
"license-checker": "^16.0.0",
725725
"listr": "^0.14.1",
726-
"lmdb-store": "^0.6.10",
726+
"lmdb-store": "^0.8.15",
727727
"load-grunt-config": "^3.0.1",
728728
"loader-utils": "^1.2.3",
729729
"log-symbols": "^2.2.0",

packages/kbn-i18n/src/react/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
*/
1919

2020
import { InjectedIntl as _InjectedIntl, InjectedIntlProps as _InjectedIntlProps } from 'react-intl';
21-
22-
export type InjectedIntl = _InjectedIntl;
23-
export type InjectedIntlProps = _InjectedIntlProps;
21+
export type { InjectedIntl, InjectedIntlProps } from 'react-intl';
2422

2523
export {
2624
intlShape,

packages/kbn-optimizer/src/node/cache.ts

Lines changed: 82 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,91 +17,67 @@
1717
* under the License.
1818
*/
1919

20-
import Path from 'path';
21-
import Fs from 'fs';
20+
import { Writable } from 'stream';
2221

23-
// @ts-expect-error no types available
22+
import chalk from 'chalk';
2423
import * as LmdbStore from 'lmdb-store';
25-
import { REPO_ROOT, UPSTREAM_BRANCH } from '@kbn/dev-utils';
26-
27-
const LMDB_PKG = JSON.parse(
28-
Fs.readFileSync(Path.resolve(REPO_ROOT, 'node_modules/lmdb-store/package.json'), 'utf8')
29-
);
30-
const CACHE_DIR = Path.resolve(
31-
REPO_ROOT,
32-
`data/node_auto_transpilation_cache/lmdb-${LMDB_PKG.version}/${UPSTREAM_BRANCH}`
33-
);
34-
35-
const reportError = () => {
36-
// right now I'm not sure we need to worry about errors, the cache isn't actually
37-
// necessary, and if the cache is broken it should just rebuild on the next restart
38-
// of the process. We don't know how often errors occur though and what types of
39-
// things might fail on different machines so we probably want some way to signal
40-
// to users that something is wrong
41-
};
4224

4325
const GLOBAL_ATIME = `${Date.now()}`;
4426
const MINUTE = 1000 * 60;
4527
const HOUR = MINUTE * 60;
4628
const DAY = HOUR * 24;
4729

48-
interface Lmdb<T> {
49-
name: string;
50-
get(key: string): T | undefined;
51-
put(key: string, value: T, version?: number, ifVersion?: number): Promise<boolean>;
52-
remove(key: string, ifVersion?: number): Promise<boolean>;
53-
removeSync(key: string): void;
54-
openDB<T2>(options: {
55-
name: string;
56-
encoding: 'msgpack' | 'string' | 'json' | 'binary';
57-
}): Lmdb<T2>;
58-
getRange(options?: {
59-
start?: T;
60-
end?: T;
61-
reverse?: boolean;
62-
limit?: number;
63-
versions?: boolean;
64-
}): Iterable<{ key: string; value: T }>;
65-
}
30+
const dbName = (db: LmdbStore.Database) =>
31+
// @ts-expect-error db.name is not a documented/typed property
32+
db.name;
6633

6734
export class Cache {
68-
private readonly codes: Lmdb<string>;
69-
private readonly atimes: Lmdb<string>;
70-
private readonly mtimes: Lmdb<string>;
71-
private readonly sourceMaps: Lmdb<any>;
35+
private readonly codes: LmdbStore.RootDatabase<string, string>;
36+
private readonly atimes: LmdbStore.Database<string, string>;
37+
private readonly mtimes: LmdbStore.Database<string, string>;
38+
private readonly sourceMaps: LmdbStore.Database<string, string>;
7239
private readonly prefix: string;
40+
private readonly log?: Writable;
41+
private readonly timer: NodeJS.Timer;
7342

74-
constructor(config: { prefix: string }) {
43+
constructor(config: { dir: string; prefix: string; log?: Writable }) {
7544
this.prefix = config.prefix;
45+
this.log = config.log;
7646

77-
this.codes = LmdbStore.open({
47+
this.codes = LmdbStore.open(config.dir, {
7848
name: 'codes',
79-
path: CACHE_DIR,
49+
encoding: 'string',
8050
maxReaders: 500,
8151
});
8252

83-
this.atimes = this.codes.openDB({
53+
// TODO: redundant 'name' syntax is necessary because of a bug that I have yet to fix
54+
this.atimes = this.codes.openDB('atimes', {
8455
name: 'atimes',
8556
encoding: 'string',
8657
});
8758

88-
this.mtimes = this.codes.openDB({
59+
this.mtimes = this.codes.openDB('mtimes', {
8960
name: 'mtimes',
9061
encoding: 'string',
9162
});
9263

93-
this.sourceMaps = this.codes.openDB({
64+
this.sourceMaps = this.codes.openDB('sourceMaps', {
9465
name: 'sourceMaps',
95-
encoding: 'msgpack',
66+
encoding: 'string',
9667
});
9768

9869
// after the process has been running for 30 minutes prune the
9970
// keys which haven't been used in 30 days. We use `unref()` to
10071
// make sure this timer doesn't hold other processes open
10172
// unexpectedly
102-
setTimeout(() => {
73+
this.timer = setTimeout(() => {
10374
this.pruneOldKeys();
104-
}, 30 * MINUTE).unref();
75+
}, 30 * MINUTE);
76+
77+
// timer.unref is not defined in jest which emulates the dom by default
78+
if (typeof this.timer.unref === 'function') {
79+
this.timer.unref();
80+
}
10581
}
10682

10783
getMtime(path: string) {
@@ -110,45 +86,78 @@ export class Cache {
11086

11187
getCode(path: string) {
11288
const key = this.getKey(path);
89+
const code = this.safeGet(this.codes, key);
11390

114-
// when we use a file from the cache set the "atime" of that cache entry
115-
// so that we know which cache items we use and which haven't been
116-
// touched in a long time (currently 30 days)
117-
this.atimes.put(key, GLOBAL_ATIME).catch(reportError);
91+
if (code !== undefined) {
92+
// when we use a file from the cache set the "atime" of that cache entry
93+
// so that we know which cache items we use and which haven't been
94+
// touched in a long time (currently 30 days)
95+
this.safePut(this.atimes, key, GLOBAL_ATIME);
96+
}
11897

119-
return this.safeGet(this.codes, key);
98+
return code;
12099
}
121100

122101
getSourceMap(path: string) {
123-
return this.safeGet(this.sourceMaps, this.getKey(path));
102+
const map = this.safeGet(this.sourceMaps, this.getKey(path));
103+
if (typeof map === 'string') {
104+
return JSON.parse(map);
105+
}
124106
}
125107

126-
update(path: string, file: { mtime: string; code: string; map: any }) {
108+
async update(path: string, file: { mtime: string; code: string; map: any }) {
127109
const key = this.getKey(path);
128110

129-
Promise.all([
130-
this.atimes.put(key, GLOBAL_ATIME),
131-
this.mtimes.put(key, file.mtime),
132-
this.codes.put(key, file.code),
133-
this.sourceMaps.put(key, file.map),
134-
]).catch(reportError);
111+
await Promise.all([
112+
this.safePut(this.atimes, key, GLOBAL_ATIME),
113+
this.safePut(this.mtimes, key, file.mtime),
114+
this.safePut(this.codes, key, file.code),
115+
this.safePut(this.sourceMaps, key, JSON.stringify(file.map)),
116+
]);
117+
}
118+
119+
close() {
120+
clearTimeout(this.timer);
135121
}
136122

137123
private getKey(path: string) {
138124
return `${this.prefix}${path}`;
139125
}
140126

141-
private safeGet<V>(db: Lmdb<V>, key: string) {
127+
private safeGet<V>(db: LmdbStore.Database<V, string>, key: string) {
142128
try {
143-
return db.get(key);
129+
const value = db.get(key);
130+
this.debug(value === undefined ? 'MISS' : 'HIT', db, key);
131+
return value;
144132
} catch (error) {
145-
process.stderr.write(
146-
`failed to read node transpilation [${db.name}] cache for [${key}]: ${error.stack}\n`
147-
);
148-
db.removeSync(key);
133+
this.logError('GET', db, key, error);
149134
}
150135
}
151136

137+
private async safePut<V>(db: LmdbStore.Database<V, string>, key: string, value: V) {
138+
try {
139+
await db.put(key, value);
140+
this.debug('PUT', db, key);
141+
} catch (error) {
142+
this.logError('PUT', db, key, error);
143+
}
144+
}
145+
146+
private debug(type: string, db: LmdbStore.Database, key: LmdbStore.Key) {
147+
if (this.log) {
148+
this.log.write(`${type} [${dbName(db)}] ${String(key)}\n`);
149+
}
150+
}
151+
152+
private logError(type: 'GET' | 'PUT', db: LmdbStore.Database, key: LmdbStore.Key, error: Error) {
153+
this.debug(`ERROR/${type}`, db, `${String(key)}: ${error.stack}`);
154+
process.stderr.write(
155+
chalk.red(
156+
`[@kbn/optimizer/node] ${type} error [${dbName(db)}/${String(key)}]: ${error.stack}\n`
157+
)
158+
);
159+
}
160+
152161
private async pruneOldKeys() {
153162
try {
154163
const ATIME_LIMIT = Date.now() - 30 * DAY;
@@ -157,9 +166,10 @@ export class Cache {
157166
const validKeys: string[] = [];
158167
const invalidKeys: string[] = [];
159168

169+
// @ts-expect-error See https://github.com/DoctorEvidence/lmdb-store/pull/18
160170
for (const { key, value } of this.atimes.getRange()) {
161-
const atime = parseInt(value, 10);
162-
if (atime < ATIME_LIMIT) {
171+
const atime = parseInt(`${value}`, 10);
172+
if (Number.isNaN(atime) || atime < ATIME_LIMIT) {
163173
invalidKeys.push(key);
164174
} else {
165175
validKeys.push(key);

0 commit comments

Comments
 (0)