Skip to content

Commit

Permalink
[6.x] Deprecate xpack:defaultAdminEmail for monitoring alerts (#22195) (
Browse files Browse the repository at this point in the history
#22765)

Backports the following commits to 6.x:
 - Deprecate xpack:defaultAdminEmail for monitoring alerts  (#22195)
  • Loading branch information
legrego authored Sep 6, 2018
1 parent 295b9bf commit 263c916
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 46 deletions.
4 changes: 1 addition & 3 deletions docs/monitoring/cluster-alerts.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ To receive email notifications for the Cluster Alerts:

1. Configure an email account as described in
{xpack-ref}/actions-email.html#configuring-email[Configuring Email Accounts].
2. Navigate to the *Management* page in {kib}.
3. Go to the *Advanced Settings* page, find the `xpack:defaultAdminEmail`
setting, and enter your email address.
2. Configure the `xpack.monitoring.cluster_alerts.email_notifications.email_address` setting in `kibana.yml` with your email address.

Email notifications are sent only when Cluster Alerts are triggered and resolved.
65 changes: 64 additions & 1 deletion x-pack/plugins/monitoring/__tests__/deprecations.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,73 @@ describe('monitoring plugin deprecations', function () {
});

it(`shouldn't log when node_resolver isn't present`, function () {
const settings = { };
const settings = {};

const log = sinon.spy();
transformDeprecations(settings, log);
expect(log.called).to.be(false);
});

describe('cluster_alerts.email_notifications.email_address', function () {
it(`shouldn't log when email notifications are disabled`, function () {
const settings = {
cluster_alerts: {
email_notifications: {
enabled: false
}
}
};

const log = sinon.spy();
transformDeprecations(settings, log);
expect(log.called).to.be(false);
});

it(`shouldn't log when cluster alerts are disabled`, function () {
const settings = {
cluster_alerts: {
enabled: false,
email_notifications: {
enabled: true
}
}
};

const log = sinon.spy();
transformDeprecations(settings, log);
expect(log.called).to.be(false);
});

it(`shouldn't log when email_address is specified`, function () {
const settings = {
cluster_alerts: {
enabled: true,
email_notifications: {
enabled: true,
email_address: 'foo@bar.com'
}
}
};

const log = sinon.spy();
transformDeprecations(settings, log);
expect(log.called).to.be(false);
});

it(`should log when email_address is missing, but alerts/notifications are both enabled`, function () {
const settings = {
cluster_alerts: {
enabled: true,
email_notifications: {
enabled: true
}
}
};

const log = sinon.spy();
transformDeprecations(settings, log);
expect(log.called).to.be(true);
});
});

});
9 changes: 7 additions & 2 deletions x-pack/plugins/monitoring/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const CALCULATE_DURATION_UNTIL = 'until';
/**
* In order to show ML Jobs tab in the Elasticsearch section / tab navigation, license must be supported
*/
export const ML_SUPPORTED_LICENSES = [ 'trial', 'platinum' ];
export const ML_SUPPORTED_LICENSES = ['trial', 'platinum'];

