Skip to content

Commit

Permalink
upcoming: [M3-8369] – Add "Encrypt Volume" checkbox in Edit Volume dr…
Browse files Browse the repository at this point in the history
…awer (#10787)
  • Loading branch information
dwiley-akamai authored Aug 19, 2024
1 parent bb375ff commit 0083246
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Add 'Encrypt Volume' checkbox in Edit Volume drawer ([#10787](https://github.com/linode/manager/pull/10787))
3 changes: 3 additions & 0 deletions packages/manager/src/components/Encryption/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,6 @@ export const BLOCK_STORAGE_ENCRYPTION_OVERHEAD_CAVEAT =

export const BLOCK_STORAGE_USER_SIDE_ENCRYPTION_CAVEAT =
'User-side encryption on top of encryption-enabled volumes is discouraged at this time, as it could severely impact your volume performance.';

export const BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY =
'The encryption setting cannot be changed after creation.';
83 changes: 83 additions & 0 deletions packages/manager/src/features/Volumes/EditVolumeDrawer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { waitFor } from '@testing-library/react';
import * as React from 'react';

import { accountFactory, volumeFactory } from 'src/factories';
import { HttpResponse, http, server } from 'src/mocks/testServer';
import { renderWithTheme } from 'src/utilities/testHelpers';

import { EditVolumeDrawer } from './EditVolumeDrawer';

const accountEndpoint = '*/v4/account';
const encryptionLabelText = 'Encrypt Volume';

describe('EditVolumeDrawer', () => {
/* @TODO BSE: Remove feature flagging/conditionality once BSE is fully rolled out */

it('should display a disabled checkbox for volume encryption if the user has the account capability and the feature flag is on', async () => {
const volume = volumeFactory.build();

server.use(
http.get(accountEndpoint, () => {
return HttpResponse.json(
accountFactory.build({ capabilities: ['Block Storage Encryption'] })
);
})
);

const { getByLabelText } = renderWithTheme(
<EditVolumeDrawer onClose={vi.fn} open volume={volume} />,
{
flags: { blockStorageEncryption: true },
}
);

await waitFor(() => {
expect(getByLabelText(encryptionLabelText)).not.toBeNull();
expect(getByLabelText(encryptionLabelText)).toBeDisabled();
});
});

it('should not display a checkbox for volume encryption if the user has the account capability but the feature flag is off', async () => {
const volume = volumeFactory.build();

server.use(
http.get(accountEndpoint, () => {
return HttpResponse.json(
accountFactory.build({ capabilities: ['Block Storage Encryption'] })
);
})
);

const { queryByRole } = renderWithTheme(
<EditVolumeDrawer onClose={vi.fn} open volume={volume} />,
{
flags: { blockStorageEncryption: false },
}
);

await waitFor(() => {
expect(queryByRole('checkbox')).not.toBeInTheDocument();
});
});

it('should not display a checkbox for volume encryption if the feature flag is on but the user lacks the account capability', async () => {
const volume = volumeFactory.build();

server.use(
http.get(accountEndpoint, () => {
return HttpResponse.json(accountFactory.build({ capabilities: [] }));
})
);

const { queryByRole } = renderWithTheme(
<EditVolumeDrawer onClose={vi.fn} open volume={volume} />,
{
flags: { blockStorageEncryption: true },
}
);

await waitFor(() => {
expect(queryByRole('checkbox')).not.toBeInTheDocument();
});
});
});
26 changes: 25 additions & 1 deletion packages/manager/src/features/Volumes/EditVolumeDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Volume } from '@linode/api-v4';
import { UpdateVolumeSchema } from '@linode/validation';
import { useFormik } from 'formik';
import React from 'react';

import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel';
import { Box } from 'src/components/Box';
import { Checkbox } from 'src/components/Checkbox';
import { Drawer } from 'src/components/Drawer';
import { BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY } from 'src/components/Encryption/constants';
import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils';
import { Notice } from 'src/components/Notice/Notice';
import { TagsInput } from 'src/components/TagsInput/TagsInput';
import { TextField } from 'src/components/TextField';
Expand All @@ -15,6 +18,8 @@ import {
handleGeneralErrors,
} from 'src/utilities/formikErrorUtils';

import type { Volume } from '@linode/api-v4';

interface Props {
onClose: () => void;
open: boolean;
Expand All @@ -28,6 +33,10 @@ export const EditVolumeDrawer = (props: Props) => {

const { mutateAsync: updateVolume } = useUpdateVolumeMutation();

const {
isBlockStorageEncryptionFeatureEnabled,
} = useIsBlockStorageEncryptionFeatureEnabled();

const isReadOnly =
grants !== undefined &&
grants.volume.find((grant) => grant.id === volume?.id)?.permissions ===
Expand Down Expand Up @@ -114,6 +123,21 @@ export const EditVolumeDrawer = (props: Props) => {
name="tags"
value={values.tags?.map((t) => ({ label: t, value: t })) ?? []}
/>
{isBlockStorageEncryptionFeatureEnabled && (
<Box
sx={{
marginLeft: '2px',
marginTop: '16px',
}}
>
<Checkbox
checked={volume?.encryption === 'enabled'}
disabled
text="Encrypt Volume"
toolTipText={BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY}
/>
</Box>
)}
<ActionsPanel
primaryButtonProps={{
disabled: isReadOnly || !dirty,
Expand Down

0 comments on commit 0083246

Please sign in to comment.