Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface SimplifiedPackagePolicy {
policy_id?: string | null;
policy_ids: string[];
output_id?: string;
cloud_connector_id?: string | null;
namespace: string;
name: string;
description?: string;
Expand Down Expand Up @@ -172,6 +173,7 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
vars: packageLevelVars,
supports_agentless: supportsAgentless,
supports_cloud_connector: supportsCloudConnector,
cloud_connector_id: cloudConnectorId,
additional_datastreams_permissions: additionalDatastreamsPermissions,
} = data;
const packagePolicy = {
Expand All @@ -184,6 +186,7 @@ export function simplifiedPackagePolicytoNewPackagePolicy(
),
supports_agentless: supportsAgentless,
supports_cloud_connector: supportsCloudConnector,
cloud_connector_id: cloudConnectorId,
output_id: outputId,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,15 @@ async function savePackagePolicy(pkgPolicy: CreatePackagePolicyRequest['body'])
export const updateAgentlessCloudConnectorConfig = (
packagePolicy: NewPackagePolicy,
newAgentPolicy: NewAgentPolicy,
setNewAgentPolicy: (policy: NewAgentPolicy) => void,
setPackagePolicy: (policy: NewPackagePolicy) => void
setNewAgentPolicy: (policy: NewAgentPolicy) => void
) => {
const input = packagePolicy.inputs?.filter(
(pinput: NewPackagePolicyInput) => pinput.enabled === true
)[0];

const enabled = input?.streams?.[0]?.vars?.['aws.supports_cloud_connectors']?.value;
if (
newAgentPolicy.agentless?.cloud_connectors?.enabled !== enabled &&
newAgentPolicy.agentless?.cloud_connectors?.enabled !==
packagePolicy.supports_cloud_connector &&
newAgentPolicy?.supports_agentless
) {
let targetCsp;
Expand All @@ -171,30 +170,22 @@ export const updateAgentlessCloudConnectorConfig = (
cloud_connectors: undefined,
},
});

setPackagePolicy({
...packagePolicy,
supports_cloud_connector: false,
});
return;
}

if (newAgentPolicy.agentless?.cloud_connectors?.enabled !== enabled) {
if (
newAgentPolicy.agentless?.cloud_connectors?.enabled !== packagePolicy.supports_cloud_connector
) {
setNewAgentPolicy({
...newAgentPolicy,
agentless: {
...newAgentPolicy.agentless,
cloud_connectors: {
enabled,
enabled: packagePolicy.supports_cloud_connector ?? false,
target_csp: targetCsp,
},
},
});

setPackagePolicy({
...packagePolicy,
supports_cloud_connector: true,
});
}
}
};
Expand Down Expand Up @@ -441,12 +432,7 @@ export function useOnSubmit({
}
}, [newInputs, prevSetupTechnology, selectedSetupTechnology, updatePackagePolicy, packagePolicy]);

updateAgentlessCloudConnectorConfig(
packagePolicy,
newAgentPolicy,
setNewAgentPolicy,
setPackagePolicy
);
updateAgentlessCloudConnectorConfig(packagePolicy, newAgentPolicy, setNewAgentPolicy);

const onSaveNavigate = useOnSaveNavigate({
queryParamsPolicyId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export {
INTEGRATIONS_PLUGIN_ID,
EPM_API_ROUTES,
AGENT_API_ROUTES,
CLOUD_CONNECTOR_API_ROUTES,
SO_SEARCH_LIMIT,
AGENT_POLICY_SAVED_OBJECT_TYPE,
LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE,
Expand Down
13 changes: 12 additions & 1 deletion x-pack/platform/plugins/shared/fleet/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ export const plugin = (initializerContext: PluginInitializerContext) => {
};

export type { NewPackagePolicy, KibanaSavedObjectType } from './types';
export type {
CloudConnectorSO,
CloudConnectorListOptions,
CreateCloudConnectorRequest,
CloudConnectorVars,
CloudConnectorVarsRecord,
CloudProvider,
CloudConnectorSecretVar,
CloudConnectorSecretVarValue,
AwsCloudConnectorVars,
} from './types';
export { SetupTechnology } from './types';
export {
SetupTechnologySelector,
Expand Down Expand Up @@ -61,7 +72,7 @@ export type {
UIExtensionsStorage,
} from './types/ui_extensions';

export { pagePathGetters, EPM_API_ROUTES } from './constants';
export { pagePathGetters, EPM_API_ROUTES, CLOUD_CONNECTOR_API_ROUTES } from './constants';
export { pkgKeyFromPackageInfo } from './services';
export type { CustomAssetsAccordionProps } from './components/custom_assets_accordion';
export { CustomAssetsAccordion } from './components/custom_assets_accordion';
Expand Down
6 changes: 6 additions & 0 deletions x-pack/platform/plugins/shared/fleet/server/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ export class CloudConnectorInvalidVarsError extends FleetError {
}
}

export class CloudConnectorUpdateError extends FleetError {
constructor(message: string) {
super(`Error updating cloud connector in Fleet, ${message}`);
}
}

export class AgentPolicyNameExistsError extends AgentPolicyError {}
export class AgentReassignmentError extends FleetError {}
export class PackagePolicyIneligibleForUpgradeError extends FleetError {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,42 @@ export const getCloudConnectorsHandler: FleetRequestHandler<
});
}
};

