Wizard: add compliance step
The Insights compliance support reuses most of the existing OpenSCAP step. Depending on the state of the feature flag, it will show radio buttons allowing users to switch between regular openscap and Insights compliance.
This commit is contained in:
parent
571fe18861
commit
e43357bf55
3 changed files with 326 additions and 94 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
|
|
@ -18,6 +18,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import OscapProfileInformation from './OscapProfileInformation';
|
import OscapProfileInformation from './OscapProfileInformation';
|
||||||
|
|
||||||
|
import { usePoliciesQuery, PolicyRead } from '../../../../store/complianceApi';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
||||||
import {
|
import {
|
||||||
DistributionProfileItem,
|
DistributionProfileItem,
|
||||||
|
|
@ -29,9 +30,11 @@ import {
|
||||||
Services,
|
Services,
|
||||||
} from '../../../../store/imageBuilderApi';
|
} from '../../../../store/imageBuilderApi';
|
||||||
import {
|
import {
|
||||||
changeOscapProfile,
|
changeCompliance,
|
||||||
selectDistribution,
|
selectDistribution,
|
||||||
selectProfile,
|
selectComplianceProfileID,
|
||||||
|
selectCompliancePolicyID,
|
||||||
|
selectCompliancePolicyTitle,
|
||||||
addPackage,
|
addPackage,
|
||||||
addPartition,
|
addPartition,
|
||||||
changeFileSystemConfigurationType,
|
changeFileSystemConfigurationType,
|
||||||
|
|
@ -42,47 +45,125 @@ import {
|
||||||
changeMaskedServices,
|
changeMaskedServices,
|
||||||
changeDisabledServices,
|
changeDisabledServices,
|
||||||
changeKernelAppend,
|
changeKernelAppend,
|
||||||
|
selectComplianceType,
|
||||||
} from '../../../../store/wizardSlice';
|
} from '../../../../store/wizardSlice';
|
||||||
import { useHasSpecificTargetOnly } from '../../utilities/hasSpecificTargetOnly';
|
import { useHasSpecificTargetOnly } from '../../utilities/hasSpecificTargetOnly';
|
||||||
import { parseSizeUnit } from '../../utilities/parseSizeUnit';
|
import { parseSizeUnit } from '../../utilities/parseSizeUnit';
|
||||||
import { Partition, Units } from '../FileSystem/FileSystemConfiguration';
|
import { Partition, Units } from '../FileSystem/FileSystemConfiguration';
|
||||||
|
|
||||||
|
const OpenSCAPFGLabel = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
OpenSCAP profile
|
||||||
|
<Popover
|
||||||
|
maxWidth="30rem"
|
||||||
|
bodyContent={
|
||||||
|
<TextContent>
|
||||||
|
<Text>
|
||||||
|
To run a manual compliance scan in OpenSCAP, download this image.
|
||||||
|
</Text>
|
||||||
|
</TextContent>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="plain"
|
||||||
|
aria-label="About OpenSCAP"
|
||||||
|
isInline
|
||||||
|
className="pf-u-pl-sm pf-u-pt-0 pf-u-pb-0 pf-u-pr-0"
|
||||||
|
>
|
||||||
|
<HelpIcon />
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const ProfileSelector = () => {
|
const ProfileSelector = () => {
|
||||||
const oscapProfile = useAppSelector(selectProfile);
|
const policyID = useAppSelector(selectCompliancePolicyID);
|
||||||
|
const policyTitle = useAppSelector(selectCompliancePolicyTitle);
|
||||||
|
const profileID = useAppSelector(selectComplianceProfileID);
|
||||||
const release = useAppSelector(selectDistribution);
|
const release = useAppSelector(selectDistribution);
|
||||||
|
const majorVersion = release.split('-')[1];
|
||||||
const hasWslTargetOnly = useHasSpecificTargetOnly('wsl');
|
const hasWslTargetOnly = useHasSpecificTargetOnly('wsl');
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const complianceType = useAppSelector(selectComplianceType);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: profiles,
|
data: profiles,
|
||||||
isFetching,
|
isFetching,
|
||||||
isSuccess,
|
isSuccess,
|
||||||
isError,
|
isError,
|
||||||
refetch,
|
refetch,
|
||||||
} = useGetOscapProfilesQuery({
|
} = useGetOscapProfilesQuery(
|
||||||
distribution: release,
|
{
|
||||||
});
|
distribution: release,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skip: complianceType === 'compliance',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: policies,
|
||||||
|
isFetching: isFetchingPolicies,
|
||||||
|
isSuccess: isSuccessPolicies,
|
||||||
|
} = usePoliciesQuery(
|
||||||
|
{
|
||||||
|
filter: `os_major_version=${majorVersion}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skip: complianceType === 'openscap',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const { data: currentProfileData } = useGetOscapCustomizationsQuery(
|
const { data: currentProfileData } = useGetOscapCustomizationsQuery(
|
||||||
{
|
{
|
||||||
distribution: release,
|
distribution: release,
|
||||||
// @ts-ignore if openScapProfile is undefined the query is going to get skipped
|
// @ts-ignore if openScapProfile is undefined the query is going to get skipped
|
||||||
profile: oscapProfile,
|
profile: profileID,
|
||||||
},
|
},
|
||||||
{ skip: !oscapProfile }
|
{ skip: !profileID }
|
||||||
);
|
);
|
||||||
|
|
||||||
const [trigger] = useLazyGetOscapCustomizationsQuery();
|
const [trigger] = useLazyGetOscapCustomizationsQuery();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!policies || policies.data === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policyID && !policyTitle) {
|
||||||
|
for (const p of policies.data) {
|
||||||
|
const pol = p as PolicyRead;
|
||||||
|
if (pol.id === policyID) {
|
||||||
|
dispatch(
|
||||||
|
changeCompliance({
|
||||||
|
policyID: pol.id,
|
||||||
|
profileID: pol.ref_id,
|
||||||
|
policyTitle: pol.title,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isSuccessPolicies]);
|
||||||
|
|
||||||
const handleToggle = () => {
|
const handleToggle = () => {
|
||||||
if (!isOpen) {
|
if (!isOpen && complianceType === 'openscap') {
|
||||||
refetch();
|
refetch();
|
||||||
}
|
}
|
||||||
setIsOpen(!isOpen);
|
setIsOpen(!isOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
dispatch(changeOscapProfile(undefined));
|
dispatch(
|
||||||
|
changeCompliance({
|
||||||
|
profileID: undefined,
|
||||||
|
policyID: undefined,
|
||||||
|
policyTitle: undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
clearOscapPackages(currentProfileData?.packages || []);
|
clearOscapPackages(currentProfileData?.packages || []);
|
||||||
dispatch(changeFileSystemConfigurationType('automatic'));
|
dispatch(changeFileSystemConfigurationType('automatic'));
|
||||||
handleServices(undefined);
|
handleServices(undefined);
|
||||||
|
|
@ -142,9 +223,9 @@ const ProfileSelector = () => {
|
||||||
|
|
||||||
const handleSelect = (
|
const handleSelect = (
|
||||||
_event: React.MouseEvent<Element, MouseEvent>,
|
_event: React.MouseEvent<Element, MouseEvent>,
|
||||||
selection: OScapSelectOptionValueType
|
selection: OScapSelectOptionValueType | ComplianceSelectOptionValueType
|
||||||
) => {
|
) => {
|
||||||
if (selection.id === undefined) {
|
if (selection.profileID === undefined) {
|
||||||
// handle user has selected 'None' case
|
// handle user has selected 'None' case
|
||||||
handleClear();
|
handleClear();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -152,7 +233,7 @@ const ProfileSelector = () => {
|
||||||
trigger(
|
trigger(
|
||||||
{
|
{
|
||||||
distribution: release,
|
distribution: release,
|
||||||
profile: selection.id,
|
profile: selection.profileID as DistributionProfileItem,
|
||||||
},
|
},
|
||||||
true // preferCacheValue
|
true // preferCacheValue
|
||||||
)
|
)
|
||||||
|
|
@ -164,7 +245,24 @@ const ProfileSelector = () => {
|
||||||
handlePackages(oldOscapPackages, newOscapPackages);
|
handlePackages(oldOscapPackages, newOscapPackages);
|
||||||
handleServices(response.services);
|
handleServices(response.services);
|
||||||
dispatch(changeKernelAppend(response.kernel?.append || ''));
|
dispatch(changeKernelAppend(response.kernel?.append || ''));
|
||||||
dispatch(changeOscapProfile(selection.id));
|
if (complianceType === 'openscap') {
|
||||||
|
dispatch(
|
||||||
|
changeCompliance({
|
||||||
|
profileID: selection.profileID,
|
||||||
|
policyID: undefined,
|
||||||
|
policyTitle: undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const compl = selection as ComplianceSelectOptionValueType;
|
||||||
|
dispatch(
|
||||||
|
changeCompliance({
|
||||||
|
profileID: compl.profileID,
|
||||||
|
policyID: compl.policyID,
|
||||||
|
policyTitle: compl.toString(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
|
|
@ -180,67 +278,77 @@ const ProfileSelector = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const complianceOptions = () => {
|
||||||
|
if (!policies || policies.data === undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = [<ComplianceNoneOption key="compliance-non-option" />];
|
||||||
|
for (const p of policies.data) {
|
||||||
|
if (p === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const pol = p as PolicyRead;
|
||||||
|
res.push(<ComplianceSelectOption key={pol.id} policy={pol} />);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
isRequired={true}
|
isRequired={true}
|
||||||
data-testid="profiles-form-group"
|
data-testid="profiles-form-group"
|
||||||
label={
|
label={complianceType === 'openscap' ? <OpenSCAPFGLabel /> : <>Policy</>}
|
||||||
<>
|
|
||||||
OpenSCAP profile
|
|
||||||
<Popover
|
|
||||||
maxWidth="30rem"
|
|
||||||
bodyContent={
|
|
||||||
<TextContent>
|
|
||||||
<Text>
|
|
||||||
To run a manual compliance scan in OpenSCAP, download this
|
|
||||||
image.
|
|
||||||
</Text>
|
|
||||||
</TextContent>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="plain"
|
|
||||||
aria-label="About OpenSCAP"
|
|
||||||
isInline
|
|
||||||
className="pf-u-pl-sm pf-u-pt-0 pf-u-pb-0 pf-u-pr-0"
|
|
||||||
>
|
|
||||||
<HelpIcon />
|
|
||||||
</Button>
|
|
||||||
</Popover>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Select
|
{complianceType === 'openscap' && (
|
||||||
loadingVariant={isFetching ? 'spinner' : undefined}
|
<Select
|
||||||
ouiaId="profileSelect"
|
loadingVariant={isFetching ? 'spinner' : undefined}
|
||||||
variant={SelectVariant.typeahead}
|
ouiaId="profileSelect"
|
||||||
onToggle={handleToggle}
|
variant={SelectVariant.typeahead}
|
||||||
onSelect={handleSelect}
|
onToggle={handleToggle}
|
||||||
onClear={handleClear}
|
onSelect={handleSelect}
|
||||||
maxHeight="300px"
|
onClear={handleClear}
|
||||||
selections={oscapProfile}
|
maxHeight="300px"
|
||||||
isOpen={isOpen}
|
selections={profileID}
|
||||||
placeholderText="Select a profile"
|
isOpen={isOpen}
|
||||||
typeAheadAriaLabel="Select a profile"
|
placeholderText="Select a profile"
|
||||||
isDisabled={!isSuccess || hasWslTargetOnly}
|
typeAheadAriaLabel="Select a profile"
|
||||||
onFilter={(_event, value) => {
|
isDisabled={!isSuccess || hasWslTargetOnly}
|
||||||
if (profiles) {
|
onFilter={(_event, value) => {
|
||||||
return [<OScapNoneOption key="oscap-none-option" />].concat(
|
if (profiles) {
|
||||||
profiles.map((profile_id, index) => {
|
return [<OScapNoneOption key="oscap-none-option" />].concat(
|
||||||
return (
|
profiles.map((profile_id, index) => {
|
||||||
<OScapSelectOption
|
return (
|
||||||
key={index}
|
<OScapSelectOption
|
||||||
profile_id={profile_id}
|
key={index}
|
||||||
filter={value}
|
profile_id={profile_id}
|
||||||
/>
|
filter={value}
|
||||||
);
|
/>
|
||||||
})
|
);
|
||||||
);
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{options()}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
{complianceType === 'compliance' && (
|
||||||
|
<Select
|
||||||
|
isDisabled={isFetchingPolicies}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
onToggle={handleToggle}
|
||||||
|
selections={
|
||||||
|
isFetchingPolicies
|
||||||
|
? 'Loading policies'
|
||||||
|
: policyTitle || policyID || 'None'
|
||||||
}
|
}
|
||||||
}}
|
ouiaId="compliancePolicySelect"
|
||||||
>
|
>
|
||||||
{options()}
|
{complianceOptions()}
|
||||||
</Select>
|
</Select>
|
||||||
|
)}
|
||||||
{isError && (
|
{isError && (
|
||||||
<Alert
|
<Alert
|
||||||
title="Error fetching the profiles"
|
title="Error fetching the profiles"
|
||||||
|
|
@ -267,7 +375,7 @@ type OScapSelectOptionPropType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type OScapSelectOptionValueType = {
|
type OScapSelectOptionValueType = {
|
||||||
id: DistributionProfileItem;
|
profileID: DistributionProfileItem;
|
||||||
toString: () => string;
|
toString: () => string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -291,7 +399,7 @@ const OScapSelectOption = ({
|
||||||
id: DistributionProfileItem,
|
id: DistributionProfileItem,
|
||||||
name?: string
|
name?: string
|
||||||
): OScapSelectOptionValueType => ({
|
): OScapSelectOptionValueType => ({
|
||||||
id,
|
profileID: id,
|
||||||
toString: () => name || '',
|
toString: () => name || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -303,9 +411,52 @@ const OScapSelectOption = ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
type ComplianceSelectOptionPropType = {
|
||||||
|
policy: PolicyRead;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ComplianceSelectOptionValueType = {
|
||||||
|
policyID: string;
|
||||||
|
profileID: string;
|
||||||
|
toString: () => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ComplianceNoneOption = () => {
|
||||||
|
return (
|
||||||
|
<SelectOption value={{ toString: () => 'None', compareTo: () => false }} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ComplianceSelectOption = ({ policy }: ComplianceSelectOptionPropType) => {
|
||||||
|
const selectObj = (
|
||||||
|
policyID: string,
|
||||||
|
profileID: string,
|
||||||
|
title: string
|
||||||
|
): ComplianceSelectOptionValueType => ({
|
||||||
|
policyID,
|
||||||
|
profileID,
|
||||||
|
toString: () => title,
|
||||||
|
});
|
||||||
|
|
||||||
|
const descr = (
|
||||||
|
<>
|
||||||
|
Threshold: {policy.compliance_threshold}
|
||||||
|
<br />
|
||||||
|
Active systems: {policy.total_system_count}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectOption
|
||||||
|
key={policy.id}
|
||||||
|
value={selectObj(policy.id!, policy.ref_id!, policy.title!)}
|
||||||
|
description={descr}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const Oscap = () => {
|
export const Oscap = () => {
|
||||||
const oscapProfile = useAppSelector(selectProfile);
|
const oscapProfile = useAppSelector(selectComplianceProfileID);
|
||||||
const environments = useAppSelector(selectImageTypes);
|
const environments = useAppSelector(selectImageTypes);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,44 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
import { Button, Form, Text, Title } from '@patternfly/react-core';
|
import {
|
||||||
|
Button,
|
||||||
|
Form,
|
||||||
|
FormGroup,
|
||||||
|
Radio,
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
} from '@patternfly/react-core';
|
||||||
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
|
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
|
||||||
|
import { useFlag } from '@unleash/proxy-client-react';
|
||||||
|
|
||||||
import { Oscap } from './Oscap';
|
import { Oscap } from './Oscap';
|
||||||
|
|
||||||
import { COMPLIANCE_AND_VULN_SCANNING_URL } from '../../../../constants';
|
import {
|
||||||
|
COMPLIANCE_AND_VULN_SCANNING_URL,
|
||||||
|
COMPLIANCE_PROD_URL,
|
||||||
|
COMPLIANCE_STAGE_URL,
|
||||||
|
} from '../../../../constants';
|
||||||
import { imageBuilderApi } from '../../../../store/enhancedImageBuilderApi';
|
import { imageBuilderApi } from '../../../../store/enhancedImageBuilderApi';
|
||||||
import { useAppSelector } from '../../../../store/hooks';
|
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
|
||||||
import { selectDistribution } from '../../../../store/wizardSlice';
|
import {
|
||||||
|
ComplianceType,
|
||||||
|
changeComplianceType,
|
||||||
|
selectDistribution,
|
||||||
|
selectComplianceType,
|
||||||
|
} from '../../../../store/wizardSlice';
|
||||||
|
import { useGetEnvironment } from '../../../../Utilities/useGetEnvironment';
|
||||||
|
|
||||||
const OscapStep = () => {
|
const OscapStep = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const complianceEnabled = useFlag('image-builder.compliance.enabled');
|
||||||
|
const complianceType = useAppSelector(selectComplianceType);
|
||||||
const prefetchOscapProfile = imageBuilderApi.usePrefetch(
|
const prefetchOscapProfile = imageBuilderApi.usePrefetch(
|
||||||
'getOscapProfiles',
|
'getOscapProfiles',
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
const { isProd } = useGetEnvironment();
|
||||||
const release = useAppSelector(selectDistribution);
|
const release = useAppSelector(selectDistribution);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
prefetchOscapProfile({ distribution: release });
|
prefetchOscapProfile({ distribution: release });
|
||||||
// This useEffect hook should run *only* on mount and therefore has an empty
|
// This useEffect hook should run *only* on mount and therefore has an empty
|
||||||
|
|
@ -26,24 +49,78 @@ const OscapStep = () => {
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form>
|
||||||
<Title headingLevel="h1" size="xl">
|
<Title headingLevel="h1" size="xl">
|
||||||
OpenSCAP profile
|
{complianceEnabled ? 'Compliance' : 'OpenSCAP profile'}
|
||||||
</Title>
|
</Title>
|
||||||
<Text>
|
{complianceEnabled && (
|
||||||
OpenSCAP enables you to automatically monitor the adherence of your
|
<FormGroup>
|
||||||
registered RHEL systems to a selected regulatory compliance profile.
|
<Radio
|
||||||
<br />
|
id="openscap radio openscap type"
|
||||||
<Button
|
label="OpenSCAP"
|
||||||
component="a"
|
name="oscap-radio-openscap"
|
||||||
target="_blank"
|
isChecked={complianceType === 'openscap'}
|
||||||
variant="link"
|
onChange={() =>
|
||||||
icon={<ExternalLinkAltIcon />}
|
dispatch(changeComplianceType('openscap' as ComplianceType))
|
||||||
iconPosition="right"
|
}
|
||||||
isInline
|
/>
|
||||||
href={COMPLIANCE_AND_VULN_SCANNING_URL}
|
<Radio
|
||||||
>
|
id="openscap radio compliance type"
|
||||||
Documentation
|
label="Insights compliance"
|
||||||
</Button>
|
name="oscap-radio-compliance"
|
||||||
</Text>
|
isChecked={complianceType === 'compliance'}
|
||||||
|
onChange={() =>
|
||||||
|
dispatch(changeComplianceType('compliance' as ComplianceType))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
{(!complianceEnabled || complianceType === 'openscap') && (
|
||||||
|
<Text>
|
||||||
|
OpenSCAP enables you to automatically monitor the adherence of your
|
||||||
|
registered RHEL systems to a selected regulatory compliance profile.
|
||||||
|
<br />
|
||||||
|
<Button
|
||||||
|
component="a"
|
||||||
|
target="_blank"
|
||||||
|
variant="link"
|
||||||
|
icon={<ExternalLinkAltIcon />}
|
||||||
|
iconPosition="right"
|
||||||
|
isInline
|
||||||
|
href={COMPLIANCE_AND_VULN_SCANNING_URL}
|
||||||
|
>
|
||||||
|
Documentation
|
||||||
|
</Button>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{complianceType === 'compliance' && (
|
||||||
|
<Text>
|
||||||
|
Insights compliance enables you to monitor the adherence of your
|
||||||
|
registered RHEL systems to a selected compliance policy.
|
||||||
|
<br />
|
||||||
|
<Button
|
||||||
|
component="a"
|
||||||
|
target="_blank"
|
||||||
|
variant="link"
|
||||||
|
icon={<ExternalLinkAltIcon />}
|
||||||
|
iconPosition="right"
|
||||||
|
isInline
|
||||||
|
href={isProd() ? COMPLIANCE_PROD_URL : COMPLIANCE_STAGE_URL}
|
||||||
|
>
|
||||||
|
Define new policies in Insights Compliance
|
||||||
|
</Button>
|
||||||
|
<br />
|
||||||
|
<Button
|
||||||
|
component="a"
|
||||||
|
target="_blank"
|
||||||
|
variant="link"
|
||||||
|
icon={<ExternalLinkAltIcon />}
|
||||||
|
iconPosition="right"
|
||||||
|
isInline
|
||||||
|
href={COMPLIANCE_AND_VULN_SCANNING_URL}
|
||||||
|
>
|
||||||
|
Documentation
|
||||||
|
</Button>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
<Oscap />
|
<Oscap />
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ export const RELEASE_LIFECYCLE_URL =
|
||||||
'https://access.redhat.com/support/policy/updates/errata';
|
'https://access.redhat.com/support/policy/updates/errata';
|
||||||
export const AZURE_AUTH_URL =
|
export const AZURE_AUTH_URL =
|
||||||
'https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow';
|
'https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow';
|
||||||
|
export const COMPLIANCE_PROD_URL =
|
||||||
|
'https://console.redhat.com/insights/compliance/scappolicies';
|
||||||
|
export const COMPLIANCE_STAGE_URL =
|
||||||
|
'https://console.stage.redhat.com/insights/compliance/scappolicies';
|
||||||
export const ACTIVATION_KEYS_PROD_URL =
|
export const ACTIVATION_KEYS_PROD_URL =
|
||||||
'https://console.redhat.com/insights/connector/activation-keys';
|
'https://console.redhat.com/insights/connector/activation-keys';
|
||||||
export const ACTIVATION_KEYS_STAGE_URL =
|
export const ACTIVATION_KEYS_STAGE_URL =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue