[Cloud Security] Fix wrong fleet url in cloudFormation (#166130)

solves:
- https://github.com/elastic/security-team/issues/7482

choose the correct Fleet URL in case there is more than one fleet
server.

---------

Co-authored-by: Maxim Kholod <maxim.kholod@elastic.co>
This commit is contained in:
Ido Cohen 2023-09-25 10:44:55 +03:00 committed by GitHub
parent 14e4987ae6
commit 48d293f29a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 19 deletions

View file

@ -20,8 +20,14 @@ import {
import { FormattedMessage } from '@kbn/i18n-react'; import { FormattedMessage } from '@kbn/i18n-react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { useAgentPolicyWithPackagePolicies } from '../../../../../../../components/agent_enrollment_flyout/hooks';
import type { AgentPolicy, PackagePolicy } from '../../../../../types'; import type { AgentPolicy, PackagePolicy } from '../../../../../types';
import { sendGetEnrollmentAPIKeys, useCreateCloudFormationUrl } from '../../../../../hooks'; import {
sendGetEnrollmentAPIKeys,
useCreateCloudFormationUrl,
useFleetServerHostsForPolicy,
} from '../../../../../hooks';
import { getCloudFormationPropsFromPackagePolicy } from '../../../../../services'; import { getCloudFormationPropsFromPackagePolicy } from '../../../../../services';
import { CloudFormationGuide } from '../../../../../components'; import { CloudFormationGuide } from '../../../../../components';
@ -31,7 +37,7 @@ export const PostInstallCloudFormationModal: React.FunctionComponent<{
agentPolicy: AgentPolicy; agentPolicy: AgentPolicy;
packagePolicy: PackagePolicy; packagePolicy: PackagePolicy;
}> = ({ onConfirm, onCancel, agentPolicy, packagePolicy }) => { }> = ({ onConfirm, onCancel, agentPolicy, packagePolicy }) => {
const { data: apyKeysData } = useQuery(['cloudFormationApiKeys'], () => const { data: apiKeysData, isLoading } = useQuery(['cloudFormationApiKeys'], () =>
sendGetEnrollmentAPIKeys({ sendGetEnrollmentAPIKeys({
page: 1, page: 1,
perPage: 1, perPage: 1,
@ -39,11 +45,16 @@ export const PostInstallCloudFormationModal: React.FunctionComponent<{
}) })
); );
const { agentPolicyWithPackagePolicies } = useAgentPolicyWithPackagePolicies(agentPolicy.id);
const { fleetServerHosts } = useFleetServerHostsForPolicy(agentPolicyWithPackagePolicies);
const fleetServerHost = fleetServerHosts[0];
const cloudFormationProps = getCloudFormationPropsFromPackagePolicy(packagePolicy); const cloudFormationProps = getCloudFormationPropsFromPackagePolicy(packagePolicy);
const { cloudFormationUrl, error, isError, isLoading } = useCreateCloudFormationUrl({ const { cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({
enrollmentAPIKey: apyKeysData?.data?.items[0]?.api_key, enrollmentAPIKey: apiKeysData?.data?.items[0]?.api_key,
cloudFormationProps, cloudFormationProps,
fleetServerHost,
}); });
return ( return (

View file

@ -18,15 +18,18 @@ import type { CloudSecurityIntegration } from './types';
interface Props { interface Props {
enrollmentAPIKey?: string; enrollmentAPIKey?: string;
cloudSecurityIntegration: CloudSecurityIntegration; cloudSecurityIntegration: CloudSecurityIntegration;
fleetServerHost: string;
} }
export const CloudFormationInstructions: React.FunctionComponent<Props> = ({ export const CloudFormationInstructions: React.FunctionComponent<Props> = ({
enrollmentAPIKey, enrollmentAPIKey,
cloudSecurityIntegration, cloudSecurityIntegration,
fleetServerHost,
}) => { }) => {
const { isLoading, cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({ const { cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({
enrollmentAPIKey, enrollmentAPIKey,
cloudFormationProps: cloudSecurityIntegration?.cloudFormationProps, cloudFormationProps: cloudSecurityIntegration?.cloudFormationProps,
fleetServerHost,
}); });
if (error && isError) { if (error && isError) {
@ -42,7 +45,7 @@ export const CloudFormationInstructions: React.FunctionComponent<Props> = ({
<EuiSkeletonText <EuiSkeletonText
lines={3} lines={3}
size="m" size="m"
isLoading={isLoading || cloudSecurityIntegration?.isLoading} isLoading={cloudSecurityIntegration?.isLoading}
contentAriaLabel={i18n.translate( contentAriaLabel={i18n.translate(
'xpack.fleet.agentEnrollment.cloudFormation.loadingAriaLabel', 'xpack.fleet.agentEnrollment.cloudFormation.loadingAriaLabel',
{ {

View file

@ -220,6 +220,8 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
const agentVersion = useAgentVersion(); const agentVersion = useAgentVersion();
const fleetServerHost = fleetServerHosts?.[0];
const installManagedCommands = ManualInstructions({ const installManagedCommands = ManualInstructions({
apiKey: enrollToken, apiKey: enrollToken,
fleetServerHosts, fleetServerHosts,
@ -260,6 +262,7 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
selectedApiKeyId, selectedApiKeyId,
enrollToken, enrollToken,
cloudSecurityIntegration, cloudSecurityIntegration,
fleetServerHost,
}) })
); );
} else if (cloudSecurityIntegration?.cloudShellUrl) { } else if (cloudSecurityIntegration?.cloudShellUrl) {
@ -279,7 +282,7 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
selectedApiKeyId, selectedApiKeyId,
isK8s, isK8s,
cloudSecurityIntegration, cloudSecurityIntegration,
fleetServerHost: fleetServerHosts?.[0], fleetServerHost,
enrollToken, enrollToken,
}) })
); );
@ -324,7 +327,7 @@ export const ManagedSteps: React.FunctionComponent<InstructionProps> = ({
enrollToken, enrollToken,
installManagedCommands, installManagedCommands,
isK8s, isK8s,
fleetServerHosts, fleetServerHost,
onClickViewAgents, onClickViewAgents,
link, link,
enrolledAgentIds, enrolledAgentIds,

View file

@ -23,12 +23,14 @@ export const InstallCloudFormationManagedAgentStep = ({
enrollToken, enrollToken,
isComplete, isComplete,
cloudSecurityIntegration, cloudSecurityIntegration,
fleetServerHost,
}: { }: {
selectedApiKeyId?: string; selectedApiKeyId?: string;
apiKeyData?: GetOneEnrollmentAPIKeyResponse | null; apiKeyData?: GetOneEnrollmentAPIKeyResponse | null;
enrollToken?: string; enrollToken?: string;
isComplete?: boolean; isComplete?: boolean;
cloudSecurityIntegration?: CloudSecurityIntegration | undefined; cloudSecurityIntegration?: CloudSecurityIntegration | undefined;
fleetServerHost: string;
}): EuiContainedStepProps => { }): EuiContainedStepProps => {
const nonCompleteStatus = selectedApiKeyId ? undefined : 'disabled'; const nonCompleteStatus = selectedApiKeyId ? undefined : 'disabled';
const status = isComplete ? 'complete' : nonCompleteStatus; const status = isComplete ? 'complete' : nonCompleteStatus;
@ -43,6 +45,7 @@ export const InstallCloudFormationManagedAgentStep = ({
<CloudFormationInstructions <CloudFormationInstructions
cloudSecurityIntegration={cloudSecurityIntegration} cloudSecurityIntegration={cloudSecurityIntegration}
enrollmentAPIKey={enrollToken} enrollmentAPIKey={enrollToken}
fleetServerHost={fleetServerHost}
/> />
) : ( ) : (
<React.Fragment /> <React.Fragment />

View file

@ -13,35 +13,31 @@ import type {
} from '../components/agent_enrollment_flyout/types'; } from '../components/agent_enrollment_flyout/types';
import { useAgentVersion } from './use_agent_version'; import { useAgentVersion } from './use_agent_version';
import { useGetSettings } from './use_request';
const CLOUD_FORMATION_DEFAULT_ACCOUNT_TYPE = 'single-account'; const CLOUD_FORMATION_DEFAULT_ACCOUNT_TYPE = 'single-account';
export const useCreateCloudFormationUrl = ({ export const useCreateCloudFormationUrl = ({
enrollmentAPIKey, enrollmentAPIKey,
cloudFormationProps, cloudFormationProps,
fleetServerHost,
}: { }: {
enrollmentAPIKey: string | undefined; enrollmentAPIKey?: string;
cloudFormationProps: CloudFormationProps | undefined; cloudFormationProps?: CloudFormationProps;
fleetServerHost?: string;
}) => { }) => {
const { data, isLoading } = useGetSettings();
const agentVersion = useAgentVersion(); const agentVersion = useAgentVersion();
let isError = false; let isError = false;
let error: string | undefined; let error: string | undefined;
// Default fleet server host if (!fleetServerHost) {
const fleetServerHost = data?.item.fleet_server_hosts?.[0];
if (!fleetServerHost && !isLoading) {
isError = true; isError = true;
error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noFleetServerHost', { error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noFleetServerHost', {
defaultMessage: 'No Fleet Server host found', defaultMessage: 'No Fleet Server host found',
}); });
} }
if (!enrollmentAPIKey && !isLoading) { if (!enrollmentAPIKey) {
isError = true; isError = true;
error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noApiKey', { error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noApiKey', {
defaultMessage: 'No enrollment token found', defaultMessage: 'No enrollment token found',
@ -60,7 +56,6 @@ export const useCreateCloudFormationUrl = ({
: undefined; : undefined;
return { return {
isLoading,
cloudFormationUrl, cloudFormationUrl,
isError, isError,
error, error,