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

[Cloud Security] Add is_internal flag to fleet server hosts configuration #175983

Merged
merged 11 commits into from
Feb 2, 2024
Merged
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
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
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
Loading