Skip to content

Commit

Permalink
feat(HMS-1245): UI AWS permission check
Browse files Browse the repository at this point in the history
  • Loading branch information
avitova committed Aug 25, 2023
1 parent de7afae commit 7e0f63c
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 18 deletions.
11 changes: 10 additions & 1 deletion src/API/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import axios from 'axios';
import { AZURE_PROVIDER } from '../constants';
import { AWS_PROVIDER, AZURE_PROVIDER } from '../constants';
import { imageBuilderURL, provisioningUrl } from './helpers';

const typesUrlForProvider = (provider, region) => {
Expand Down Expand Up @@ -72,3 +72,12 @@ export const fetchLaunchTemplates = async (sourceID, region) => {
} = await axios.get(provisioningUrl(`sources/${sourceID}/launch_templates?region=${region}`));
return data;
};

export const checkPermissions = async (provider, sourceID, region) => {
switch (provider) {
case AWS_PROVIDER: {
const { data } = await axios.get(provisioningUrl(`sources/${sourceID}/validate_permissions?region=${region}`));
return data;
}
}
};
1 change: 1 addition & 0 deletions src/API/queryKeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export const PUBKEYS_QUERY_KEY = 'pubkeys';
export const instanceTypesQueryKeys = (region) => ['instanceTypes', region];
export const IMAGE_REGIONS_KEY = 'image_region';
export const TEMPLATES_KEY = 'templates';
export const PERMISSION_CHECK_KEY = 'permissions';
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import PropTypes from 'prop-types';
import React from 'react';
import { Form, FormGroup, Popover, Title, Button } from '@patternfly/react-core';
import { Form, FormGroup, Popover, Title, Button, FormAlert, Alert } from '@patternfly/react-core';
import { HelpIcon } from '@patternfly/react-icons';
import { useQuery } from 'react-query';

import { AWS_PROVIDER } from '../../../../constants';
import { imageProps } from '../../helpers';
Expand All @@ -11,12 +12,22 @@ import InstanceTypesSelect from '../../../InstanceTypesSelect';
import RegionsSelect from '../../../RegionsSelect';
import { useWizardContext } from '../../../Common/WizardContext';
import TemplatesSelect from '../../../TemplateSelect';
import { checkPermissions } from '../../../../API';

const AccountCustomizationsAWS = ({ setStepValidated, image }) => {
const [{ chosenSource, chosenRegion, chosenInstanceType }, setWizardContext] = useWizardContext();
const { data: missingPermissions } = useQuery(
[`permissions`, `${chosenRegion}-${chosenSource}`],
() => checkPermissions(image.provider, chosenSource, chosenRegion),
{
select: (perm) => perm.missing_entities,
enabled: !!chosenRegion && !!chosenSource,
}
);
const [validations, setValidation] = React.useState({
sources: chosenSource ? 'success' : 'default',
sources: chosenSource ? ((missingPermissions || []).length == 0 ? 'success' : 'warning') : 'default',
types: chosenInstanceType ? 'success' : 'default',
region: 'default',
});

const onRegionChange = ({ region, imageID }) => {
Expand All @@ -33,18 +44,52 @@ const AccountCustomizationsAWS = ({ setStepValidated, image }) => {
setStepValidated(!errorExists);
}, [validations]);

React.useEffect(() => {
if ((missingPermissions || []).length != 0) {
if (validations.sources !== 'error') {
setValidation((prevValidations) => ({
...prevValidations,
sources: 'warning',
}));
}
if (validations.region !== 'error') {
setValidation((prevValidations) => ({
...prevValidations,
region: 'warning',
}));
}
} else {
setValidation((prevValidations) => ({
...prevValidations,
sources: chosenSource ? 'success' : 'default',
region: 'default',
}));
}
}, [missingPermissions]);

return (
<Form>
<Title ouiaId="account_custom_title" headingLevel="h1" size="xl">
Account and customizations | Amazon
</Title>
<FormGroup
label="Select account"
validated={validations.sources}
helperTextInvalid="Please pick a value"
isRequired
fieldId="aws-select-source"
>
{(missingPermissions || []).length != 0 && (
<FormAlert>
<Alert isExpandable isInline variant="warning" title={`Launch might fail due to missing permissions.`}>
<>
<p>
Check if <a href="https://console.aws.amazon.com/iam/">policies</a> in your {image.provider} account for the selected region are set
as{' '}
<a href="https://github.com/RHEnVision/provisioning-backend/blob/main/docs/configure-amazon-role.md#service-account-policy">
our documentation
</a>{' '}
recommends. Following permissions might be missing:
</p>
<p>{(missingPermissions || []).join(', ')}</p>
</>
</Alert>
</FormAlert>
)}
<FormGroup label="Select account" validated="warning" helperTextInvalid="Please pick a value" isRequired fieldId="aws-select-source">
<SourcesSelect
image={image}
setValidation={(validation) =>
Expand All @@ -53,6 +98,7 @@ const AccountCustomizationsAWS = ({ setStepValidated, image }) => {
sources: validation,
}))
}
validated={validations.sources}
/>
</FormGroup>
<FormGroup
Expand All @@ -75,7 +121,13 @@ const AccountCustomizationsAWS = ({ setStepValidated, image }) => {
</Popover>
}
>
<RegionsSelect provider={AWS_PROVIDER} onChange={onRegionChange} composeID={image.id} currentRegion={chosenRegion} />
<RegionsSelect
provider={AWS_PROVIDER}
onChange={onRegionChange}
composeID={image.id}
currentRegion={chosenRegion}
validated={validations.region}
/>
</FormGroup>
<FormGroup
label="Select instance type"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const AccountCustomizationsAzure = ({ setStepValidated, image }) => {
sources: validation,
}))
}
validated={validations.sources}
/>
</FormGroup>
<FormGroup
Expand All @@ -74,7 +75,13 @@ const AccountCustomizationsAzure = ({ setStepValidated, image }) => {
</Popover>
}
>
<RegionsSelect provider={AZURE_PROVIDER} currentRegion={wizardContext.chosenRegion} onChange={onRegionChange} composeID={image.id} />
<RegionsSelect
provider={AZURE_PROVIDER}
currentRegion={wizardContext.chosenRegion}
onChange={onRegionChange}
composeID={image.id}
validated={'default'}
/>
</FormGroup>
<FormGroup
label="Select instance size"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const AccountCustomizationsGCP = ({ setStepValidated, image }) => {
sources: validation,
}))
}
validated={validations.sources}
/>
</FormGroup>
<FormGroup
Expand All @@ -75,7 +76,13 @@ const AccountCustomizationsGCP = ({ setStepValidated, image }) => {
</Popover>
}
>
<RegionsSelect provider={GCP_PROVIDER} onChange={onRegionChange} composeID={image.id} currentRegion={wizardContext.chosenRegion} />
<RegionsSelect
provider={GCP_PROVIDER}
onChange={onRegionChange}
composeID={image.id}
currentRegion={wizardContext.chosenRegion}
validated={'default'}
/>
</FormGroup>
<FormGroup
label="Select machine type"
Expand Down
4 changes: 3 additions & 1 deletion src/Components/RegionsSelect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IMAGE_REGIONS_KEY } from '../../API/queryKeys';
import { fetchImageClones, fetchImageCloneStatus } from '../../API';
import { defaultRegionByProvider } from '../Common/helpers';

