Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/api-v4/.changeset/pr-13171-added-1764924231615.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Added
---

`Akamai Cloud Pulse Logs LKE-E Audit ` to the `AccountCapability` type ([#13171](https://github.com/linode/manager/pull/13171))
1 change: 1 addition & 0 deletions packages/api-v4/src/account/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const accountCapabilities = [
'Akamai Cloud Load Balancer',
'Akamai Cloud Pulse',
'Akamai Cloud Pulse Logs',
'Akamai Cloud Pulse Logs LKE-E Audit',
'Block Storage',
'Block Storage Encryption',
'Cloud Firewall',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Changed
---

Logs: in Stream Form limit access to "lke_audit_logs" type based on Akamai Cloud Pulse Logs LKE-E Audit capability ([#13171](https://github.com/linode/manager/pull/13171))
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { streamType } from '@linode/api-v4';
import { mockDestination } from 'support/constants/delivery';
import { mockGetAccount } from 'support/intercepts/account';
import {
mockCreateDestination,
mockCreateStream,
Expand All @@ -12,9 +13,11 @@ import { ui } from 'support/ui';
import { logsStreamForm } from 'support/ui/pages/logs-stream-form';
import { randomLabel } from 'support/util/random';

import { kubernetesClusterFactory } from 'src/factories';
import { accountFactory, kubernetesClusterFactory } from 'src/factories';

describe('Create Stream', () => {
const account = accountFactory.build();

beforeEach(() => {
mockAppendFeatureFlags({
aclpLogs: {
Expand All @@ -23,6 +26,14 @@ describe('Create Stream', () => {
bypassAccountCapabilities: true,
},
});

mockGetAccount({
...account,
capabilities: [
...account.capabilities,
'Akamai Cloud Pulse Logs LKE-E Audit',
],
});
});

describe('given Audit Logs Stream Type', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,23 @@
import React from 'react';
import { describe, expect } from 'vitest';

import { accountFactory } from 'src/factories';
import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers';

import { StreamFormGeneralInfo } from './StreamFormGeneralInfo';

const queryMocks = vi.hoisted(() => ({
useAccount: vi.fn().mockReturnValue({}),
}));

vi.mock('@linode/queries', async () => {
const actual = await vi.importActual('@linode/queries');
return {
...actual,
useAccount: queryMocks.useAccount,
};
});

describe('StreamFormGeneralInfo', () => {
describe('when in create mode', () => {
it('should render Name input and allow to type text', async () => {
Expand All @@ -24,35 +37,77 @@
});
});

it('should render Stream type input and allow to select different options', async () => {
renderWithThemeAndHookFormContext({
component: <StreamFormGeneralInfo mode="create" />,
useFormOptions: {
defaultValues: {
stream: {
type: streamType.AuditLogs,
describe('when user has Akamai Cloud Pulse Logs LKE-E Audit capability', () => {
it('should render Stream type input and allow to select different options', async () => {
const account = accountFactory.build({
capabilities: ['Akamai Cloud Pulse Logs LKE-E Audit'],
});

queryMocks.useAccount.mockReturnValue({
data: account,
isLoading: false,
error: null,
});

renderWithThemeAndHookFormContext({
component: <StreamFormGeneralInfo mode="create" />,
useFormOptions: {
defaultValues: {
stream: {
type: streamType.AuditLogs,
},
},
},
},
});
});

const streamTypesAutocomplete = screen.getByRole('combobox');
const streamTypesAutocomplete = screen.getByRole('combobox');

expect(streamTypesAutocomplete).toHaveValue('Audit Logs');

// Open the dropdown
await userEvent.click(streamTypesAutocomplete);
expect(streamTypesAutocomplete).toHaveValue('Audit Logs');

Check warning on line 65 in packages/manager/src/features/Delivery/Streams/StreamForm/StreamFormGeneralInfo.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":65,"column":53,"nodeType":"Literal","endLine":65,"endColumn":65}

// Select the "Kubernetes API Audit Logs" option
const kubernetesApiAuditLogs = await screen.findByText(
'Kubernetes API Audit Logs'
);
await userEvent.click(kubernetesApiAuditLogs);
// Open the dropdown
await userEvent.click(streamTypesAutocomplete);

await waitFor(() => {
expect(streamTypesAutocomplete).toHaveValue(
// Select the "Kubernetes API Audit Logs" option
const kubernetesApiAuditLogs = await screen.findByText(
'Kubernetes API Audit Logs'
);
await userEvent.click(kubernetesApiAuditLogs);

await waitFor(() => {

Check warning on line 76 in packages/manager/src/features/Delivery/Streams/StreamForm/StreamFormGeneralInfo.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Refactor this code to not nest functions more than 4 levels deep. Raw Output: {"ruleId":"sonarjs/no-nested-functions","severity":1,"message":"Refactor this code to not nest functions more than 4 levels deep.","line":76,"column":26,"nodeType":null,"endLine":76,"endColumn":28}
expect(streamTypesAutocomplete).toHaveValue(
'Kubernetes API Audit Logs'
);
});
});
});

describe('when user does not have Akamai Cloud Pulse Logs LKE-E Audit capability', () => {
it('should render disabled Stream type input with Audit Logs selected', async () => {
const account = accountFactory.build({
capabilities: [],
});

queryMocks.useAccount.mockReturnValue({
data: account,
isLoading: false,
error: null,
});

renderWithThemeAndHookFormContext({
component: <StreamFormGeneralInfo mode="create" />,
useFormOptions: {
defaultValues: {
stream: {
type: streamType.AuditLogs,
},
},
},
});

const streamTypesAutocomplete = screen.getByRole('combobox');

expect(streamTypesAutocomplete).toBeDisabled();
expect(streamTypesAutocomplete).toHaveValue('Audit Logs');
});
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { streamType } from '@linode/api-v4';
import { useAccount } from '@linode/queries';
import {
Autocomplete,
Box,
Expand Down Expand Up @@ -35,6 +36,10 @@ export const StreamFormGeneralInfo = (props: StreamFormGeneralInfoProps) => {

const theme = useTheme();
const { control, setValue } = useFormContext<StreamAndDestinationFormType>();
const { data: account } = useAccount();
const isLkeEAuditLogsTypeSelectionDisabled = !account?.capabilities?.includes(
'Akamai Cloud Pulse Logs LKE-E Audit'
);

const capitalizedMode = capitalize(mode);
const description = {
Expand All @@ -47,8 +52,13 @@ export const StreamFormGeneralInfo = (props: StreamFormGeneralInfoProps) => {
audit_logs: `Logs Delivery Streams ${capitalizedMode}-Audit Logs`,
lke_audit_logs: `Logs Delivery Streams ${capitalizedMode}-Kubernetes Audit Logs`,
};

const filteredStreamTypeOptions = isLkeEAuditLogsTypeSelectionDisabled
? streamTypeOptions.filter(({ value }) => value !== streamType.LKEAuditLogs)
: streamTypeOptions;

const streamTypeOptionsWithPendo: AutocompleteOption[] =
streamTypeOptions.map((option) => ({
filteredStreamTypeOptions.map((option) => ({
...option,
pendoId: pendoIds[option.value as StreamType],
}));
Expand Down Expand Up @@ -98,7 +108,9 @@ export const StreamFormGeneralInfo = (props: StreamFormGeneralInfoProps) => {
render={({ field, fieldState }) => (
<Autocomplete
disableClearable
disabled={isFormInEditMode(mode)}
disabled={
isFormInEditMode(mode) || isLkeEAuditLogsTypeSelectionDisabled
}
errorText={fieldState.error?.message}
label="Stream Type"
onBlur={field.onBlur}
Expand Down