Skip to content

Commit

Permalink
[Cloud Security] Add is_internal flag to fleet server hosts configura…
Browse files Browse the repository at this point in the history
…tion (elastic#175983)

## Summary

- Follow up after elastic#175546
- Part of elastic#165251

introducing a new `is_internal` config option for
`xpack.fleet.fleetServerHosts`. The usage is currently to protect the
internal fleet server hosts in the UI:

- filter them out in the Settings UI
- disable internal hosts in the agent policy form



### Checklist

Delete any items that are not applicable to this PR.

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [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
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed

---------

Co-authored-by: kibanamachine <[email protected]>
Co-authored-by: David Kilfoyle <[email protected]>
  • Loading branch information
3 people authored and CoenWarmer committed Feb 15, 2024
1 parent c069b79 commit 4fac842
Show file tree
Hide file tree
Showing 23 changed files with 217 additions and 11 deletions.
2 changes: 2 additions & 0 deletions docs/settings/fleet-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ List of {fleet-server} hosts that are configured when the {fleet} app starts.
=====
`is_default`:::
Whether or not this host should be the default to use for {fleet-server}.
`is_internal`:::
If `true` the host will not appear in the UI, and can only be managed through `kibana.yml` or the {fleet} API.
`proxy_id`:::
Unique ID of the proxy to access the {fleet-server} host.
=====
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-check-mappings-update-cli/current_fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@
"fleet-fleet-server-host": [
"host_urls",
"is_default",
"is_internal",
"is_preconfigured",
"name",
"proxy_id"
Expand Down
4 changes: 4 additions & 0 deletions packages/kbn-check-mappings-update-cli/current_mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,10 @@
"is_default": {
"type": "boolean"
},
"is_internal": {
"type": "boolean",
"index": false
},
"host_urls": {
"type": "keyword",
"index": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
"file": "6b65ae5899b60ebe08656fd163ea532e557d3c98",
"file-upload-usage-collection-telemetry": "06e0a8c04f991e744e09d03ab2bd7f86b2088200",
"fileShare": "5be52de1747d249a221b5241af2838264e19aaa1",
"fleet-fleet-server-host": "b04898fcde07f4ce86e844c8fe2f4b23b77ef60a",
"fleet-fleet-server-host": "69be15f6b6f2a2875ad3c7050ddea7a87f505417",
"fleet-message-signing-keys": "93421f43fed2526b59092a4e3c65d64bc2266c0f",
"fleet-preconfiguration-deletion-record": "c52ea1e13c919afe8a5e8e3adbb7080980ecc08e",
"fleet-proxy": "6cb688f0d2dd856400c1dbc998b28704ff70363d",
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/fleet/common/openapi/bundled.json
Original file line number Diff line number Diff line change
Expand Up @@ -5083,6 +5083,9 @@
"is_default": {
"type": "boolean"
},
"is_internal": {
"type": "boolean"
},
"host_urls": {
"type": "array",
"items": {
Expand Down Expand Up @@ -5195,6 +5198,9 @@
"is_default": {
"type": "boolean"
},
"is_internal": {
"type": "boolean"
},
"host_urls": {
"type": "array",
"items": {
Expand Down Expand Up @@ -8904,6 +8910,9 @@
"is_default": {
"type": "boolean"
},
"is_internal": {
"type": "boolean"
},
"is_preconfigured": {
"type": "boolean"
},
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/fleet/common/openapi/bundled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,8 @@ paths:
type: string
is_default:
type: boolean
is_internal:
type: boolean
host_urls:
type: array
items:
Expand Down Expand Up @@ -3241,6 +3243,8 @@ paths:
type: string
is_default:
type: boolean
is_internal:
type: boolean
host_urls:
type: array
items:
Expand Down Expand Up @@ -5762,6 +5766,8 @@ components:
type: string
is_default:
type: boolean
is_internal:
type: boolean
is_preconfigured:
type: boolean
host_urls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ properties:
type: string
is_default:
type: boolean
is_internal:
type: boolean
is_preconfigured:
type: boolean
host_urls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ post:
type: string
is_default:
type: boolean
is_internal:
type: boolean
host_urls:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ put:
type: string
is_default:
type: boolean
is_internal:
type: boolean
host_urls:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface NewFleetServerHost {
host_urls: string[];
is_default: boolean;
is_preconfigured: boolean;
is_internal?: boolean;
proxy_id?: string | null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface PutFleetServerHostsRequest {
name?: string;
host_urls?: string[];
is_default?: boolean;
is_internal?: boolean;
proxy_id?: string | null;
};
}
Expand All @@ -29,6 +30,7 @@ export interface PostFleetServerHostsRequest {
name?: string;
host_urls?: string[];
is_default?: boolean;
is_internal?: boolean;
proxy_id?: string | null;
};
}
Expand Down
11 changes: 11 additions & 0 deletions x-pack/plugins/fleet/cypress/e2e/fleet_settings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ describe('Edit settings', () => {
host_urls: ['https://localhost:8220'],
is_default: true,
},
{
id: 'fleet-internal-host',
name: 'Internal Host',
host_urls: ['https://internal:8220'],
is_default: false,
is_internal: true,
},
],
page: 1,
perPage: 10000,
Expand Down Expand Up @@ -160,4 +167,8 @@ describe('Edit settings', () => {
expect(interception.request.body.name).to.equal('output-logstash-1');
});
});

it('should not display internal fleet server hosts', () => {
cy.getBySel(SETTINGS_FLEET_SERVER_HOSTS.TABLE).should('not.contain', 'Internal Host');
});
});
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/cypress/screens/fleet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export const SETTINGS_OUTPUTS_KAFKA = {
export const SETTINGS_FLEET_SERVER_HOSTS = {
ADD_BUTTON: 'settings.fleetServerHosts.addFleetServerHostBtn',
EDIT_BUTTON: 'fleetServerHostsTable.edit.btn',
TABLE: 'settingsFleetServerHostsTable',
};

export const AGENT_POLICY_FORM = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useLicense } from '../../../../../../hooks/use_license';
import type { LicenseService } from '../../../../services';
import type { AgentPolicy } from '../../../../types';

import { useOutputOptions } from './hooks';
import { useOutputOptions, useFleetServerHostsOptions } from './hooks';

jest.mock('../../../../../../hooks/use_license');

Expand Down Expand Up @@ -153,6 +153,35 @@ const mockApiCallsWithInternalOutputs = (http: MockedFleetStartServices['http'])
});
};