const RegionsSelect = ({ provider, currentRegion, composeID, onChange }) => {
const RegionsSelect = ({ provider, currentRegion, composeID, onChange, validated }) => {
const [isOpen, setIsOpen] = React.useState(false);

const {
Expand Down Expand Up @@ -72,6 +72,7 @@ const RegionsSelect = ({ provider, currentRegion, composeID, onChange }) => {
onToggle={onToggle}
onSelect={onSelect}
isDisabled={!MULTIPLE_REGION_SUPPORT.includes(provider)}
validated={validated}
>
{images.map(({ id, region }) => (
<SelectOption aria-label="Region item" key={id} value={region} />
Expand All @@ -85,6 +86,7 @@ RegionsSelect.propTypes = {
composeID: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
currentRegion: PropTypes.string,
validated: PropTypes.string.isRequired,
};

export default RegionsSelect;
16 changes: 12 additions & 4 deletions src/Components/SourcesSelect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { imageProps } from '../ProvisioningWizard/helpers';
import { useSourcesForImage } from '../Common/Hooks/sources';
import { useWizardContext } from '../Common/WizardContext';

const SourcesSelect = ({ setValidation, image }) => {
const SourcesSelect = ({ setValidation, image, validated }) => {
const [{ chosenSource }, setWizardContext] = useWizardContext();
const [isOpen, setIsOpen] = React.useState(false);
const [selected, setSelected] = React.useState(null);
Expand All @@ -19,14 +19,18 @@ const SourcesSelect = ({ setValidation, image }) => {
onSuccess: (sources) => {
if (chosenSource) {
setSelected(selectObject(chosenSource, sources.find((source) => source.id === chosenSource).name));
setValidation('success');
if (validated !== 'warning') {
setValidation('success');
}
} else if (sources.length === 1) {
setSelected(selectObject(sources[0].id, sources[0].name));
setWizardContext((prevState) => ({
...prevState,
chosenSource: sources[0].id,
}));
setValidation('success');
if (validated !== 'warning') {
setValidation('success');
}
}
},
});
Expand All @@ -42,7 +46,9 @@ const SourcesSelect = ({ setValidation, image }) => {
...prevState,
chosenSource: selection.id,
}));
setValidation('success');
if (validated !== 'warning') {
setValidation('success');
}
}
setIsOpen(false);
};
Expand Down Expand Up @@ -76,6 +82,7 @@ const SourcesSelect = ({ setValidation, image }) => {
onSelect={onSelect}
placeholderText="Select account"
aria-label="Select account"
validated={validated === 'error' || validated === 'warning' ? validated : 'default'}
>
{sources && selectItemsMapper()}
</Select>
Expand All @@ -85,6 +92,7 @@ const SourcesSelect = ({ setValidation, image }) => {
SourcesSelect.propTypes = {
setValidation: PropTypes.func.isRequired,
image: imageProps,
validated: PropTypes.string.isRequired,
};

export default SourcesSelect;

0 comments on commit 7e0f63c

Please sign in to comment.