Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upcoming: [M3-8869] - Update types for NodeBalancer UDP support #11321

Merged
Merged
5 changes: 5 additions & 0 deletions packages/api-v4/.changeset/pr-11321-added-1733240671518.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Added
---

Types for UDP NodeBalancer support ([#11321](https://github.com/linode/manager/pull/11321))
102 changes: 93 additions & 9 deletions packages/api-v4/src/nodebalancers/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
type TCPAlgorithm = 'roundrobin' | 'leastconn' | 'source';
type UDPAlgorithm = 'roundrobin' | 'leastconn' | 'ring_hash';

export type Algorithm = TCPAlgorithm | UDPAlgorithm;

export type Protocol = 'http' | 'https' | 'tcp' | 'udp';

type TCPStickiness = 'none' | 'table' | 'http_cookie';
type UDPStickiness = 'none' | 'session' | 'source_ip';

export type Stickiness = TCPStickiness | UDPStickiness;

export interface NodeBalancer {
id: number;
label: string;
hostname: string;
/**
* Maximum number of new TCP connections that a client (identified by a specific source IP)
* is allowed to initiate every second.
*/
client_conn_throttle: number;
/**
* Maximum number of new UDP sessions that a client (identified by a specific source IP)
* is allowed to initiate every second.
*
* @todo Remove optionality once UDP support is live
*/
client_udp_sess_throttle?: number;
region: string;
ipv4: string;
ipv6: null | string;
Expand Down Expand Up @@ -31,11 +54,15 @@ export interface BalancerTransfer {
total: number;
}

/**
* 'none' is reserved for nodes used in UDP configurations. They don't support different modes.
*/
export type NodeBalancerConfigNodeMode =
| 'accept'
| 'reject'
| 'backup'
| 'drain';
| 'drain'
| 'none';

export interface NodeBalancerConfig {
id: number;
Expand All @@ -44,22 +71,31 @@ export interface NodeBalancerConfig {
check_passive: boolean;
ssl_cert: string;
nodes_status: NodesStatus;
protocol: 'http' | 'https' | 'tcp';
protocol: Protocol;
ssl_commonname: string;
check_interval: number;
check_attempts: number;
check_timeout: number;
check_body: string;
check_path: string;
/**
* @todo Remove optionality once UDP support is live
*/
udp_check_port?: number;
/**
* @readonly This is returned by the API but *not* editable
* @todo Remove optionality once UDP support is live
* @default 16
*/
udp_session_timeout?: number;
proxy_protocol: NodeBalancerProxyProtocol;
check: 'none' | 'connection' | 'http' | 'http_body';
ssl_key: string;
stickiness: 'none' | 'table' | 'http_cookie';
algorithm: 'roundrobin' | 'leastconn' | 'source';
stickiness: Stickiness;
algorithm: Algorithm;
ssl_fingerprint: string;
cipher_suite: 'recommended' | 'legacy';
nodes: NodeBalancerConfigNode[];
modifyStatus?: 'new';
}

export type NodeBalancerProxyProtocol = 'none' | 'v1' | 'v2';
Expand All @@ -82,16 +118,48 @@ export interface NodeBalancerStats {

export interface CreateNodeBalancerConfig {
port?: number;
protocol?: 'http' | 'https' | 'tcp';
algorithm?: 'roundrobin' | 'leastconn' | 'source';
stickiness?: 'none' | 'table' | 'http_cookie';
/**
* If `udp` is chosen:
* - `check_passive` must be `false` or unset
* - `proxy_protocol` must be `none` or unset
* - The various SSL related fields like `ssl_cert`, `ssl_key`, `cipher_suite_recommended` should not be set
*/
protocol?: Protocol;
/**
* @default "none"
*/
proxy_protocol?: NodeBalancerProxyProtocol;
/**
* The algorithm for this configuration.
*
* TCP and HTTP support `roundrobin`, `leastconn`, and `source`
* UDP supports `roundrobin`, `leastconn`, and `ring_hash`
*
* @default roundrobin
*/
algorithm?: Algorithm;
/**
* Session stickiness for this configuration.
*
* TCP and HTTP support `none`, `table`, and `http_cookie`
* UDP supports `none`, `session`, and `source_ip`
*
* @default `session` for UDP
* @default `none` for TCP and HTTP
*/
stickiness?: Stickiness;
check?: 'none' | 'connection' | 'http' | 'http_body';
check_interval?: number;
check_timeout?: number;
check_attempts?: number;
check_path?: string;
check_body?: string;
check_passive?: boolean;
/**
* Must be between 1 and 65535
* @default 80
*/
udp_check_port?: number;
cipher_suite?: 'recommended' | 'legacy';
ssl_cert?: string;
ssl_key?: string;
Expand All @@ -102,6 +170,9 @@ export type UpdateNodeBalancerConfig = CreateNodeBalancerConfig;
export interface CreateNodeBalancerConfigNode {
address: string;
label: string;
/**
* Should not be specified when creating a node used on a UDP configuration
*/
mode?: NodeBalancerConfigNodeMode;
weight?: number;
}
Expand All @@ -126,8 +197,21 @@ export interface NodeBalancerConfigNodeWithPort extends NodeBalancerConfigNode {
export interface CreateNodeBalancerPayload {
region?: string;
label?: string;
/**
* The connections per second throttle for TCP and HTTP connections
*
* Must be between 0 and 20. Set to 0 to disable throttling.
* @default 0
*/
client_conn_throttle?: number;
configs: any;
/**
* The connections per second throttle for UDP sessions
*
* Must be between 0 and 20. Set to 0 to disable throttling.
* @default 0
*/
client_udp_sess_throttle?: number;
configs: CreateNodeBalancerConfig[];
firewall_id?: number;
tags?: string[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Clean up NodeBalancer related types ([#11321](https://github.com/linode/manager/pull/11321))
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export const NodeBalancerConfigPanel = (

const algorithmHelperText = {
leastconn: LEAST_CONNECTIONS_ALGORITHM_HELPER_TEXT,
ring_hash: '', // @todo Add copy as part of UDP NodeBalancer project
roundrobin: ROUND_ROBIN_ALGORITHM_HELPER_TEXT,
source: SOURCE_ALGORITHM_HELPER_TEXT,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ import { sendCreateNodeBalancerEvent } from 'src/utilities/analytics/customEvent
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils';
import { getGDPRDetails } from 'src/utilities/formatRegion';
import { getAPIErrorFor } from 'src/utilities/getAPIErrorFor';
import { PRICE_ERROR_TOOLTIP_TEXT } from 'src/utilities/pricing/constants';
import { DOCS_LINK_LABEL_DC_PRICING } from 'src/utilities/pricing/constants';
import { PRICE_ERROR_TOOLTIP_TEXT } from 'src/utilities/pricing/constants';
import {
getDCSpecificPriceByType,
renderMonthlyPriceToCorrectDecimalPlace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getNodeBalancerConfigs,
updateNodeBalancerConfig,
updateNodeBalancerConfigNode,
} from '@linode/api-v4/lib/nodebalancers';
} from '@linode/api-v4';
import { Accordion, Box, Button, Typography } from '@linode/ui';
import { styled } from '@mui/material/styles';
import {
Expand Down Expand Up @@ -49,12 +49,13 @@ import type {
NodeBalancerConfigFieldsWithStatus,
NodeBalancerConfigNodeFields,
} from '../types';
import type { Grants } from '@linode/api-v4';
import type {
APIError,
Grants,
NodeBalancerConfig,
NodeBalancerConfigNode,
} from '@linode/api-v4/lib/nodebalancers';
import type { APIError, ResourcePage } from '@linode/api-v4/lib/types';
ResourcePage,
} from '@linode/api-v4';
import type { Lens } from 'ramda';
import type { RouteComponentProps } from 'react-router-dom';
import type { PromiseLoaderResponse } from 'src/components/PromiseLoader/PromiseLoader';
Expand Down
65 changes: 22 additions & 43 deletions packages/manager/src/features/NodeBalancers/types.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,44 @@
import type {
NodeBalancerConfigNodeMode,
APIError,
Algorithm,
NodeBalancerConfigNode,
NodeBalancerProxyProtocol,
} from '@linode/api-v4/lib/nodebalancers/types';
import type { APIError } from '@linode/api-v4/lib/types';
Protocol,
Stickiness,
UpdateNodeBalancerConfig,
} from '@linode/api-v4';

export interface NodeBalancerConfigFieldsWithStatus
extends NodeBalancerConfigFields {
/**
* Exists for the sake of local operations
*/
modifyStatus?: 'new';
}
export interface ExtendedNodeBalancerConfigNode {
address: string;
config_id?: number;
errors?: APIError[];
id: number;
label: string;
mode?: NodeBalancerConfigNodeMode;
modifyStatus?: 'delete' | 'new' | 'update';
nodebalancer_id: number;
port?: number;
status: 'DOWN' | 'UP' | 'unknown';
weight?: number;
}

export interface NodeBalancerConfigFields {
algorithm?: 'leastconn' | 'roundrobin' | 'source';
check?: 'connection' | 'http' | 'http_body' | 'none';
check_attempts?: number /** 1..30 */;
check_body?: string;
check_interval?: number;
check_passive?: boolean;
check_path?: string;
check_timeout?: number /** 1..30 */;
cipher_suite?: 'legacy' | 'recommended';
export interface NodeBalancerConfigFields extends UpdateNodeBalancerConfig {
id?: number;
nodes: NodeBalancerConfigNodeFields[];
port?: number /** 1..65535 */;
protocol?: 'http' | 'https' | 'tcp';
proxy_protocol?: NodeBalancerProxyProtocol;
ssl_cert?: string;
ssl_key?: string;
stickiness?: 'http_cookie' | 'none' | 'table';
}

export interface NodeBalancerConfigNodeFields {
export interface NodeBalancerConfigNodeFields
extends Partial<NodeBalancerConfigNode> {
address: string;
config_id?: number;
errors?: APIError[];
id?: number;
label: string;
mode?: NodeBalancerConfigNodeMode;
/* for the sake of local operations */
/**
* Exists for the sake of local operations
*/
modifyStatus?: 'delete' | 'new' | 'update';
nodebalancer_id?: number;
/**
* @note `port` is an "extended" field. The API includes it in the `address`
*/
port?: number;
status?: 'DOWN' | 'UP' | 'unknown';
weight?: number;
}

export interface NodeBalancerConfigPanelProps {
addNode: (nodeIdx?: number) => void;
algorithm: 'leastconn' | 'roundrobin' | 'source';
algorithm: Algorithm;
checkBody: string;
checkPassive: boolean;

Expand Down Expand Up @@ -113,10 +92,10 @@ export interface NodeBalancerConfigPanelProps {
onSslCertificateChange: (v: string) => void;
port: number;
privateKey: string;
protocol: 'http' | 'https' | 'tcp';
protocol: Protocol;
proxyProtocol: NodeBalancerProxyProtocol;
removeNode: (nodeIdx: number) => void;
sessionStickiness: 'http_cookie' | 'none' | 'table';
sessionStickiness: Stickiness;
sslCertificate: string;
submitting?: boolean;
}
3 changes: 1 addition & 2 deletions packages/manager/src/features/NodeBalancers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { filter, isNil } from 'ramda';
import { getErrorMap } from 'src/utilities/errorUtils';

import type {
ExtendedNodeBalancerConfigNode,
NodeBalancerConfigFields,
NodeBalancerConfigFieldsWithStatus,
NodeBalancerConfigNodeFields,
Expand Down Expand Up @@ -51,7 +50,7 @@ export const nodeForRequest = (node: NodeBalancerConfigNodeFields) => ({
weight: +node.weight!,
});

export const formatAddress = (node: ExtendedNodeBalancerConfigNode) => ({
export const formatAddress = (node: NodeBalancerConfigNodeFields) => ({
...node,
address: `${node.address}:${node.port}`,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/validation": Added
---

Validation for UDP NodeBalancer support ([#11321](https://github.com/linode/manager/pull/11321))
Loading
Loading