Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Alerting] Handling connectors with missing secrets during rule creation and action execution #98618

Merged
merged 23 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7f3f1bf
[Connectors][API] Updated connectors with enabledAfterImport flag
YulNaumenko Apr 23, 2021
fe1755f
fixed functional tests
YulNaumenko Apr 26, 2021
b5cecc1
Merge remote-tracking branch upstream/master
YulNaumenko Apr 26, 2021
d307369
added new field to connectors API docs
YulNaumenko Apr 26, 2021
8f1a0d6
added update unit test
YulNaumenko Apr 26, 2021
aaa0673
fixed test
YulNaumenko Apr 26, 2021
d54d06f
renamed enableAfterImport to isMissingSecrets
YulNaumenko Apr 26, 2021
adf3bf0
removed onExport
YulNaumenko Apr 26, 2021
7cfc83d
revert the logic of true/false for isMissingSecrets
YulNaumenko Apr 26, 2021
4f56afa
fixed test
YulNaumenko Apr 26, 2021
b950b18
fixed tests
YulNaumenko Apr 27, 2021
defad11
added unit test
YulNaumenko Apr 27, 2021
d15d490
fixed docs
YulNaumenko Apr 27, 2021
7f11c3d
fixed import text and button labels
YulNaumenko Apr 27, 2021
236221b
fixed import text
YulNaumenko Apr 27, 2021
8a4da38
fixed text
YulNaumenko Apr 27, 2021
92e1543
Showing placeholder message when connector is missing secrets
ymao1 Apr 27, 2021
4761ba8
Merge branch 'master' of https://github.com/elastic/kibana into alert…
ymao1 Apr 28, 2021
04bdef7
Throwing error on isMissingSecrets = true before executing actions
ymao1 Apr 28, 2021
3f4a025
Hiding connectors with missing secrets from dropdown
ymao1 Apr 28, 2021
47cf26a
Checking for connectors with missing secrets during action validation…
ymao1 Apr 28, 2021
62ba67e
Merge branch 'master' of https://github.com/elastic/kibana into alert…
ymao1 May 3, 2021
2e52cc2
Updating error wording
ymao1 May 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions x-pack/plugins/actions/server/create_execute_function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,35 @@ describe('execute()', () => {
);
});

test('throws when isMissingSecrets is true for connector', async () => {
const executeFn = createExecutionEnqueuerFunction({
taskManager: mockTaskManager,
isESOCanEncrypt: true,
actionTypeRegistry: actionTypeRegistryMock.create(),
preconfiguredActions: [],
});
savedObjectsClient.get.mockResolvedValueOnce({
id: '123',
type: 'action',
attributes: {
name: 'mock-action',
isMissingSecrets: true,
actionTypeId: 'mock-action',
},
references: [],
});
await expect(
executeFn(savedObjectsClient, {
id: '123',
params: { baz: false },
spaceId: 'default',
apiKey: null,
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Unable to execute action because the referenced connector is incorrectly configured. Please review the configuration for the \\"mock-action\\" connector."`
);
});

test('should ensure action type is enabled', async () => {
const mockedActionTypeRegistry = actionTypeRegistryMock.create();
const executeFn = createExecutionEnqueuerFunction({
Expand Down
20 changes: 12 additions & 8 deletions x-pack/plugins/actions/server/create_execute_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,18 @@ export function createExecutionEnqueuerFunction({
);
}

const actionTypeId = await getActionTypeId(
const { actionTypeId, name, isMissingSecrets } = await getAction(
unsecuredSavedObjectsClient,
preconfiguredActions,
id
);

if (isMissingSecrets) {
throw new Error(
`Unable to execute action because the referenced connector is incorrectly configured. Please review the configuration for the "${name}" connector.`
ymao1 marked this conversation as resolved.
Show resolved Hide resolved
);
}

if (!actionTypeRegistry.isActionExecutable(id, actionTypeId, { notifyUsage: true })) {
actionTypeRegistry.ensureActionTypeEnabled(actionTypeId);
}
Expand Down Expand Up @@ -91,18 +97,16 @@ function executionSourceAsSavedObjectReferences(executionSource: ActionExecutorO
: {};
}

async function getActionTypeId(
async function getAction(
unsecuredSavedObjectsClient: SavedObjectsClientContract,
preconfiguredActions: PreConfiguredAction[],
actionId: string
): Promise<string> {
): Promise<PreConfiguredAction | RawAction> {
const pcAction = preconfiguredActions.find((action) => action.id === actionId);
if (pcAction) {
return pcAction.actionTypeId;
return pcAction;
}

const {
attributes: { actionTypeId },
} = await unsecuredSavedObjectsClient.get<RawAction>('action', actionId);
return actionTypeId;
const { attributes } = await unsecuredSavedObjectsClient.get<RawAction>('action', actionId);
return attributes;
}
34 changes: 30 additions & 4 deletions x-pack/plugins/alerting/server/alerts_client/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export class AlertsClient {
throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`);
}

this.validateActions(alertType, data.actions);
await this.validateActions(alertType, data.actions);

const createTime = Date.now();
const { references, actions } = await this.denormalizeActions(data.actions);
Expand Down Expand Up @@ -728,7 +728,7 @@ export class AlertsClient {
data.params,
alertType.validate?.params
);
this.validateActions(alertType, data.actions);
await this.validateActions(alertType, data.actions);

const { actions, references } = await this.denormalizeActions(data.actions);
const username = await this.getUserName();
Expand Down Expand Up @@ -1434,10 +1434,36 @@ export class AlertsClient {
};
}

private validateActions(
private async validateActions(
alertType: UntypedNormalizedAlertType,
actions: NormalizedAlertAction[]
): void {
): Promise<void> {
if (actions.length === 0) {
return;
}

// check for actions using connectors with missing secrets
const actionsClient = await this.getActionsClient();
const actionIds = [...new Set(actions.map((action) => action.id))];
const actionResults = (await actionsClient.getBulk(actionIds)) || [];
const actionsUsingConnectorsWithMissingSecrets = actionResults.filter(
(result) => result.isMissingSecrets
);

if (actionsUsingConnectorsWithMissingSecrets.length) {
throw Boom.badRequest(
i18n.translate('xpack.alerting.alertsClient.validateActions.misconfiguredConnector', {
defaultMessage: 'Invalid connectors: {groups}',
values: {
groups: actionsUsingConnectorsWithMissingSecrets
.map((connector) => connector.name)
.join(', '),
},
})
);
}

// check for actions with invalid action groups
const { actionGroups: alertTypeActionGroups } = alertType;
const usedAlertActionGroups = actions.map((action) => action.group);
const availableAlertTypeActionGroups = new Set(map(alertTypeActionGroups, 'id'));
Expand Down
Loading