mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Osquery cypress optimizations (#152332)
This PR refactors Osquery E2E tests in a way that makes all the tests "stand alone". Up until now we were passing state between suites that made them dependant on each other (i.e. tests further down the line were expecting artifacts to be created by previous ones). From now on, each suite creates all the needed artifacts on its own and removes them once completed. Since there are no longer any dependencies between tests, each and every one can be run independently. Additionally we have dropped Kibana archiver in favour of api calls. --------- Co-authored-by: Tomasz Ciecierski <ciecierskitomek@gmail.com> Co-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
56a785198a
commit
8eb73eab9f
114 changed files with 2598 additions and 2621 deletions
|
@ -33,5 +33,8 @@ export default defineCypressConfig({
|
|||
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:5601',
|
||||
experimentalRunAllSpecs: true,
|
||||
experimentalMemoryManagement: true,
|
||||
numTestsKeptInMemory: 10,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,23 +6,39 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
cleanupPack,
|
||||
cleanupAgentPolicy,
|
||||
cleanupSavedQuery,
|
||||
loadSavedQuery,
|
||||
} from '../../tasks/api_fixtures';
|
||||
import { CREATE_PACKAGE_POLICY_SAVE_BTN } from '../../screens/integrations';
|
||||
import {
|
||||
createOldOsqueryPath,
|
||||
FLEET_AGENT_POLICIES,
|
||||
NAV_SEARCH_INPUT_OSQUERY_RESULTS,
|
||||
navigateTo,
|
||||
OLD_OSQUERY_MANAGER,
|
||||
OSQUERY,
|
||||
} from '../../tasks/navigation';
|
||||
import { addIntegration, closeModalIfVisible, closeToastIfVisible } from '../../tasks/integrations';
|
||||
import {
|
||||
addCustomIntegration,
|
||||
closeModalIfVisible,
|
||||
generateRandomStringName,
|
||||
integrationExistsWithinPolicyDetails,
|
||||
interceptPackId,
|
||||
interceptAgentPolicyId,
|
||||
policyContainsIntegration,
|
||||
} from '../../tasks/integrations';
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { findAndClickButton, findFormFieldByRowsLabelAndType } from '../../tasks/live_query';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { DEFAULT_POLICY, OSQUERY_POLICY } from '../../screens/fleet';
|
||||
|
||||
describe('ALL - Add Integration', () => {
|
||||
const integration = 'Osquery Manager';
|
||||
let savedQueryId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -30,142 +46,166 @@ describe('ALL - Add Integration', () => {
|
|||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
});
|
||||
|
||||
it('validate osquery is not available and nav search links to integration', () => {
|
||||
cy.visit(OSQUERY);
|
||||
cy.intercept('GET', '**/internal/osquery/status', (req) => {
|
||||
req.continue((res) => res.send({ ...res.body, install_status: undefined }));
|
||||
});
|
||||
cy.contains('Add this integration to run and schedule queries for Elastic Agent.');
|
||||
cy.contains('Add Osquery Manager');
|
||||
cy.getBySel('osquery-add-integration-button');
|
||||
cy.getBySel('nav-search-input').type('Osquery');
|
||||
cy.get('[title="Osquery • Management"]').should('exist');
|
||||
cy.get('[title="Osquery Logs • Integration"]').should('exist');
|
||||
cy.get('[title="Osquery Manager • Integration"]').should('exist').click();
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.MANAGEMENT}"]`).should('exist');
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.LOGS}"]`).should('exist');
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.MANAGER}"]`).should('exist').click();
|
||||
});
|
||||
|
||||
it.skip('should add the old integration and be able to upgrade it', () => {
|
||||
describe('Add and upgrade integration', () => {
|
||||
const oldVersion = '0.7.4';
|
||||
const [integrationName, policyName] = generateRandomStringName(2);
|
||||
let policyId: string;
|
||||
|
||||
cy.visit(OLD_OSQUERY_MANAGER);
|
||||
addIntegration();
|
||||
cy.contains('osquery_manager-1');
|
||||
cy.visit('app/fleet/policies');
|
||||
cy.contains(/^Default Fleet Server policy$/).click();
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('View policy').click();
|
||||
cy.contains('name: osquery_manager-1');
|
||||
cy.contains(`version: ${oldVersion}`);
|
||||
cy.get('.euiFlyoutFooter').within(() => {
|
||||
cy.contains('Close').click();
|
||||
before(() => {
|
||||
interceptAgentPolicyId((agentPolicyId) => {
|
||||
policyId = agentPolicyId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cleanupAgentPolicy(policyId);
|
||||
});
|
||||
|
||||
it('should add the old integration and be able to upgrade it', () => {
|
||||
cy.visit(createOldOsqueryPath(oldVersion));
|
||||
addCustomIntegration(integrationName, policyName);
|
||||
cy.contains(integrationName);
|
||||
policyContainsIntegration(integrationName, policyName);
|
||||
cy.contains(`version: ${oldVersion}`);
|
||||
cy.getBySel('euiFlyoutCloseButton').click();
|
||||
cy.getBySel('PackagePoliciesTableUpgradeButton').click();
|
||||
cy.getBySel('saveIntegration').click();
|
||||
cy.contains(`Successfully updated '${integrationName}'`);
|
||||
policyContainsIntegration(integrationName, policyName);
|
||||
cy.contains(`version: ${oldVersion}`).should('not.exist');
|
||||
});
|
||||
cy.contains(/^Osquery Manager$/).click();
|
||||
cy.contains(/^Settings$/).click();
|
||||
cy.contains(/^Upgrade to latest version$/).click();
|
||||
closeModalIfVisible();
|
||||
cy.contains('Updated Osquery Manager and upgraded policies', { timeout: 60000 });
|
||||
cy.visit('app/fleet/policies');
|
||||
cy.contains(/^Default Fleet Server policy$/).click();
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('View policy').click();
|
||||
cy.contains('name: osquery_manager-1');
|
||||
cy.contains(`version: ${oldVersion}`).should('not.exist');
|
||||
cy.visit('app/integrations/detail/osquery_manager/policies');
|
||||
cy.contains('Loading integration policies').should('exist');
|
||||
cy.contains('Loading integration policies').should('not.exist');
|
||||
cy.getBySel('integrationPolicyTable')
|
||||
.get('.euiTableRow', { timeout: 60000 })
|
||||
.should('have.lengthOf.above', 0);
|
||||
cy.get('.euiTableCellContent').get('.euiPopover__anchor').get(`[aria-label="Open"]`).click();
|
||||
cy.contains(/^Delete integration$/).click();
|
||||
closeModalIfVisible();
|
||||
cy.contains(/^Deleted integration 'osquery_manager-1'$/);
|
||||
cy.contains(/^Settings$/).click();
|
||||
cy.contains(/^Uninstall Osquery Manager$/).click();
|
||||
closeModalIfVisible();
|
||||
cy.contains(/^Successfully uninstalled Osquery Manager$/);
|
||||
});
|
||||
|
||||
it('add integration', () => {
|
||||
cy.visit(FLEET_AGENT_POLICIES);
|
||||
cy.contains(DEFAULT_POLICY).click();
|
||||
cy.contains('Add integration').click();
|
||||
cy.contains(integration).click();
|
||||
addIntegration();
|
||||
cy.contains('osquery_manager-');
|
||||
closeToastIfVisible();
|
||||
cy.visit(OSQUERY);
|
||||
cy.contains('Live queries history');
|
||||
describe('Add integration to policy', () => {
|
||||
const [integrationName, policyName] = generateRandomStringName(2);
|
||||
let policyId: string;
|
||||
|
||||
before(() => {
|
||||
interceptAgentPolicyId((agentPolicyId) => {
|
||||
policyId = agentPolicyId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cleanupAgentPolicy(policyId);
|
||||
});
|
||||
|
||||
it('add integration', () => {
|
||||
cy.visit(FLEET_AGENT_POLICIES);
|
||||
cy.getBySel('createAgentPolicyButton').click();
|
||||
cy.getBySel('createAgentPolicyNameField').type(policyName);
|
||||
cy.getBySel('createAgentPolicyFlyoutBtn').click();
|
||||
cy.getBySel('agentPolicyNameLink').contains(policyName).click();
|
||||
cy.getBySel('addPackagePolicyButton').click();
|
||||
cy.getBySel('integration-card:epr:osquery_manager').click();
|
||||
cy.getBySel('addIntegrationPolicyButton').click();
|
||||
cy.getBySel('agentPolicySelect').within(() => {
|
||||
cy.contains(policyName);
|
||||
});
|
||||
cy.getBySel('packagePolicyNameInput')
|
||||
.wait(500)
|
||||
.type(`{selectall}{backspace}${integrationName}`);
|
||||
cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click();
|
||||
cy.getBySel('confirmModalCancelButton').click();
|
||||
cy.get(`[title="${integrationName}"]`).should('exist');
|
||||
cy.visit(OSQUERY);
|
||||
cy.contains('Live queries history');
|
||||
});
|
||||
});
|
||||
|
||||
it(`add integration to ${OSQUERY_POLICY}`, () => {
|
||||
cy.visit(FLEET_AGENT_POLICIES);
|
||||
cy.contains(OSQUERY_POLICY).click();
|
||||
cy.contains('Add integration').click();
|
||||
cy.contains(integration).click();
|
||||
addIntegration(OSQUERY_POLICY);
|
||||
cy.contains('osquery_manager-');
|
||||
});
|
||||
|
||||
it('should have integration and packs copied when upgrading integration', () => {
|
||||
const packageName = 'osquery_manager';
|
||||
describe('Upgrade policy with existing packs', () => {
|
||||
const oldVersion = '1.2.0';
|
||||
const [policyName, integrationName, packName] = generateRandomStringName(3);
|
||||
let policyId: string;
|
||||
let packId: string;
|
||||
|
||||
cy.visit(`app/integrations/detail/${packageName}-${oldVersion}/overview`);
|
||||
cy.contains('Add Osquery Manager').click();
|
||||
cy.contains('Save and continue').click();
|
||||
cy.contains('Add Elastic Agent later').click();
|
||||
cy.contains('Upgrade');
|
||||
cy.contains('Agent policy 1').click();
|
||||
cy.get('tr')
|
||||
.should('contain', 'osquery_manager-3')
|
||||
.and('contain', 'Osquery Manager')
|
||||
.and('contain', `v${oldVersion}`);
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('View policy').click();
|
||||
cy.contains('name: osquery_manager-3');
|
||||
cy.contains(`version: ${oldVersion}`);
|
||||
cy.get('.euiFlyoutFooter').within(() => {
|
||||
cy.contains('Close').click();
|
||||
before(() => {
|
||||
interceptAgentPolicyId((agentPolicyId) => {
|
||||
policyId = agentPolicyId;
|
||||
});
|
||||
interceptPackId((pack) => {
|
||||
packId = pack;
|
||||
});
|
||||
});
|
||||
navigateTo('app/osquery/packs');
|
||||
findAndClickButton('Add pack');
|
||||
findFormFieldByRowsLabelAndType('Name', 'Integration');
|
||||
findFormFieldByRowsLabelAndType(
|
||||
'Scheduled agent policies (optional)',
|
||||
'Agent policy 1 {downArrow} {enter}'
|
||||
);
|
||||
findAndClickButton('Add query');
|
||||
cy.react('EuiComboBox', {
|
||||
props: { placeholder: 'Search for a query to run, or write a new query below' },
|
||||
})
|
||||
.click()
|
||||
.type('{downArrow} {enter}');
|
||||
cy.contains(/^Save$/).click();
|
||||
cy.contains(/^Save pack$/).click();
|
||||
cy.contains(/^Successfully created "Integration" pack$/).click();
|
||||
cy.visit('app/fleet/policies');
|
||||
cy.contains('Agent policy 1').click();
|
||||
cy.contains('Upgrade').click();
|
||||
cy.contains(/^Advanced$/).click();
|
||||
cy.contains('"Integration":');
|
||||
cy.contains(/^Upgrade integration$/).click();
|
||||
cy.contains(/^osquery_manager-3$/).click();
|
||||
cy.contains(/^Advanced$/).click();
|
||||
cy.contains('"Integration":');
|
||||
cy.contains('Cancel').click();
|
||||
closeModalIfVisible();
|
||||
cy.get('tr')
|
||||
.should('contain', 'osquery_manager-3')
|
||||
.and('contain', 'Osquery Manager')
|
||||
.and('contain', 'v')
|
||||
.and('not.contain', `v${oldVersion}`);
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('View policy').click();
|
||||
cy.contains('name: osquery_manager-3');
|
||||
|
||||
// test list of prebuilt queries
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.waitForReact();
|
||||
cy.react('EuiTableRow').should('have.length.above', 5);
|
||||
after(() => {
|
||||
cleanupPack(packId);
|
||||
cleanupAgentPolicy(policyId);
|
||||
});
|
||||
|
||||
it('should have integration and packs copied when upgrading integration', () => {
|
||||
cy.visit(`app/integrations/detail/osquery_manager-${oldVersion}/overview`);
|
||||
addCustomIntegration(integrationName, policyName);
|
||||
cy.getBySel('integrationPolicyUpgradeBtn');
|
||||
cy.get(`[title="${policyName}"]`).click();
|
||||
cy.get(`[title="${integrationName}"]`)
|
||||
.parents('tr')
|
||||
.within(() => {
|
||||
cy.contains('Osquery Manager');
|
||||
cy.getBySel('PackagePoliciesTableUpgradeButton');
|
||||
cy.contains(`v${oldVersion}`);
|
||||
cy.getBySel('agentActionsBtn').click();
|
||||
});
|
||||
integrationExistsWithinPolicyDetails(integrationName);
|
||||
cy.contains(`version: ${oldVersion}`);
|
||||
cy.getBySel('euiFlyoutCloseButton').click();
|
||||
|
||||
navigateTo('app/osquery/packs');
|
||||
findAndClickButton('Add pack');
|
||||
findFormFieldByRowsLabelAndType('Name', packName);
|
||||
findFormFieldByRowsLabelAndType(
|
||||
'Scheduled agent policies (optional)',
|
||||
`${policyName} {downArrow}{enter}{esc}`
|
||||
);
|
||||
findAndClickButton('Add query');
|
||||
cy.getBySel('savedQuerySelect').click().type('{downArrow}{enter}');
|
||||
cy.contains(/^Save$/).click();
|
||||
cy.contains(/^Save pack$/).click();
|
||||
cy.contains(`Successfully created "${packName}" pack`).click();
|
||||
cy.visit('app/fleet/policies');
|
||||
cy.get(`[title="${policyName}"]`).click();
|
||||
cy.getBySel('PackagePoliciesTableUpgradeButton').click();
|
||||
cy.contains(/^Advanced$/).click();
|
||||
cy.getBySel('codeEditorContainer').within(() => {
|
||||
cy.contains(`"${packName}":`);
|
||||
});
|
||||
cy.getBySel('saveIntegration').click();
|
||||
cy.get(`a[title="${integrationName}"]`).click();
|
||||
cy.contains(/^Advanced$/).click();
|
||||
cy.getBySel('codeEditorContainer').within(() => {
|
||||
cy.contains(`"${packName}":`);
|
||||
});
|
||||
cy.contains('Cancel').click();
|
||||
closeModalIfVisible();
|
||||
cy.get(`[title="${integrationName}"]`)
|
||||
.parents('tr')
|
||||
.within(() => {
|
||||
cy.getBySel('PackagePoliciesTableUpgradeButton').should('not.exist');
|
||||
cy.contains('Osquery Manager').and('not.contain', `v${oldVersion}`);
|
||||
});
|
||||
integrationExistsWithinPolicyDetails(integrationName);
|
||||
|
||||
// test list of prebuilt queries
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.waitForReact();
|
||||
cy.react('EuiTableRow').should('have.length.above', 5);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,32 +6,51 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
addLastLiveQueryToCase,
|
||||
addLiveQueryToCase,
|
||||
checkActionItemsInResults,
|
||||
viewRecentCaseAndCheckResults,
|
||||
} from '../../tasks/live_query';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLES } from '../../test';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { loadLiveQuery, loadCase, cleanupCase } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('Add to Cases', () => {
|
||||
let liveQueryId: string;
|
||||
let liveQueryQuery: string;
|
||||
|
||||
before(() => {
|
||||
loadLiveQuery({
|
||||
agent_all: true,
|
||||
query: "SELECT * FROM os_version where name='Ubuntu';",
|
||||
}).then((liveQuery) => {
|
||||
liveQueryId = liveQuery.action_id;
|
||||
liveQueryQuery = liveQuery.queries[0].query;
|
||||
});
|
||||
});
|
||||
|
||||
describe('observability', () => {
|
||||
let caseId: string;
|
||||
let caseTitle: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'case_observability');
|
||||
login(ROLES.soc_manager);
|
||||
loadCase('observability').then((caseInfo) => {
|
||||
caseId = caseInfo.id;
|
||||
caseTitle = caseInfo.title;
|
||||
});
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'case_observability');
|
||||
cleanupCase(caseId);
|
||||
});
|
||||
|
||||
it('should add result a case and not have add to timeline in result', () => {
|
||||
addLastLiveQueryToCase();
|
||||
cy.contains('Test Obs case has been updated');
|
||||
addLiveQueryToCase(liveQueryId, caseId);
|
||||
cy.contains(`${caseTitle} has been updated`);
|
||||
viewRecentCaseAndCheckResults();
|
||||
|
||||
cy.contains("SELECT * FROM os_version where name='Ubuntu';");
|
||||
cy.contains(liveQueryQuery);
|
||||
checkActionItemsInResults({
|
||||
lens: true,
|
||||
discover: true,
|
||||
|
@ -40,20 +59,27 @@ describe('Add to Cases', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('security', () => {
|
||||
let caseId: string;
|
||||
let caseTitle: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'case_security');
|
||||
login(ROLES.soc_manager);
|
||||
loadCase('securitySolution').then((caseInfo) => {
|
||||
caseId = caseInfo.id;
|
||||
caseTitle = caseInfo.title;
|
||||
});
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'case_security');
|
||||
cleanupCase(caseId);
|
||||
});
|
||||
|
||||
it('should add result a case and have add to timeline in result', () => {
|
||||
addLastLiveQueryToCase();
|
||||
cy.contains('Test Security Case has been updated');
|
||||
addLiveQueryToCase(liveQueryId, caseId);
|
||||
cy.contains(`${caseTitle} has been updated`);
|
||||
viewRecentCaseAndCheckResults();
|
||||
|
||||
cy.contains("SELECT * FROM os_version where name='Ubuntu';");
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import {
|
||||
checkActionItemsInResults,
|
||||
|
@ -15,53 +14,63 @@ import {
|
|||
selectAllAgents,
|
||||
submitQuery,
|
||||
} from '../../tasks/live_query';
|
||||
import { ROLES } from '../../test';
|
||||
import { loadSpace, loadPack, cleanupPack, cleanupSpace } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('ALL - Custom space', () => {
|
||||
const CUSTOM_SPACE = 'custom-space';
|
||||
const PACK_NAME = 'testpack';
|
||||
before(() => {
|
||||
login(ROLES.admin);
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/spaces/space',
|
||||
body: {
|
||||
id: CUSTOM_SPACE,
|
||||
name: CUSTOM_SPACE,
|
||||
},
|
||||
failOnStatusCode: false,
|
||||
headers: { 'kbn-xsrf': 'create-space' },
|
||||
});
|
||||
});
|
||||
['default', 'custom-space'].forEach((spaceName) => {
|
||||
describe(`[${spaceName}]`, () => {
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
let spaceId: string;
|
||||
|
||||
after(() => {
|
||||
login(ROLES.admin);
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: '/api/spaces/space/custom-space',
|
||||
headers: { 'kbn-xsrf': 'delete-space' },
|
||||
});
|
||||
});
|
||||
|
||||
['default', 'custom-space'].forEach((space) => {
|
||||
describe(`[${space}]`, () => {
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'pack', space);
|
||||
cy.wrap(
|
||||
new Promise<string>((resolve) => {
|
||||
if (spaceName !== 'default') {
|
||||
loadSpace().then((space) => {
|
||||
spaceId = space.id;
|
||||
resolve(spaceId);
|
||||
});
|
||||
} else {
|
||||
spaceId = 'default';
|
||||
resolve(spaceId);
|
||||
}
|
||||
})
|
||||
).then((space) => {
|
||||
loadPack(
|
||||
{
|
||||
queries: {
|
||||
test: {
|
||||
interval: 10,
|
||||
query: 'select * from uptime;',
|
||||
ecs_mapping: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
space as string
|
||||
).then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
navigateTo(`/s/${space}/app/osquery`);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo(`/s/${spaceId}/app/osquery`);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'pack', space);
|
||||
cleanupPack(packId, spaceId);
|
||||
if (spaceName !== 'default') {
|
||||
cleanupSpace(spaceId);
|
||||
}
|
||||
});
|
||||
|
||||
it('Discover should be opened in new tab in results table', () => {
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery('select * from uptime; ');
|
||||
inputQuery('select * from uptime;');
|
||||
submitQuery();
|
||||
checkResults();
|
||||
checkActionItemsInResults({
|
||||
|
@ -82,11 +91,12 @@ describe('ALL - Custom space', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
it(`runs packs normally on ${space}`, () => {
|
||||
|
||||
it('runs packs normally', () => {
|
||||
cy.contains('Packs').click();
|
||||
cy.contains('Create pack').click();
|
||||
cy.react('CustomItemAction', {
|
||||
props: { item: { attributes: { name: PACK_NAME } } },
|
||||
props: { item: { attributes: { name: packName } } },
|
||||
}).click();
|
||||
selectAllAgents();
|
||||
cy.contains('Submit').click();
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
*/
|
||||
|
||||
import { getAdvancedButton } from '../../screens/integrations';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLES } from '../../test';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import {
|
||||
checkResults,
|
||||
|
@ -21,7 +20,7 @@ import {
|
|||
|
||||
describe('EcsMapping', () => {
|
||||
before(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
|
@ -36,7 +35,7 @@ describe('EcsMapping', () => {
|
|||
submitQuery();
|
||||
checkResults();
|
||||
cy.contains('[ "test1", "test2" ]');
|
||||
typeInECSFieldInput('labels{downArrow}{enter}', 1);
|
||||
typeInECSFieldInput('client.domain{downArrow}{enter}', 1);
|
||||
|
||||
getOsqueryFieldTypes('Static value', 1);
|
||||
|
||||
|
|
|
@ -6,29 +6,32 @@
|
|||
*/
|
||||
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { ROLES } from '../../test';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { loadSavedQuery, cleanupSavedQuery } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('ALL - Edit saved query', () => {
|
||||
const SAVED_QUERY_ID = 'Saved-Query-Id';
|
||||
let savedQueryName: string;
|
||||
let savedQueryId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
savedQueryName = data.attributes.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
});
|
||||
|
||||
it('by changing ecs mappings and platforms', () => {
|
||||
cy.getBySel('pagination-button-next').click();
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { index: 1, item: { attributes: { id: savedQueryName } } },
|
||||
}).click();
|
||||
cy.contains('Custom key/value pairs.').should('exist');
|
||||
cy.contains('Hours of uptime').should('exist');
|
||||
|
@ -69,7 +72,7 @@ describe('ALL - Edit saved query', () => {
|
|||
cy.wait(5000);
|
||||
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { index: 1, item: { attributes: { id: savedQueryName } } },
|
||||
}).click();
|
||||
cy.contains('Custom key/value pairs').should('not.exist');
|
||||
cy.contains('Hours of uptime').should('not.exist');
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import {
|
||||
addToCase,
|
||||
|
@ -26,24 +25,69 @@ import {
|
|||
RESULTS_TABLE_CELL_WRRAPER,
|
||||
} from '../../screens/live_query';
|
||||
import { getAdvancedButton } from '../../screens/integrations';
|
||||
import { ROLES } from '../../test';
|
||||
import {
|
||||
loadPack,
|
||||
loadSavedQuery,
|
||||
cleanupPack,
|
||||
cleanupCase,
|
||||
cleanupSavedQuery,
|
||||
loadCase,
|
||||
} from '../../tasks/api_fixtures';
|
||||
|
||||
describe('ALL - Live Query', () => {
|
||||
let packId: string;
|
||||
let packName: string;
|
||||
let savedQueryId: string;
|
||||
let savedQueryName: string;
|
||||
let caseId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'ecs_mapping_1');
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'example_pack');
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'case_security');
|
||||
loadPack({
|
||||
queries: {
|
||||
system_memory_linux_elastic: {
|
||||
ecs_mapping: {},
|
||||
interval: 3600,
|
||||
platform: 'linux',
|
||||
query: 'SELECT * FROM memory_info;',
|
||||
},
|
||||
system_info_elastic: {
|
||||
ecs_mapping: {},
|
||||
interval: 3600,
|
||||
platform: 'linux,windows,darwin',
|
||||
query: 'SELECT * FROM system_info;',
|
||||
},
|
||||
failingQuery: {
|
||||
ecs_mapping: {},
|
||||
interval: 10,
|
||||
query: 'select opera_extensions.* from users join opera_extensions using (uid);',
|
||||
},
|
||||
},
|
||||
}).then((pack) => {
|
||||
packId = pack.id;
|
||||
packName = pack.attributes.name;
|
||||
});
|
||||
loadSavedQuery({
|
||||
interval: '3600',
|
||||
query: 'select * from uptime;',
|
||||
ecs_mapping: {},
|
||||
}).then((savedQuery) => {
|
||||
savedQueryId = savedQuery.id;
|
||||
savedQueryName = savedQuery.attributes.name;
|
||||
});
|
||||
loadCase('securitySolution').then((caseInfo) => {
|
||||
caseId = caseInfo.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'ecs_mapping_1');
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'example_pack');
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'case_security');
|
||||
cleanupPack(packId);
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
cleanupCase(caseId);
|
||||
});
|
||||
|
||||
it('should validate the form', () => {
|
||||
|
@ -52,7 +96,7 @@ describe('ALL - Live Query', () => {
|
|||
cy.contains('Agents is a required field');
|
||||
cy.contains('Query is a required field');
|
||||
selectAllAgents();
|
||||
inputQuery('select * from uptime; ');
|
||||
inputQuery('select * from uptime;');
|
||||
submitQuery();
|
||||
cy.contains('Agents is a required field').should('not.exist');
|
||||
cy.contains('Query is a required field').should('not.exist');
|
||||
|
@ -77,7 +121,7 @@ describe('ALL - Live Query', () => {
|
|||
const cmd = Cypress.platform === 'darwin' ? '{meta}{enter}' : '{ctrl}{enter}';
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery('select * from uptime; ');
|
||||
inputQuery('select * from uptime;');
|
||||
cy.wait(500);
|
||||
// checking submit by clicking cmd+enter
|
||||
inputQuery(cmd);
|
||||
|
@ -117,8 +161,7 @@ describe('ALL - Live Query', () => {
|
|||
it('should run customized saved query', () => {
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
cy.react('SavedQueriesDropdown').type('NOMAPPING{downArrow}{enter}');
|
||||
// cy.getReact('SavedQueriesDropdown').getCurrentState().should('have.length', 1); // TODO do we need it?
|
||||
cy.react('SavedQueriesDropdown').type(`${savedQueryName}{downArrow}{enter}`);
|
||||
inputQuery('{selectall}{backspace}select * from users;');
|
||||
cy.wait(1000);
|
||||
submitQuery();
|
||||
|
@ -144,7 +187,7 @@ describe('ALL - Live Query', () => {
|
|||
cy.contains('New live query').click();
|
||||
cy.contains('Run a set of queries in a pack.').click();
|
||||
cy.get(LIVE_QUERY_EDITOR).should('not.exist');
|
||||
cy.getBySel('select-live-pack').click().type('Example{downArrow}{enter}');
|
||||
cy.getBySel('select-live-pack').click().type(`${packName}{downArrow}{enter}`);
|
||||
cy.contains('This table contains 3 rows.');
|
||||
cy.contains('system_memory_linux_elastic');
|
||||
cy.contains('system_info_elastic');
|
||||
|
@ -173,7 +216,7 @@ describe('ALL - Live Query', () => {
|
|||
cy.contains('query failed, code: 1, message: no such table: opera_extensions');
|
||||
cy.getBySel('toggleIcon-failingQuery').click();
|
||||
cy.getBySel('toggleIcon-system_memory_linux_elastic').click();
|
||||
addToCase();
|
||||
addToCase(caseId);
|
||||
viewRecentCaseAndCheckResults();
|
||||
});
|
||||
|
||||
|
|
|
@ -6,29 +6,34 @@
|
|||
*/
|
||||
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { checkResults, inputQuery, submitQuery } from '../../tasks/live_query';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { ROLES } from '../../test';
|
||||
import { loadSavedQuery, cleanupSavedQuery } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('ALL - Inventory', () => {
|
||||
let savedQueryName: string;
|
||||
let savedQueryId: string;
|
||||
|
||||
before(() => {
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
savedQueryName = data.attributes.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
});
|
||||
|
||||
it('should be able to run the query', () => {
|
||||
cy.getBySel('toggleNavButton').click();
|
||||
cy.contains('Infrastructure').click();
|
||||
|
||||
cy.wait(1000);
|
||||
|
||||
cy.getBySel('nodeContainer').first().click();
|
||||
cy.contains('Osquery').click();
|
||||
inputQuery('select * from uptime;');
|
||||
|
@ -47,7 +52,7 @@ describe('ALL - Inventory', () => {
|
|||
|
||||
cy.getBySel('comboBoxInput').first().click();
|
||||
cy.wait(500);
|
||||
cy.getBySel('comboBoxInput').first().type('saved{downArrow}{enter}');
|
||||
cy.getBySel('comboBoxInput').first().type(`${savedQueryName}{downArrow}{enter}`);
|
||||
|
||||
submitQuery();
|
||||
checkResults();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { preparePack } from '../../tasks/packs';
|
||||
import {
|
||||
addToCase,
|
||||
|
@ -19,33 +18,31 @@ import {
|
|||
viewRecentCaseAndCheckResults,
|
||||
} from '../../tasks/live_query';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLES } from '../../test';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { getSavedQueriesComplexTest } from '../../tasks/saved_queries';
|
||||
import { getRandomInt } from '../../tasks/helpers';
|
||||
import { loadCase, cleanupCase, loadPack, cleanupPack } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('ALL - Saved queries', () => {
|
||||
const randomNumber = getRandomInt();
|
||||
const SAVED_QUERY_ID = `Saved-Query-Id-${randomNumber}`;
|
||||
const SAVED_QUERY_DESCRIPTION = `Test saved query description ${randomNumber}`;
|
||||
let caseId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'case_security');
|
||||
loadCase('securitySolution').then((caseInfo) => {
|
||||
caseId = caseInfo.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'case_security');
|
||||
cleanupCase(caseId);
|
||||
});
|
||||
|
||||
getSavedQueriesComplexTest(SAVED_QUERY_ID, SAVED_QUERY_DESCRIPTION);
|
||||
getSavedQueriesComplexTest();
|
||||
|
||||
it('checks that user cant add a saved query with an ID that already exists', () => {
|
||||
it.skip('checks that user cant add a saved query with an ID that already exists', () => {
|
||||
cy.contains('Saved queries').click();
|
||||
cy.contains('Add saved query').click();
|
||||
|
||||
|
@ -65,17 +62,33 @@ describe('ALL - Saved queries', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('prebuilt ', () => {
|
||||
describe('prebuilt', () => {
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'pack_with_prebuilt_saved_queries');
|
||||
loadPack({
|
||||
queries: {
|
||||
test: {
|
||||
interval: 10,
|
||||
query: 'select * from uptime;',
|
||||
ecs_mapping: {},
|
||||
},
|
||||
},
|
||||
}).then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.getBySel('tablePaginationPopoverButton').click();
|
||||
cy.getBySel('tablePagination-50-rows').click();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'pack_with_prebuilt_saved_queries');
|
||||
cleanupPack(packId);
|
||||
});
|
||||
|
||||
it('checks result type on prebuilt saved query', () => {
|
||||
|
@ -95,7 +108,7 @@ describe('ALL - Saved queries', () => {
|
|||
selectAllAgents();
|
||||
submitQuery();
|
||||
checkResults();
|
||||
addToCase();
|
||||
addToCase(caseId);
|
||||
viewRecentCaseAndCheckResults();
|
||||
});
|
||||
|
||||
|
@ -117,10 +130,9 @@ describe('ALL - Saved queries', () => {
|
|||
});
|
||||
|
||||
it('user can edit prebuilt saved query under pack', () => {
|
||||
const PACK_NAME = 'pack_with_prebuilt_sq';
|
||||
preparePack(PACK_NAME);
|
||||
preparePack(packName);
|
||||
findAndClickButton('Edit');
|
||||
cy.contains(`Edit ${PACK_NAME}`);
|
||||
cy.contains(`Edit ${packName}`);
|
||||
findAndClickButton('Add query');
|
||||
cy.contains('Attach next query');
|
||||
|
||||
|
@ -144,7 +156,6 @@ describe('ALL - Saved queries', () => {
|
|||
});
|
||||
cy.contains('Unique identifier of the us').should('not.exist');
|
||||
cy.contains('User ID').should('not.exist');
|
||||
// cy.contains('Save').click();
|
||||
cy.react('EuiFlyoutFooter').react('EuiButton').contains('Save').click();
|
||||
|
||||
cy.react('CustomItemAction', {
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
*/
|
||||
|
||||
import { takeOsqueryActionWithParams } from '../../tasks/live_query';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLES } from '../../test';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
|
||||
describe('ALL - Timelines', () => {
|
||||
beforeEach(() => {
|
||||
login(ROLES.soc_manager);
|
||||
login(ROLE.soc_manager);
|
||||
});
|
||||
|
||||
it('should substitute osquery parameter on non-alert event take action', () => {
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { ROLES } from '../../test';
|
||||
import { checkResults, inputQuery, selectAllAgents, submitQuery } from '../../tasks/live_query';
|
||||
|
||||
describe('Admin', () => {
|
||||
beforeEach(() => {
|
||||
login(ROLES.admin);
|
||||
login(ROLE.admin);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
it('should be able to run live query with BASE All permissions', () => {
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery('select * from uptime; ');
|
||||
inputQuery('select * from uptime;');
|
||||
submitQuery();
|
||||
checkResults();
|
||||
});
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ROLES } from '../../test';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import {
|
||||
checkResults,
|
||||
findAndClickButton,
|
||||
|
@ -16,48 +14,72 @@ import {
|
|||
} from '../../tasks/live_query';
|
||||
import { closeModalIfVisible, closeToastIfVisible } from '../../tasks/integrations';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { loadPack, loadRule, cleanupRule, cleanupPack } from '../../tasks/api_fixtures';
|
||||
import { preparePack } from '../../tasks/packs';
|
||||
|
||||
describe('Alert Test', () => {
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
let ruleName: string;
|
||||
let ruleId: string;
|
||||
|
||||
describe('Alert_Test', () => {
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'pack');
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'rule');
|
||||
loadPack({
|
||||
description: '',
|
||||
enabled: true,
|
||||
queries: {
|
||||
packQuery: {
|
||||
interval: 10,
|
||||
query: 'select * from uptime;',
|
||||
ecs_mapping: {},
|
||||
},
|
||||
},
|
||||
}).then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
loadRule().then((data) => {
|
||||
ruleId = data.id;
|
||||
ruleName = data.name;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLE.alert_test);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'pack');
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'rule');
|
||||
cleanupPack(packId);
|
||||
cleanupRule(ruleId);
|
||||
});
|
||||
|
||||
describe('alert_test role', () => {
|
||||
it('should not be able to run live query', () => {
|
||||
login(ROLES.alert_test);
|
||||
beforeEach(() => {
|
||||
login(ROLE.alert_test);
|
||||
});
|
||||
|
||||
const PACK_NAME = 'testpack';
|
||||
const RULE_NAME = 'Test-rule';
|
||||
it('should not be able to run live query', () => {
|
||||
navigateTo('/app/osquery');
|
||||
cy.contains('Packs').click();
|
||||
cy.getBySel('pagination-button-next').click();
|
||||
cy.contains(PACK_NAME).click();
|
||||
preparePack(packName);
|
||||
findAndClickButton('Edit');
|
||||
cy.contains(`Edit ${PACK_NAME}`);
|
||||
cy.contains(`Edit ${packName}`);
|
||||
findFormFieldByRowsLabelAndType(
|
||||
'Scheduled agent policies (optional)',
|
||||
'fleet server {downArrow}{enter}'
|
||||
);
|
||||
findAndClickButton('Update pack');
|
||||
closeModalIfVisible();
|
||||
cy.contains(`Successfully updated "${PACK_NAME}" pack`);
|
||||
cy.contains(`Successfully updated "${packName}" pack`);
|
||||
closeToastIfVisible();
|
||||
|
||||
cy.visit('/app/security/rules');
|
||||
cy.contains(RULE_NAME).click();
|
||||
cy.contains(ruleName).click();
|
||||
cy.wait(2000);
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'false');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
cy.visit('/app/security/alerts');
|
||||
cy.getBySel('expand-event').first().click();
|
||||
cy.getBySel('take-action-dropdown-btn').click();
|
||||
cy.getBySel('osquery-action-item').click();
|
||||
|
@ -68,31 +90,22 @@ describe('Alert_Test', () => {
|
|||
});
|
||||
|
||||
describe('t1_analyst role', () => {
|
||||
it('should be able to run rule investigation guide query', () => {
|
||||
login(ROLES.t1_analyst);
|
||||
beforeEach(() => {
|
||||
login(ROLE.t1_analyst);
|
||||
|
||||
navigateTo('/app/osquery');
|
||||
|
||||
cy.visit('/app/security/alerts');
|
||||
cy.visit(`/app/security/rules/id/${ruleId}/alerts`);
|
||||
cy.getBySel('expand-event').first().click();
|
||||
|
||||
cy.wait(500);
|
||||
cy.contains('Get processes').click();
|
||||
});
|
||||
|
||||
it('should be able to run rule investigation guide query', () => {
|
||||
submitQuery();
|
||||
checkResults();
|
||||
});
|
||||
|
||||
it('should not be able to run custom query', () => {
|
||||
login(ROLES.t1_analyst);
|
||||
|
||||
navigateTo('/app/osquery');
|
||||
|
||||
cy.visit('/app/security/alerts');
|
||||
cy.getBySel('expand-event').first().click();
|
||||
|
||||
cy.wait(500);
|
||||
cy.contains('Get processes').click();
|
||||
|
||||
cy.intercept('POST', '/api/osquery/live_queries', (req) => {
|
||||
req.body.query = 'select * from processes limit 10';
|
||||
});
|
||||
|
|
|
@ -5,24 +5,25 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ROLES } from '../../test';
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { NAV_SEARCH_INPUT_OSQUERY_RESULTS } from '../../tasks/navigation';
|
||||
import { loadRule, cleanupRule } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('None', () => {
|
||||
beforeEach(() => {
|
||||
login(ROLES.none);
|
||||
login(ROLE.none);
|
||||
|
||||
cy.visit('/app/home');
|
||||
});
|
||||
|
||||
it('should not see osquery in global search', () => {
|
||||
cy.getBySel('nav-search-input').type('Osquery');
|
||||
cy.get('[title="Osquery • Management"]').should('not.exist');
|
||||
cy.get('[title="Osquery Logs • Integration"]').should('not.exist');
|
||||
cy.get('[title="Osquery Manager • Integration"]').should('not.exist');
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.MANAGEMENT}"]`).should('not.exist');
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.LOGS}"]`).should('not.exist');
|
||||
cy.get(`[url="${NAV_SEARCH_INPUT_OSQUERY_RESULTS.MANAGER}"]`).should('not.exist');
|
||||
});
|
||||
|
||||
it('should get 403 forbidded response when trying to GET osquery', () => {
|
||||
it('should get 403 forbidden response when trying to GET osquery', () => {
|
||||
cy.request({
|
||||
url: '/app/osquery/live_queries',
|
||||
failOnStatusCode: false,
|
||||
|
@ -43,15 +44,33 @@ describe('None', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not see osquery in alerts', () => {
|
||||
cy.visit('/app/security/alerts');
|
||||
cy.getBySel('expand-event').first().click({ force: true });
|
||||
cy.getBySel('take-action-dropdown-btn').click();
|
||||
cy.getBySel('osquery-action-item').should('not.exist');
|
||||
describe('Detection Engine', () => {
|
||||
let ruleId: string;
|
||||
|
||||
cy.getBySel('osquery-actions-notification').contains('0');
|
||||
cy.contains('Osquery Results').click();
|
||||
cy.contains('Permission denied').should('exist');
|
||||
cy.contains('Error while fetching live queries').should('exist');
|
||||
before(() => {
|
||||
login(ROLE.soc_manager);
|
||||
loadRule(true).then((data) => {
|
||||
ruleId = data.id;
|
||||
});
|
||||
cy.visit(`/app/security/alerts`);
|
||||
cy.getBySel('expand-event').should('exist');
|
||||
login(ROLE.none);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cleanupRule(ruleId);
|
||||
});
|
||||
|
||||
it('should not see osquery in alerts', () => {
|
||||
cy.visit(`/app/security/rules/id/${ruleId}/alerts`);
|
||||
cy.getBySel('expand-event').first().click();
|
||||
cy.getBySel('take-action-dropdown-btn').click();
|
||||
cy.getBySel('osquery-action-item').should('not.exist');
|
||||
|
||||
cy.getBySel('osquery-actions-notification').contains('0');
|
||||
cy.contains('Osquery Results').click();
|
||||
cy.contains('Permission denied').should('exist');
|
||||
cy.contains('Error while fetching live queries').should('exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,37 +5,57 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { ROLES } from '../../test';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import {
|
||||
cleanupPack,
|
||||
cleanupSavedQuery,
|
||||
loadLiveQuery,
|
||||
loadPack,
|
||||
loadSavedQuery,
|
||||
} from '../../tasks/api_fixtures';
|
||||
|
||||
describe('Reader - only READ', () => {
|
||||
const SAVED_QUERY_ID = 'Saved-Query-Id';
|
||||
let savedQueryName: string;
|
||||
let savedQueryId: string;
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
let liveQueryQuery: string;
|
||||
|
||||
before(() => {
|
||||
loadPack().then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
savedQueryName = data.attributes.id;
|
||||
});
|
||||
loadLiveQuery().then((data) => {
|
||||
liveQueryQuery = data.queries?.[0].query;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.reader);
|
||||
});
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
login(ROLE.reader);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
cleanupPack(packId);
|
||||
});
|
||||
|
||||
it('should not be able to add nor run saved queries', () => {
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.waitForReact(1000);
|
||||
cy.getBySel('pagination-button-next').click();
|
||||
cy.contains(SAVED_QUERY_ID);
|
||||
cy.contains(savedQueryName);
|
||||
cy.contains('Add saved query').should('be.disabled');
|
||||
cy.react('PlayButtonComponent', {
|
||||
props: { savedQuery: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { savedQuery: { attributes: { id: savedQueryName } } },
|
||||
options: { timeout: 3000 },
|
||||
}).should('not.exist');
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { index: 1, item: { attributes: { id: savedQueryName } } },
|
||||
}).click();
|
||||
cy.react('EuiFormRow', { props: { label: 'ID' } })
|
||||
.getBySel('input')
|
||||
|
@ -47,39 +67,43 @@ describe('Reader - only READ', () => {
|
|||
cy.contains('Update query').should('not.exist');
|
||||
cy.contains(`Delete query`).should('not.exist');
|
||||
});
|
||||
|
||||
it('should not be able to enter live queries with just read and no run saved queries', () => {
|
||||
navigateTo('/app/osquery/live_queries/new');
|
||||
cy.waitForReact(1000);
|
||||
cy.contains('Permission denied');
|
||||
});
|
||||
|
||||
it('should not be able to play in live queries history', () => {
|
||||
navigateTo('/app/osquery/live_queries');
|
||||
cy.waitForReact(1000);
|
||||
cy.contains('New live query').should('be.disabled');
|
||||
cy.contains('select * from uptime');
|
||||
cy.contains(liveQueryQuery);
|
||||
cy.react('EuiIconPlay', { options: { timeout: 3000 } }).should('not.exist');
|
||||
cy.react('ActionTableResultsButton').should('exist');
|
||||
});
|
||||
it('should not be able to add nor edit packs', () => {
|
||||
const PACK_NAME = 'removing-pack';
|
||||
|
||||
it('should not be able to add nor edit packs', () => {
|
||||
navigateTo('/app/osquery/packs');
|
||||
cy.waitForReact(1000);
|
||||
cy.contains('Add pack').should('be.disabled');
|
||||
cy.getBySel('tablePaginationPopoverButton').click();
|
||||
cy.getBySel('tablePagination-50-rows').click();
|
||||
cy.react('ActiveStateSwitchComponent', {
|
||||
props: { item: { attributes: { name: PACK_NAME } } },
|
||||
props: { item: { attributes: { name: packName } } },
|
||||
})
|
||||
.find('button')
|
||||
.should('be.disabled');
|
||||
cy.contains(PACK_NAME).click();
|
||||
cy.contains(`${PACK_NAME} details`);
|
||||
cy.contains(packName).click();
|
||||
cy.contains(`${packName} details`);
|
||||
cy.contains('Edit').should('be.disabled');
|
||||
// TODO: Verify assertions
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 0, item: { id: SAVED_QUERY_ID } },
|
||||
props: { index: 0, item: { id: savedQueryName } },
|
||||
options: { timeout: 3000 },
|
||||
}).should('not.exist');
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { id: SAVED_QUERY_ID } },
|
||||
props: { index: 1, item: { id: savedQueryName } },
|
||||
options: { timeout: 3000 },
|
||||
}).should('not.exist');
|
||||
});
|
||||
|
|
|
@ -5,40 +5,61 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { SAVED_QUERY_ID } from '../../../public/saved_queries/constants';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { ROLES } from '../../test';
|
||||
import {
|
||||
checkActionItemsInResults,
|
||||
checkResults,
|
||||
selectAllAgents,
|
||||
submitQuery,
|
||||
} from '../../tasks/live_query';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { getSavedQueriesDropdown, LIVE_QUERY_EDITOR } from '../../screens/live_query';
|
||||
import {
|
||||
cleanupPack,
|
||||
cleanupSavedQuery,
|
||||
loadLiveQuery,
|
||||
loadPack,
|
||||
loadSavedQuery,
|
||||
} from '../../tasks/api_fixtures';
|
||||
|
||||
describe('T1 Analyst - READ + runSavedQueries ', () => {
|
||||
const SAVED_QUERY_ID = 'Saved-Query-Id';
|
||||
let savedQueryName: string;
|
||||
let savedQueryId: string;
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
let liveQueryQuery: string;
|
||||
|
||||
before(() => {
|
||||
loadPack().then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
savedQueryName = data.attributes.id;
|
||||
});
|
||||
loadLiveQuery().then((data) => {
|
||||
liveQueryQuery = data.queries?.[0].query;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.t1_analyst);
|
||||
});
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
login(ROLE.t1_analyst);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
cleanupPack(packId);
|
||||
});
|
||||
|
||||
it('should be able to run saved queries but not add new ones', () => {
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.waitForReact(1000);
|
||||
cy.getBySel('pagination-button-next').click();
|
||||
cy.contains(SAVED_QUERY_ID);
|
||||
cy.contains(savedQueryName);
|
||||
cy.contains('Add saved query').should('be.disabled');
|
||||
cy.react('PlayButtonComponent', {
|
||||
props: { savedQuery: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { savedQuery: { attributes: { id: savedQueryName } } },
|
||||
})
|
||||
.should('not.be.disabled')
|
||||
.click();
|
||||
|
@ -53,42 +74,45 @@ describe('T1 Analyst - READ + runSavedQueries ', () => {
|
|||
timeline: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to play in live queries history', () => {
|
||||
navigateTo('/app/osquery/live_queries');
|
||||
cy.waitForReact(1000);
|
||||
cy.contains('New live query').should('not.be.disabled');
|
||||
cy.contains('select * from uptime');
|
||||
cy.contains(liveQueryQuery);
|
||||
cy.wait(1000);
|
||||
cy.react('EuiTableBody').first().react('CustomItemAction').first().click();
|
||||
cy.contains(SAVED_QUERY_ID);
|
||||
cy.contains(savedQueryName);
|
||||
submitQuery();
|
||||
checkResults();
|
||||
});
|
||||
// TODO UNSKIP AFTER FF
|
||||
it.skip('should be able to use saved query in a new query', () => {
|
||||
|
||||
it('should be able to use saved query in a new query', () => {
|
||||
navigateTo('/app/osquery/live_queries');
|
||||
cy.waitForReact(1000);
|
||||
cy.contains('New live query').should('not.be.disabled').click();
|
||||
selectAllAgents();
|
||||
getSavedQueriesDropdown().type(`${SAVED_QUERY_ID}{downArrow} {enter}`);
|
||||
getSavedQueriesDropdown().type(`${savedQueryName}{downArrow} {enter}`);
|
||||
cy.contains('select * from uptime');
|
||||
submitQuery();
|
||||
checkResults();
|
||||
});
|
||||
it('should not be able to add nor edit packs', () => {
|
||||
const PACK_NAME = 'removing-pack';
|
||||
|
||||
it('should not be able to add nor edit packs', () => {
|
||||
navigateTo('/app/osquery/packs');
|
||||
cy.waitForReact(1000);
|
||||
cy.getBySel('tablePaginationPopoverButton').click();
|
||||
cy.getBySel('tablePagination-50-rows').click();
|
||||
cy.contains('Add pack').should('be.disabled');
|
||||
cy.react('ActiveStateSwitchComponent', {
|
||||
props: { item: { attributes: { name: PACK_NAME } } },
|
||||
props: { item: { attributes: { name: packName } } },
|
||||
})
|
||||
.find('button')
|
||||
.should('be.disabled');
|
||||
cy.contains(PACK_NAME).click();
|
||||
cy.contains(`${PACK_NAME} details`);
|
||||
cy.contains(packName).click();
|
||||
cy.contains(`${packName} details`);
|
||||
cy.contains('Edit').should('be.disabled');
|
||||
// TODO: fix it
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 0, item: { id: SAVED_QUERY_ID } },
|
||||
options: { timeout: 3000 },
|
||||
|
@ -98,6 +122,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => {
|
|||
options: { timeout: 3000 },
|
||||
}).should('not.exist');
|
||||
});
|
||||
|
||||
it('should not be able to create new liveQuery from scratch', () => {
|
||||
navigateTo('/app/osquery');
|
||||
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { login } from '../../tasks/login';
|
||||
import { ROLE, login } from '../../tasks/login';
|
||||
import { navigateTo } from '../../tasks/navigation';
|
||||
import { ROLES } from '../../test';
|
||||
import {
|
||||
checkResults,
|
||||
selectAllAgents,
|
||||
|
@ -17,44 +16,55 @@ import {
|
|||
typeInOsqueryFieldInput,
|
||||
checkActionItemsInResults,
|
||||
} from '../../tasks/live_query';
|
||||
import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver';
|
||||
import { getSavedQueriesComplexTest } from '../../tasks/saved_queries';
|
||||
import { loadPack, loadSavedQuery, cleanupSavedQuery, cleanupPack } from '../../tasks/api_fixtures';
|
||||
|
||||
describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
|
||||
const SAVED_QUERY_ID = 'Saved-Query-Id';
|
||||
// const randomNumber = getRandomInt();
|
||||
//
|
||||
// const NEW_SAVED_QUERY_ID = `Saved-Query-Id-${randomNumber}`;
|
||||
// const NEW_SAVED_QUERY_DESCRIPTION = `Test saved query description ${randomNumber}`;
|
||||
|
||||
let savedQueryName: string;
|
||||
let savedQueryId: string;
|
||||
let packName: string;
|
||||
let packId: string;
|
||||
|
||||
before(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.LOAD, 'saved_query');
|
||||
loadPack().then((data) => {
|
||||
packId = data.id;
|
||||
packName = data.attributes.name;
|
||||
});
|
||||
loadSavedQuery().then((data) => {
|
||||
savedQueryId = data.id;
|
||||
savedQueryName = data.attributes.id;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login(ROLES.t2_analyst);
|
||||
login(ROLE.t2_analyst);
|
||||
navigateTo('/app/osquery');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query');
|
||||
cleanupSavedQuery(savedQueryId);
|
||||
cleanupPack(packId);
|
||||
});
|
||||
|
||||
// TODO unskip after FF
|
||||
// getSavedQueriesComplexTest(NEW_SAVED_QUERY_ID, NEW_SAVED_QUERY_DESCRIPTION);
|
||||
getSavedQueriesComplexTest();
|
||||
|
||||
it('should not be able to add nor edit packs', () => {
|
||||
const PACK_NAME = 'removing-pack';
|
||||
|
||||
navigateTo('/app/osquery/packs');
|
||||
cy.waitForReact(1000);
|
||||
cy.getBySel('tablePaginationPopoverButton').click();
|
||||
cy.getBySel('tablePagination-50-rows').click();
|
||||
cy.contains('Add pack').should('be.disabled');
|
||||
cy.react('ActiveStateSwitchComponent', {
|
||||
props: { item: { attributes: { name: PACK_NAME } } },
|
||||
props: { item: { attributes: { name: packName } } },
|
||||
})
|
||||
.find('button')
|
||||
.should('be.disabled');
|
||||
cy.contains(PACK_NAME).click();
|
||||
cy.contains(`${PACK_NAME} details`);
|
||||
cy.contains(packName).click();
|
||||
cy.contains(`${packName} details`);
|
||||
cy.contains('Edit').should('be.disabled');
|
||||
// TODO: fix
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 0, item: { id: SAVED_QUERY_ID } },
|
||||
options: { timeout: 3000 },
|
||||
|
@ -69,7 +79,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
|
|||
const cmd = Cypress.platform === 'darwin' ? '{meta}{enter}' : '{ctrl}{enter}';
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery('select * from uptime; ');
|
||||
inputQuery('select * from uptime;');
|
||||
cy.wait(500);
|
||||
// checking submit by clicking cmd+enter
|
||||
inputQuery(cmd);
|
||||
|
@ -90,6 +100,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
|
|||
cy.react('EuiAccordionClass', { props: { buttonContent: 'Advanced' } })
|
||||
.last()
|
||||
.click();
|
||||
|
||||
typeInECSFieldInput('message{downArrow}{enter}');
|
||||
typeInOsqueryFieldInput('days{downArrow}{enter}');
|
||||
submitQuery();
|
||||
|
@ -109,10 +120,8 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
|
|||
|
||||
it('to click the edit button and edit pack', () => {
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.getBySel('pagination-button-next').click();
|
||||
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { index: 1, item: { attributes: { id: savedQueryName } } },
|
||||
}).click();
|
||||
cy.contains('Custom key/value pairs.').should('exist');
|
||||
cy.contains('Hours of uptime').should('exist');
|
||||
|
@ -125,7 +134,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
|
|||
cy.wait(5000);
|
||||
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } },
|
||||
props: { index: 1, item: { attributes: { id: savedQueryName } } },
|
||||
}).click();
|
||||
cy.contains('Custom key/value pairs').should('not.exist');
|
||||
cy.contains('Hours of uptime').should('not.exist');
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"assignees": [],
|
||||
"closed_at": null,
|
||||
"closed_by": null,
|
||||
"connector": {
|
||||
"fields": [],
|
||||
"name": "none",
|
||||
"type": ".none"
|
||||
},
|
||||
"created_at": "2022-09-14T07:51:42.298Z",
|
||||
"created_by": {
|
||||
"email": null,
|
||||
"full_name": null,
|
||||
"username": "elastic"
|
||||
},
|
||||
"description": "Test Observability case",
|
||||
"duration": null,
|
||||
"external_service": null,
|
||||
"owner": "observability",
|
||||
"settings": {
|
||||
"syncAlerts": false
|
||||
},
|
||||
"severity": "low",
|
||||
"status": "open",
|
||||
"tags": [
|
||||
"obs"
|
||||
],
|
||||
"title": "Test Obs case",
|
||||
"updated_at": null,
|
||||
"updated_by": null
|
||||
},
|
||||
"coreMigrationVersion": "8.5.0",
|
||||
"id": "127acc90-3402-11ed-a392-0f81f7d06b71",
|
||||
"migrationVersion": {
|
||||
"cases": "8.5.0"
|
||||
},
|
||||
"references": [],
|
||||
"type": "cases",
|
||||
"updated_at": "2022-09-14T07:51:42.299Z",
|
||||
"version": "WzEwMDIwLDFd"
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"assignees": [],
|
||||
"closed_at": null,
|
||||
"closed_by": null,
|
||||
"connector": {
|
||||
"fields": [],
|
||||
"name": "none",
|
||||
"type": ".none"
|
||||
},
|
||||
"created_at": "2022-09-14T08:29:25.376Z",
|
||||
"created_by": {
|
||||
"email": null,
|
||||
"full_name": null,
|
||||
"username": "elastic"
|
||||
},
|
||||
"description": "Test security description",
|
||||
"duration": null,
|
||||
"external_service": null,
|
||||
"owner": "securitySolution",
|
||||
"settings": {
|
||||
"syncAlerts": true
|
||||
},
|
||||
"severity": "low",
|
||||
"status": "open",
|
||||
"tags": [
|
||||
"security"
|
||||
],
|
||||
"title": "Test Security Case",
|
||||
"updated_at": null,
|
||||
"updated_by": null
|
||||
},
|
||||
"coreMigrationVersion": "8.5.0",
|
||||
"id": "5760cad0-3407-11ed-b29d-758c6c3e798d",
|
||||
"migrationVersion": {
|
||||
"cases": "8.5.0"
|
||||
},
|
||||
"references": [],
|
||||
"type": "cases",
|
||||
"updated_at": "2022-09-14T08:29:25.376Z",
|
||||
"version": "WzE0OTk0LDFd"
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-02-03T07:43:10.311Z",
|
||||
"created_by": "elastic",
|
||||
"description": "fdsfsd",
|
||||
"ecs_mapping": [],
|
||||
"id": "NOMAPPING",
|
||||
"interval": 3600,
|
||||
"query": "select * from uptime;",
|
||||
"updated_at": "2022-02-03T08:22:01.662Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "ef31d680-84c4-11ec-991b-07bb2d53cda5",
|
||||
"references": [],
|
||||
"type": "osquery-saved-query",
|
||||
"updated_at": "2022-02-03T08:22:01.668Z",
|
||||
"version": "WzE3ODk5LDFd"
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-02-03T08:22:26.355Z",
|
||||
"created_by": "elastic",
|
||||
"description": "",
|
||||
"ecs_mapping": [
|
||||
{
|
||||
"key": "client.geo.continent_name",
|
||||
"value": {
|
||||
"field": "seconds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "ONE_MAPPING_CHANGED",
|
||||
"interval": 3600,
|
||||
"query": "select * from uptime;",
|
||||
"updated_at": "2022-02-03T08:24:52.429Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "6b819f40-84ca-11ec-991b-07bb2d53cda5",
|
||||
"references": [],
|
||||
"type": "osquery-saved-query",
|
||||
"updated_at": "2022-02-03T08:24:52.436Z",
|
||||
"version": "WzE3OTAwLDFd"
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-02-03T08:22:54.372Z",
|
||||
"created_by": "elastic",
|
||||
"ecs_mapping": [
|
||||
{
|
||||
"key": "labels",
|
||||
"value": {
|
||||
"field": "days"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "tags",
|
||||
"value": {
|
||||
"field": "seconds"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "client.address",
|
||||
"value": {
|
||||
"field": "total_seconds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "MULTIPLE_MAPPINGS",
|
||||
"interval": "3600",
|
||||
"query": "select * from uptime; ",
|
||||
"updated_at": "2022-02-03T08:22:54.372Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "7c348640-84ca-11ec-991b-07bb2d53cda5",
|
||||
"references": [],
|
||||
"type": "osquery-saved-query",
|
||||
"updated_at": "2022-02-03T08:22:54.375Z",
|
||||
"version": "WzE3OTAxLDFd"
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-08-01T08:01:50.452Z",
|
||||
"created_by": "elastic",
|
||||
"description": "",
|
||||
"enabled": true,
|
||||
"name": "Example",
|
||||
"queries": [
|
||||
{
|
||||
"ecs_mapping": [],
|
||||
"id": "system_memory_linux_elastic",
|
||||
"interval": 3600,
|
||||
"platform": "linux",
|
||||
"query": "SELECT * FROM memory_info;"
|
||||
},
|
||||
{
|
||||
"ecs_mapping": [],
|
||||
"id": "system_info_elastic",
|
||||
"interval": 3600,
|
||||
"platform": "linux,windows,darwin",
|
||||
"query": "SELECT * FROM system_info;"
|
||||
},
|
||||
{
|
||||
"ecs_mapping": [],
|
||||
"id": "failingQuery",
|
||||
"interval": 10,
|
||||
"query": "select opera_extensions.* from users join opera_extensions using (uid);"
|
||||
}
|
||||
],
|
||||
"updated_at": "2022-08-01T08:07:54.950Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.5.0",
|
||||
"id": "32cae340-1170-11ed-9ac3-9feb91078661",
|
||||
"references": [],
|
||||
"type": "osquery-pack",
|
||||
"updated_at": "2022-08-01T08:07:54.956Z",
|
||||
"version": "WzQ4NTksMV0="
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
{
|
||||
"queries": {
|
||||
"acpi_tables": {
|
||||
"query": "select * from acpi_tables;",
|
||||
"interval": 86400,
|
||||
"platform": "posix",
|
||||
"version": "1.3.0",
|
||||
"description": "General reporting and heuristics monitoring."
|
||||
},
|
||||
"cpuid": {
|
||||
"query": "select feature, value, output_register, output_bit, input_eax from cpuid;",
|
||||
"interval": 86400,
|
||||
"version": "1.0.4",
|
||||
"description": "General reporting and heuristics monitoring."
|
||||
},
|
||||
"smbios_tables": {
|
||||
"query": "select * from smbios_tables;",
|
||||
"interval": 86400,
|
||||
"platform": "posix",
|
||||
"version": "1.3.0",
|
||||
"description": "General reporting and heuristics monitoring."
|
||||
},
|
||||
"nvram": {
|
||||
"query": "select * from nvram where name not in ('backlight-level', 'SystemAudioVolumeDB', 'SystemAudioVolume');",
|
||||
"interval": 7200,
|
||||
"platform": "darwin",
|
||||
"version": "1.0.2",
|
||||
"description": "Report on crashes, alternate boots, and boot arguments."
|
||||
},
|
||||
"kernel_info": {
|
||||
"query": "select * from kernel_info join hash using (path);",
|
||||
"interval": 7200,
|
||||
"version": "1.4.0",
|
||||
"description": "Report the booted kernel, potential arguments, and the device."
|
||||
},
|
||||
"pci_devices": {
|
||||
"query": "select * from pci_devices;",
|
||||
"interval": 7200,
|
||||
"platform": "posix",
|
||||
"version": "1.0.4",
|
||||
"description": "Report an inventory of PCI devices. Attaches and detaches will show up in hardware_events."
|
||||
},
|
||||
"fan_speeds": {
|
||||
"query": "select * from fan_speed_sensors;",
|
||||
"interval": 7200,
|
||||
"platform": "darwin",
|
||||
"version": "1.7.1",
|
||||
"description": "Report current fan speeds in the target OSX system."
|
||||
},
|
||||
"temperatures": {
|
||||
"query": "select * from temperature_sensors;",
|
||||
"interval": 7200,
|
||||
"platform": "darwin",
|
||||
"version": "1.7.1",
|
||||
"description": "Report current machine temperatures in the target OSX system."
|
||||
},
|
||||
"usb_devices": {
|
||||
"query": "select * from usb_devices;",
|
||||
"interval": 7200,
|
||||
"platform": "posix",
|
||||
"version": "1.2.0",
|
||||
"description": "Report an inventory of USB devices. Attaches and detaches will show up in hardware_events."
|
||||
},
|
||||
"hardware_events": {
|
||||
"query" : "select * from hardware_events where path <> '' or model <> '';",
|
||||
"interval" : 7200,
|
||||
"platform": "posix",
|
||||
"removed": false,
|
||||
"version" : "1.4.5",
|
||||
"description" : "Retrieves all the hardware related events in the target OSX system.",
|
||||
"value" : "Determine if a third party device was attached to the system."
|
||||
},
|
||||
"darwin_kernel_system_controls": {
|
||||
"query": "select * from system_controls where subsystem = 'kern' and (name like '%boot%' or name like '%secure%' or name like '%single%');",
|
||||
"interval": 7200,
|
||||
"platform": "darwin",
|
||||
"version": "1.4.3",
|
||||
"description": "Double check the information reported in kernel_info and report the kernel signature."
|
||||
},
|
||||
"iokit_devicetree": {
|
||||
"query": "select * from iokit_devicetree;",
|
||||
"interval": 86400,
|
||||
"platform": "darwin",
|
||||
"version": "1.3.0",
|
||||
"description": "General inventory of IOKit's devices on OS X."
|
||||
},
|
||||
"efi_file_hashes": {
|
||||
"query": "select file.path, uid, gid, mode, 0 as atime, mtime, ctime, md5, sha1, sha256 from (select * from file where path like '/System/Library/CoreServices/%.efi' union select * from file where path like '/System/Library/LaunchDaemons/com.apple%efi%') file join hash using (path);",
|
||||
"interval": 7200,
|
||||
"removed": false,
|
||||
"version": "1.6.1",
|
||||
"platform": "darwin",
|
||||
"description": "Hash files related to EFI platform updates and EFI bootloaders on primary boot partition. This does not hash bootloaders on the EFI/boot partition."
|
||||
},
|
||||
"kernel_extensions": {
|
||||
"query" : "select * from kernel_extensions;",
|
||||
"interval" : "7200",
|
||||
"platform" : "darwin",
|
||||
"version" : "1.4.5",
|
||||
"description" : "Retrieves all the information about the current kernel extensions for the target OSX system."
|
||||
},
|
||||
"kernel_modules": {
|
||||
"query" : "select * from kernel_modules;",
|
||||
"interval" : "7200",
|
||||
"platform" : "linux",
|
||||
"version" : "1.4.5",
|
||||
"description" : "Retrieves all the information for the current kernel modules in the target Linux system."
|
||||
},
|
||||
"windows_drivers": {
|
||||
"query" : "select * from drivers;",
|
||||
"interval" : "7200",
|
||||
"platform" : "windows",
|
||||
"version" : "2.2.0",
|
||||
"description" : "Retrieves all the information for the current windows drivers in the target Windows system."
|
||||
},
|
||||
"device_nodes": {
|
||||
"query": "select file.path, uid, gid, mode, 0 as atime, mtime, ctime, block_size, type from file where directory = '/dev/';",
|
||||
"interval": "7200",
|
||||
"platform": "posix",
|
||||
"version": "1.6.0",
|
||||
"description": "Inventory all 'device' nodes in /dev/."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{"attributes":{"created_at":"2021-12-29T09:23:21.137Z","created_by":"elastic","enabled":true,"name":"hardware-monitoring","queries":[{"id":"acpi_tables","interval":86400,"platform":"darwin,linux","query":"select * from acpi_tables;","version":"1.3.0"},{"id":"cpuid","interval":86400,"query":"select feature, value, output_register, output_bit, input_eax from cpuid;","version":"1.0.4"},{"id":"smbios_tables","interval":86400,"platform":"darwin,linux","query":"select * from smbios_tables;","version":"1.3.0"},{"id":"nvram","interval":7200,"platform":"darwin","query":"select * from nvram where name not in ('backlight-level', 'SystemAudioVolumeDB', 'SystemAudioVolume');","version":"1.0.2"},{"id":"kernel_info","interval":7200,"query":"select * from kernel_info join hash using (path);","version":"1.4.0"},{"id":"pci_devices","interval":7200,"platform":"darwin,linux","query":"select * from pci_devices;","version":"1.0.4"},{"id":"fan_speeds","interval":7200,"platform":"darwin","query":"select * from fan_speed_sensors;","version":"1.7.1"},{"id":"temperatures","interval":7200,"platform":"darwin","query":"select * from temperature_sensors;","version":"1.7.1"},{"id":"usb_devices","interval":7200,"platform":"darwin,linux","query":"select * from usb_devices;","version":"1.2.0"},{"id":"hardware_events","interval":7200,"platform":"darwin,linux","query":"select * from hardware_events where path <> '' or model <> '';","version":"1.4.5"},{"id":"darwin_kernel_system_controls","interval":7200,"platform":"darwin","query":"select * from system_controls where subsystem = 'kern' and (name like '%boot%' or name like '%secure%' or name like '%single%');","version":"1.4.3"},{"id":"iokit_devicetree","interval":86400,"platform":"darwin","query":"select * from iokit_devicetree;","version":"1.3.0"},{"id":"efi_file_hashes","interval":7200,"platform":"darwin","query":"select file.path, uid, gid, mode, 0 as atime, mtime, ctime, md5, sha1, sha256 from (select * from file where path like '/System/Library/CoreServices/%.efi' union select * from file where path like '/System/Library/LaunchDaemons/com.apple%efi%') file join hash using (path);","version":"1.6.1"},{"id":"kernel_extensions","interval":7200,"platform":"darwin","query":"select * from kernel_extensions;","version":"1.4.5"},{"id":"kernel_modules","interval":7200,"platform":"linux","query":"select * from kernel_modules;","version":"1.4.5"},{"id":"windows_drivers","interval":7200,"platform":"windows","query":"select * from drivers;","version":"2.2.0"},{"id":"device_nodes","interval":7200,"platform":"darwin,linux","query":"select file.path, uid, gid, mode, 0 as atime, mtime, ctime, block_size, type from file where directory = '/dev/';","version":"1.6.0"}],"updated_at":"2021-12-29T09:23:21.137Z","updated_by":"elastic"},"coreMigrationVersion":"8.1.0","id":"f70e1920-6888-11ec-9276-97ce5eb54433","references":[],"type":"osquery-pack","updated_at":"2021-12-29T09:23:21.147Z","version":"WzI4NDMxLDJd"}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-01-28T09:01:46.147Z",
|
||||
"created_by": "elastic",
|
||||
"description": "gfd",
|
||||
"enabled": true,
|
||||
"name": "testpack",
|
||||
"queries": [
|
||||
{
|
||||
"id": "fds",
|
||||
"interval": 10,
|
||||
"query": "select * from uptime;"
|
||||
}
|
||||
],
|
||||
"updated_at": "2022-01-28T09:01:46.147Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "eb92a730-8018-11ec-88ce-bd5b5e3a7526",
|
||||
"references": [],
|
||||
"sort": [
|
||||
1643360506152,
|
||||
9062
|
||||
],
|
||||
"type": "osquery-pack",
|
||||
"updated_at": "2022-01-28T09:01:46.152Z",
|
||||
"version": "WzgzOTksMV0="
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2022-01-28T09:01:46.147Z",
|
||||
"created_by": "elastic",
|
||||
"description": "test description",
|
||||
"enabled": true,
|
||||
"name": "pack_with_prebuilt_sq",
|
||||
"queries": [
|
||||
{
|
||||
"id": "test",
|
||||
"interval": 10,
|
||||
"query": "select * from uptime;"
|
||||
}
|
||||
],
|
||||
"updated_at": "2022-01-28T09:01:46.147Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "eb92a730-8018-11ec-88ce-bd5b5e3a7527",
|
||||
"references": [],
|
||||
"sort": [
|
||||
1643360506152,
|
||||
9062
|
||||
],
|
||||
"type": "osquery-pack",
|
||||
"updated_at": "2022-01-28T09:01:46.152Z",
|
||||
"version": "WzgzOTksMV0="
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
{
|
||||
"id": "c8ca6100-802e-11ec-952d-cf6018da8e2b",
|
||||
"type": "alert",
|
||||
"namespaces": [
|
||||
"default"
|
||||
],
|
||||
"updated_at": "2022-01-28T11:38:23.009Z",
|
||||
"version": "WzE5MjksMV0=",
|
||||
"attributes": {
|
||||
"name": "Test-rule",
|
||||
"tags": [],
|
||||
"alertTypeId": "siem.queryRule",
|
||||
"consumer": "siem",
|
||||
"params": {
|
||||
"author": [],
|
||||
"description": "asd",
|
||||
"ruleId": "22308402-5e0e-421b-8d22-a47ddc4b0188",
|
||||
"falsePositives": [],
|
||||
"from": "now-360s",
|
||||
"immutable": false,
|
||||
"license": "",
|
||||
"outputIndex": ".siem-signals-default",
|
||||
"meta": {
|
||||
"from": "1m",
|
||||
"kibana_siem_app_url": "http://localhost:5601/app/security"
|
||||
},
|
||||
"maxSignals": 100,
|
||||
"riskScore": 21,
|
||||
"riskScoreMapping": [],
|
||||
"severity": "low",
|
||||
"severityMapping": [],
|
||||
"threat": [],
|
||||
"to": "now",
|
||||
"references": [],
|
||||
"version": 1,
|
||||
"exceptionsList": [],
|
||||
"type": "query",
|
||||
"language": "kuery",
|
||||
"index": [
|
||||
"apm-*-transaction*",
|
||||
"traces-apm*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"query": "_id:*",
|
||||
"filters": [],
|
||||
"note": "!{osquery{\"query\":\"SELECT * FROM os_version where name='{{host.os.name}}';\",\"label\":\"Get processes\",\"ecs_mapping\":{\"labels\":{\"field\":\"arch\"}}}}\n\n!{osquery{\"query\":\"select * from users;\",\"label\":\"Get users\"}}"
|
||||
},
|
||||
"schedule": {
|
||||
"interval": "5m"
|
||||
},
|
||||
"enabled": true,
|
||||
"actions": [],
|
||||
"throttle": null,
|
||||
"notifyWhen": "onActiveAlert",
|
||||
"apiKeyOwner": "elastic",
|
||||
"legacyId": null,
|
||||
"createdBy": "elastic",
|
||||
"updatedBy": "elastic",
|
||||
"createdAt": "2022-01-28T11:38:17.540Z",
|
||||
"updatedAt": "2022-01-28T11:38:19.894Z",
|
||||
"muteAll": true,
|
||||
"mutedInstanceIds": [],
|
||||
"executionStatus": {
|
||||
"status": "ok",
|
||||
"lastExecutionDate": "2022-01-28T11:38:21.638Z",
|
||||
"error": null,
|
||||
"lastDuration": 1369
|
||||
},
|
||||
"monitoring": {
|
||||
"execution": {
|
||||
"history": [
|
||||
{
|
||||
"success": true,
|
||||
"timestamp": 1643369903007
|
||||
}
|
||||
],
|
||||
"calculated_metrics": {
|
||||
"success_ratio": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"versionApiKeyLastmodified": "8.1.0"
|
||||
},
|
||||
"scheduledTaskId": "c8ca6100-802e-11ec-952d-cf6018da8e2b"
|
||||
},
|
||||
"references": [],
|
||||
"migrationVersion": {
|
||||
"alert": "8.0.0"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0"
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"attributes": {
|
||||
"created_at": "2021-12-21T08:54:07.802Z",
|
||||
"created_by": "elastic",
|
||||
"description": "Test saved query description",
|
||||
"ecs_mapping": [
|
||||
{
|
||||
"key": "labels",
|
||||
"value": {
|
||||
"field": "hours"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "Saved-Query-Id",
|
||||
"interval": "3600",
|
||||
"query": "select * from uptime;",
|
||||
"platform": "linux,darwin",
|
||||
"updated_at": "2021-12-21T08:54:38.648Z",
|
||||
"updated_by": "elastic"
|
||||
},
|
||||
"coreMigrationVersion": "8.1.0",
|
||||
"id": "8eae68b0-623b-11ec-8b00-d5db3ac3cda1",
|
||||
"references": [],
|
||||
"type": "osquery-saved-query",
|
||||
"updated_at": "2021-12-21T08:54:38.653Z",
|
||||
"version": "Wzg5MywxXQ=="
|
||||
}
|
|
@ -9,5 +9,5 @@ export const ADD_AGENT_BUTTON = 'addAgentButton';
|
|||
|
||||
export const AGENT_POLICIES_TAB = 'fleet-agent-policies-tab';
|
||||
export const ENROLLMENT_TOKENS_TAB = 'fleet-enrollment-tokens-tab';
|
||||
export const DEFAULT_POLICY = 'Default Fleet Server policy';
|
||||
export const DEFAULT_POLICY = 'Fleet Server policy';
|
||||
export const OSQUERY_POLICY = 'Osquery policy';
|
||||
|
|
237
x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
Normal file
237
x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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 type {
|
||||
RuleCreateProps,
|
||||
RuleResponse,
|
||||
} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema';
|
||||
import type { AgentPolicy } from '@kbn/fleet-plugin/common';
|
||||
import type { CaseResponse } from '@kbn/cases-plugin/common';
|
||||
import type { SavedQuerySOFormData } from '../../public/saved_queries/form/use_saved_query_form';
|
||||
import type { LiveQueryDetailsItem } from '../../public/actions/use_live_query_details';
|
||||
import type { PackSavedObject, PackItem } from '../../public/packs/types';
|
||||
import type { SavedQuerySO } from '../../public/routes/saved_queries/list';
|
||||
import { generateRandomStringName } from './integrations';
|
||||
import { request } from './common';
|
||||
|
||||
export const savedQueryFixture = {
|
||||
id: generateRandomStringName(1)[0],
|
||||
description: 'Test saved query description',
|
||||
ecs_mapping: { labels: { field: 'hours' } },
|
||||
interval: '3600',
|
||||
query: 'select * from uptime;',
|
||||
platform: 'linux,darwin',
|
||||
};
|
||||
|
||||
export const packFixture = () => ({
|
||||
description: generateRandomStringName(1)[0],
|
||||
enabled: true,
|
||||
name: generateRandomStringName(1)[0],
|
||||
queries: {
|
||||
[generateRandomStringName(1)[0]]: {
|
||||
ecs_mapping: {},
|
||||
interval: 3600,
|
||||
query: 'select * from uptime;',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const multiQueryPackFixture = () => ({
|
||||
description: generateRandomStringName(1)[0],
|
||||
enabled: true,
|
||||
name: generateRandomStringName(1)[0],
|
||||
queries: {
|
||||
[generateRandomStringName(1)[0]]: {
|
||||
ecs_mapping: {},
|
||||
interval: 3600,
|
||||
platform: 'linux',
|
||||
query: 'SELECT * FROM memory_info;',
|
||||
},
|
||||
[generateRandomStringName(1)[0]]: {
|
||||
ecs_mapping: {},
|
||||
interval: 3600,
|
||||
platform: 'linux,windows,darwin',
|
||||
query: 'SELECT * FROM system_info;',
|
||||
},
|
||||
[generateRandomStringName(1)[0]]: {
|
||||
ecs_mapping: {},
|
||||
interval: 10,
|
||||
query: 'select opera_extensions.* from users join opera_extensions using (uid);',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const loadSavedQuery = (payload: SavedQuerySOFormData = savedQueryFixture) =>
|
||||
request<{ data: SavedQuerySO }>({
|
||||
method: 'POST',
|
||||
body: {
|
||||
...payload,
|
||||
id: payload.id ?? generateRandomStringName(1)[0],
|
||||
},
|
||||
url: '/api/osquery/saved_queries',
|
||||
}).then((response) => response.body.data);
|
||||
|
||||
export const cleanupSavedQuery = (id: string) => {
|
||||
request({ method: 'DELETE', url: `/api/osquery/saved_queries/${id}` });
|
||||
};
|
||||
|
||||
export const loadPack = (payload: Partial<PackItem> = {}, space = 'default') =>
|
||||
request<{ data: PackSavedObject }>({
|
||||
method: 'POST',
|
||||
body: {
|
||||
...payload,
|
||||
name: payload.name ?? generateRandomStringName(1)[0],
|
||||
shards: {},
|
||||
queries: payload.queries ?? {},
|
||||
enabled: payload.enabled || true,
|
||||
},
|
||||
url: `/s/${space}/api/osquery/packs`,
|
||||
}).then((response) => response.body.data);
|
||||
|
||||
export const cleanupPack = (id: string, space = 'default') => {
|
||||
request({ method: 'DELETE', url: `/s/${space}/api/osquery/packs/${id}` });
|
||||
};
|
||||
|
||||
export const loadLiveQuery = (
|
||||
payload = {
|
||||
agent_all: true,
|
||||
query: 'select * from uptime;',
|
||||
}
|
||||
) =>
|
||||
request<{
|
||||
data: LiveQueryDetailsItem & { queries: NonNullable<LiveQueryDetailsItem['queries']> };
|
||||
}>({
|
||||
method: 'POST',
|
||||
body: payload,
|
||||
url: `/api/osquery/live_queries`,
|
||||
}).then((response) => response.body.data);
|
||||
|
||||
export const loadRule = (includeResponseActions = false) =>
|
||||
request<RuleResponse>({
|
||||
method: 'POST',
|
||||
body: {
|
||||
type: 'query',
|
||||
index: [
|
||||
'apm-*-transaction*',
|
||||
'auditbeat-*',
|
||||
'endgame-*',
|
||||
'filebeat-*',
|
||||
'logs-*',
|
||||
'packetbeat-*',
|
||||
'traces-apm*',
|
||||
'winlogbeat-*',
|
||||
'-*elastic-cloud-logs-*',
|
||||
],
|
||||
filters: [],
|
||||
language: 'kuery',
|
||||
query: '_id:*',
|
||||
author: [],
|
||||
false_positives: [],
|
||||
references: [],
|
||||
risk_score: 21,
|
||||
risk_score_mapping: [],
|
||||
severity: 'low',
|
||||
severity_mapping: [],
|
||||
threat: [],
|
||||
name: `Test rule ${generateRandomStringName(1)[0]}`,
|
||||
description: 'Test rule',
|
||||
tags: [],
|
||||
license: '',
|
||||
interval: '1m',
|
||||
from: 'now-120s',
|
||||
to: 'now',
|
||||
meta: { from: '1m', kibana_siem_app_url: 'http://localhost:5620/app/security' },
|
||||
actions: [],
|
||||
enabled: true,
|
||||
throttle: 'no_actions',
|
||||
note: '!{osquery{"query":"SELECT * FROM os_version where name=\'{{host.os.name}}\';","label":"Get processes","ecs_mapping":{"host.os.platform":{"field":"platform"}}}}\n\n!{osquery{"query":"select * from users;","label":"Get users"}}',
|
||||
...(includeResponseActions
|
||||
? {
|
||||
response_actions: [
|
||||
{
|
||||
params: {
|
||||
query: "SELECT * FROM os_version where name='{{host.os.name}}';",
|
||||
ecs_mapping: {
|
||||
'host.os.platform': {
|
||||
field: 'platform',
|
||||
},
|
||||
},
|
||||
},
|
||||
action_type_id: '.osquery',
|
||||
},
|
||||
{
|
||||
params: {
|
||||
query: 'select * from users;',
|
||||
},
|
||||
action_type_id: '.osquery',
|
||||
},
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
} as RuleCreateProps,
|
||||
url: `/api/detection_engine/rules`,
|
||||
}).then((response) => response.body);
|
||||
|
||||
export const cleanupRule = (id: string) => {
|
||||
request({ method: 'DELETE', url: `/api/detection_engine/rules?id=${id}` });
|
||||
};
|
||||
|
||||
export const loadCase = (owner: string) =>
|
||||
request<CaseResponse>({
|
||||
method: 'POST',
|
||||
url: '/api/cases',
|
||||
body: {
|
||||
title: `Test ${owner} case ${generateRandomStringName(1)[0]}`,
|
||||
tags: [],
|
||||
severity: 'low',
|
||||
description: 'Test security case',
|
||||
assignees: [],
|
||||
connector: { id: 'none', name: 'none', type: '.none', fields: null },
|
||||
settings: { syncAlerts: true },
|
||||
owner,
|
||||
},
|
||||
}).then((response) => response.body);
|
||||
|
||||
export const cleanupCase = (id: string) => {
|
||||
request({ method: 'DELETE', url: '/api/cases', qs: { ids: JSON.stringify([id]) } });
|
||||
};
|
||||
|
||||
export const loadSpace = () => {
|
||||
const spaceId = generateRandomStringName(1)[0];
|
||||
|
||||
return request<{ id: string }>({
|
||||
method: 'POST',
|
||||
url: '/api/spaces/space',
|
||||
body: {
|
||||
id: spaceId,
|
||||
name: spaceId,
|
||||
},
|
||||
failOnStatusCode: false,
|
||||
}).then((response) => response.body);
|
||||
};
|
||||
|
||||
export const cleanupSpace = (id: string) =>
|
||||
request({
|
||||
method: 'DELETE',
|
||||
url: `/api/spaces/space/${id}`,
|
||||
});
|
||||
|
||||
export const loadAgentPolicy = () =>
|
||||
request<{ item: AgentPolicy }>({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: generateRandomStringName(1)[0],
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
monitoring_enabled: ['logs', 'metrics'],
|
||||
inactivity_timeout: 1209600,
|
||||
},
|
||||
url: '/api/fleet/agent_policies',
|
||||
}).then((response) => response.body.item);
|
||||
|
||||
export const cleanupAgentPolicy = (agentPolicyId: string) =>
|
||||
request({ method: 'POST', body: { agentPolicyId }, url: '/api/fleet/agent_policies/delete' });
|
22
x-pack/plugins/osquery/cypress/tasks/common.ts
Normal file
22
x-pack/plugins/osquery/cypress/tasks/common.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const API_AUTH = {
|
||||
user: Cypress.env('ELASTICSEARCH_USERNAME'),
|
||||
pass: Cypress.env('ELASTICSEARCH_PASSWORD'),
|
||||
};
|
||||
|
||||
export const API_HEADERS = { 'kbn-xsrf': 'cypress' };
|
||||
|
||||
export const request = <T = unknown>(
|
||||
options: Partial<Cypress.RequestOptions>
|
||||
): Cypress.Chainable<Cypress.Response<T>> =>
|
||||
cy.request<T>({
|
||||
auth: API_AUTH,
|
||||
headers: API_HEADERS,
|
||||
...options,
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const getRandomInt = () => Math.floor(Math.random() * 100);
|
|
@ -28,6 +28,53 @@ export const addIntegration = (agentPolicy = DEFAULT_POLICY) => {
|
|||
closeModalIfVisible();
|
||||
};
|
||||
|
||||
export const addCustomIntegration = (integrationName: string, policyName: string) => {
|
||||
cy.getBySel(ADD_POLICY_BTN).click();
|
||||
cy.getBySel(DATA_COLLECTION_SETUP_STEP).find('.euiLoadingSpinner').should('not.exist');
|
||||
cy.getBySel('packagePolicyNameInput').type(`{selectall}{backspace}${integrationName}`);
|
||||
cy.getBySel('createAgentPolicyNameField').type(`{selectall}{backspace}${policyName}`);
|
||||
cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click();
|
||||
// No agent is enrolled with this policy, close "Add agent" modal
|
||||
cy.getBySel('confirmModalCancelButton').click();
|
||||
};
|
||||
|
||||
export const policyContainsIntegration = (integrationName: string, policyName: string) => {
|
||||
cy.visit('app/fleet/policies');
|
||||
cy.contains(policyName).click();
|
||||
integrationExistsWithinPolicyDetails(integrationName);
|
||||
};
|
||||
|
||||
export const integrationExistsWithinPolicyDetails = (integrationName: string) => {
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('View policy').click();
|
||||
cy.contains(`name: ${integrationName}`);
|
||||
};
|
||||
|
||||
export const interceptAgentPolicyId = (cb: (policyId: string) => void) => {
|
||||
cy.intercept('POST', '**/api/fleet/agent_policies**', (req) => {
|
||||
req.continue((res) => {
|
||||
cb(res.body.item.id);
|
||||
|
||||
return res.send(res.body);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const interceptPackId = (cb: (packId: string) => void) => {
|
||||
cy.intercept('POST', '**/api/osquery/packs', (req) => {
|
||||
req.continue((res) => {
|
||||
if (res.body.data) {
|
||||
cb(res.body.data.id);
|
||||
}
|
||||
|
||||
return res.send(res.body);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const generateRandomStringName = (length: number) =>
|
||||
Array.from({ length }, () => Math.random().toString(36).substring(2));
|
||||
|
||||
export function closeModalIfVisible() {
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find(CONFIRM_MODAL_BTN_SEL).length) {
|
||||
|
|
|
@ -61,7 +61,7 @@ export const getOsqueryFieldTypes = (value: 'Osquery value' | 'Static value', in
|
|||
};
|
||||
|
||||
export const findFormFieldByRowsLabelAndType = (label: string, text: string) => {
|
||||
cy.react('EuiFormRow', { props: { label } }).type(text);
|
||||
cy.react('EuiFormRow', { props: { label } }).type(`${text}{downArrow}{enter}`);
|
||||
};
|
||||
|
||||
export const deleteAndConfirm = (type: string) => {
|
||||
|
@ -80,46 +80,47 @@ export const findAndClickButton = (text: string) => {
|
|||
|
||||
export const toggleRuleOffAndOn = (ruleName: string) => {
|
||||
cy.visit('/app/security/rules');
|
||||
cy.contains(ruleName);
|
||||
cy.wait(2000);
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'false');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
};
|
||||
|
||||
export const loadAlertsEvents = () => {
|
||||
cy.visit('/app/security/alerts');
|
||||
cy.getBySel('header-page-title').contains('Alerts').should('exist');
|
||||
cy.getBySel('expand-event')
|
||||
.first()
|
||||
cy.contains(ruleName)
|
||||
.parents('tr')
|
||||
.within(() => {
|
||||
cy.get(`[data-is-loading="true"]`).should('exist');
|
||||
});
|
||||
cy.getBySel('expand-event')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(`[data-is-loading="true"]`).should('not.exist');
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'false');
|
||||
cy.getBySel('ruleSwitch').click();
|
||||
cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true');
|
||||
});
|
||||
};
|
||||
|
||||
export const addToCase = () => {
|
||||
export const loadRuleAlerts = (ruleName: string) => {
|
||||
cy.visit('/app/security/rules');
|
||||
cy.contains(ruleName).click();
|
||||
cy.getBySel('alertsTable').within(() => {
|
||||
cy.getBySel('expand-event')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(`[data-is-loading="true"]`).should('exist');
|
||||
});
|
||||
cy.getBySel('expand-event')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(`[data-is-loading="true"]`).should('not.exist');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const addToCase = (caseId: string) => {
|
||||
cy.contains('Add to Case').click();
|
||||
cy.contains('Select case');
|
||||
cy.getBySelContains('cases-table-row-');
|
||||
cy.getBySelContains('cases-table-row-select-').click();
|
||||
cy.getBySelContains(`cases-table-row-select-${caseId}`).click();
|
||||
};
|
||||
|
||||
export const addLastLiveQueryToCase = () => {
|
||||
cy.waitForReact();
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1 },
|
||||
})
|
||||
.first()
|
||||
.click();
|
||||
export const addLiveQueryToCase = (actionId: string, caseId: string) => {
|
||||
cy.react('ActionsTableComponent').within(() => {
|
||||
cy.getBySel(`row-${actionId}`).react('ActionTableResultsButton').click();
|
||||
});
|
||||
cy.contains('Live query details');
|
||||
addToCase();
|
||||
addToCase(caseId);
|
||||
};
|
||||
|
||||
const casesOsqueryResultRegex = /attached Osquery results[\s]?[\d]+[\s]?seconds ago/;
|
||||
|
|
|
@ -8,7 +8,38 @@
|
|||
import * as yaml from 'js-yaml';
|
||||
import type { UrlObject } from 'url';
|
||||
import Url from 'url';
|
||||
import type { ROLES } from '../test';
|
||||
import type { Role } from '@kbn/security-plugin/common';
|
||||
import { request } from './common';
|
||||
import adminRole from '../../scripts/roles_users/admin/role.json';
|
||||
import alertTestRole from '../../scripts/roles_users/alert_test/role.json';
|
||||
import noneRole from '../../scripts/roles_users/none/role.json';
|
||||
import platformEngineerRole from '../../scripts/roles_users/platform_engineer/role.json';
|
||||
import readerRole from '../../scripts/roles_users/reader/role.json';
|
||||
import socManagerRole from '../../scripts/roles_users/soc_manager/role.json';
|
||||
import t1AnalystRole from '../../scripts/roles_users/t1_analyst/role.json';
|
||||
import t2AnalystRole from '../../scripts/roles_users/t2_analyst/role.json';
|
||||
|
||||
export enum ROLE {
|
||||
soc_manager = 'soc_manager',
|
||||
reader = 'reader',
|
||||
t1_analyst = 't1_analyst',
|
||||
t2_analyst = 't2_analyst',
|
||||
platform_engineer = 'platform_engineer',
|
||||
admin = 'admin', // base: ['all']
|
||||
alert_test = 'alert_test',
|
||||
none = 'none',
|
||||
}
|
||||
|
||||
export const rolesMapping: { [key in ROLE]: Omit<Role, 'name'> } = {
|
||||
admin: adminRole,
|
||||
alert_test: alertTestRole,
|
||||
none: noneRole,
|
||||
platform_engineer: platformEngineerRole,
|
||||
reader: readerRole,
|
||||
soc_manager: socManagerRole,
|
||||
t1_analyst: t1AnalystRole,
|
||||
t2_analyst: t2AnalystRole,
|
||||
};
|
||||
|
||||
/**
|
||||
* Credentials in the `kibana.dev.yml` config file will be used to authenticate
|
||||
|
@ -53,7 +84,7 @@ const LOGIN_API_ENDPOINT = '/internal/security/login';
|
|||
* @param role string role/user to log in with
|
||||
* @param route string route to visit
|
||||
*/
|
||||
export const getUrlWithRoute = (role: ROLES, route: string) => {
|
||||
export const getUrlWithRoute = (role: ROLE, route: string) => {
|
||||
const url = Cypress.config().baseUrl;
|
||||
const kibana = new URL(String(url));
|
||||
const theUrl = `${Url.format({
|
||||
|
@ -105,38 +136,42 @@ export const getCurlScriptEnvVars = () => ({
|
|||
KIBANA_URL: Cypress.config().baseUrl,
|
||||
});
|
||||
|
||||
export const postRoleAndUser = (role: ROLES) => {
|
||||
const env = getCurlScriptEnvVars();
|
||||
const detectionsRoleScriptPath = `./scripts/roles_users/${role}/post_role.sh`;
|
||||
const detectionsRoleJsonPath = `./scripts/roles_users/${role}/role.json`;
|
||||
const detectionsUserScriptPath = `./scripts/roles_users/${role}/post_user.sh`;
|
||||
const detectionsUserJsonPath = `./scripts/roles_users/${role}/user.json`;
|
||||
|
||||
export const postRoleAndUser = (role: ROLE) => {
|
||||
const rolePrivileges = rolesMapping[role];
|
||||
// post the role
|
||||
cy.exec(`bash ${detectionsRoleScriptPath} ${detectionsRoleJsonPath}`, {
|
||||
env,
|
||||
request({
|
||||
method: 'PUT',
|
||||
url: `/api/security/role/${role}`,
|
||||
body: rolePrivileges,
|
||||
});
|
||||
|
||||
// post the user associated with the role to elasticsearch
|
||||
cy.exec(`bash ${detectionsUserScriptPath} ${detectionsUserJsonPath}`, {
|
||||
env,
|
||||
request({
|
||||
method: 'POST',
|
||||
url: `/internal/security/users/${role}`,
|
||||
body: {
|
||||
username: role,
|
||||
password: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
roles: [role],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteRoleAndUser = (role: ROLES) => {
|
||||
const env = getCurlScriptEnvVars();
|
||||
const detectionsUserDeleteScriptPath = `./scripts/roles_users/${role}/delete_user.sh`;
|
||||
|
||||
// delete the role
|
||||
cy.exec(`bash ${detectionsUserDeleteScriptPath}`, {
|
||||
env,
|
||||
export const deleteRoleAndUser = (role: ROLE) => {
|
||||
request({
|
||||
method: 'DELETE',
|
||||
url: `/internal/security/users/${role}`,
|
||||
});
|
||||
request({
|
||||
method: 'DELETE',
|
||||
url: `/api/security/role/${role}`,
|
||||
});
|
||||
};
|
||||
|
||||
export const loginWithUser = (user: User) => {
|
||||
const url = Cypress.config().baseUrl;
|
||||
|
||||
cy.request({
|
||||
request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: url && !url.includes('localhost') ? 'cloud-basic' : 'basic',
|
||||
|
@ -152,7 +187,7 @@ export const loginWithUser = (user: User) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const loginWithRole = async (role: ROLES) => {
|
||||
export const loginWithRole = async (role: ROLE) => {
|
||||
postRoleAndUser(role);
|
||||
const theUrl = Url.format({
|
||||
auth: `${role}:changeme`,
|
||||
|
@ -189,7 +224,7 @@ export const loginWithRole = async (role: ROLES) => {
|
|||
* To speed the execution of tests, prefer this non-interactive authentication,
|
||||
* which is faster than authentication via Kibana's interactive login page.
|
||||
*/
|
||||
export const login = (role?: ROLES) => {
|
||||
export const login = (role?: ROLE) => {
|
||||
if (role != null) {
|
||||
loginWithRole(role);
|
||||
} else if (credentialsProvidedByEnvironment()) {
|
||||
|
|
|
@ -12,7 +12,6 @@ export const INTEGRATIONS = 'app/integrations#/';
|
|||
export const FLEET = 'app/fleet/';
|
||||
export const FLEET_AGENT_POLICIES = 'app/fleet/policies';
|
||||
export const OSQUERY = 'app/osquery';
|
||||
export const OLD_OSQUERY_MANAGER = 'app/integrations/detail/osquery_manager-0.7.4/settings';
|
||||
export const NEW_LIVE_QUERY = 'app/osquery/live_queries/new';
|
||||
export const OSQUERY_INTEGRATION_PAGE = '/app/fleet/integrations/osquery_manager/add-integration';
|
||||
export const navigateTo = (page: string, opts?: Partial<Cypress.VisitOptions>) => {
|
||||
|
@ -28,3 +27,12 @@ export const navigateTo = (page: string, opts?: Partial<Cypress.VisitOptions>) =
|
|||
export const openNavigationFlyout = () => {
|
||||
cy.get(TOGGLE_NAVIGATION_BTN).click();
|
||||
};
|
||||
|
||||
export const createOldOsqueryPath = (version: string) =>
|
||||
`app/integrations/detail/osquery_manager-${version}/settings`;
|
||||
|
||||
export enum NAV_SEARCH_INPUT_OSQUERY_RESULTS {
|
||||
MANAGEMENT = '/app/osquery',
|
||||
LOGS = '/app/integrations/detail/osquery/overview',
|
||||
MANAGER = '/app/integrations/detail/osquery_manager/overview',
|
||||
}
|
||||
|
|
|
@ -5,10 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { some } from 'lodash';
|
||||
import type { UsePacksResponse } from '../../public/packs/use_packs';
|
||||
import { request } from './common';
|
||||
import { closeModalIfVisible, closeToastIfVisible } from './integrations';
|
||||
import { cleanupPack } from './api_fixtures';
|
||||
|
||||
export const preparePack = (packName: string) => {
|
||||
cy.contains('Packs').click();
|
||||
cy.getBySel('tablePaginationPopoverButton').click();
|
||||
cy.getBySel('tablePagination-50-rows').click();
|
||||
const createdPack = cy.contains(packName);
|
||||
createdPack.click();
|
||||
};
|
||||
|
@ -34,3 +40,16 @@ export const activatePack = (packName: string) => {
|
|||
cy.contains(`Successfully activated "${packName}" pack`).should('exist');
|
||||
closeToastIfVisible();
|
||||
};
|
||||
|
||||
export const cleanupAllPrebuiltPacks = () => {
|
||||
request<UsePacksResponse>({
|
||||
method: 'GET',
|
||||
url: '/api/osquery/packs',
|
||||
}).then((response) => {
|
||||
const prebuiltPacks = response.body.data?.filter((pack) =>
|
||||
some(pack.references, { type: 'osquery-pack-asset' })
|
||||
);
|
||||
|
||||
return Promise.all(prebuiltPacks?.map((pack) => cleanupPack(pack.id)));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { RESULTS_TABLE_BUTTON } from '../screens/live_query';
|
||||
import { closeToastIfVisible } from './integrations';
|
||||
import { closeToastIfVisible, generateRandomStringName } from './integrations';
|
||||
import {
|
||||
checkResults,
|
||||
BIG_QUERY,
|
||||
|
@ -18,114 +18,120 @@ import {
|
|||
} from './live_query';
|
||||
import { navigateTo } from './navigation';
|
||||
|
||||
export const getSavedQueriesComplexTest = (savedQueryId: string, savedQueryDescription: string) =>
|
||||
it(
|
||||
'should create a new query and verify: \n ' +
|
||||
'- hidden columns, full screen and sorting \n' +
|
||||
'- pagination \n' +
|
||||
'- query can viewed (status), edited and deleted ',
|
||||
() => {
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery(BIG_QUERY);
|
||||
submitQuery();
|
||||
checkResults();
|
||||
// enter fullscreen
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('exist');
|
||||
cy.contains('Exit fullscreen').should('not.exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).click();
|
||||
export const getSavedQueriesComplexTest = () =>
|
||||
describe('Saved queries Complex Test', () => {
|
||||
const suffix = generateRandomStringName(1)[0];
|
||||
const savedQueryId = `Saved-Query-Id-${suffix}`;
|
||||
const savedQueryDescription = `Test saved query description ${suffix}`;
|
||||
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter Fullscreen$/).should('not.exist');
|
||||
cy.contains('Exit fullscreen').should('exist');
|
||||
it(
|
||||
'should create a new query and verify: \n ' +
|
||||
'- hidden columns, full screen and sorting \n' +
|
||||
'- pagination \n' +
|
||||
'- query can viewed (status), edited and deleted ',
|
||||
() => {
|
||||
cy.contains('New live query').click();
|
||||
selectAllAgents();
|
||||
inputQuery(BIG_QUERY);
|
||||
submitQuery();
|
||||
checkResults();
|
||||
// enter fullscreen
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('exist');
|
||||
cy.contains('Exit fullscreen').should('not.exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).click();
|
||||
|
||||
// hidden columns
|
||||
cy.contains('columns hidden').should('not.exist');
|
||||
cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'osquery.cmdline' } }).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.cwd' },
|
||||
}).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.disk_bytes_written.number' },
|
||||
}).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
// change pagination
|
||||
cy.getBySel('pagination-button-next').click().wait(500).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter Fullscreen$/).should('not.exist');
|
||||
cy.contains('Exit fullscreen').should('exist');
|
||||
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('not.exist');
|
||||
cy.contains('Exit fullscreen').should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).click();
|
||||
// hidden columns
|
||||
cy.contains('columns hidden').should('not.exist');
|
||||
cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'osquery.cmdline' } }).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.cwd' },
|
||||
}).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.disk_bytes_written.number' },
|
||||
}).click();
|
||||
cy.contains(/Hide column$/).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
// change pagination
|
||||
cy.getBySel('pagination-button-next').click().wait(500).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
|
||||
// sorting
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.egid' },
|
||||
}).click();
|
||||
cy.contains(/Sort A-Z$/).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('not.exist');
|
||||
cy.contains('Exit fullscreen').should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).click();
|
||||
|
||||
// visit Status results
|
||||
cy.react('EuiTab', { props: { id: 'status' } }).click();
|
||||
cy.react('EuiTableRow').should('have.lengthOf', 2);
|
||||
// sorting
|
||||
cy.react('EuiDataGridHeaderCellWrapper', {
|
||||
props: { id: 'osquery.egid' },
|
||||
}).click();
|
||||
cy.contains(/Sort A-Z$/).click();
|
||||
cy.contains('columns hidden').should('exist');
|
||||
cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover');
|
||||
cy.contains(/Enter fullscreen$/).should('exist');
|
||||
|
||||
// save new query
|
||||
cy.contains('Exit full screen').should('not.exist');
|
||||
cy.contains('Save for later').click();
|
||||
cy.contains('Save query');
|
||||
findFormFieldByRowsLabelAndType('ID', savedQueryId);
|
||||
findFormFieldByRowsLabelAndType('Description (optional)', savedQueryDescription);
|
||||
cy.react('EuiButtonDisplay').contains('Save').click();
|
||||
cy.contains('Successfully saved');
|
||||
closeToastIfVisible();
|
||||
// visit Status results
|
||||
cy.react('EuiTab', { props: { id: 'status' } }).click();
|
||||
cy.react('EuiTableRow').should('have.lengthOf', 2);
|
||||
|
||||
// play saved query
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('PlayButtonComponent', {
|
||||
props: { savedQuery: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
selectAllAgents();
|
||||
submitQuery();
|
||||
// save new query
|
||||
cy.contains('Exit full screen').should('not.exist');
|
||||
cy.contains('Save for later').click();
|
||||
cy.contains('Save query');
|
||||
findFormFieldByRowsLabelAndType('ID', savedQueryId);
|
||||
findFormFieldByRowsLabelAndType('Description (optional)', savedQueryDescription);
|
||||
cy.react('EuiButtonDisplay').contains('Save').click();
|
||||
cy.contains('Successfully saved');
|
||||
closeToastIfVisible();
|
||||
|
||||
// edit saved query
|
||||
cy.contains('Saved queries').click();
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
findFormFieldByRowsLabelAndType('Description (optional)', ' Edited');
|
||||
// Run in test configuration
|
||||
cy.contains('Test configuration').click();
|
||||
selectAllAgents();
|
||||
submitQuery();
|
||||
checkResults();
|
||||
// play saved query
|
||||
navigateTo('/app/osquery/saved_queries');
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('PlayButtonComponent', {
|
||||
props: { savedQuery: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
selectAllAgents();
|
||||
submitQuery();
|
||||
|
||||
// Disabled submit button in test configuration
|
||||
cy.contains('Submit').should('not.be.disabled');
|
||||
// this clears the input
|
||||
inputQuery('{selectall}{backspace}{selectall}{backspace}');
|
||||
cy.contains('Submit').should('be.disabled');
|
||||
inputQuery(BIG_QUERY);
|
||||
cy.contains('Submit').should('not.be.disabled');
|
||||
// edit saved query
|
||||
cy.contains('Saved queries').click();
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
findFormFieldByRowsLabelAndType('Description (optional)', ' Edited');
|
||||
// Run in test configuration
|
||||
cy.contains('Test configuration').click();
|
||||
selectAllAgents();
|
||||
submitQuery();
|
||||
checkResults();
|
||||
|
||||
// Save edited
|
||||
cy.react('EuiButton').contains('Update query').click();
|
||||
cy.contains(`${savedQueryDescription} Edited`);
|
||||
// Disabled submit button in test configuration
|
||||
cy.contains('Submit').should('not.be.disabled');
|
||||
// this clears the input
|
||||
inputQuery('{selectall}{backspace}{selectall}{backspace}');
|
||||
cy.contains('Submit').should('be.disabled');
|
||||
inputQuery(BIG_QUERY);
|
||||
cy.contains('Submit').should('not.be.disabled');
|
||||
|
||||
// delete saved query
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
deleteAndConfirm('query');
|
||||
cy.contains(savedQueryId).should('exist');
|
||||
cy.contains(savedQueryId).should('not.exist');
|
||||
}
|
||||
);
|
||||
// Save edited
|
||||
cy.react('EuiButton').contains('Update query').click();
|
||||
cy.contains(`${savedQueryDescription} Edited`);
|
||||
|
||||
// delete saved query
|
||||
cy.contains(savedQueryId);
|
||||
cy.react('CustomItemAction', {
|
||||
props: { index: 1, item: { attributes: { id: savedQueryId } } },
|
||||
}).click();
|
||||
deleteAndConfirm('query');
|
||||
cy.contains(savedQueryId).should('exist');
|
||||
cy.contains(savedQueryId).should('not.exist');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// For the source of these roles please consult the PR these were introduced https://github.com/elastic/kibana/pull/81866#issue-511165754
|
||||
export enum ROLES {
|
||||
soc_manager = 'soc_manager',
|
||||
reader = 'reader',
|
||||
t1_analyst = 't1_analyst',
|
||||
t2_analyst = 't2_analyst',
|
||||
hunter = 'hunter',
|
||||
rule_author = 'rule_author',
|
||||
platform_engineer = 'platform_engineer',
|
||||
detections_admin = 'detections_admin',
|
||||
admin = 'admin', // base: ['all']
|
||||
alert_test = 'alert_test',
|
||||
none = 'none',
|
||||
}
|
|
@ -24,6 +24,10 @@
|
|||
{
|
||||
"path": "../tsconfig.json",
|
||||
"force": true
|
||||
}
|
||||
},
|
||||
"@kbn/security-plugin",
|
||||
"@kbn/security-solution-plugin",
|
||||
"@kbn/fleet-plugin",
|
||||
"@kbn/cases-plugin"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -264,6 +264,13 @@ const ActionsTableComponent = () => {
|
|||
[actionsData, pageIndex, pageSize]
|
||||
);
|
||||
|
||||
const rowProps = useCallback(
|
||||
(data) => ({
|
||||
'data-test-subj': `row-${data._source.action_id}`,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiBasicTable
|
||||
items={actionsData?.data?.items ?? EMPTY_ARRAY}
|
||||
|
@ -271,6 +278,8 @@ const ActionsTableComponent = () => {
|
|||
columns={columns}
|
||||
pagination={pagination}
|
||||
onChange={onTableChange}
|
||||
rowProps={rowProps}
|
||||
data-test-subj="liveQueryActionsTable"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ export interface LiveQueryDetailsItem {
|
|||
'@timestamp': string;
|
||||
agent_all: boolean;
|
||||
agent_ids: string[];
|
||||
agent_platforoms: string[];
|
||||
agent_platforms: string[];
|
||||
agent_policy_ids: string[];
|
||||
agents: string[];
|
||||
user_id?: string;
|
||||
|
|
|
@ -72,6 +72,7 @@ const OsqueryAppEmptyStateComponent = () => {
|
|||
href={integrationHref}
|
||||
onClick={integrationClick}
|
||||
iconType="plusInCircleFilled"
|
||||
data-test-subj="osquery-add-integration-button"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.osquery.emptyState.addOsqueryManagerButton"
|
||||
|
|
|
@ -145,7 +145,7 @@ const PackFormComponent: React.FC<PackFormProps> = ({
|
|||
async (values: PackFormData) => {
|
||||
const serializer = ({
|
||||
shards: _,
|
||||
policy_ids: payloadPolicyIds,
|
||||
policy_ids: payloadAgentPolicyIds,
|
||||
queries,
|
||||
...restPayload
|
||||
}: PackFormData) => {
|
||||
|
@ -158,7 +158,7 @@ const PackFormComponent: React.FC<PackFormProps> = ({
|
|||
})
|
||||
) as string[])
|
||||
: [];
|
||||
const policies = [...payloadPolicyIds, ...mappedShards];
|
||||
const policies = [...payloadAgentPolicyIds, ...mappedShards];
|
||||
|
||||
return {
|
||||
...restPayload,
|
||||
|
|
|
@ -12,6 +12,10 @@ import { useKibana } from '../common/lib/kibana';
|
|||
import { PACKS_ID } from './constants';
|
||||
import type { PackSavedObject } from './types';
|
||||
|
||||
export type UsePacksResponse = Omit<SavedObjectsFindResponse, 'savedObjects'> & {
|
||||
data: PackSavedObject[];
|
||||
};
|
||||
|
||||
export const usePacks = ({
|
||||
isLive = false,
|
||||
pageIndex = 0,
|
||||
|
@ -21,11 +25,7 @@ export const usePacks = ({
|
|||
}) => {
|
||||
const { http } = useKibana().services;
|
||||
|
||||
return useQuery<
|
||||
Omit<SavedObjectsFindResponse, 'savedObjects'> & {
|
||||
data: PackSavedObject[];
|
||||
}
|
||||
>(
|
||||
return useQuery<UsePacksResponse>(
|
||||
[PACKS_ID, { pageIndex, pageSize, sortField, sortOrder }],
|
||||
() =>
|
||||
http.get('/api/osquery/packs', {
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/admin
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/admin | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as adminUser from './user.json';
|
||||
import * as adminRole from './role.json';
|
||||
|
||||
export { adminUser, adminRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/admin \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/admin \
|
||||
-d @${USER}
|
|
@ -1,15 +1,18 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": ["all"],
|
||||
"feature": {},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["admin"],
|
||||
"full_name": "Admin",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/alert_test
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/alert_test | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as alertTestUser from './user.json';
|
||||
import * as alertTestRole from './role.json';
|
||||
|
||||
export { alertTestUser, alertTestRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/alert_test \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/alert_test \
|
||||
-d @${USER}
|
|
@ -14,10 +14,12 @@
|
|||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"discover": ["read"],
|
||||
"infrastructure": ["read"],
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["alert_test"],
|
||||
"full_name": "Alert Test",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './platform_engineer';
|
||||
export * from './reader';
|
||||
export * from './t1_analyst';
|
||||
export * from './t2_analyst';
|
||||
export * from './soc_manager';
|
||||
export * from './alert_test';
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/none
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/none | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as noneUser from './user.json';
|
||||
import * as noneRole from './role.json';
|
||||
|
||||
export { noneUser, noneRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/none \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/none \
|
||||
-d @${USER}
|
|
@ -14,10 +14,12 @@
|
|||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"discover": ["read"],
|
||||
"infrastructure": ["read"],
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["none"],
|
||||
"full_name": "Osquery none",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/platform_engineer
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/platform_engineer | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as platformEngineerUser from './user.json';
|
||||
import * as platformEngineerRole from './role.json';
|
||||
|
||||
export { platformEngineerUser, platformEngineerRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/platform_engineer \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/platform_engineer \
|
||||
-d @${USER}
|
|
@ -1,14 +1,17 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"fleet": ["all"],
|
||||
"osquery": ["all"]
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["platform_engineer"],
|
||||
"full_name": "Platform Engineer",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/reader
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/reader | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as readerUser from './user.json';
|
||||
import * as readerRole from './role.json';
|
||||
|
||||
export { readerUser, readerRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/reader \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/reader \
|
||||
-d @${USER}
|
|
@ -1,14 +1,17 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"osquery": ["read"]
|
||||
},
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["reader"],
|
||||
"full_name": "Reader",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/soc_manager
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/soc_manager | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as socManagerUser from './user.json';
|
||||
import * as socManagerRole from './role.json';
|
||||
|
||||
export { socManagerUser, socManagerRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/soc_manager \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/soc_manager \
|
||||
-d @${USER}
|
|
@ -10,10 +10,12 @@
|
|||
"names": ["*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"discover": ["all"],
|
||||
"infrastructure": ["read"],
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["soc_manager"],
|
||||
"full_name": "SOC Manager",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/t1_analyst
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/t1_analyst | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as t1AnalystUser from './user.json';
|
||||
import * as t1AnalystRole from './role.json';
|
||||
|
||||
export { t1AnalystUser, t1AnalystRole };
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
ROLE_CONFIG=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/t1_analyst \
|
||||
-d @${ROLE_CONFIG}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/t1_analyst \
|
||||
-d @${USER}
|
|
@ -14,10 +14,12 @@
|
|||
"names": ["logs-osquery_manager*"],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
],
|
||||
"run_as": []
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"base": [],
|
||||
"feature": {
|
||||
"siem": ["all"],
|
||||
"osquery": ["read", "run_saved_queries" ]
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["t1_analyst"],
|
||||
"full_name": "T1 Analyst",
|
||||
"email": "osquery@example.com"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/t2_analyst
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/t2_analyst | jq -S .
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* 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 * as t2AnalystUser from './user.json';
|
||||
import * as t2AnalystRole from './role.json';
|
||||
|
||||
export { t2AnalystUser, t2AnalystRole };
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue