Skip to content

Commit

Permalink
upcoming: [M3-8145] – Update LDE copy in Linode Create flow when Dist…
Browse files Browse the repository at this point in the history
…ributed region is selected (#10576)
  • Loading branch information
dwiley-akamai committed Jun 14, 2024
1 parent b18db95 commit a5f18c7
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Revise LDE copy in Linode Create flow when Distributed region is selected ([#10576](https://github.com/linode/manager/pull/10576))
107 changes: 72 additions & 35 deletions packages/manager/src/components/AccessPanel/AccessPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import { makeStyles } from 'tss-react/mui';

import {
DISK_ENCRYPTION_DEFAULT_DISTRIBUTED_INSTANCES,
DISK_ENCRYPTION_DISTRIBUTED_DESCRIPTION,
DISK_ENCRYPTION_GENERAL_DESCRIPTION,
DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY,
ENCRYPT_DISK_DISABLED_REBUILD_DISTRIBUTED_REGION_REASON,
Expand All @@ -13,6 +15,7 @@ import {
import { DiskEncryption } from 'src/components/DiskEncryption/DiskEncryption';
import { useIsDiskEncryptionFeatureEnabled } from 'src/components/DiskEncryption/utils';
import { Paper } from 'src/components/Paper';
import { getIsDistributedRegion } from 'src/components/RegionSelect/RegionSelect.utils';
import { SuspenseLoader } from 'src/components/SuspenseLoader';
import { Typography } from 'src/components/Typography';
import { useRegionsQuery } from 'src/queries/regions/regions';
Expand Down Expand Up @@ -67,6 +70,21 @@ interface Props {
toggleDiskEncryptionEnabled?: () => void;
}

interface DiskEncryptionDescriptionDeterminants {
isDistributedRegion: boolean | undefined; // Linode Create flow (region selected for a not-yet-created linode)
isInRebuildFlow: boolean | undefined;
isLKELinode: boolean | undefined;
linodeIsInDistributedRegion: boolean | undefined; // Linode Rebuild flow (linode exists already)
}

interface DiskEncryptionDisabledReasonDeterminants {
isDistributedRegion: boolean | undefined; // Linode Create flow (region selected for a not-yet-created linode)
isInRebuildFlow: boolean | undefined;
isLKELinode: boolean | undefined;
linodeIsInDistributedRegion: boolean | undefined; // Linode Rebuild flow (linode exists already)
regionSupportsDiskEncryption: boolean;
}

export const AccessPanel = (props: Props) => {
const {
authorizedUsers,
Expand Down Expand Up @@ -106,49 +124,68 @@ export const AccessPanel = (props: Props) => {
'Disk Encryption'
);

const isDistributedRegion = getIsDistributedRegion(
regions ?? [],
selectedRegion ?? ''
);

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) =>
_handleChange(e.target.value);

const determineRebuildFlowDiskEncryptionDescription = ({
const determineDiskEncryptionDescription = ({
isDistributedRegion,
isInRebuildFlow,
isLKELinode,
linodeIsInDistributedRegion,
}: {
isLKELinode: boolean | undefined;
linodeIsInDistributedRegion: boolean | undefined;
}) => {
if (isLKELinode) {
return ENCRYPT_DISK_REBUILD_LKE_COPY;
}
}: DiskEncryptionDescriptionDeterminants) => {
// Linode Rebuild flow descriptions
if (isInRebuildFlow) {
// the order is significant: all Distributed instances are encrypted (broadest)
if (linodeIsInDistributedRegion) {
return ENCRYPT_DISK_REBUILD_DISTRIBUTED_COPY;
}

if (linodeIsInDistributedRegion) {
return ENCRYPT_DISK_REBUILD_DISTRIBUTED_COPY;
if (isLKELinode) {
return ENCRYPT_DISK_REBUILD_LKE_COPY;
}

if (!isLKELinode && !linodeIsInDistributedRegion) {
return ENCRYPT_DISK_REBUILD_STANDARD_COPY;
}
}

return ENCRYPT_DISK_REBUILD_STANDARD_COPY;
// Linode Create flow descriptions
return isDistributedRegion
? DISK_ENCRYPTION_DISTRIBUTED_DESCRIPTION
: DISK_ENCRYPTION_GENERAL_DESCRIPTION;
};

const determineEncryptDiskDisabledReason = ({
const determineDiskEncryptionDisabledReason = ({
isDistributedRegion,
isInRebuildFlow,
isLKELinode,
linodeIsInDistributedRegion,
regionSupportsDiskEncryption,
}: {
isLKELinode: boolean | undefined;
linodeIsInDistributedRegion: boolean | undefined;
regionSupportsDiskEncryption: boolean;
}) => {
if (isLKELinode) {
return ENCRYPT_DISK_DISABLED_REBUILD_LKE_REASON;
}
}: DiskEncryptionDisabledReasonDeterminants) => {
if (isInRebuildFlow) {
// the order is significant: setting can't be changed for *any* Distributed instances (broadest)
if (linodeIsInDistributedRegion) {
return ENCRYPT_DISK_DISABLED_REBUILD_DISTRIBUTED_REGION_REASON;
}

if (linodeIsInDistributedRegion) {
return ENCRYPT_DISK_DISABLED_REBUILD_DISTRIBUTED_REGION_REASON;
}
if (isLKELinode) {
return ENCRYPT_DISK_DISABLED_REBUILD_LKE_REASON;
}

if (!regionSupportsDiskEncryption) {
return DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY;
if (!regionSupportsDiskEncryption) {
return DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY;
}
}

return '';
// Linode Create flow disabled reasons
return isDistributedRegion
? DISK_ENCRYPTION_DEFAULT_DISTRIBUTED_INSTANCES
: DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY;
};

/**
Expand All @@ -165,20 +202,20 @@ export const AccessPanel = (props: Props) => {
<>
<Divider spacingBottom={20} spacingTop={24} />
<DiskEncryption
descriptionCopy={
isInRebuildFlow
? determineRebuildFlowDiskEncryptionDescription({
isLKELinode,
linodeIsInDistributedRegion,
})
: DISK_ENCRYPTION_GENERAL_DESCRIPTION
}
descriptionCopy={determineDiskEncryptionDescription({
isDistributedRegion,
isInRebuildFlow,
isLKELinode,
linodeIsInDistributedRegion,
})}
disabled={
!regionSupportsDiskEncryption ||
isLKELinode ||
linodeIsInDistributedRegion
}
disabledReason={determineEncryptDiskDisabledReason({
disabledReason={determineDiskEncryptionDisabledReason({
isDistributedRegion,
isInRebuildFlow,
isLKELinode,
linodeIsInDistributedRegion,
regionSupportsDiskEncryption,
Expand Down
15 changes: 12 additions & 3 deletions packages/manager/src/components/DiskEncryption/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ import React from 'react';

import { Link } from 'src/components/Link';

// @TODO LDE: Update "Learn more" link
const DISK_ENCRYPTION_GUIDE_LINK =
'https://www.linode.com/docs/products/compute/compute-instances/guides/local-disk-encryption';

export const DISK_ENCRYPTION_GENERAL_DESCRIPTION = (
<>
Secure this Linode using data at rest encryption. Data center systems take
care of encrypting and decrypting for you. After the Linode is created, use
Rebuild to enable or disable this feature. <Link to="">Learn more</Link>.
Rebuild to enable or disable this feature.{' '}
<Link to={DISK_ENCRYPTION_GUIDE_LINK}>Learn more</Link>.
</>
);

export const DISK_ENCRYPTION_DISTRIBUTED_DESCRIPTION =
'Distributed Compute Instances are secured using disk encryption. Encryption and decryption are automatically managed for you.';

const DISK_ENCRYPTION_UPDATE_PROTECT_CLUSTERS_DOCS_LINK =
'https://www.linode.com/docs/products/compute/compute-instances/guides/local-disk-encryption/';

Expand All @@ -28,7 +34,10 @@ export const DISK_ENCRYPTION_UPDATE_PROTECT_CLUSTERS_BANNER_KEY =
'disk-encryption-update-protect-clusters-banner';

export const DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY =
'Disk encryption is not available in the selected region.';
'Disk encryption is not available in the selected region. Select another region to use Disk Encryption.';

export const DISK_ENCRYPTION_DEFAULT_DISTRIBUTED_INSTANCES =
'Distributed Compute Instances are encrypted. This setting can not be changed.';

// Guidance
export const DISK_ENCRYPTION_NODE_POOL_GUIDANCE_COPY =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ describe('Security', () => {
});

await findByLabelText(
'Disk encryption is not available in the selected region.'
'Disk encryption is not available in the selected region. Select another region to use Disk Encryption.'
);
});
});
20 changes: 18 additions & 2 deletions packages/manager/src/features/Linodes/LinodeCreatev2/Security.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import { Controller, useFormContext, useWatch } from 'react-hook-form';

import UserSSHKeyPanel from 'src/components/AccessPanel/UserSSHKeyPanel';
import {
DISK_ENCRYPTION_DEFAULT_DISTRIBUTED_INSTANCES,
DISK_ENCRYPTION_DISTRIBUTED_DESCRIPTION,
DISK_ENCRYPTION_GENERAL_DESCRIPTION,
DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY,
} from 'src/components/DiskEncryption/constants';
import { DiskEncryption } from 'src/components/DiskEncryption/DiskEncryption';
import { useIsDiskEncryptionFeatureEnabled } from 'src/components/DiskEncryption/utils';
import { Divider } from 'src/components/Divider';
import { Paper } from 'src/components/Paper';
import { getIsDistributedRegion } from 'src/components/RegionSelect/RegionSelect.utils';
import { Skeleton } from 'src/components/Skeleton';
import { Typography } from 'src/components/Typography';
import { inputMaxWidth } from 'src/foundations/themes/light';
Expand Down Expand Up @@ -38,6 +41,11 @@ export const Security = () => {
'Disk Encryption'
);

const isDistributedRegion = getIsDistributedRegion(
regions ?? [],
selectedRegion?.id ?? ''
);

const isLinodeCreateRestricted = useRestrictedGlobalGrantCheck({
globalGrantType: 'add_linodes',
});
Expand Down Expand Up @@ -87,12 +95,20 @@ export const Security = () => {
<Controller
render={({ field, fieldState }) => (
<DiskEncryption
descriptionCopy={
isDistributedRegion
? DISK_ENCRYPTION_DISTRIBUTED_DESCRIPTION
: DISK_ENCRYPTION_GENERAL_DESCRIPTION
}
disabledReason={
isDistributedRegion
? DISK_ENCRYPTION_DEFAULT_DISTRIBUTED_INSTANCES
: DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY
}
onChange={(checked) =>
field.onChange(checked ? 'enabled' : 'disabled')
}
descriptionCopy={DISK_ENCRYPTION_GENERAL_DESCRIPTION}
disabled={!regionSupportsDiskEncryption}
disabledReason={DISK_ENCRYPTION_UNAVAILABLE_IN_REGION_COPY}
error={fieldState.error?.message}
isEncryptDiskChecked={field.value === 'enabled'}
/>
Expand Down

0 comments on commit a5f18c7

Please sign in to comment.