store/cockpitApi: query for oscap customizations
Use the oscap & scap-security guide packages on the host to get the customizations for an OpenSCAP profile item.
This commit is contained in:
parent
12a2649198
commit
c7cd9e8de3
5 changed files with 93 additions and 10 deletions
|
|
@ -24,7 +24,11 @@ import {
|
||||||
RHEL_10_BETA,
|
RHEL_10_BETA,
|
||||||
RHEL_10,
|
RHEL_10,
|
||||||
} from '../../../../constants';
|
} from '../../../../constants';
|
||||||
import { useGetOscapProfilesQuery } from '../../../../store/backendApi';
|
import {
|
||||||
|
useGetOscapProfilesQuery,
|
||||||
|
useGetOscapCustomizationsQuery,
|
||||||
|
useLazyGetOscapCustomizationsQuery,
|
||||||
|
} from '../../../../store/backendApi';
|
||||||
import { usePoliciesQuery, PolicyRead } from '../../../../store/complianceApi';
|
import { usePoliciesQuery, PolicyRead } from '../../../../store/complianceApi';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
||||||
import {
|
import {
|
||||||
|
|
@ -32,8 +36,6 @@ import {
|
||||||
DistributionProfileItem,
|
DistributionProfileItem,
|
||||||
Filesystem,
|
Filesystem,
|
||||||
OpenScapProfile,
|
OpenScapProfile,
|
||||||
useGetOscapCustomizationsQuery,
|
|
||||||
useLazyGetOscapCustomizationsQuery,
|
|
||||||
Services,
|
Services,
|
||||||
} from '../../../../store/imageBuilderApi';
|
} from '../../../../store/imageBuilderApi';
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,10 @@ import {
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
|
|
||||||
import { RELEASES } from '../../../../constants';
|
import { RELEASES } from '../../../../constants';
|
||||||
|
import { useGetOscapCustomizationsQuery } from '../../../../store/backendApi';
|
||||||
import { PolicyRead, usePolicyQuery } from '../../../../store/complianceApi';
|
import { PolicyRead, usePolicyQuery } from '../../../../store/complianceApi';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
||||||
import {
|
import { OpenScapProfile } from '../../../../store/imageBuilderApi';
|
||||||
OpenScapProfile,
|
|
||||||
useGetOscapCustomizationsQuery,
|
|
||||||
} from '../../../../store/imageBuilderApi';
|
|
||||||
import {
|
import {
|
||||||
changeCompliance,
|
changeCompliance,
|
||||||
selectCompliancePolicyID,
|
selectCompliancePolicyID,
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,11 @@ import {
|
||||||
COMPLIANCE_AND_VULN_SCANNING_URL,
|
COMPLIANCE_AND_VULN_SCANNING_URL,
|
||||||
COMPLIANCE_URL,
|
COMPLIANCE_URL,
|
||||||
} from '../../../../constants';
|
} from '../../../../constants';
|
||||||
import { useBackendPrefetch } from '../../../../store/backendApi';
|
import {
|
||||||
|
useBackendPrefetch,
|
||||||
|
useGetOscapCustomizationsQuery,
|
||||||
|
} from '../../../../store/backendApi';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
||||||
import { useGetOscapCustomizationsQuery } from '../../../../store/imageBuilderApi';
|
|
||||||
import {
|
import {
|
||||||
ComplianceType,
|
ComplianceType,
|
||||||
selectComplianceProfileID,
|
selectComplianceProfileID,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,14 @@ export const useGetOscapProfilesQuery = process.env.IS_ON_PREMISE
|
||||||
? cockpitQueries.useGetOscapProfilesQuery
|
? cockpitQueries.useGetOscapProfilesQuery
|
||||||
: serviceQueries.useGetOscapProfilesQuery;
|
: serviceQueries.useGetOscapProfilesQuery;
|
||||||
|
|
||||||
|
export const useGetOscapCustomizationsQuery = process.env.IS_ON_PREMISE
|
||||||
|
? cockpitQueries.useGetOscapCustomizationsQuery
|
||||||
|
: serviceQueries.useGetOscapCustomizationsQuery;
|
||||||
|
|
||||||
|
export const useLazyGetOscapCustomizationsQuery = process.env.IS_ON_PREMISE
|
||||||
|
? cockpitQueries.useLazyGetOscapCustomizationsQuery
|
||||||
|
: serviceQueries.useLazyGetOscapCustomizationsQuery;
|
||||||
|
|
||||||
export const useComposeBlueprintMutation = process.env.IS_ON_PREMISE
|
export const useComposeBlueprintMutation = process.env.IS_ON_PREMISE
|
||||||
? cockpitQueries.useComposeBlueprintMutation
|
? cockpitQueries.useComposeBlueprintMutation
|
||||||
: serviceQueries.useComposeBlueprintMutation;
|
: serviceQueries.useComposeBlueprintMutation;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import path from 'path';
|
||||||
// We also needed to create an alias in vitest to make this work.
|
// We also needed to create an alias in vitest to make this work.
|
||||||
import cockpit from 'cockpit';
|
import cockpit from 'cockpit';
|
||||||
import { fsinfo } from 'cockpit/fsinfo';
|
import { fsinfo } from 'cockpit/fsinfo';
|
||||||
|
import TOML from 'toml';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
// We have to work around RTK query here, since it doesn't like splitting
|
// We have to work around RTK query here, since it doesn't like splitting
|
||||||
|
|
@ -18,7 +19,10 @@ import { v4 as uuidv4 } from 'uuid';
|
||||||
// bit so that the `cockpitApi` doesn't become a monolith.
|
// bit so that the `cockpitApi` doesn't become a monolith.
|
||||||
import { contentSourcesApi } from './contentSourcesApi';
|
import { contentSourcesApi } from './contentSourcesApi';
|
||||||
|
|
||||||
import { mapHostedToOnPrem } from '../../Components/Blueprints/helpers/onPremToHostedBlueprintMapper';
|
import {
|
||||||
|
mapHostedToOnPrem,
|
||||||
|
mapOnPremToHosted,
|
||||||
|
} from '../../Components/Blueprints/helpers/onPremToHostedBlueprintMapper';
|
||||||
import { BLUEPRINTS_DIR } from '../../constants';
|
import { BLUEPRINTS_DIR } from '../../constants';
|
||||||
import {
|
import {
|
||||||
ComposeBlueprintApiResponse,
|
ComposeBlueprintApiResponse,
|
||||||
|
|
@ -48,6 +52,8 @@ import {
|
||||||
UpdateBlueprintApiResponse,
|
UpdateBlueprintApiResponse,
|
||||||
UpdateBlueprintApiArg,
|
UpdateBlueprintApiArg,
|
||||||
DistributionProfileItem,
|
DistributionProfileItem,
|
||||||
|
GetOscapCustomizationsApiResponse,
|
||||||
|
GetOscapCustomizationsApiArg,
|
||||||
} from '../service/imageBuilderApi';
|
} from '../service/imageBuilderApi';
|
||||||
|
|
||||||
const lookupDatastreamDistro = (distribution: string) => {
|
const lookupDatastreamDistro = (distribution: string) => {
|
||||||
|
|
@ -347,6 +353,71 @@ export const cockpitApi = contentSourcesApi.injectEndpoints({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
getOscapCustomizations: builder.query<
|
||||||
|
GetOscapCustomizationsApiResponse,
|
||||||
|
GetOscapCustomizationsApiArg
|
||||||
|
>({
|
||||||
|
queryFn: async ({ distribution, profile }) => {
|
||||||
|
try {
|
||||||
|
const dsDistro = lookupDatastreamDistro(distribution);
|
||||||
|
let result = (await cockpit.spawn(
|
||||||
|
[
|
||||||
|
'oscap',
|
||||||
|
'xccdf',
|
||||||
|
'generate',
|
||||||
|
'fix',
|
||||||
|
'--fix-type',
|
||||||
|
'blueprint',
|
||||||
|
'--profile',
|
||||||
|
profile,
|
||||||
|
`/usr/share/xml/scap/ssg/content/ssg-${dsDistro}-ds.xml`,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
superuser: 'try',
|
||||||
|
}
|
||||||
|
)) as string;
|
||||||
|
|
||||||
|
const parsed = TOML.parse(result);
|
||||||
|
const blueprint = mapOnPremToHosted(parsed);
|
||||||
|
|
||||||
|
result = (await cockpit.spawn(
|
||||||
|
[
|
||||||
|
'oscap',
|
||||||
|
'info',
|
||||||
|
'--profile',
|
||||||
|
profile,
|
||||||
|
`/usr/share/xml/scap/ssg/content/ssg-${dsDistro}-ds.xml`,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
superuser: 'try',
|
||||||
|
}
|
||||||
|
)) as string;
|
||||||
|
|
||||||
|
const descriptionLine = result
|
||||||
|
.split('\n')
|
||||||
|
.filter((s) => s.includes('Description: '));
|
||||||
|
|
||||||
|
const description =
|
||||||
|
descriptionLine.length > 0
|
||||||
|
? descriptionLine[0].split('Description: ')[1]
|
||||||
|
: '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
...blueprint.customizations,
|
||||||
|
openscap: {
|
||||||
|
profile_id: profile,
|
||||||
|
// the profile name is stored in the description
|
||||||
|
profile_name: blueprint.description,
|
||||||
|
profile_description: description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
composeBlueprint: builder.mutation<
|
composeBlueprint: builder.mutation<
|
||||||
ComposeBlueprintApiResponse,
|
ComposeBlueprintApiResponse,
|
||||||
ComposeBlueprintApiArg
|
ComposeBlueprintApiArg
|
||||||
|
|
@ -526,6 +597,8 @@ export const {
|
||||||
useUpdateBlueprintMutation,
|
useUpdateBlueprintMutation,
|
||||||
useDeleteBlueprintMutation,
|
useDeleteBlueprintMutation,
|
||||||
useGetOscapProfilesQuery,
|
useGetOscapProfilesQuery,
|
||||||
|
useGetOscapCustomizationsQuery,
|
||||||
|
useLazyGetOscapCustomizationsQuery,
|
||||||
useComposeBlueprintMutation,
|
useComposeBlueprintMutation,
|
||||||
useGetComposesQuery,
|
useGetComposesQuery,
|
||||||
useGetBlueprintComposesQuery,
|
useGetBlueprintComposesQuery,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue