Skip to content

Commit

Permalink
Merge branch 'master' into security/spaces-logout-redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Feb 10, 2020
2 parents 97ed15d + a02232d commit 481120b
Show file tree
Hide file tree
Showing 64 changed files with 1,078 additions and 210 deletions.
47 changes: 47 additions & 0 deletions docs/settings/alert-action-settings.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[role="xpack"]
[[alert-action-settings-kb]]
=== Alerting and action settings in Kibana
++++
<titleabbrev>Alerting and action settings</titleabbrev>
++++

Alerts and actions are enabled by default in {kib}, but require you configure the following in order to use them:

. <<using-kibana-with-security,Set up {kib} to work with {stack} {security-features}>>.
. <<configuring-tls-kib-es,Set up TLS encryption between {kib} and {es}>>.
. <<general-alert-action-settings,Specify a value for `xpack.encrypted_saved_objects.encryptionKey`>>.

You can configure the following settings in the `kibana.yml` file.


[float]
[[general-alert-action-settings]]
==== General settings

`xpack.encrypted_saved_objects.encryptionKey`::

A string of 32 or more characters used to encrypt sensitive properties on alerts and actions before they're stored in {es}. Third party credentials &mdash; such as the username and password used to connect to an SMTP service &mdash; are an example of encrypted properties.
+
If not set, {kib} will generate a random key on startup, but all alert and action functions will be blocked. Generated keys are not allowed for alerts and actions because when a new key is generated on restart, existing encrypted data becomes inaccessible. For the same reason, alerts and actions in high-availability deployments of {kib} will behave unexpectedly if the key isn't the same on all instances of {kib}.
+
Although the key can be specified in clear text in `kibana.yml`, it's recommended to store this key securely in the <<secure-settings,{kib} Keystore>>.

[float]
[[alert-settings]]
==== Action settings

`xpack.actions.whitelistedHosts`::
A list of hostnames that {kib} is allowed to connect to when built-in actions are triggered. It defaults to `[*]`, allowing any host, but keep in mind the potential for SSRF attacks when hosts are not explicitly whitelisted. An empty list `[]` can be used to block built-in actions from making any external connections.
+
Note that hosts associated with built-in actions, such as Slack and PagerDuty, are not automatically whitelisted. If you are not using the default `[*]` setting, you must ensure that the corresponding endpoints are whitelisted as well.

`xpack.actions.enabledActionTypes`::
A list of action types that are enabled. It defaults to `[*]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, and `.webhook`. An empty list `[]` will disable all action types.
+
Disabled action types will not appear as an option when creating new connectors, but existing connectors and actions of that type will remain in {kib} and will not function.

[float]
[[action-settings]]
==== Alert settings

You do not need to configure any additional settings to use alerting in {kib}.
1 change: 1 addition & 0 deletions docs/settings/settings-xkb.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include::{asciidoc-dir}/../../shared/settings.asciidoc[]

For more {kib} configuration settings, see <<settings>>.

include::alert-action-settings.asciidoc[]
include::apm-settings.asciidoc[]
include::dev-settings.asciidoc[]
include::graph-settings.asciidoc[]
Expand Down
11 changes: 1 addition & 10 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -457,16 +457,7 @@ Rollup user interface.

`i18n.locale`:: *Default: en* Set this value to change the Kibana interface language. Valid locales are: `en`, `zh-CN`, `ja-JP`.

`xpack.actions.enabledActionTypes:`:: *Default: +[ {asterisk} ]+* Set this value
to an array of action types that are enabled. An element of `*` indicates all
action types registered are enabled. The action types provided by Kibana are:
`.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, `.webhook`.

`xpack.actions.whitelistedHosts:`:: *Default: +[ {asterisk} ]+* Set this value
to an array of host names which actions such as email, slack, pagerduty, and
webhook can connect to. An element of `*` indicates any host can be connected
to. An empty array indicates no hosts can be connected to.

include::{docdir}/settings/alert-action-settings.asciidoc[]
include::{docdir}/settings/apm-settings.asciidoc[]
include::{docdir}/settings/dev-settings.asciidoc[]
include::{docdir}/settings/graph-settings.asciidoc[]
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/data/public/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export { SuggestionsComponent } from './typeahead/suggestions_component';
export { IndexPatternSelect } from './index_pattern_select';
export { FilterBar } from './filter_bar';
export { QueryStringInput } from './query_string_input/query_string_input';
export { SearchBar, SearchBarProps } from './search_bar';
export { SearchBar, SearchBarProps, StatefulSearchBarProps } from './search_bar';

