Skip to content

Commit

Permalink
upcoming: [APL-55] - Application platform for Linode Kubernetes (lino…
Browse files Browse the repository at this point in the history
…de#10753)

* apl integration

* fix: added missing apl_enabled to call

* feat: apl beta check

* final styling changes

* Split conditional beta call in seperate functions and types

* removed beta type in favor for simplicity

* replaced optional apl_enabled parameter with required parameter

* reverted apl_enabled as required

* somehow this exclamation mark got removed

* added test for array for breadcrumbs

* minor styling tweaks and some comments
  • Loading branch information
dennisvankekem authored Oct 8, 2024
1 parent f51b555 commit c0d8900
Show file tree
Hide file tree
Showing 23 changed files with 433 additions and 68 deletions.
35 changes: 32 additions & 3 deletions packages/api-v4/src/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createKubeClusterSchema } from '@linode/validation/lib/kubernetes.schema';
import { API_ROOT } from '../constants';
import { API_ROOT, BETA_API_ROOT } from '../constants';
import Request, {
setData,
setMethod,
Expand Down Expand Up @@ -41,17 +41,46 @@ export const getKubernetesCluster = (clusterID: number) =>
setURL(`${API_ROOT}/lke/clusters/${encodeURIComponent(clusterID)}`)
);

/**
* getKubernetesClusterBeta
*
* Return details about a single Kubernetes cluster from beta API
*/
export const getKubernetesClusterBeta = (clusterID: number) =>
Request<KubernetesCluster>(
setMethod('GET'),
setURL(`${BETA_API_ROOT}/lke/clusters/${encodeURIComponent(clusterID)}`)
);

/**
* createKubernetesClusters
*
* Create a new cluster.
*/
export const createKubernetesCluster = (data: CreateKubeClusterPayload) =>
Request<KubernetesCluster>(
export const createKubernetesCluster = (data: CreateKubeClusterPayload) => {
return Request<KubernetesCluster>(
setMethod('POST'),
setURL(`${API_ROOT}/lke/clusters`),
setData(data, createKubeClusterSchema)
);
};

/**
* createKubernetesClustersBeta
*
* Create a new cluster with the BETA api whenever feature flag for APL is enabled
* and APL is set to enabled in the UI
*
* duplicated function of createKubernetesCluster
* necessary to call BETA_API_ROOT in a seperate function based on feature flag
*/
export const createKubernetesClusterBeta = (data: CreateKubeClusterPayload) => {
return Request<KubernetesCluster>(
setMethod('POST'),
setURL(`${BETA_API_ROOT}/lke/clusters`),
setData(data, createKubeClusterSchema)
);
};

/**
* updateKubernetesCluster
Expand Down
2 changes: 2 additions & 0 deletions packages/api-v4/src/kubernetes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface KubernetesCluster {
id: number;
tags: string[];
control_plane: ControlPlaneOptions;
apl_enabled?: boolean; // this is not the ideal solution, but a necessary compromise to prevent a lot of duplicated code.
}

export interface KubeNodePoolResponse {
Expand Down Expand Up @@ -69,4 +70,5 @@ export interface CreateKubeClusterPayload {
node_pools: CreateNodePoolData[];
k8s_version?: string; // Will be caught by Yup if undefined
control_plane?: ControlPlaneOptions;
apl_enabled?: boolean; // this is not the ideal solution, but a necessary compromise to prevent a lot of duplicated code.
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ describe('Breadcrumb component', () => {
expect(getAllByTestId('link-text')).toHaveLength(2);
});

it('removes multiple crumbs when given an array of indices', () => {
const { getAllByTestId } = render(
wrapWithTheme(<Breadcrumb {...props} removeCrumbX={[1, 2]} />)
);
expect(getAllByTestId('link-text')).toHaveLength(1);
});

it('renders an editable text field given editable props', () => {
const { queryByTestId } = render(
wrapWithTheme(
Expand Down
17 changes: 13 additions & 4 deletions packages/manager/src/components/Breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface BreadcrumbProps {
/**
* A number indicating the position of the crumb to remove. Not zero indexed.
*/
removeCrumbX?: number;
removeCrumbX?: number | number[];
}

