-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fleet] Show pipelines and mappings editor for input packages #154077
Changes from 8 commits
59ab0f7
8d39052
e225d26
0586cec
e4d81c5
a44dd61
e572506
061f280
e2fde5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { | ||
ADD_INTEGRATION_POLICY_BTN, | ||
CREATE_PACKAGE_POLICY_SAVE_BTN, | ||
INTEGRATION_NAME_LINK, | ||
POLICY_EDITOR, | ||
} from '../screens/integrations'; | ||
import { EXISTING_HOSTS_TAB } from '../screens/fleet'; | ||
import { CONFIRM_MODAL } from '../screens/navigation'; | ||
|
||
const TEST_PACKAGE = 'input_package-1.0.0'; | ||
const agentPolicyId = 'test-input-package-policy'; | ||
const agentPolicyName = 'Test input package policy'; | ||
const inputPackagePolicyName = 'input-package-policy'; | ||
|
||
function editPackagePolicyandShowAdvanced() { | ||
cy.visit(`/app/integrations/detail/${TEST_PACKAGE}/policies`); | ||
|
||
cy.getBySel(INTEGRATION_NAME_LINK).contains(inputPackagePolicyName).click(); | ||
|
||
cy.get('button').contains('Change defaults').click(); | ||
cy.get('[data-test-subj^="advancedStreamOptionsToggle"]').click(); | ||
} | ||
describe('Input package create and edit package policy', () => { | ||
before(() => { | ||
cy.task('installTestPackage', TEST_PACKAGE); | ||
|
||
cy.request({ | ||
method: 'POST', | ||
url: `/api/fleet/agent_policies`, | ||
body: { | ||
id: agentPolicyId, | ||
name: agentPolicyName, | ||
description: 'desc', | ||
namespace: 'default', | ||
monitoring_enabled: [], | ||
}, | ||
headers: { 'kbn-xsrf': 'cypress' }, | ||
}); | ||
}); | ||
after(() => { | ||
// delete agent policy | ||
cy.request({ | ||
method: 'POST', | ||
url: `/api/fleet/agent_policies/delete`, | ||
headers: { 'kbn-xsrf': 'cypress' }, | ||
body: JSON.stringify({ | ||
agentPolicyId, | ||
}), | ||
}); | ||
cy.task('uninstallTestPackage', TEST_PACKAGE); | ||
}); | ||
it('should successfully create a package policy', () => { | ||
cy.visit(`/app/integrations/detail/${TEST_PACKAGE}/overview`); | ||
cy.getBySel(ADD_INTEGRATION_POLICY_BTN).click(); | ||
|
||
cy.getBySel(POLICY_EDITOR.POLICY_NAME_INPUT).click().clear().type(inputPackagePolicyName); | ||
cy.getBySel('multiTextInput-paths') | ||
.find('[data-test-subj="multiTextInputRow-0"]') | ||
.click() | ||
.type('/var/log/test.log'); | ||
|
||
cy.getBySel('multiTextInput-tags') | ||
.find('[data-test-subj="multiTextInputRow-0"]') | ||
.click() | ||
.type('tag1'); | ||
|
||
cy.getBySel(POLICY_EDITOR.DATASET_SELECT).click().type('testdataset'); | ||
|
||
cy.getBySel(EXISTING_HOSTS_TAB).click(); | ||
|
||
cy.getBySel(POLICY_EDITOR.AGENT_POLICY_SELECT).click().get(`#${agentPolicyId}`).click(); | ||
cy.wait(500); // wait for policy id to be set | ||
cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); | ||
|
||
cy.getBySel(CONFIRM_MODAL.CANCEL_BUTTON).click(); | ||
}); | ||
|
||
it('should show pipelines editor with link to pipeline', () => { | ||
editPackagePolicyandShowAdvanced(); | ||
cy.getBySel(POLICY_EDITOR.INSPECT_PIPELINES_BTN).click(); | ||
cy.getBySel(CONFIRM_MODAL.CONFIRM_BUTTON).click(); | ||
cy.get('body').should('not.contain', 'Pipeline not found'); | ||
cy.get('body').should('contain', '"managed_by": "fleet"'); | ||
}); | ||
it('should show mappings editor with link to create custom template', () => { | ||
editPackagePolicyandShowAdvanced(); | ||
cy.getBySel(POLICY_EDITOR.EDIT_MAPPINGS_BTN).click(); | ||
cy.getBySel(CONFIRM_MODAL.CONFIRM_BUTTON).click(); | ||
cy.get('body').should('contain', 'logs-testdataset@custom'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,42 @@ | |
* 2.0. | ||
*/ | ||
|
||
import { promisify } from 'util'; | ||
|
||
import fs from 'fs'; | ||
|
||
import fetch from 'node-fetch'; | ||
import { createEsClientForTesting } from '@kbn/test'; | ||
|
||
const plugin: Cypress.PluginConfig = (on, config) => { | ||
const client = createEsClientForTesting({ | ||
esUrl: config.env.ELASTICSEARCH_URL, | ||
}); | ||
|
||
async function kibanaFetch(opts: { | ||
method: string; | ||
path: string; | ||
body?: any; | ||
contentType?: string; | ||
}) { | ||
const { method, path, body, contentType } = opts; | ||
const Authorization = `Basic ${Buffer.from( | ||
`elastic:${config.env.ELASTICSEARCH_PASSWORD}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does anyone know how to add an env var with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you tried |
||
).toString('base64')}`; | ||
|
||
const url = `${config.env.KIBANA_URL}${path}`; | ||
const res = await fetch(url, { | ||
method, | ||
headers: { | ||
'kbn-xsrf': 'cypress', | ||
'Content-Type': contentType || 'application/json', | ||
Authorization, | ||
}, | ||
...(body ? { body } : {}), | ||
}); | ||
|
||
return res.json(); | ||
} | ||
on('task', { | ||
async insertDoc({ index, doc, id }: { index: string; doc: any; id: string }) { | ||
return client.create({ id, document: doc, index, refresh: 'wait_for' }); | ||
|
@@ -37,6 +67,23 @@ const plugin: Cypress.PluginConfig = (on, config) => { | |
conflicts: 'proceed', | ||
}); | ||
}, | ||
async installTestPackage(packageName: string) { | ||
const zipPath = require.resolve('../packages/' + packageName + '.zip'); | ||
const zipContent = await promisify(fs.readFile)(zipPath, 'base64'); | ||
return kibanaFetch({ | ||
method: 'POST', | ||
path: '/api/fleet/epm/packages', | ||
body: Buffer.from(zipContent, 'base64'), | ||
contentType: 'application/zip', | ||
}); | ||
}, | ||
|
||
async uninstallTestPackage(packageName: string) { | ||
return kibanaFetch({ | ||
method: 'DELETE', | ||
path: `/api/fleet/epm/packages/${packageName}`, | ||
}); | ||
}, | ||
}); | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,9 @@ | |
*/ | ||
|
||
import { useRouteMatch } from 'react-router-dom'; | ||
import { useQuery } from '@tanstack/react-query'; | ||
|
||
import { useLink } from '../../../../hooks'; | ||
import { sendRequestForRq, useLink } from '../../../../hooks'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! |
||
|
||
export function usePackagePolicyEditorPageUrl(dataStreamId?: string) { | ||
const { | ||
|
@@ -27,3 +28,32 @@ export function usePackagePolicyEditorPageUrl(dataStreamId?: string) { | |
|
||
return `${baseUrl}${dataStreamId ? `?datastreamId=${encodeURIComponent(dataStreamId)}` : ''}`; | ||
} | ||
|
||
export function useIndexTemplateExists( | ||
templateName: string, | ||
enabled: boolean | ||
): { | ||
exists?: boolean; | ||
isLoading: boolean; | ||
} { | ||
const { data, isLoading } = useQuery( | ||
['indexTemplateExists', templateName], | ||
() => | ||
sendRequestForRq({ | ||
path: `/api/index_management/index_templates/${templateName}`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if this is the best way to call another Kibana API directly or use a service/hook from the index management plugin. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've just had a go at this but it creates a cyclic dependency in the plugins so I'm going to leave it as it is. |
||
method: 'get', | ||
}), | ||
{ enabled: enabled || !!templateName } | ||
); | ||
|
||
if (isLoading) { | ||
return { | ||
isLoading: true, | ||
}; | ||
} | ||
|
||
return { | ||
exists: !!data, | ||
isLoading: false, | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,11 @@ import { usePackagePolicyEditorPageUrl } from './datastream_hooks'; | |
|
||
export interface PackagePolicyEditorDatastreamMappingsProps { | ||
packageInfo: PackageInfo; | ||
packageInputStream: { id?: string; data_stream: { dataset: string; type: string } }; | ||
packageInputStream: { | ||
id?: string; | ||
data_stream: { dataset: string; type: string }; | ||
}; | ||
customDataset?: string; | ||
} | ||
|
||
function useComponentTemplates(dataStream: { dataset: string; type: string }) { | ||
|
@@ -35,8 +39,10 @@ function useComponentTemplates(dataStream: { dataset: string; type: string }) { | |
|
||
export const PackagePolicyEditorDatastreamMappings: React.FunctionComponent< | ||
PackagePolicyEditorDatastreamMappingsProps | ||
> = ({ packageInputStream, packageInfo }) => { | ||
const dataStream = packageInputStream.data_stream; | ||
> = ({ packageInputStream, packageInfo, customDataset }) => { | ||
const dataStream = customDataset | ||
? { ...packageInputStream.data_stream, dataset: customDataset } | ||
: packageInputStream.data_stream; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe you could extract this ternary in a small function to be reused below, since it's the same code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think for just 2 uses I'm going to keep it as is as it's not likely to be used anywhere else in the future |
||
const pageUrl = usePackagePolicyEditorPageUrl(packageInputStream.id); | ||
|
||
const { application, docLinks } = useStartServices(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding these tests Mark!