Skip to content

Commit

Permalink
feat: [M3-6722] – VPC endpoints, validation, & React Query queries (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dwiley-akamai authored Jul 6, 2023
1 parent ae14377 commit 5b5cf30
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 5 deletions.
5 changes: 5 additions & 0 deletions packages/api-v4/.changeset/pr-9361-added-1688422080839.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Added
---

Endpoints for VPC ([#9361](https://github.com/linode/manager/pull/9361))
12 changes: 7 additions & 5 deletions packages/api-v4/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export * from './account';

export * from './databases';

export * from './domains';

export * from './entity-transfers';

export * from './firewalls';

export * from './images';
Expand All @@ -16,6 +20,8 @@ export * from './managed';

export * from './networking';

export * from './nodebalancers';

export * from './object-storage';

export * from './profile';
Expand All @@ -34,11 +40,7 @@ export * from './vlans';

export * from './volumes';

export * from './nodebalancers';

export * from './databases';

export * from './entity-transfers';
export * from './vpcs';

export {
baseRequest,
Expand Down
3 changes: 3 additions & 0 deletions packages/api-v4/src/vpcs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './vpcs';

export * from './types';
34 changes: 34 additions & 0 deletions packages/api-v4/src/vpcs/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export interface VPC {
id: number;
label: string;
description: string;
region: string;
subnets: Subnet[];
created: string;
updated: string;
}

export interface CreateVPCPayload {
label: string;
description?: string;
region: string;
subnets?: SubnetPostObject[];
}

export interface UpdateVPCPayload {
label?: string;
description?: string;
}

export interface SubnetPostObject {
label: string;
ipv4: string;
ipv6: string;
}

export interface Subnet extends SubnetPostObject {
id: number;
linodes: number[];
created: string;
updated: string;
}
81 changes: 81 additions & 0 deletions packages/api-v4/src/vpcs/vpcs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
createVPCSchema,
updateVPCSchema,
} from '@linode/validation/lib/vpcs.schema';
import { BETA_API_ROOT as API_ROOT } from '../constants';
import Request, {
setData,
setMethod,
setParams,
setURL,
setXFilter,
} from '../request';
import { Filter, ResourcePage as Page, Params } from '../types';
import { CreateVPCPayload, UpdateVPCPayload, VPC } from './types';

// VPC methods
/**
* getVPCs
*
* Return a paginated list of VPCs on this account.
*
*/
export const getVPCs = (params?: Params, filter?: Filter) =>
Request<Page<VPC>>(
setURL(`${API_ROOT}/vpcs`),
setMethod('GET'),
setParams(params),
setXFilter(filter)
);

/**
* getVPC
*
* Return details for a single specified VPC.
*
*/
export const getVPC = (vpcID: number) =>
Request<VPC>(
setURL(`${API_ROOT}/vpcs/${encodeURIComponent(vpcID)}`),
setMethod('GET')
);

/**
* createVPC
*
* Create a new VPC in the specified region.
*
*/
export const createVPC = (data: CreateVPCPayload) =>
Request<VPC>(
setURL(`${API_ROOT}/vpcs`),
setMethod('POST'),
setData(data, createVPCSchema)
);

/**
* updateVPC
*
* Update a VPC.
*
*/
export const updateVPC = (vpcID: number, data: UpdateVPCPayload) =>
Request<VPC>(
setURL(`${API_ROOT}/vpcs/${encodeURIComponent(vpcID)}`),
setMethod('PUT'),
setData(data, updateVPCSchema)
);

/**
* deleteVPC
*
* Delete a single specified VPC.
*
*/
export const deleteVPC = (vpcID: number) =>
Request<{}>(
setURL(`${API_ROOT}/vpcs/${encodeURIComponent(vpcID)}`),
setMethod('DELETE')
);

// Subnet methods
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-9361-added-1688421871670.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

React Query methods for VPC ([#9361](https://github.com/linode/manager/pull/9361))
64 changes: 64 additions & 0 deletions packages/manager/src/queries/vpcs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
CreateVPCPayload,
UpdateVPCPayload,
VPC,
createVPC,
deleteVPC,
getVPC,
getVPCs,
updateVPC,
} from '@linode/api-v4';
import {
APIError,
Filter,
Params,
ResourcePage,
} from '@linode/api-v4/lib/types';
import { useMutation, useQuery, useQueryClient } from 'react-query';

export const queryKey = 'vpcs';

export const useVPCsQuery = (params: Params, filter: Filter) => {
return useQuery<ResourcePage<VPC>, APIError[]>(
[queryKey, 'paginated', params, filter],
() => getVPCs(params, filter),
{ keepPreviousData: true }
);
};

export const useVPCQuery = (id: number) => {
return useQuery<VPC, APIError[]>([queryKey, 'vpc', id], () => getVPC(id));
};

export const useCreateVPCMutation = () => {
const queryClient = useQueryClient();
return useMutation<VPC, APIError[], CreateVPCPayload>(createVPC, {
onSuccess: (VPC) => {
queryClient.invalidateQueries([queryKey, 'paginated']);
queryClient.setQueryData([queryKey, 'vpc', VPC.id], VPC);
},
});
};

export const useUpdateVPCMutation = (id: number) => {
const queryClient = useQueryClient();
return useMutation<VPC, APIError[], UpdateVPCPayload>(
(data) => updateVPC(id, data),
{
onSuccess: (VPC) => {
queryClient.invalidateQueries([queryKey, 'paginated']);
queryClient.setQueryData<VPC>([queryKey, 'vpc', VPC.id], VPC);
},
}
);
};

export const useDeleteVPCMutation = (id: number) => {
const queryClient = useQueryClient();
return useMutation<{}, APIError[]>(() => deleteVPC(id), {
onSuccess: () => {
queryClient.invalidateQueries([queryKey, 'paginated']);
queryClient.removeQueries([queryKey, 'vpc', id]);
},
});
};
5 changes: 5 additions & 0 deletions packages/validation/.changeset/pr-9361-added-1688422154757.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/validation": Added
---

Validation for VPC creation and updates ([#9361](https://github.com/linode/manager/pull/9361))
1 change: 1 addition & 0 deletions packages/validation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from './support.schema';
export * from './transfers.schema';
export * from './twofactor.schema';
export * from './volumes.schema';
export * from './vpcs.schema';
39 changes: 39 additions & 0 deletions packages/validation/src/vpcs.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { array, object, string } from 'yup';

const LABEL_MESSAGE = 'VPC label must be between 1 and 64 characters.';

export const createVPCSchema = object({
label: string()
.test(
'no two dashes in a row',
'Must not contain two dashes in a row',
(value) => !value?.includes('--')
)
.required('Label is required')
.min(1, LABEL_MESSAGE)
.max(64, LABEL_MESSAGE)
.matches(
/[a-zA-Z0-9-]+/,
'Must include only ASCII letters, numbers, and dashes'
),
description: string(),
region: string().required('Region is required'),
subnets: array().of(object()),
});

export const updateVPCSchema = object({
label: string()
.notRequired()
.test(
'no two dashes in a row',
'Must not contain two dashes in a row',
(value) => !value?.includes('--')
)
.min(1, LABEL_MESSAGE)
.max(64, LABEL_MESSAGE)
.matches(
/[a-zA-Z0-9-]+/,
'Must include only ASCII letters, numbers, and dashes'
),
description: string().notRequired(),
});

0 comments on commit 5b5cf30

Please sign in to comment.