// @internal
export {
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/data/public/ui/search_bar/create_search_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps)
filterManager: data.query.filterManager,
});
const { timeRange, refreshInterval } = useTimefilter({
dateRangeFrom: props.dateRangeFrom,
dateRangeTo: props.dateRangeTo,
refreshInterval: props.refreshInterval,
isRefreshPaused: props.isRefreshPaused,
timefilter: data.query.timefilter.timefilter,
});

Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/ui/search_bar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
*/

export { SearchBar, SearchBarProps } from './search_bar';
export { StatefulSearchBarProps } from './create_search_bar';
18 changes: 15 additions & 3 deletions src/plugins/data/public/ui/search_bar/lib/use_timefilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,27 @@

import { useState, useEffect } from 'react';
import { Subscription } from 'rxjs';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { DataPublicPluginStart, TimeRange, RefreshInterval } from 'src/plugins/data/public';

interface UseTimefilterProps {
dateRangeFrom?: string;
dateRangeTo?: string;
refreshInterval?: number;
isRefreshPaused?: boolean;
timefilter: DataPublicPluginStart['query']['timefilter']['timefilter'];
}

export const useTimefilter = (props: UseTimefilterProps) => {
const [timeRange, setTimerange] = useState(props.timefilter.getTime());
const [refreshInterval, setRefreshInterval] = useState(props.timefilter.getRefreshInterval());
const initialTimeRange: TimeRange = {
from: props.dateRangeFrom || props.timefilter.getTime().from,
to: props.dateRangeTo || props.timefilter.getTime().to,
};
const initialRefreshInterval: RefreshInterval = {
value: props.refreshInterval || props.timefilter.getRefreshInterval().value,
pause: props.isRefreshPaused || props.timefilter.getRefreshInterval().pause,
};
const [timeRange, setTimerange] = useState(initialTimeRange);
const [refreshInterval, setRefreshInterval] = useState(initialRefreshInterval);

useEffect(() => {
const subscriptions = new Subscription();
Expand Down
10 changes: 5 additions & 5 deletions src/plugins/data/public/ui/search_bar/search_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,8 @@ interface SearchBarInjectedDeps {
timeHistory: TimeHistoryContract;
// Filter bar
onFiltersUpdated?: (filters: esFilters.Filter[]) => void;
// Date picker
dateRangeFrom?: string;
dateRangeTo?: string;
// Autorefresh
onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void;
isRefreshPaused?: boolean;
refreshInterval?: number;
}

export interface SearchBarOwnProps {
Expand All @@ -69,6 +64,11 @@ export interface SearchBarOwnProps {
showDatePicker?: boolean;
showAutoRefreshOnly?: boolean;
filters?: esFilters.Filter[];
// Date picker
isRefreshPaused?: boolean;
refreshInterval?: number;
dateRangeFrom?: string;
dateRangeTo?: string;
// Query bar - should be in SearchBarInjectedDeps
query?: Query;
// Show when user has privileges to save
Expand Down
14 changes: 1 addition & 13 deletions src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ import { TopNavMenu } from './top_nav_menu';
import { TopNavMenuData } from './top_nav_menu_data';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';

const mockTimeHistory = {
add: () => {},
get: () => {
return [];
},
};

const dataShim = {
ui: {
SearchBar: () => <div className="searchBar" />,
Expand Down Expand Up @@ -76,12 +69,7 @@ describe('TopNavMenu', () => {

it('Should render search bar', () => {
const component = shallowWithIntl(
<TopNavMenu
appName={'test'}
showSearchBar={true}
timeHistory={mockTimeHistory}
data={dataShim as any}
/>
<TopNavMenu appName={'test'} showSearchBar={true} data={dataShim as any} />
);

expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0);
Expand Down
5 changes: 2 additions & 3 deletions src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ import { I18nProvider } from '@kbn/i18n/react';

import { TopNavMenuData } from './top_nav_menu_data';
import { TopNavMenuItem } from './top_nav_menu_item';
import { SearchBarProps, DataPublicPluginStart } from '../../../data/public';
import { StatefulSearchBarProps, DataPublicPluginStart } from '../../../data/public';

export type TopNavMenuProps = Partial<SearchBarProps> & {
appName: string;
export type TopNavMenuProps = StatefulSearchBarProps & {
config?: TopNavMenuData[];
showSearchBar?: boolean;
data?: DataPublicPluginStart;
Expand Down
9 changes: 9 additions & 0 deletions x-pack/legacy/plugins/alerting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Table of Contents
- [`DELETE /api/alert/{id}`: Delete alert](#delete-apialertid-delete-alert)
- [`GET /api/alert/_find`: Find alerts](#get-apialertfind-find-alerts)
- [`GET /api/alert/{id}`: Get alert](#get-apialertid-get-alert)
- [`GET /api/alert/{id}/state`: Get alert state](#get-apialertidstate-get-alert-state)
- [`GET /api/alert/types`: List alert types](#get-apialerttypes-list-alert-types)
- [`PUT /api/alert/{id}`: Update alert](#put-apialertid-update-alert)
- [`POST /api/alert/{id}/_enable`: Enable an alert](#post-apialertidenable-enable-an-alert)
Expand Down Expand Up @@ -273,6 +274,14 @@ Params:
|---|---|---|
|id|The id of the alert you're trying to get.|string|

### `GET /api/alert/{id}/state`: Get alert state

Params:

|Property|Description|Type|
|---|---|---|
|id|The id of the alert whose state you're trying to get.|string|

### `GET /api/alert/types`: List alert types

No parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ describe('updateLastScheduledActions()', () => {
state: {},
meta: {
lastScheduledActions: {
date: new Date(),
date: new Date().toISOString(),
group: 'default',
},
},
Expand All @@ -216,3 +216,19 @@ describe('toJSON', () => {
);
});
});

describe('toRaw', () => {
test('returns unserialised underlying state and meta', () => {
const raw = {
state: { foo: true },
meta: {
lastScheduledActions: {
date: new Date(),
group: 'default',
},
},
};
const alertInstance = new AlertInstance(raw);
expect(alertInstance.toRaw()).toEqual(raw);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,41 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as t from 'io-ts';

import { State, Context } from '../types';
import { DateFromString } from '../lib/types';
import { parseDuration } from '../lib';

interface Meta {
lastScheduledActions?: {
group: string;
date: Date;
};
}

interface ScheduledExecutionOptions {
actionGroup: string;
context: Context;
state: State;
}

interface ConstructorOptions {
state?: State;
meta?: Meta;
}
const metaSchema = t.partial({
lastScheduledActions: t.type({
group: t.string,
date: DateFromString,
}),
});
type AlertInstanceMeta = t.TypeOf<typeof metaSchema>;

const stateSchema = t.record(t.string, t.unknown);
type AlertInstanceState = t.TypeOf<typeof stateSchema>;

export const rawAlertInstance = t.partial({
state: stateSchema,
meta: metaSchema,
});
export type RawAlertInstance = t.TypeOf<typeof rawAlertInstance>;

export class AlertInstance {
private scheduledExecutionOptions?: ScheduledExecutionOptions;
private meta: Meta;
private state: State;
private meta: AlertInstanceMeta;
private state: AlertInstanceState;

constructor({ state = {}, meta = {} }: ConstructorOptions = {}) {
constructor({ state = {}, meta = {} }: RawAlertInstance = {}) {
this.state = state;
this.meta = meta;
}
Expand All @@ -48,7 +55,7 @@ export class AlertInstance {
if (
this.meta.lastScheduledActions &&
this.meta.lastScheduledActions.group === actionGroup &&
new Date(this.meta.lastScheduledActions.date).getTime() + throttleMills > Date.now()
this.meta.lastScheduledActions.date.getTime() + throttleMills > Date.now()
) {
return true;
}
Expand Down Expand Up @@ -89,6 +96,10 @@ export class AlertInstance {
* Used to serialize alert instance state
*/
toJSON() {
return rawAlertInstance.encode(this.toRaw());
}

toRaw(): RawAlertInstance {
return {
state: this.state,
meta: this.meta,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test('reuses existing instances', () => {
Object {
"meta": Object {
"lastScheduledActions": Object {
"date": 1970-01-01T00:00:00.000Z,
"date": "1970-01-01T00:00:00.000Z",
"group": "default",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { AlertInstance } from './alert_instance';
export { AlertInstance, RawAlertInstance, rawAlertInstance } from './alert_instance';
export { createAlertInstanceFactory } from './create_alert_instance_factory';
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const createAlertsClientMock = () => {
const mocked: jest.Mocked<Schema> = {
create: jest.fn(),
get: jest.fn(),
getAlertState: jest.fn(),
find: jest.fn(),
delete: jest.fn(),
update: jest.fn(),
Expand Down
Loading

0 comments on commit 481120b

Please sign in to comment.