/**
* Metadata service URLs for the different cloud services that have constant URLs (e.g., unlike GCP, which is a constant prefix).
Expand Down Expand Up @@ -135,7 +135,12 @@ export const DEFAULT_NO_DATA_MESSAGE_WITH_FILTER = (
);

export const TABLE_ACTION_UPDATE_FILTER = 'UPDATE_FILTER';
export const TABLE_ACTION_RESET_PAGING = 'RESET_PAGING';
export const TABLE_ACTION_RESET_PAGING = 'RESET_PAGING';

export const DEBOUNCE_SLOW_MS = 17; // roughly how long it takes to render a frame at 60fps
export const DEBOUNCE_FAST_MS = 10; // roughly how long it takes to render a frame at 100fps

/**
* Configuration key for setting the email address used for cluster alert notifications.
*/
export const CLUSTER_ALERTS_ADDRESS_CONFIG_KEY = 'cluster_alerts.email_notifications.email_address';
5 changes: 3 additions & 2 deletions x-pack/plugins/monitoring/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { XPACK_INFO_API_DEFAULT_POLL_FREQUENCY_IN_MILLIS } from '../../server/li
*/
export const config = (Joi) => {
const { array, boolean, number, object, string } = Joi;
const DEFAULT_REQUEST_HEADERS = [ 'authorization' ];
const DEFAULT_REQUEST_HEADERS = ['authorization'];

return object({
ccs: object({
Expand Down Expand Up @@ -49,7 +49,8 @@ export const config = (Joi) => {
enabled: boolean().default(true),
index: string().default('.monitoring-alerts-6'),
email_notifications: object({
enabled: boolean().default(true)
enabled: boolean().default(true),
email_address: string().email(),
}).default()
}).default(),
xpack_api_polling_frequency_millis: number().default(XPACK_INFO_API_DEFAULT_POLL_FREQUENCY_IN_MILLIS),
Expand Down
12 changes: 10 additions & 2 deletions x-pack/plugins/monitoring/deprecations.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { get, has, set } from 'lodash';
import { CLUSTER_ALERTS_ADDRESS_CONFIG_KEY } from './common/constants';

/**
* Re-writes deprecated user-defined config settings and logs warnings as a
Expand All @@ -29,7 +30,7 @@ export const deprecations = ({ rename }) => {
delete settings.elasticsearch.ssl.verify;

log('Config key "xpack.monitoring.elasticsearch.ssl.verify" is deprecated. ' +
'It has been replaced with "xpack.monitoring.elasticsearch.ssl.verificationMode"');
'It has been replaced with "xpack.monitoring.elasticsearch.ssl.verificationMode"');
},
(settings, log) => {
if (has(settings, 'node_resolver')) {
Expand All @@ -40,7 +41,14 @@ export const deprecations = ({ rename }) => {
(settings, log) => {
if (has(settings, 'report_stats')) {
log('Config key "xpack.monitoring.report_stats" is deprecated and will be removed in 7.0. ' +
'Use "xpack.xpack_main.telemetry.enabled" instead.');
'Use "xpack.xpack_main.telemetry.enabled" instead.');
}
},
(settings, log) => {
const clusterAlertsEnabled = get(settings, 'cluster_alerts.enabled');
const emailNotificationsEnabled = clusterAlertsEnabled && get(settings, 'cluster_alerts.email_notifications.enabled');
if (emailNotificationsEnabled && !get(settings, CLUSTER_ALERTS_ADDRESS_CONFIG_KEY)) {
log(`Config key "${CLUSTER_ALERTS_ADDRESS_CONFIG_KEY}" will be required for email notifications to work in 7.0."`);
}
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@ import expect from 'expect.js';
import { checkForEmailValue } from '../get_settings_collector';

describe('getSettingsCollector / checkForEmailValue', () => {
const mockLogger = {
warn: () => { }
};

it('ignores shouldUseNull=true value and returns email if email value if one is set', async () => {
const shouldUseNull = true;
const getDefaultAdminEmailMock = () => 'test@elastic.co';
expect(await checkForEmailValue(undefined, undefined, shouldUseNull, getDefaultAdminEmailMock)).to.be('test@elastic.co');
expect(await checkForEmailValue(undefined, undefined, mockLogger, shouldUseNull, getDefaultAdminEmailMock)).to.be('test@elastic.co');
});

it('ignores shouldUseNull=false value and returns email if email value if one is set', async () => {
const shouldUseNull = false;
const getDefaultAdminEmailMock = () => 'test@elastic.co';
expect(await checkForEmailValue(undefined, undefined, shouldUseNull, getDefaultAdminEmailMock)).to.be('test@elastic.co');
expect(await checkForEmailValue(undefined, undefined, mockLogger, shouldUseNull, getDefaultAdminEmailMock)).to.be('test@elastic.co');
});

it('returns a null if no email value is set and null is allowed', async () => {
const shouldUseNull = true;
const getDefaultAdminEmailMock = () => null;
expect(await checkForEmailValue(undefined, undefined, shouldUseNull, getDefaultAdminEmailMock)).to.be(null);
expect(await checkForEmailValue(undefined, undefined, mockLogger, shouldUseNull, getDefaultAdminEmailMock)).to.be(null);
});

it('returns undefined if no email value is set and null is not allowed', async () => {
const shouldUseNull = false;
const getDefaultAdminEmailMock = () => null;
expect(await checkForEmailValue(undefined, undefined, shouldUseNull, getDefaultAdminEmailMock)).to.be(undefined);
expect(await checkForEmailValue(undefined, undefined, mockLogger, shouldUseNull, getDefaultAdminEmailMock)).to.be(undefined);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,23 @@ import sinon from 'sinon';
import { set } from 'lodash';

import { XPACK_DEFAULT_ADMIN_EMAIL_UI_SETTING } from '../../../../../../server/lib/constants';
import { getDefaultAdminEmail } from '../get_settings_collector';
import { getDefaultAdminEmail, resetDeprecationWarning } from '../get_settings_collector';
import { CLUSTER_ALERTS_ADDRESS_CONFIG_KEY } from '../../../../common/constants';

describe('getSettingsCollector / getDefaultAdminEmail', () => {
function setup({ enabled = true, docExists = true, adminEmail = 'admin@email.com' }) {
function setup({ enabled = true, docExists = true, defaultAdminEmail = 'default-admin@email.com', adminEmail = null }) {
const config = { get: sinon.stub() };

config.get
.withArgs('xpack.monitoring.cluster_alerts.email_notifications.enabled')
.returns(enabled);

if (adminEmail) {
config.get
.withArgs(`xpack.monitoring.${CLUSTER_ALERTS_ADDRESS_CONFIG_KEY}`)
.returns(adminEmail);
}

config.get
.withArgs('kibana.index')
.returns('.kibana');
Expand All @@ -29,8 +36,8 @@ describe('getSettingsCollector / getDefaultAdminEmail', () => {

const doc = {};
if (docExists) {
if (adminEmail) {
set(doc, ['_source', 'config', XPACK_DEFAULT_ADMIN_EMAIL_UI_SETTING], adminEmail);
if (defaultAdminEmail) {
set(doc, ['_source', 'config', XPACK_DEFAULT_ADMIN_EMAIL_UI_SETTING], defaultAdminEmail);
} else {
set(doc, '_source.config', {});
}
Expand All @@ -46,41 +53,131 @@ describe('getSettingsCollector / getDefaultAdminEmail', () => {
}))
.returns(doc);

const log = {
warn: sinon.stub()
};

return {
config,
callCluster
callCluster,
log,
};
}

describe('xpack.monitoring.cluster_alerts.email_notifications.enabled = false', () => {
it('returns null', async () => {
const { config, callCluster } = setup({ enabled: false });
expect(await getDefaultAdminEmail(config, callCluster)).to.be(null);
sinon.assert.notCalled(callCluster);
describe('using xpack:defaultAdminEmail', () => {
beforeEach(() => {
resetDeprecationWarning();
});
});

describe('doc does not exist', () => {
it('returns null', async () => {
const { config, callCluster } = setup({ docExists: false });
expect(await getDefaultAdminEmail(config, callCluster)).to.be(null);
sinon.assert.calledOnce(callCluster);
describe('xpack.monitoring.cluster_alerts.email_notifications.enabled = false', () => {

it('returns null', async () => {
const { config, callCluster, log } = setup({ enabled: false });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be(null);
sinon.assert.notCalled(callCluster);
});

it('does not log a deprecation warning', async () => {
const { config, callCluster, log } = setup({ enabled: false });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.notCalled(log.warn);
});
});
});

describe('value is not defined', () => {
it('returns null', async () => {
const { config, callCluster } = setup({ adminEmail: false });
expect(await getDefaultAdminEmail(config, callCluster)).to.be(null);
sinon.assert.calledOnce(callCluster);
describe('doc does not exist', () => {
it('returns null', async () => {
const { config, callCluster, log } = setup({ docExists: false });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be(null);
sinon.assert.calledOnce(callCluster);
});

it('logs a deprecation warning', async () => {
const { config, callCluster, log } = setup({ docExists: false });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.calledOnce(log.warn);
});
});

describe('value is not defined', () => {
it('returns null', async () => {
const { config, callCluster, log } = setup({ defaultAdminEmail: false });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be(null);
sinon.assert.calledOnce(callCluster);
});

it('logs a deprecation warning', async () => {
const { config, callCluster, log } = setup({ defaultAdminEmail: false });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.calledOnce(log.warn);
});
});

describe('value is defined', () => {
it('returns value', async () => {
const { config, callCluster, log } = setup({ defaultAdminEmail: 'hello@world' });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be('hello@world');
sinon.assert.calledOnce(callCluster);
});

it('logs a deprecation warning', async () => {
const { config, callCluster, log } = setup({ defaultAdminEmail: 'hello@world' });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.calledOnce(log.warn);
});
});
});

describe('value is defined', () => {
it('returns value', async () => {
const { config, callCluster } = setup({ adminEmail: 'hello@world' });
expect(await getDefaultAdminEmail(config, callCluster)).to.be('hello@world');
sinon.assert.calledOnce(callCluster);
describe('using xpack.monitoring.cluster_alerts.email_notifications.email_address', () => {
beforeEach(() => {
resetDeprecationWarning();
});

describe('xpack.monitoring.cluster_alerts.email_notifications.enabled = false', () => {
it('returns null', async () => {
const { config, callCluster, log } = setup({ enabled: false });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be(null);
sinon.assert.notCalled(callCluster);
});

it('does not log a deprecation warning', async () => {
const { config, callCluster, log } = setup({ enabled: false });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.notCalled(log.warn);
});
});

describe('value is not defined', () => {
it('returns value from xpack:defaultAdminEmail', async () => {
const { config, callCluster, log } = setup({
defaultAdminEmail: 'default-admin@email.com',
adminEmail: false
});
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be('default-admin@email.com');
sinon.assert.calledOnce(callCluster);
});

it('logs a deprecation warning', async () => {
const { config, callCluster, log } = setup({
defaultAdminEmail: 'default-admin@email.com',
adminEmail: false
});
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.calledOnce(log.warn);
});
});

describe('value is defined', () => {
it('returns value', async () => {
const { config, callCluster, log } = setup({ adminEmail: 'hello@world' });
expect(await getDefaultAdminEmail(config, callCluster, log)).to.be('hello@world');
sinon.assert.notCalled(callCluster);
});

it('does not log a deprecation warning', async () => {
const { config, callCluster, log } = setup({ adminEmail: 'hello@world' });
await getDefaultAdminEmail(config, callCluster, log);
sinon.assert.notCalled(log.warn);
});
});
});
});
Loading

0 comments on commit 263c916

Please sign in to comment.