/**
Expand All @@ -64,10 +64,19 @@ export const Breadcrumb = (props: BreadcrumbProps) => {
const url = pathname && pathname.slice(1);
const allPaths = url.split('/');

const pathMap = removeCrumbX
? removeByIndex(allPaths, removeCrumbX - 1)
: allPaths;
let pathMap;

if (Array.isArray(removeCrumbX)) {
// Sort the indices in descending order
const indicesToRemove = new Set(removeCrumbX.map((index) => index - 1));

// Filter out the indices to remove
pathMap = allPaths.filter((_, index) => !indicesToRemove.has(index));
} else if (removeCrumbX != null) {
pathMap = removeByIndex(allPaths, removeCrumbX - 1);
} else {
pathMap = allPaths;
}
const hasError = Boolean(onEditHandlers?.errorText);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface LandingHeaderProps {
onButtonClick?: () => void;
onButtonKeyPress?: (e: React.KeyboardEvent<HTMLButtonElement>) => void;
onDocsClick?: () => void;
removeCrumbX?: number;
removeCrumbX?: number | number[];
shouldHideDocsAndCreateButtons?: boolean;
title?: JSX.Element | string;
}
Expand Down
1 change: 1 addition & 0 deletions packages/manager/src/dev-tools/FeatureFlagTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const MOCK_FEATURE_FLAGS_STORAGE_KEY = 'devTools/mock-feature-flags';
*/
const options: { flag: keyof Flags; label: string }[] = [
{ flag: 'aclp', label: 'CloudPulse' },
{ flag: 'apl', label: 'Application platform for LKE' },
{ flag: 'blockStorageEncryption', label: 'Block Storage Encryption (BSE)' },
{ flag: 'disableLargestGbPlans', label: 'Disable Largest GB Plans' },
{ flag: 'gecko2', label: 'Gecko' },
Expand Down
1 change: 1 addition & 0 deletions packages/manager/src/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export interface Flags {
aclpReadEndpoint: string;
aclpResourceTypeMap: CloudPulseResourceTypeMapFlag[];
apiMaintenance: APIMaintenance;
apl: boolean;
apicliButtonCopy: string;
apicliDxToolsAdditions: boolean;
blockStorageEncryption: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react';

import { Box } from 'src/components/Box';
import { Chip } from 'src/components/Chip';
import { FormControl } from 'src/components/FormControl';
import { FormControlLabel } from 'src/components/FormControlLabel';
import { FormLabel } from 'src/components/FormLabel';
import { Link } from 'src/components/Link';
import { Radio } from 'src/components/Radio/Radio';
import { RadioGroup } from 'src/components/RadioGroup';
import { Typography } from 'src/components/Typography';

export interface APLProps {
setAPL: (apl: boolean) => void;
setHighAvailability: (ha: boolean | undefined) => void;
}

export const APLCopy = () => (
<Typography>
Add a pre-paved path to build, deploy, monitor and secure applications.
<br />
<Link to="https://otomi.io">
Learn more about Application Platform for LKE.
</Link>
</Typography>
);

export const ApplicationPlatform = (props: APLProps) => {
const { setAPL, setHighAvailability } = props;

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setAPL(e.target.value === 'yes');
setHighAvailability(e.target.value === 'yes');
};

return (
<FormControl>
<FormLabel
sx={(theme) => ({
'&&.MuiFormLabel-root.Mui-focused': {
color: theme.name === 'dark' ? 'white' : theme.color.black,
},
})}
>
<Box alignItems="center" display="flex" flexDirection="row">
<Typography variant="inherit">
Application Platform for LKE
</Typography>
<Chip color="primary" label="BETA" sx={{ ml: 1 }} />
</Box>
</FormLabel>
<APLCopy />
<RadioGroup onChange={(e) => handleChange(e)}>
<FormControlLabel
label={
<Typography>Yes, enable Application platform for LKE.</Typography>
}
control={<Radio />}
name="yes"
value="yes"
/>
<FormControlLabel control={<Radio />} label="No" name="no" value="no" />
</RadioGroup>
</FormControl>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export const useStyles = makeStyles()((theme: Theme) => ({
},
}));

export const StyledRegionSelectStack = styled(Stack, {
label: 'StyledRegionSelectStack',
export const StyledFieldWithDocsStack = styled(Stack, {
label: 'StyledFieldWithDocsStack',
})(({ theme }) => ({
flexDirection: 'row',
[theme.breakpoints.down('md')]: {
Expand Down
Loading

0 comments on commit c0d8900

Please sign in to comment.