Skip to content

Commit

Permalink
[8.x] [Cloud Security] Fleet validation using the RequiredVars and CS…
Browse files Browse the repository at this point in the history
…PM showing validation errors (#207130) (#208545)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Cloud Security] Fleet validation using the RequiredVars and CSPM
showing validation errors
(#207130)](#207130)

<!--- Backport version: 9.6.4 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT
[{"author":{"name":"seanrathier","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-01-28T06:18:50Z","message":"[Cloud
Security] Fleet validation using the RequiredVars and CSPM showing
validation errors
(#207130)","sha":"bec72f00ac2ccb3ee72661cdebbcc180b07f78f8","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Fleet","v9.0.0","Team:Cloud
Security","backport:prev-minor"],"title":"[Cloud Security] Fleet
validation using the RequiredVars and CSPM showing validation
errors","number":207130,"url":"https://github.com/elastic/kibana/pull/207130","mergeCommit":{"message":"[Cloud
Security] Fleet validation using the RequiredVars and CSPM showing
validation errors
(#207130)","sha":"bec72f00ac2ccb3ee72661cdebbcc180b07f78f8"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/207130","number":207130,"mergeCommit":{"message":"[Cloud
Security] Fleet validation using the RequiredVars and CSPM showing
validation errors
(#207130)","sha":"bec72f00ac2ccb3ee72661cdebbcc180b07f78f8"}}]}]
BACKPORT-->
  • Loading branch information
seanrathier authored Jan 28, 2025
1 parent 5340aed commit a00cde5
Show file tree
Hide file tree
Showing 21 changed files with 789 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import { safeLoad } from 'js-yaml';

import { installationStatuses } from '../constants';
import type { PackageInfo, NewPackagePolicy, RegistryPolicyTemplate } from '../types';
import type {
PackageInfo,
NewPackagePolicy,
RegistryPolicyTemplate,
NewPackagePolicyInputStream,
} from '../types';

import {
validatePackagePolicy,
Expand Down Expand Up @@ -775,6 +780,334 @@ describe('Fleet - validatePackagePolicy()', () => {
});
});

describe('Fleet - validateConditionalRequiredVars()', () => {
const createMockRequiredVarPackageInfo = (streams: unknown) => {
return {
name: 'mock-package',
title: 'Mock package',
version: '0.0.0',
description: 'description',
type: 'mock',
categories: [],
requirement: { kibana: { versions: '' }, elasticsearch: { versions: '' } },
format_version: '',
download: '',
path: '',
assets: {
kibana: {
dashboard: [],
visualization: [],
search: [],
'index-pattern': [],
},
},
status: installationStatuses.NotInstalled,
data_streams: [
{
dataset: 'foo',
streams,
},
{
dataset: 'bar',
streams: [
{
input: 'bar',
title: 'Bar',
vars: [
{ name: 'bar-name', type: 'text', required: true },
{ name: 'bar-age', type: 'text' },
],
},
{
input: 'with-no-stream-vars',
title: 'Bar stream no vars',
enabled: true,
},
],
},
],
policy_templates: [
{
name: 'pkgPolicy1',
title: 'Package policy 1',
description: 'test package policy',
inputs: [
{
type: 'foo',
title: 'Foo',
vars: [
{ default: 'foo-input-var-value', name: 'foo-input-var-name', type: 'text' },
{
default: 'foo-input2-var-value',
name: 'foo-input2-var-name',
required: true,
type: 'text',
},
{ name: 'foo-input3-var-name', type: 'text', required: true, multi: true },
],
},
{
type: 'bar',
title: 'Bar',
vars: [
{
default: ['value1', 'value2'],
name: 'bar-input-var-name',
type: 'text',
multi: true,
},
{ name: 'bar-input2-var-name', required: true, type: 'text' },
],
},
{
type: 'with-no-config-or-streams',
title: 'With no config or streams',
},
{
type: 'with-disabled-streams',
title: 'With disabled streams',
},
{
type: 'with-no-stream-vars',
enabled: true,
vars: [{ required: true, name: 'var-name', type: 'text' }],
},
],
},
],
} as unknown as PackageInfo;
};

const createPackagePolicyForRequiredVars = (streams: NewPackagePolicyInputStream[]) => {
return {
name: 'pkgPolicy1-1',
namespace: 'default',
policy_id: 'test-policy',
policy_ids: ['test-policy'],
enabled: true,
inputs: [
{
type: 'foo-input',
policy_template: 'pkgPolicy1',
enabled: true,
streams,
},
],
vars: {},
};
};

it('should return package policy validation error if invalid required_vars exist', () => {
const mockPackageInfoRequireVars = createMockRequiredVarPackageInfo([
{
title: 'Foo',
input: 'foo-input',
vars: [
{ name: 'foo-name', type: 'text' },
{ name: 'foo-age', type: 'text' },
],
required_vars: {
'foo-required-var-name': [{ name: 'foo-name' }, { name: 'foo-age', value: '1' }],
},
},
]);
const invalidPackagePolicyWithRequiredVars = createPackagePolicyForRequiredVars([
{
data_stream: { dataset: 'foo', type: 'logs' },
enabled: true,
vars: { 'foo-name': { type: 'text' }, 'foo-age': { type: 'text' } },
},
]);

const validationResults = validatePackagePolicy(
invalidPackagePolicyWithRequiredVars,
mockPackageInfoRequireVars,
safeLoad
);

expect(validationResults).toEqual(
expect.objectContaining({
inputs: {
'foo-input': {
streams: {
foo: {
required_vars: {
'foo-required-var-name': [
{ name: 'foo-name', invalid: true },
{ name: 'foo-age', invalid: true },
],
},
vars: {
'foo-name': null,
'foo-age': null,
},
},
},
},
},
})
);

expect(validationHasErrors(validationResults)).toBe(true);
});

it('should return package policy validation error if partial invalid required_vars exist', () => {
const mockPackageInfoRequireVars = createMockRequiredVarPackageInfo([
{
title: 'Foo',
input: 'foo-input',
vars: [
{ name: 'foo-name', type: 'text' },
{ name: 'foo-age', type: 'text' },
],
required_vars: {
'foo-required-var-name': [{ name: 'foo-name' }, { name: 'foo-age', value: '1' }],
},
},
]);
const invalidPackagePolicyWithRequiredVars = createPackagePolicyForRequiredVars([
{
data_stream: { dataset: 'foo', type: 'logs' },
enabled: true,
vars: { 'foo-name': { type: 'text' }, 'foo-age': { type: 'text', value: '1' } },
},
]);

const validationResults = validatePackagePolicy(
invalidPackagePolicyWithRequiredVars,
mockPackageInfoRequireVars,
safeLoad
);

expect(validationResults).toEqual(
expect.objectContaining({
inputs: {
'foo-input': {
streams: {
foo: {
required_vars: {
'foo-required-var-name': [{ name: 'foo-name', invalid: true }],
},
vars: {
'foo-name': null,
'foo-age': null,
},
},
},
},
},
})
);

expect(validationHasErrors(validationResults)).toBe(true);
});

it('should not return package policy validation errors if required_vars have existence and a value', () => {
const mockPackageInfoRequireVars = createMockRequiredVarPackageInfo([
{
title: 'Foo',
input: 'foo-input',
vars: [
{ name: 'foo-name', type: 'text' },
{ name: 'foo-age', type: 'text' },
],
required_vars: {
'foo-required-var-name': [{ name: 'foo-name' }, { name: 'foo-age', value: '1' }],
},
},
]);
const invalidPackagePolicyWithRequiredVars = createPackagePolicyForRequiredVars([
{
data_stream: { dataset: 'foo', type: 'logs' },
enabled: true,
vars: {
'foo-name': { type: 'text', value: 'Some name' },
'foo-age': { type: 'text', value: '1' },
},
},
]);

const validationResults = validatePackagePolicy(
invalidPackagePolicyWithRequiredVars,
mockPackageInfoRequireVars,
safeLoad
);

expect(validationResults).toEqual(
expect.objectContaining({
inputs: {
'foo-input': {
streams: {
foo: {
vars: {
'foo-name': null,
'foo-age': null,
},
},
},
},
},
})
);

expect(validationHasErrors(validationResults)).toBe(false);
});

it('should not return package policy validation errors if required_vars all have values', () => {
const mockPackageInfoRequireVars = createMockRequiredVarPackageInfo([
{
title: 'Foo',
input: 'foo-input',
vars: [
{ name: 'foo-name', type: 'text' },
{ name: 'foo-age', type: 'text' },
],
required_vars: {
'foo-required-var-name': [
{ name: 'foo-name', value: 'Some name' },
{ name: 'foo-age', value: '1' },
],
},
},
]);
const invalidPackagePolicyWithRequiredVars = createPackagePolicyForRequiredVars([
{
data_stream: { dataset: 'foo', type: 'logs' },
enabled: true,
vars: {
'foo-name': { type: 'text', value: 'Some name' },
'foo-age': { type: 'text', value: '1' },
},
},
]);

const validationResults = validatePackagePolicy(
invalidPackagePolicyWithRequiredVars,
mockPackageInfoRequireVars,
safeLoad
);

expect(validationResults).toEqual(
expect.objectContaining({
inputs: {
'foo-input': {
streams: {
foo: {
vars: {
'foo-name': null,
'foo-age': null,
},
},
},
},
},
})
);

expect(validationHasErrors(validationResults)).toBe(false);
});
});

describe('Fleet - validationHasErrors()', () => {
it('returns true for stream validation results with errors', () => {
expect(
Expand Down
Loading

0 comments on commit a00cde5

Please sign in to comment.