[Fleet] Allow to overrides agent policy (#159414)

This commit is contained in:
Nicolas Chaulet 2023-06-14 08:39:50 -04:00 committed by GitHub
parent 8ac83df620
commit 92eb219ef0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 130 additions and 4 deletions

View file

@ -1572,6 +1572,10 @@
},
"is_protected": {
"type": "boolean"
},
"overrides": {
"type": "flattened",
"index": false
}
}
},

View file

@ -103,7 +103,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
"index-pattern": "997108a9ea1e8076e22231e1c95517cdb192b9c5",
"infrastructure-monitoring-log-view": "5f86709d3c27aed7a8379153b08ee5d3d90d77f5",
"infrastructure-ui-source": "113182d6895764378dfe7fa9fa027244f3a457c4",
"ingest-agent-policies": "8a91f7b9507605222901543167f48c313591daec",
"ingest-agent-policies": "f11cc19275f4c3e4ee7c5cd6423b6706b21b989d",
"ingest-download-sources": "d7edc5e588d9afa61c4b831604582891c54ef1c7",
"ingest-outputs": "3f1e998887d48a706333b67885d1ad8f3217cd90",
"ingest-package-policies": "7d0e8d288e193e0a8a153bb420c6056bc862c4c3",

View file

@ -6826,7 +6826,7 @@
"type": "number"
},
"package_policies": {
"description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policy with the ?full=true parameter",
"description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter",
"type": "array",
"items": {
"$ref": "#/components/schemas/package_policy"
@ -6866,6 +6866,11 @@
"is_protected": {
"description": "Indicates whether the agent policy has tamper protection enabled. Default false.",
"type": "boolean"
},
"overrides": {
"type": "object",
"description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.",
"nullable": true
}
},
"required": [

View file

@ -4364,7 +4364,8 @@ components:
package_policies:
description: >-
This field is present only when retrieving a single agent policy, or
when retrieving a list of agent policy with the ?full=true parameter
when retrieving a list of agent policies with the ?full=true
parameter
type: array
items:
$ref: '#/components/schemas/package_policy'
@ -4394,6 +4395,13 @@ components:
Indicates whether the agent policy has tamper protection enabled.
Default false.
type: boolean
overrides:
type: object
description: >-
Override settings that are defined in the agent policy. Input
settings cannot be overridden. The override option should be used
only in unusual circumstances and not as a routine procedure.
nullable: true
required:
- id
- status

View file

@ -33,7 +33,7 @@ properties:
inactivity_timeout:
type: number
package_policies:
description: This field is present only when retrieving a single agent policy, or when retrieving a list of agent policy with the ?full=true parameter
description: This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter
type: array
items:
$ref: ./package_policy.yaml
@ -61,6 +61,10 @@ properties:
is_protected:
description: Indicates whether the agent policy has tamper protection enabled. Default false.
type: boolean
overrides:
type: object
description: Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.
nullable: true
required:
- id
- status

View file

@ -34,6 +34,7 @@ export interface NewAgentPolicy {
schema_version?: string;
agent_features?: Array<{ name: string; enabled: boolean }>;
is_protected?: boolean;
overrides?: { [key: string]: any } | null;
}
// SO definition for this type is declared in server/types/interfaces

View file

@ -125,6 +125,7 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({
},
},
is_protected: { type: 'boolean' },
overrides: { type: 'flattened', index: false },
},
},
migrations: {

View file

@ -7,6 +7,7 @@
import type { SavedObjectsClientContract } from '@kbn/core/server';
import { safeLoad } from 'js-yaml';
import deepMerge from 'deepmerge';
import type {
FullAgentPolicy,
@ -216,6 +217,10 @@ export async function getFullAgentPolicy(
};
}
if (agentPolicy.overrides) {
return deepMerge<FullAgentPolicy>(fullAgentPolicy, agentPolicy.overrides);
}
return fullAgentPolicy;
}

View file

@ -48,6 +48,17 @@ export const AgentPolicyBaseSchema = {
)
),
is_protected: schema.maybe(schema.boolean()),
overrides: schema.maybe(
schema.nullable(
schema.recordOf(schema.string(), schema.any(), {
validate: (val) => {
if (Object.keys(val).some((key) => key.match(/^inputs(\.)?/))) {
return 'inputs overrides is not allowed';
}
},
})
)
),
};
export const NewAgentPolicySchema = schema.object({

View file

@ -52,6 +52,7 @@ export interface AgentPolicySOAttributes {
status: ValueOf<AgentPolicyStatus>;
package_policies?: PackagePolicy[];
agents?: number;
overrides?: any | null;
}
export interface AgentSOAttributes {

View file

@ -865,6 +865,92 @@ export default function (providerContext: FtrProviderContext) {
.map((item: any) => item.name);
expect(installedPackagesAfterUpdate).to.contain('elastic_agent');
});
it('should allow to set overrides', async () => {
const {
body: { item: originalPolicy },
} = await supertest
.post(`/api/fleet/agent_policies`)
.set('kbn-xsrf', 'xxxx')
.send({
name: `Override Test ${Date.now()}`,
description: 'Initial description',
namespace: 'default',
})
.expect(200);
agentPolicyId = originalPolicy.id;
createdPolicyIds.push(agentPolicyId as string);
const {
body: { item: updatedPolicy },
} = await supertest
.put(`/api/fleet/agent_policies/${agentPolicyId}`)
.set('kbn-xsrf', 'xxxx')
.send({
name: originalPolicy.name,
description: originalPolicy.description,
namespace: 'default',
overrides: {
agent: {
logging: {
level: 'debug',
},
},
},
})
.expect(200);
// eslint-disable-next-line @typescript-eslint/naming-convention
const { id, updated_at, ...newPolicy } = updatedPolicy;
expect(newPolicy).to.eql({
status: 'active',
name: originalPolicy.name,
description: originalPolicy.description,
namespace: 'default',
is_managed: false,
revision: 2,
schema_version: FLEET_AGENT_POLICIES_SCHEMA_VERSION,
updated_by: 'elastic',
inactivity_timeout: 1209600,
package_policies: [],
is_protected: false,
overrides: {
agent: {
logging: {
level: 'debug',
},
},
},
});
});
it('should not allow to set inputs inside overrides', async () => {
const {
body: { item: originalPolicy },
} = await supertest
.post(`/api/fleet/agent_policies`)
.set('kbn-xsrf', 'xxxx')
.send({
name: `Override Test ${Date.now()}`,
description: 'Initial description',
namespace: 'default',
})
.expect(200);
agentPolicyId = originalPolicy.id;
createdPolicyIds.push(agentPolicyId as string);
await supertest
.put(`/api/fleet/agent_policies/${agentPolicyId}`)
.set('kbn-xsrf', 'xxxx')
.send({
name: `Override Test ${Date.now()}`,
description: 'Updated description',
namespace: 'default',
overrides: {
inputs: [],
},
})
.expect(400);
});
});
describe('POST /api/fleet/agent_policies/delete', () => {