const mockApiCallsWithInternalFleetServerHost = (http: MockedFleetStartServices['http']) => {
http.get.mockImplementation(async (path) => {
if (typeof path !== 'string') {
throw new Error('Invalid request');
}
if (path === '/api/fleet/fleet_server_hosts') {
return {
data: {
items: [
{
id: 'default-host',
name: 'Default',
is_default: true,
},
{
id: 'internal-output',
name: 'Internal',
is_default: false,
is_internal: true,
},
],
},
};
}

return defaultHttpClientGetImplementation(path);
});
};

describe('useOutputOptions', () => {
it('should generate enabled options if the licence is platinium', async () => {
const testRenderer = createFleetTestRendererMock();
Expand Down Expand Up @@ -636,3 +665,30 @@ describe('useOutputOptions', () => {
`);
});
});

describe('useFleetServerHostsOptions', () => {
it('should not enable internal fleet server hosts', async () => {
const testRenderer = createFleetTestRendererMock();
mockApiCallsWithInternalFleetServerHost(testRenderer.startServices.http);
const { result, waitForNextUpdate } = testRenderer.renderHook(() =>
useFleetServerHostsOptions({} as AgentPolicy)
);
expect(result.current.isLoading).toBeTruthy();

await waitForNextUpdate();
expect(result.current.fleetServerHostsOptions).toMatchInlineSnapshot(`
Array [
Object {
"disabled": undefined,
"inputDisplay": "Default (currently Default)",
"value": "@@##DEFAULT_SELECT##@@",
},
Object {
"disabled": true,
"inputDisplay": "Internal",
"value": "internal-output",
},
]
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,12 @@ export function useFleetServerHostsOptions(agentPolicy: Partial<NewAgentPolicy |
...fleetServerHostsRequest.data.items
.filter((item) => !item.is_default)
.map((item) => {
const isInternalFleetServerHost = !!item.is_internal;

return {
value: item.id,
inputDisplay: item.name,
disabled: isInternalFleetServerHost,
};
}),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,11 @@ export const FleetServerHostsTable: React.FunctionComponent<FleetServerHostsTabl
];
}, [getHref, deleteFleetServerHost]);

return <EuiBasicTable columns={columns} items={fleetServerHosts} />;
return (
<EuiBasicTable
columns={columns}
items={fleetServerHosts}
data-test-subj="settingsFleetServerHostsTable"
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const SettingsApp = withConfirmModalProvider(() => {

const { outputs, fleetServerHosts, downloadSources, proxies } = useSettingsAppData();
const outputItems = outputs.data?.items.filter((item) => !item.is_internal);
const fleetServerHostsItems = fleetServerHosts.data?.items.filter((item) => !item.is_internal);

const { deleteOutput } = useDeleteOutput(outputs.resendRequest);
const { deleteDownloadSource } = useDeleteDownloadSource(downloadSources.resendRequest);
Expand Down Expand Up @@ -81,7 +82,7 @@ export const SettingsApp = withConfirmModalProvider(() => {
(outputs.isLoading && outputs.isInitialRequest) ||
!outputItems ||
(fleetServerHosts.isLoading && fleetServerHosts.isInitialRequest) ||
!fleetServerHosts.data?.items ||
!fleetServerHostsItems ||
(downloadSources.isLoading && downloadSources.isInitialRequest) ||
!downloadSources.data?.items ||
(proxies.isLoading && proxies.isInitialRequest) ||
Expand All @@ -99,7 +100,7 @@ export const SettingsApp = withConfirmModalProvider(() => {
<Routes>
<Route path={FLEET_ROUTING_PATHS.settings_edit_fleet_server_hosts}>
{(route: { match: { params: { itemId: string } } }) => {
const fleetServerHost = fleetServerHosts.data?.items.find(
const fleetServerHost = fleetServerHostsItems.find(
(o) => route.match.params.itemId === o.id
);
if (!fleetServerHost) {
Expand Down Expand Up @@ -198,7 +199,7 @@ export const SettingsApp = withConfirmModalProvider(() => {
deleteFleetProxy={deleteFleetProxy}
proxies={proxies.data.items}
outputs={outputItems}
fleetServerHosts={fleetServerHosts.data.items}
fleetServerHosts={fleetServerHostsItems}
deleteOutput={deleteOutput}
deleteFleetServerHost={deleteFleetServerHost}
downloadSources={downloadSources.data.items}
Expand Down
13 changes: 13 additions & 0 deletions x-pack/plugins/fleet/server/saved_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,11 +626,24 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({
properties: {
name: { type: 'keyword' },
is_default: { type: 'boolean' },
is_internal: { type: 'boolean', index: false },
host_urls: { type: 'keyword', index: false },
is_preconfigured: { type: 'boolean' },
proxy_id: { type: 'keyword' },
},
},
modelVersions: {
'1': {
changes: [
{
type: 'mappings_addition',
addedMappings: {
is_internal: { type: 'boolean', index: false },
},
},
],
},
},
},
[FLEET_PROXY_SAVED_OBJECT_TYPE]: {
name: FLEET_PROXY_SAVED_OBJECT_TYPE,
Expand Down
Loading

0 comments on commit 4fac842

Please sign in to comment.