Skip to content

Commit

Permalink
[Fleet] Fix serverless proxy support bugs (elastic#176732)
Browse files Browse the repository at this point in the history
## Summary

Closes elastic#176728

This PR fixes two bugs:
1. "Add Fleet Server" button above the Agents table opens the wrong
flyout. This button is now hidden in serverless.
2. Output PUT request when hosts are not passed.

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
jillguyonnet authored and fkanout committed Mar 4, 2024
1 parent 105fbe3 commit 8b9969b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import type { Agent, AgentPolicy } from '../../../../types';
import { SearchBar } from '../../../../components';
import { AGENTS_INDEX, AGENTS_PREFIX } from '../../../../constants';

import { useStartServices } from '../../../../hooks';

import { AgentBulkActions } from './bulk_actions';
import type { SelectionMode } from './types';
import { AgentActivityButton } from './agent_activity_button';
Expand Down Expand Up @@ -91,6 +93,7 @@ export const SearchAndFilterBar: React.FunctionComponent<SearchAndFilterBarProps
}) => {
const { isFirstTimeAgentUser, isLoading: isFirstTimeAgentUserLoading } =
useIsFirstTimeAgentUserQuery();
const { cloud } = useStartServices();

return (
<>
Expand All @@ -107,23 +110,25 @@ export const SearchAndFilterBar: React.FunctionComponent<SearchAndFilterBarProps
showAgentActivityTour={showAgentActivityTour}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiToolTip
content={
<FormattedMessage
id="xpack.fleet.agentList.addFleetServerButton.tooltip"
defaultMessage="Fleet Server is a component of the Elastic Stack used to centrally manage Elastic Agents"
/>
}
>
<EuiButton onClick={onClickAddFleetServer} data-test-subj="addFleetServerButton">
<FormattedMessage
id="xpack.fleet.agentList.addFleetServerButton"
defaultMessage="Add Fleet Server"
/>
</EuiButton>
</EuiToolTip>
</EuiFlexItem>
{!cloud?.isServerlessEnabled && (
<EuiFlexItem grow={false}>
<EuiToolTip
content={
<FormattedMessage
id="xpack.fleet.agentList.addFleetServerButton.tooltip"
defaultMessage="Fleet Server is a component of the Elastic Stack used to centrally manage Elastic Agents"
/>
}
>
<EuiButton onClick={onClickAddFleetServer} data-test-subj="addFleetServerButton">
<FormattedMessage
id="xpack.fleet.agentList.addFleetServerButton"
defaultMessage="Add Fleet Server"
/>
</EuiButton>
</EuiToolTip>
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
<EuiToolTip
content={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ describe('fleet server hosts handler', () => {
expect(res).toEqual({ body: { item: { id: 'host1' } } });
});

it('should return ok on put in serverless if host urls are not passed', async () => {
jest.spyOn(appContextService, 'getCloud').mockReturnValue({ isServerlessEnabled: true } as any);

const res = await putFleetServerHostHandler(
mockContext,
{ body: { name: ['Renamed'] }, params: { outputId: 'host1' } } as any,
mockResponse as any
);

expect(res).toEqual({ body: { item: { id: 'host1' } } });
});

it('should return ok on put in stateful if host url is different from default', async () => {
jest
.spyOn(appContextService, 'getCloud')
Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/fleet/server/routes/output/handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ describe('output handler', () => {
expect(res).toEqual({ body: { item: { id: 'output1' } } });
});

it('should return ok on put elasticsearch output in serverless if host url is not passed', async () => {
jest.spyOn(appContextService, 'getCloud').mockReturnValue({ isServerlessEnabled: true } as any);

const res = await putOutputHandler(
mockContext,
{
body: { type: 'elasticsearch', name: 'Renamed output' },
params: { outputId: 'output1' },
} as any,
mockResponse as any
);

expect(res).toEqual({ body: { item: { id: 'output1' } } });
});

it('should return ok on put elasticsearch output in stateful if host url is different from default', async () => {
jest
.spyOn(appContextService, 'getCloud')
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/fleet/server/routes/output/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ async function validateOutputServerless(
throw Boom.badRequest('Output type remote_elasticsearch not supported in serverless');
}
// Elasticsearch outputs must have the default host URL in serverless.
// No need to validate on update if hosts are not passed.
if (outputId && !output.hosts) {
return;
}
const defaultOutput = await outputService.get(soClient, SERVERLESS_DEFAULT_OUTPUT_ID);
let originalOutput;
if (outputId) {
Expand Down

0 comments on commit 8b9969b

Please sign in to comment.