mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.16] [ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API (#208033) (#208658)
# Backport This will backport the following commits from `main` to `8.16`: - [[ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API (#208033)](https://github.com/elastic/kibana/pull/208033) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Antonio","email":"antonio.coelho@elastic.co"},"sourceCommit":{"committedDate":"2025-01-29T00:37:12Z","message":"[ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API (#208033)\n\nCloses #207188\r\n\r\n## Summary\r\n\r\nThis is a freak scenario that is hard to reproduce. That is why I did\r\nnot add a test in\r\n`x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts`.\r\nWe cannot create a connector with an unregistered type so there is no\r\nway to test deletion in the functional tests.\r\n\r\nI added a unit test and there are steps below to test manually too.\r\n\r\n### How to reproduce\r\n\r\n1. Create a connector, let's say `Pagerduty`.\r\n2. Stop Kibana.\r\n3. Change the connector type id in\r\n`stack_connectors/server/connector_types/pagerduty/index.ts`\r\n - `'.pagerduty'` -> `'.pagerduty-foobar'`.\r\n- This will mean that when you restart Kibana a new connector ID will be\r\nregistered and the existing connector you created will be invalid/not\r\nsupported.\r\n4. Restart Kibana.\r\n5. Try to delete the connector.\r\n\r\nIf this PR works, you can delete the connector, and an error should be\r\nlogged in the Kibana console.\r\n\r\nOn main the deletion would have failed.","sha":"e5d38af58bbd6bd62c2869516c383383245a3d0d","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:ResponseOps","v9.0.0","Feature:Actions/ConnectorsManagement","backport:prev-major"],"title":"[ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API","number":208033,"url":"https://github.com/elastic/kibana/pull/208033","mergeCommit":{"message":"[ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API (#208033)\n\nCloses #207188\r\n\r\n## Summary\r\n\r\nThis is a freak scenario that is hard to reproduce. That is why I did\r\nnot add a test in\r\n`x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts`.\r\nWe cannot create a connector with an unregistered type so there is no\r\nway to test deletion in the functional tests.\r\n\r\nI added a unit test and there are steps below to test manually too.\r\n\r\n### How to reproduce\r\n\r\n1. Create a connector, let's say `Pagerduty`.\r\n2. Stop Kibana.\r\n3. Change the connector type id in\r\n`stack_connectors/server/connector_types/pagerduty/index.ts`\r\n - `'.pagerduty'` -> `'.pagerduty-foobar'`.\r\n- This will mean that when you restart Kibana a new connector ID will be\r\nregistered and the existing connector you created will be invalid/not\r\nsupported.\r\n4. Restart Kibana.\r\n5. Try to delete the connector.\r\n\r\nIf this PR works, you can delete the connector, and an error should be\r\nlogged in the Kibana console.\r\n\r\nOn main the deletion would have failed.","sha":"e5d38af58bbd6bd62c2869516c383383245a3d0d"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208033","number":208033,"mergeCommit":{"message":"[ResponseOps][Actions] Allow to delete connectors with unsupported connector type using the API (#208033)\n\nCloses #207188\r\n\r\n## Summary\r\n\r\nThis is a freak scenario that is hard to reproduce. That is why I did\r\nnot add a test in\r\n`x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts`.\r\nWe cannot create a connector with an unregistered type so there is no\r\nway to test deletion in the functional tests.\r\n\r\nI added a unit test and there are steps below to test manually too.\r\n\r\n### How to reproduce\r\n\r\n1. Create a connector, let's say `Pagerduty`.\r\n2. Stop Kibana.\r\n3. Change the connector type id in\r\n`stack_connectors/server/connector_types/pagerduty/index.ts`\r\n - `'.pagerduty'` -> `'.pagerduty-foobar'`.\r\n- This will mean that when you restart Kibana a new connector ID will be\r\nregistered and the existing connector you created will be invalid/not\r\nsupported.\r\n4. Restart Kibana.\r\n5. Try to delete the connector.\r\n\r\nIf this PR works, you can delete the connector, and an error should be\r\nlogged in the Kibana console.\r\n\r\nOn main the deletion would have failed.","sha":"e5d38af58bbd6bd62c2869516c383383245a3d0d"}}]}] BACKPORT--> Co-authored-by: Antonio <antonio.coelho@elastic.co>
This commit is contained in:
parent
2599c82f58
commit
3512420dbf
4 changed files with 98 additions and 3 deletions
|
@ -2170,6 +2170,39 @@ describe('delete()', () => {
|
|||
`"System action system-connector-.cases is not allowed to delete."`
|
||||
);
|
||||
});
|
||||
|
||||
test('deleting unregistered action types works as expected', async () => {
|
||||
const expectedResult = Symbol();
|
||||
unsecuredSavedObjectsClient.delete.mockResolvedValueOnce(expectedResult);
|
||||
unsecuredSavedObjectsClient.get = jest.fn().mockResolvedValueOnce({
|
||||
id: '2',
|
||||
type: 'action',
|
||||
attributes: {
|
||||
actionTypeId: 'unregistered-action-type-id',
|
||||
isMissingSecrets: false,
|
||||
config: {},
|
||||
secrets: {},
|
||||
},
|
||||
references: [],
|
||||
});
|
||||
|
||||
const result = await actionsClient.delete({ id: '2' });
|
||||
expect(result).toEqual(expectedResult);
|
||||
|
||||
// the event is logged but no error is thrown as expected
|
||||
expect(logger.error).toHaveBeenCalledWith(
|
||||
`Failed fetching action type from registry: Action type \"unregistered-action-type-id\" is not registered. - deletion will proceed.`
|
||||
);
|
||||
|
||||
// deletion is called with the right params
|
||||
expect(unsecuredSavedObjectsClient.delete).toHaveBeenCalledTimes(1);
|
||||
expect(unsecuredSavedObjectsClient.delete.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"action",
|
||||
"2",
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update()', () => {
|
||||
|
|
|
@ -43,6 +43,7 @@ import {
|
|||
ActionTypeExecutorResult,
|
||||
ConnectorTokenClientContract,
|
||||
HookServices,
|
||||
ActionType,
|
||||
} from '../types';
|
||||
import { PreconfiguredActionDisabledModificationError } from '../lib/errors/preconfigured_action_disabled_modification';
|
||||
import {
|
||||
|
@ -460,14 +461,22 @@ export class ActionsClient {
|
|||
attributes: { actionTypeId, config },
|
||||
} = rawAction;
|
||||
|
||||
const actionType = this.context.actionTypeRegistry.get(actionTypeId);
|
||||
let actionType: ActionType | undefined;
|
||||
try {
|
||||
actionType = this.context.actionTypeRegistry.get(actionTypeId);
|
||||
} catch (e) {
|
||||
this.context.logger.error(
|
||||
`Failed fetching action type from registry: ${e.message} - deletion will proceed.`
|
||||
);
|
||||
}
|
||||
|
||||
const result = await this.context.unsecuredSavedObjectsClient.delete('action', id);
|
||||
|
||||
const hookServices: HookServices = {
|
||||
scopedClusterClient: this.context.scopedClusterClient,
|
||||
};
|
||||
|
||||
if (actionType.postDeleteHook) {
|
||||
if (actionType && actionType.postDeleteHook) {
|
||||
try {
|
||||
await actionType.postDeleteHook({
|
||||
connectorId: id,
|
||||
|
|
|
@ -9,7 +9,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||
import expect from '@kbn/expect';
|
||||
import { ESTestIndexTool, ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers';
|
||||
|
||||
import { UserAtSpaceScenarios } from '../../../scenarios';
|
||||
import { UserAtSpaceScenarios, SuperuserAtSpace1 } from '../../../scenarios';
|
||||
import { getUrlPrefix, ObjectRemover } from '../../../../common/lib';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
|
||||
|
@ -19,6 +19,8 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
const es = getService('es');
|
||||
const retry = getService('retry');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
const esTestIndexTool = new ESTestIndexTool(es, retry);
|
||||
|
||||
describe('delete', () => {
|
||||
|
@ -28,6 +30,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
await esTestIndexTool.destroy();
|
||||
await esTestIndexTool.setup();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esTestIndexTool.destroy();
|
||||
await objectRemover.removeAll();
|
||||
|
@ -297,5 +300,35 @@ export default function deleteActionTests({ getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should delete a connector with an unsupported type', async () => {
|
||||
await kibanaServer.importExport.load(
|
||||
'x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/fixtures/unsupported_connector_type.json'
|
||||
);
|
||||
|
||||
const { space, user } = SuperuserAtSpace1;
|
||||
const { body: createdConnector } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'My Connector',
|
||||
connector_type_id: 'test.index-record',
|
||||
config: {
|
||||
unencrypted: `This value shouldn't get encrypted`,
|
||||
},
|
||||
secrets: {
|
||||
encrypted: 'This value should be encrypted',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.delete(`${getUrlPrefix(space.id)}/api/actions/connector/${createdConnector.id}`)
|
||||
.auth(user.username, user.password)
|
||||
.set('kbn-xsrf', 'foo');
|
||||
|
||||
expect(response.statusCode).to.eql(204);
|
||||
expect(response.body).to.eql('');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"attributes": {
|
||||
"actionTypeId": ".invalid-type",
|
||||
"config": {
|
||||
"apiUrl": "https://localhost:5601/"
|
||||
},
|
||||
"isMissingSecrets": true,
|
||||
"name": "Invalid connector",
|
||||
"secrets": {}
|
||||
},
|
||||
"coreMigrationVersion": "8.8.0",
|
||||
"created_at": "2025-01-28T08:46:46.614Z",
|
||||
"id": "e6dca811-c3c1-4eca-8eb0-54c792c0b662",
|
||||
"managed": false,
|
||||
"references": [],
|
||||
"type": "action",
|
||||
"typeMigrationVersion": "10.1.0",
|
||||
"updated_at": "2025-01-28T08:46:46.614Z",
|
||||
"version": "WzUsMl0="
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue