Skip to content

Commit

Permalink
Fixes #38116 - Handle version removal for multi-CV hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
pavanshekar committed Jan 22, 2025
1 parent 363db98 commit bf66961
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ class ReassignObjects < Actions::Base
def plan(content_view_environment, options)
concurrence do
content_view_environment.hosts.each do |host|
plan_action(Host::Reassign, host, options[:system_content_view_id], options[:system_environment_id])
content_facet_attributes = host.content_facet
if content_facet_attributes.multi_content_view_environment?
content_facet_attributes.content_view_environments -= [content_view_environment]
else
plan_action(Host::Reassign, host, options[:system_content_view_id], options[:system_environment_id])
end
end

content_view_environment.activation_keys.each do |key|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState, useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import useDeepCompareEffect from 'use-deep-compare-effect';
import { ExpandableSection, SelectOption } from '@patternfly/react-core';
import { ExpandableSection, SelectOption, Alert, AlertActionCloseButton } from '@patternfly/react-core';
import { STATUS } from 'foremanReact/constants';
import { translate as __ } from 'foremanReact/common/I18n';
import EnvironmentPaths from '../../../../components/EnvironmentPaths/EnvironmentPaths';
import getContentViews from '../../../../ContentViewsActions';
import { selectContentViewError, selectContentViews, selectContentViewStatus } from '../../../../ContentViewSelectors';
import { selectCVHosts } from '../../../ContentViewDetailSelectors';
import AffectedHosts from '../affectedHosts';
import DeleteContext from '../DeleteContext';
import ContentViewSelect from '../../../../components/ContentViewSelect/ContentViewSelect';
Expand All @@ -25,6 +26,13 @@ const CVReassignHostsForm = () => {
cvId, versionEnvironments, selectedEnvSet, selectedEnvForHost, setSelectedEnvForHost,
currentStep, selectedCVForHosts, setSelectedCVNameForHosts, setSelectedCVForHosts,
} = useContext(DeleteContext);
const [alertDismissed, setAlertDismissed] = useState(false);
const hostResponse = useSelector(selectCVHosts);

const multiCVWarning = hostResponse?.results?.some?.(host =>
host.content_facet_attributes?.multi_content_view_environment);

const multiCVRemovalInfo = __('This content view version is used in one or more multi-environment hosts. The version will simply be removed from the multi-environment hosts. The content view and lifecycle environment you select here will only apply to single-environment hosts. See hammer activation-key --help for more details.');

// Fetch content views for selected environment to reassign hosts to.
useDeepCompareEffect(
Expand Down Expand Up @@ -103,6 +111,17 @@ const CVReassignHostsForm = () => {

return (
<>
{!alertDismissed && multiCVWarning && (
<Alert
ouiaId="multi-cv-warning-alert"
variant="warning"
isInline
title={__('Warning')}
actionClose={<AlertActionCloseButton onClose={() => setAlertDismissed(true)} />}
>
<p>{multiCVRemovalInfo}</p>
</Alert>
)}
<EnvironmentPaths
userCheckedItems={selectedEnvForHost}
setUserCheckedItems={setSelectedEnvForHost}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@ const CVVersionRemoveReview = () => {
} = useContext(DeleteContext);
const activationKeysResponse = useSelector(state => selectCVActivationKeys(state, cvId));
const hostsResponse = useSelector(state => selectCVHosts(state, cvId));
const { results: hostResponse } = hostsResponse;
const { results: akResponse } = activationKeysResponse;
const { results: hostResponse = [] } = hostsResponse || {};
const { results: akResponse = [] } = activationKeysResponse || {};
const selectedEnv = versionEnvironments.filter(env => selectedEnvSet.has(env.id));
const versionDeleteInfo = __(`Version ${versionNameToRemove} will be deleted from all environments. It will no longer be available for promotion.`);
const removalNotice = __(`Version ${versionNameToRemove} will be removed from the environments listed below, and will remain available for later promotion. ` +
'Changes listed below will be effective after clicking Remove.');

const multiCVHosts = hostResponse?.filter(host =>
host.content_facet_attributes?.multi_content_view_environment) || [];
const multiCVHostsCount = multiCVHosts.length;

const singleCVHostsCount = (hostResponse?.length || 0) - multiCVHostsCount;

const multiCVActivationKeys = akResponse.filter(key => key.multi_content_view_environment);
const multiCVActivationKeysCount = multiCVActivationKeys.length;

const singleCVActivationKeysCount = akResponse.length - multiCVActivationKeysCount;

return (
<>
<WizardHeader title={__('Review details')} />
Expand Down Expand Up @@ -53,20 +64,52 @@ const CVVersionRemoveReview = () => {
{affectedHosts &&
<>
<h3>{__('Content hosts')}</h3>
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem><p>{__(`${pluralize(hostResponse.length, 'host')} will be moved to content view ${selectedCVNameForHosts} in `)}</p></FlexItem>
<FlexItem><Label isTruncated color="purple" href={`/lifecycle_environments/${selectedEnvForHost[0].id}`}>{selectedEnvForHost[0].name}</Label></FlexItem>
</Flex>
{singleCVHostsCount > 0 && (
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem><p>{__(`${pluralize(singleCVHostsCount, 'host')} will be moved to content view ${selectedCVNameForHosts} in `)}</p></FlexItem>
<FlexItem><Label isTruncated color="purple" href={`/lifecycle_environments/${selectedEnvForHost[0].id}`}>{selectedEnvForHost[0].name}</Label></FlexItem>
</Flex>
)}
{multiCVHostsCount > 0 && (
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem>
<p>
{__(`Content view environment
${selectedEnv
?.map(({ name }) => `${name}/${multiCVHosts[0]?.content_facet_attributes?.content_view?.name}`)
.join(', ')}
will be removed from ${pluralize(multiCVHostsCount, 'multi-environment host')}.`)}
</p>
</FlexItem>
</Flex>
)}
</>}
{affectedActivationKeys &&
<>
<h3>{__('Activation keys')}</h3>
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem><p>{__(`${pluralize(akResponse.length, 'activation key')} will be moved to content view ${selectedCVNameForAK} in `)}</p></FlexItem>
<FlexItem><Label isTruncated color="purple" href={`/lifecycle_environments/${selectedEnvForAK[0].id}`}>{selectedEnvForAK[0].name}</Label></FlexItem>
</Flex>
{singleCVActivationKeysCount > 0 && (
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem><p>{__(`${pluralize(singleCVActivationKeysCount, 'activation key')} will be moved to content view ${selectedCVNameForAK} in `)}</p></FlexItem>
<FlexItem><Label isTruncated color="purple" href={`/lifecycle_environments/${selectedEnvForAK[0].id}`}>{selectedEnvForAK[0].name}</Label></FlexItem>
</Flex>
)}
{multiCVActivationKeysCount > 0 && (
<Flex>
<FlexItem><ExclamationTriangleIcon /></FlexItem>
<FlexItem>
<p>
{__(`Content view environment
${selectedEnv
?.map(({ name }) => `${name}/${multiCVActivationKeys[0]?.content_view?.name}`)
.join(', ')}
will be removed from ${pluralize(multiCVActivationKeysCount, 'multi-environment activation key')}.`)}
</p>
</FlexItem>
</Flex>
)}
</>}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const AffectedHosts = ({
const columnHeaders = [
__('Name'),
__('Environment'),
__('Multi Content View Environment'),
];
const emptyContentTitle = __('No matching hosts found.');
const emptyContentBody = __("Given criteria doesn't match any hosts. Try changing your rule.");
Expand Down Expand Up @@ -63,13 +64,17 @@ const AffectedHosts = ({
{results?.map(({
name,
id,
content_facet_attributes: { lifecycle_environment: environment },
content_facet_attributes: {
lifecycle_environment: environment,
multi_content_view_environment: multiContentViewEnvironment,
},
}) => (
<Tr ouiaId={id} key={id}>
<Td>
<a rel="noreferrer" target="_blank" href={urlBuilder(`new/hosts/${id}`, '')}>{name}</a>
</Td>
<Td><EnvironmentLabels environments={environment} /></Td>
<Td>{ multiContentViewEnvironment ? 'Yes' : 'No' }</Td>
</Tr>
))
}
Expand Down

0 comments on commit bf66961

Please sign in to comment.