[Fleet] show --install-servers in Add agent flyout if certain inputs are in agent policy (#214136)

## Summary

Closes https://github.com/elastic/kibana/issues/211899

Show `--install-servers` in Add agent flyout if agent policy has one of
`apm, fleet-server, cloudbeat` inputs

CSPM integration:
<img width="1561" alt="image"
src="https://github.com/user-attachments/assets/94fbc6f1-2e9a-4285-a8b9-7e2c3aa1a0ab"
/>

APM integration:
<img width="1561" alt="image"
src="https://github.com/user-attachments/assets/f7567ae3-bd4d-4efd-90d5-08a114178cf2"
/>

Agent policy without `--install-servers`:
<img width="1575" alt="image"
src="https://github.com/user-attachments/assets/1571675b-b32c-46be-8c92-d83bb9aa9d12"
/>

Cloud asset inventory (prerelease):
<img width="1572" alt="image"
src="https://github.com/user-attachments/assets/2ffb275a-5fad-430f-b757-5783e88c3a79"
/>



### 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
This commit is contained in:
Julia Bardi 2025-03-12 17:09:07 +01:00 committed by GitHub
parent 3338092efc
commit bed491dc1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 74 additions and 5 deletions

View file

@ -8,6 +8,7 @@
import {
getRootIntegrations,
getRootPrivilegedDataStreams,
hasInstallServersInputs,
isRootPrivilegesRequired,
} from './package_helpers';
@ -119,3 +120,41 @@ describe('getRootIntegrations', () => {
expect(res).toEqual([]);
});
});
describe('hasInstallServersInputs', () => {
it('should return true if any package policy has fleet-server input', () => {
const res = hasInstallServersInputs([
{
inputs: [{ type: 'fleet-server' }],
} as any,
]);
expect(res).toBe(true);
});
it('should return true if any package policy has apm input', () => {
const res = hasInstallServersInputs([
{
inputs: [{ type: 'apm' }],
} as any,
]);
expect(res).toBe(true);
});
it('should return true if any package policy has cloudbeat input', () => {
const res = hasInstallServersInputs([
{
inputs: [{ type: 'cloudbeat/cis_aws' }],
} as any,
]);
expect(res).toBe(true);
});
it('should return false if no package policy has install servers inputs', () => {
const res = hasInstallServersInputs([
{
inputs: [{ type: 'system' }],
} as any,
]);
expect(res).toBe(false);
});
});

View file

@ -42,3 +42,13 @@ export function getRootIntegrations(
(pkg) => pkg!.name
).map((pkg) => ({ name: pkg!.name, title: pkg!.title }));
}
const INSTALL_SERVERS_INPUTS = ['cloudbeat', 'apm', 'fleet-server'];
export function hasInstallServersInputs(packagePolicies: PackagePolicy[]): boolean {
return packagePolicies.some((policy) =>
policy.inputs.some(
(input) => INSTALL_SERVERS_INPUTS.includes(input.type) || input.type.startsWith('cloudbeat')
)
);
}

View file

@ -21,7 +21,10 @@ import { ManualInstructions } from '../../../../../../../../../components/enroll
import { KubernetesManifestApplyStep } from '../../../../../../../../../components/agent_enrollment_flyout/steps/run_k8s_apply_command_step';
import { getRootIntegrations } from '../../../../../../../../../../common/services';
import {
getRootIntegrations,
hasInstallServersInputs,
} from '../../../../../../../../../../common/services';
import type { InstallAgentPageProps } from './types';
@ -64,11 +67,14 @@ export const InstallElasticAgentManagedPageStep: React.FC<InstallAgentPageProps>
const isK8s =
props.packageInfo.name === 'kubernetes' ? 'IS_KUBERNETES_MULTIPAGE' : 'IS_NOT_KUBERNETES';
const showInstallServers = hasInstallServersInputs(agentPolicy?.package_policies ?? []);
const installManagedCommands = ManualInstructions({
apiKey: enrollmentAPIKey.api_key,
fleetProxy,
fleetServerHost,
agentVersion: agentVersion || '',
showInstallServers,
});
const steps = [

View file

@ -11,7 +11,7 @@ import { EuiSteps, EuiLoadingSpinner } from '@elastic/eui';
import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps';
import { getRootIntegrations } from '../../../../common/services';
import { getRootIntegrations, hasInstallServersInputs } from '../../../../common/services';
import { getGcpIntegrationDetailsFromAgentPolicy } from '../../cloud_security_posture/services';
@ -177,6 +177,8 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
const { gcpProjectId, gcpOrganizationId, gcpAccountType } =
getGcpIntegrationDetailsFromAgentPolicy(selectedPolicy);
const showInstallServers = hasInstallServersInputs(agentPolicy?.package_policies ?? []);
const installManagedCommands = ManualInstructions({
apiKey: enrollToken,
fleetServerHost,
@ -187,6 +189,7 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
gcpProjectId,
gcpOrganizationId,
gcpAccountType,
showInstallServers,
});
const instructionsSteps = useMemo(() => {

View file

@ -11,7 +11,8 @@ import type { DownloadSource, FleetProxy } from '../../../types';
function getfleetServerHostsEnrollArgs(
apiKey: string,
fleetServerHost: string,
fleetProxy?: FleetProxy
fleetProxy?: FleetProxy,
showInstallServers: boolean = false
) {
const proxyHeadersArgs = fleetProxy?.proxy_headers
? Object.entries(fleetProxy.proxy_headers).reduce((acc, [proxyKey, proyVal]) => {
@ -21,7 +22,10 @@ function getfleetServerHostsEnrollArgs(
}, '')
: '';
const proxyArgs = fleetProxy ? ` --proxy-url=${fleetProxy.url}${proxyHeadersArgs}` : '';
return `--url=${fleetServerHost || `FLEET_SERVER_HOST`} --enrollment-token=${apiKey}${proxyArgs}`;
const showInstallServersArgs = showInstallServers ? ' --install-servers' : '';
return `--url=${
fleetServerHost || `FLEET_SERVER_HOST`
} --enrollment-token=${apiKey}${proxyArgs}${showInstallServersArgs}`;
}
export const getDownloadBaseUrl = (downloadSource?: DownloadSource) => {
@ -67,6 +71,7 @@ export const ManualInstructions = ({
gcpProjectId = '<PROJECT_ID>',
gcpOrganizationId = '<ORGANIZATION_ID>',
gcpAccountType,
showInstallServers,
}: {
apiKey: string;
fleetServerHost: string;
@ -77,8 +82,14 @@ export const ManualInstructions = ({
gcpProjectId?: string;
gcpOrganizationId?: string;
gcpAccountType?: string;
showInstallServers?: boolean;
}) => {
const enrollArgs = getfleetServerHostsEnrollArgs(apiKey, fleetServerHost, fleetProxy);
const enrollArgs = getfleetServerHostsEnrollArgs(
apiKey,
fleetServerHost,
fleetProxy,
showInstallServers
);
const downloadBaseUrl = getDownloadBaseUrl(downloadSource);
const fleetServerUrl = enrollArgs?.split('--url=')?.pop()?.split('--enrollment')[0];