Skip to content

Commit

Permalink
[Defend Workflows] Add API versioning to Osquery (#160243)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsonpl authored Jul 1, 2023
1 parent 055a104 commit b83f881
Show file tree
Hide file tree
Showing 56 changed files with 2,253 additions and 1,908 deletions.
9 changes: 9 additions & 0 deletions x-pack/plugins/osquery/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ export const ACTION_RESPONSES_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.action.
export const DEFAULT_PLATFORM = 'linux,windows,darwin';

export const CASE_ATTACHMENT_TYPE_ID = 'osquery';

export const API_VERSIONS = {
public: {
v1: '2023-10-31',
},
internal: {
v1: '1',
},
};
34 changes: 26 additions & 8 deletions x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import { recurse } from 'cypress-recurse';
import { find } from 'lodash';
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../../common/constants';
import { FLEET_AGENT_POLICIES, navigateTo } from '../../tasks/navigation';
import {
checkActionItemsInResults,
Expand Down Expand Up @@ -46,6 +48,7 @@ import {
loadPack,
cleanupAgentPolicy,
} from '../../tasks/api_fixtures';
import { request } from '../../tasks/common';

describe('ALL - Packs', () => {
let savedQueryId: string;
Expand Down Expand Up @@ -225,12 +228,17 @@ describe('ALL - Packs', () => {
query: 'select * from uptime;',
},
};
cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => {
request<{ items: PackagePolicy[] }>({
url: '/internal/osquery/fleet_wrapper/package_policies',
headers: {
'Elastic-Api-Version': API_VERSIONS.internal.v1,
},
}).then((response) => {
const item = response.body.items.find(
(policy: { policy_id: string }) => policy.policy_id === 'fleet-server-policy'
(policy: PackagePolicy) => policy.policy_id === 'fleet-server-policy'
);

expect(item.inputs[0].config.osquery.value.packs[packName].queries).to.deep.equal(
expect(item?.inputs[0].config?.osquery.value.packs[packName].queries).to.deep.equal(
queries
);
});
Expand Down Expand Up @@ -829,10 +837,15 @@ describe('ALL - Packs', () => {
addIntegration(agentPolicy);
cy.contains('Add Elastic Agent later').click();
cy.contains('osquery_manager-');
cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => {
request<{ items: PackagePolicy[] }>({
url: '/internal/osquery/fleet_wrapper/package_policies',
headers: {
'Elastic-Api-Version': API_VERSIONS.internal.v1,
},
}).then((response) => {
const item = find(response.body.items, ['policy_id', agentPolicyId]);

expect(item.inputs[0].config.osquery.value.packs[globalPack]).to.deep.equal({
expect(item?.inputs[0].config?.osquery.value.packs[globalPack]).to.deep.equal({
shard: 100,
queries: {},
});
Expand Down Expand Up @@ -879,12 +892,17 @@ describe('ALL - Packs', () => {
cy.contains(`Successfully created "${shardPack}" pack`);
closeToastIfVisible();

cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => {
request<{ items: PackagePolicy[] }>({
url: '/internal/osquery/fleet_wrapper/package_policies',
headers: {
'Elastic-Api-Version': API_VERSIONS.internal.v1,
},
}).then((response) => {
const shardPolicy = response.body.items.find(
(policy: { policy_id: string }) => policy.policy_id === 'fleet-server-policy'
(policy: PackagePolicy) => policy.policy_id === 'fleet-server-policy'
);

expect(shardPolicy.inputs[0].config.osquery.value.packs[shardPack]).to.deep.equal({
expect(shardPolicy?.inputs[0].config?.osquery.value.packs[shardPack]).to.deep.equal({
shard: 15,
queries: {},
});
Expand Down
40 changes: 36 additions & 4 deletions x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema';
import type { AgentPolicy } from '@kbn/fleet-plugin/common';
import type { Case } from '@kbn/cases-plugin/common';
import { API_VERSIONS } from '../../common/constants';
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';
Expand Down Expand Up @@ -72,11 +73,20 @@ export const loadSavedQuery = (payload: SavedQuerySOFormData = savedQueryFixture
...payload,
id: payload.id ?? generateRandomStringName(1)[0],
},
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
url: '/api/osquery/saved_queries',
}).then((response) => response.body.data);

export const cleanupSavedQuery = (id: string) => {
request({ method: 'DELETE', url: `/api/osquery/saved_queries/${id}` });
request({
method: 'DELETE',
url: `/api/osquery/saved_queries/${id}`,
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
});
};

export const loadPack = (payload: Partial<PackItem> = {}, space = 'default') =>
Expand All @@ -89,11 +99,20 @@ export const loadPack = (payload: Partial<PackItem> = {}, space = 'default') =>
queries: payload.queries ?? {},
enabled: payload.enabled || true,
},
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
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}` });
request({
method: 'DELETE',
url: `/s/${space}/api/osquery/packs/${id}`,
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
});
};

export const loadLiveQuery = (
Expand All @@ -108,6 +127,9 @@ export const loadLiveQuery = (
method: 'POST',
body: payload,
url: `/api/osquery/live_queries`,
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
}).then((response) => response.body.data);

export const loadRule = (includeResponseActions = false) =>
Expand Down Expand Up @@ -177,7 +199,13 @@ export const loadRule = (includeResponseActions = false) =>
}).then((response) => response.body);

export const cleanupRule = (id: string) => {
request({ method: 'DELETE', url: `/api/detection_engine/rules?id=${id}` });
request({
method: 'DELETE',
url: `/api/detection_engine/rules?id=${id}`,
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
});
};

export const loadCase = (owner: string) =>
Expand All @@ -197,7 +225,11 @@ export const loadCase = (owner: string) =>
}).then((response) => response.body);

export const cleanupCase = (id: string) => {
request({ method: 'DELETE', url: '/api/cases', qs: { ids: JSON.stringify([id]) } });
request({
method: 'DELETE',
url: '/api/cases',
qs: { ids: JSON.stringify([id]) },
});
};

export const loadSpace = () => {
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/osquery/cypress/tasks/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ export const request = <T = unknown>(
): Cypress.Chainable<Cypress.Response<T>> =>
cy.request<T>({
auth: API_AUTH,
headers: API_HEADERS,
...options,
headers: { ...API_HEADERS, ...options.headers },
});
4 changes: 4 additions & 0 deletions x-pack/plugins/osquery/cypress/tasks/packs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { some } from 'lodash';
import { API_VERSIONS } from '../../common/constants';
import type { UsePacksResponse } from '../../public/packs/use_packs';
import { request } from './common';
import { closeModalIfVisible, closeToastIfVisible } from './integrations';
Expand Down Expand Up @@ -45,6 +46,9 @@ export const cleanupAllPrebuiltPacks = () => {
request<UsePacksResponse>({
method: 'GET',
url: '/api/osquery/packs',
headers: {
'Elastic-Api-Version': API_VERSIONS.public.v1,
},
}).then((response) => {
const prebuiltPacks = response.body.data?.filter((pack) =>
some(pack.references, { type: 'osquery-pack-asset' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
*/

import { useQuery } from '@tanstack/react-query';
import { API_VERSIONS } from '../../common/constants';
import { useKibana } from '../common/lib/kibana';

export const useActionResultsPrivileges = () => {
const { http } = useKibana().services;

return useQuery(
['actionResultsPrivileges'],
() => http.get('/internal/osquery/privileges_check'),
() => http.get('/internal/osquery/privileges_check', { version: API_VERSIONS.internal.v1 }),
{
keepPreviousData: true,
}
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/osquery/public/actions/use_all_live_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { useQuery } from '@tanstack/react-query';

import { i18n } from '@kbn/i18n';
import { API_VERSIONS } from '../../common/constants';
import { createFilter } from '../common/helpers';
import { useKibana } from '../common/lib/kibana';
import type { ActionEdges, ActionsStrategyResponse } from '../../common/search_strategy';
Expand Down Expand Up @@ -50,6 +51,7 @@ export const useAllLiveQueries = ({
http.get<{ data: Omit<ActionsStrategyResponse, 'edges'> & { items: ActionEdges } }>(
'/api/osquery/live_queries',
{
version: API_VERSIONS.public.v1,
query: {
filterQuery: createFilter(filterQuery),
page: activePage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import { filter } from 'lodash';
import type { ECSMapping } from '@kbn/osquery-io-ts-types';
import { API_VERSIONS } from '../../common/constants';
import { useKibana } from '../common/lib/kibana';
import type { ESTermQuery } from '../../common/typed_json';
import { useErrorToast } from '../common/hooks/use_error_toast';
Expand Down Expand Up @@ -63,7 +64,7 @@ export const useLiveQueryDetails = ({

return useQuery<{ data: LiveQueryDetailsItem }, Error, LiveQueryDetailsItem>(
['liveQueries', { actionId, filterQuery, queryIds }],
() => http.get(`/api/osquery/live_queries/${actionId}`),
() => http.get(`/api/osquery/live_queries/${actionId}`, { version: API_VERSIONS.public.v1 }),
{
enabled: !skip && !!actionId,
refetchInterval: isLive ? 5000 : false,
Expand Down
36 changes: 22 additions & 14 deletions x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query';

import { i18n } from '@kbn/i18n';
import type { GetAgentPoliciesResponseItem } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../common/constants';
import { useKibana } from '../common/lib/kibana';
import { useErrorToast } from '../common/hooks/use_error_toast';

Expand All @@ -24,19 +25,26 @@ export const useAgentPolicies = () => {
agentPoliciesById: Record<string, GetAgentPoliciesResponseItem>;
agentPolicies: GetAgentPoliciesResponseItem[];
}
>(['agentPolicies'], () => http.get('/internal/osquery/fleet_wrapper/agent_policies'), {
initialData: [],
keepPreviousData: true,
select: (response) => ({
agentPoliciesById: mapKeys(response, 'id'),
agentPolicies: response,
}),
onSuccess: () => setErrorToast(),
onError: (error) =>
setErrorToast(error as Error, {
title: i18n.translate('xpack.osquery.agent_policies.fetchError', {
defaultMessage: 'Error while fetching agent policies',
}),
>(
['agentPolicies'],
() =>
http.get('/internal/osquery/fleet_wrapper/agent_policies', {
version: API_VERSIONS.internal.v1,
}),
{
initialData: [],
keepPreviousData: true,
select: (response) => ({
agentPoliciesById: mapKeys(response, 'id'),
agentPolicies: response,
}),
});
onSuccess: () => setErrorToast(),
onError: (error) =>
setErrorToast(error as Error, {
title: i18n.translate('xpack.osquery.agent_policies.fetchError', {
defaultMessage: 'Error while fetching agent policies',
}),
}),
}
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useQuery } from '@tanstack/react-query';

import { i18n } from '@kbn/i18n';
import type { AgentPolicy } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../common/constants';
import { useKibana } from '../common/lib/kibana';
import { useErrorToast } from '../common/hooks/use_error_toast';

Expand All @@ -24,7 +25,10 @@ export const useAgentPolicy = ({ policyId, skip, silent }: UseAgentPolicy) => {

return useQuery<{ item: AgentPolicy }, Error, AgentPolicy>(
['agentPolicy', { policyId }],
() => http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`),
() =>
http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`, {
version: API_VERSIONS.internal.v1,
}),
{
enabled: !!(policyId && !skip),
keepPreviousData: true,
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/osquery/public/agents/use_agent_details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n';
import { useQuery } from '@tanstack/react-query';

import type { GetOneAgentResponse } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../common/constants';
import { useErrorToast } from '../common/hooks/use_error_toast';
import { useKibana } from '../common/lib/kibana';

Expand All @@ -24,7 +25,10 @@ export const useAgentDetails = ({ agentId, silent, skip }: UseAgentDetails) => {

return useQuery<GetOneAgentResponse, unknown, GetOneAgentResponse['item']>(
['agentDetails', agentId],
() => http.get(`/internal/osquery/fleet_wrapper/agents/${agentId}`),
() =>
http.get(`/internal/osquery/fleet_wrapper/agents/${agentId}`, {
version: API_VERSIONS.internal.v1,
}),
{
enabled: !skip,
retry: false,
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/osquery/public/agents/use_agent_policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { UseQueryResult } from '@tanstack/react-query';
import { useQueries } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import type { GetOneAgentPolicyResponse } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../common/constants';
import { useKibana } from '../common/lib/kibana';
import { useErrorToast } from '../common/hooks/use_error_toast';

Expand All @@ -20,7 +21,10 @@ export const useAgentPolicies = (policyIds: string[] = []) => {
const agentResponse = useQueries({
queries: policyIds.map((policyId) => ({
queryKey: ['agentPolicy', policyId],
queryFn: () => http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`),
queryFn: () =>
http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`, {
version: API_VERSIONS.internal.v1,
}),
enabled: policyIds.length > 0,
onSuccess: () => setErrorToast(),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useQuery } from '@tanstack/react-query';

import type { Agent } from '@kbn/fleet-plugin/common';
import { AGENTS_PREFIX } from '@kbn/fleet-plugin/common';
import { API_VERSIONS } from '../../common/constants';
import { useErrorToast } from '../common/hooks/use_error_toast';
import { useKibana } from '../common/lib/kibana';

Expand All @@ -34,6 +35,7 @@ export const useAgentPolicyAgentIds = ({
const kuery = `${AGENTS_PREFIX}.policy_id:${agentPolicyId}`;

return http.get(`/internal/osquery/fleet_wrapper/agents`, {
version: API_VERSIONS.internal.v1,
query: {
kuery,
perPage: 10000,
Expand Down
Loading

0 comments on commit b83f881

Please sign in to comment.