export interface UpdateCloudConnectorRequest {
name?: string;
vars?: CloudConnectorVars;
cloudProvider?: CloudProvider;
packagePolicyCount?: number;
updated_at?: string;
}

export const updateCloudConnectorHandler: FleetRequestHandler<
{ id: string },
undefined,
UpdateCloudConnectorRequest
> = async (context, request, response) => {
const fleetContext = await context.fleet;
const { internalSoClient } = fleetContext;
const logger = appContextService
.getLogger()
.get('CloudConnectorService updateCloudConnectorHandler');

try {
logger.info(`Updating cloud connector with id: ${request.params.id}`);
const cloudConnector = await cloudConnectorService.update(
internalSoClient,
request.params.id,
request.body
);
logger.info('Successfully updated cloud connector');
return response.ok({ body: cloudConnector });
} catch (error) {
logger.error('Failed to update cloud connector', error.message);
return response.customError({
statusCode: 400,
body: {
message: error.message,
},
});
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-ser
import type {
CloudConnectorSO,
CloudConnectorListOptions,
CloudConnectorSecretVarValue,
CloudConnectorSecretReference,
} from '../../common/types/models/cloud_connector';
import type { CloudConnectorSOAttributes } from '../types/so_attributes';
import type { CreateCloudConnectorRequest } from '../routes/cloud_connector/handlers';
import type {
CreateCloudConnectorRequest,
UpdateCloudConnectorRequest,
} from '../routes/cloud_connector/handlers';
import { CLOUD_CONNECTOR_SAVED_OBJECT_TYPE } from '../../common/constants';

import {
CloudConnectorCreateError,
CloudConnectorGetListError,
CloudConnectorInvalidVarsError,
CloudConnectorUpdateError,
} from '../errors';

import { appContextService } from './app_context';
Expand All @@ -34,6 +38,11 @@ export interface CloudConnectorServiceInterface {
soClient: SavedObjectsClientContract,
options?: CloudConnectorListOptions
): Promise<CloudConnectorSO[]>;
update(
soClient: SavedObjectsClientContract,
id: string,
cloudConnector: UpdateCloudConnectorRequest
): Promise<CloudConnectorSO>;
}

export class CloudConnectorService implements CloudConnectorServiceInterface {
Expand Down Expand Up @@ -138,6 +147,59 @@ export class CloudConnectorService implements CloudConnectorServiceInterface {
}
}

async update(
soClient: SavedObjectsClientContract,
id: string,
cloudConnector: UpdateCloudConnectorRequest
): Promise<CloudConnectorSO> {
const logger = this.getLogger('update');

try {
logger.info(`Updating cloud connector with id: ${id}`);

// Get the existing cloud connector
const existingCloudConnector = await soClient.get<CloudConnectorSOAttributes>(
CLOUD_CONNECTOR_SAVED_OBJECT_TYPE,
id
);

// Validate the update request if vars are provided
if (cloudConnector.vars) {
this.validateCloudConnectorDetails({
name: cloudConnector.name || existingCloudConnector.attributes.name,
vars: cloudConnector.vars,
cloudProvider:
cloudConnector.cloudProvider || existingCloudConnector.attributes.cloudProvider,
});
}

// Prepare the update attributes
const updateAttributes: Partial<CloudConnectorSOAttributes> = {
updated_at: new Date().toISOString(),
};

// Update the cloud connector
const updatedSavedObject = await soClient.update<CloudConnectorSOAttributes>(
CLOUD_CONNECTOR_SAVED_OBJECT_TYPE,
id,
{ ...updateAttributes, ...cloudConnector }
);

logger.info(`Successfully updated cloud connector with id: ${id}`);

return {
id: updatedSavedObject.id,
...existingCloudConnector.attributes,
...updatedSavedObject.attributes,
};
} catch (error) {
logger.error(`Failed to update cloud connector with id: ${id}`, error.message);
throw new CloudConnectorUpdateError(
`CloudConnectorService Failed to update cloud connector: ${error.message}\n${error.stack}`
);
}
}

private validateCloudConnectorDetails(cloudConnector: CreateCloudConnectorRequest) {
const logger = this.getLogger('validate cloud connector details');
const vars = cloudConnector.vars;
Expand All @@ -152,7 +214,7 @@ export class CloudConnectorService implements CloudConnectorServiceInterface {

// Check for AWS variables
if (roleArn) {
const externalId: CloudConnectorSecretVarValue | undefined = vars.external_id?.value;
const externalId: CloudConnectorSecretReference | undefined = vars.external_id?.value;

if (!externalId) {
logger.error('Package policy must contain valid external_id secret reference');
Expand Down
Loading