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

[8.x] [Fleet] use defaultFleetErrorHandler in all fleet routes (#200741) #200803

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions x-pack/plugins/fleet/dev_docs/fleet_router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Fleet router

All the fleet API routes are wrapped with a custom handler see [fleet_router](../server/services/security/fleet_router.ts) that provides error handling and security.

## Error handling

All non catched errors in Fleet API will go throuh a default error handler, that will allow to transform known error in response with predefined status code.

## Security

Fleet router also provide an easy way to declare authorization rules for Fleet routes. This can be done via the `fleetAuthz` property via a function or an object with required roles.

Examples:

```typescript
router.versioned.get({
path: OUTPUT_API_ROUTES.LIST_PATTERN,
fleetAuthz: (authz) => {
return authz.fleet.readSettings || authz.fleet.readAgentPolicies;
},
summary: 'Get outputs',
});
```

```typescript
router.versioned.post({
path: OUTPUT_API_ROUTES.CREATE_PATTERN,
fleetAuthz: {
fleet: { allSettings: true },
},
summary: 'Create output',
});
```
63 changes: 27 additions & 36 deletions x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type {
} from '../../types/rest_spec';
import type { ActionsService } from '../../services/agents';
import type { PostNewAgentActionResponse } from '../../../common/types/rest_spec';
import { defaultFleetErrorHandler } from '../../errors';
import { getCurrentNamespace } from '../../services/spaces/get_current_namespace';

export const postNewAgentActionHandlerBuilder = function (
Expand All @@ -27,55 +26,47 @@ export const postNewAgentActionHandlerBuilder = function (
TypeOf<typeof PostNewAgentActionRequestSchema.body>
> {
return async (context, request, response) => {
try {
const core = await context.core;
const esClient = core.elasticsearch.client.asInternalUser;
const soClient = core.savedObjects.client;
const core = await context.core;
const esClient = core.elasticsearch.client.asInternalUser;
const soClient = core.savedObjects.client;

const agent = await actionsService.getAgent(esClient, soClient, request.params.agentId);
const agent = await actionsService.getAgent(esClient, soClient, request.params.agentId);

const newAgentAction = request.body.action;
const newAgentAction = request.body.action;

const savedAgentAction = await actionsService.createAgentAction(esClient, {
created_at: new Date().toISOString(),
...newAgentAction,
agents: [agent.id],
namespaces: [getCurrentNamespace(soClient)],
});
const savedAgentAction = await actionsService.createAgentAction(esClient, {
created_at: new Date().toISOString(),
...newAgentAction,
agents: [agent.id],
namespaces: [getCurrentNamespace(soClient)],
});

const body: PostNewAgentActionResponse = {
item: savedAgentAction,
};
const body: PostNewAgentActionResponse = {
item: savedAgentAction,
};

return response.ok({ body });
} catch (error) {
return defaultFleetErrorHandler({ error, response });
}
return response.ok({ body });
};
};

export const postCancelActionHandlerBuilder = function (
actionsService: ActionsService
): RequestHandler<TypeOf<typeof PostCancelActionRequestSchema.params>, undefined, undefined> {
return async (context, request, response) => {
try {
const core = await context.core;
const esClient = core.elasticsearch.client.asInternalUser;
const soClient = core.savedObjects.client;
const core = await context.core;
const esClient = core.elasticsearch.client.asInternalUser;
const soClient = core.savedObjects.client;

const action = await actionsService.cancelAgentAction(
esClient,
soClient,
request.params.actionId
);
const action = await actionsService.cancelAgentAction(
esClient,
soClient,
request.params.actionId
);

const body: PostNewAgentActionResponse = {
item: action,
};
const body: PostNewAgentActionResponse = {
item: action,
};

return response.ok({ body });
} catch (error) {
return defaultFleetErrorHandler({ error, response });
}
return response.ok({ body });
};
};
Loading
Loading