This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 3c7ddb7 feat: Upstream health check (#489)
3c7ddb7 is described below
commit 3c7ddb70c5f172d96ee6fd17775e052205ad29d3
Author: liuxiran <[email protected]>
AuthorDate: Mon Sep 21 23:37:12 2020 +0800
feat: Upstream health check (#489)
* feat: upstream healthy check
* fix: show active health check switch and passive health check switch at
the same time
* fix: update refer to the code review
---
src/pages/Upstream/Create.tsx | 24 +-
src/pages/Upstream/components/Preview.tsx | 7 +-
src/pages/Upstream/components/Step1.tsx | 439 +++++++++++++++++++++++++++++-
src/pages/Upstream/locales/en-US.ts | 24 ++
src/pages/Upstream/locales/zh-CN.ts | 24 ++
src/pages/Upstream/transform.ts | 13 +-
src/pages/Upstream/typing.d.ts | 27 ++
7 files changed, 550 insertions(+), 8 deletions(-)
diff --git a/src/pages/Upstream/Create.tsx b/src/pages/Upstream/Create.tsx
index 405ecb9..5f4e817 100644
--- a/src/pages/Upstream/Create.tsx
+++ b/src/pages/Upstream/Create.tsx
@@ -28,15 +28,29 @@ import { transformCreate, transformFetch } from
'./transform';
const Page: React.FC = (props) => {
const [step, setStep] = useState(1);
+ const [active, setActive] = useState(false);
+ const [passive, setPassive] = useState(false);
const [form1] = Form.useForm();
const { formatMessage } = useIntl();
+ const onChange = (checkActive: boolean, checkPassive: boolean) => {
+ setActive(checkActive);
+ setPassive(checkPassive);
+ };
+
useEffect(() => {
const { id } = (props as any).match.params;
if (id) {
fetchOne(id).then((data) => {
- form1.setFieldsValue(transformFetch(data));
+ const transformData = transformFetch(data);
+ form1.setFieldsValue(transformData);
+ if (transformData.active) {
+ setActive(true);
+ }
+ if (transformData.passive) {
+ setPassive(true);
+ }
});
}
}, []);
@@ -77,8 +91,12 @@ const Page: React.FC = (props) => {
<Steps.Step title={formatMessage({ id: 'upstream.create.preview'
})} />
</Steps>
- {step === 1 && <Step1 form={form1} />}
- {step === 2 && <Preview form1={form1} />}
+ {step === 1 && (
+ <Step1 form={form1} isActive={active} onChange={onChange}
isPassive={passive} />
+ )}
+ {step === 2 && (
+ <Preview form1={form1} isActive={active} onChange={onChange}
isPassive={passive} />
+ )}
</Card>
</PageContainer>
<ActionBar step={step} lastStep={2} onChange={onStepChange} />
diff --git a/src/pages/Upstream/components/Preview.tsx
b/src/pages/Upstream/components/Preview.tsx
index 92d436f..f73cf16 100644
--- a/src/pages/Upstream/components/Preview.tsx
+++ b/src/pages/Upstream/components/Preview.tsx
@@ -21,8 +21,13 @@ import Step1 from './Step1';
type Props = {
form1: FormInstance;
+ isActive: boolean;
+ isPassive: boolean;
+ onChange(a: boolean, p: boolean): void;
};
-const Page: React.FC<Props> = ({ form1 }) => <Step1 form={form1} disabled />;
+const Page: React.FC<Props> = ({ form1, isActive, onChange, isPassive }) => (
+ <Step1 form={form1} disabled isActive={isActive} onChange={onChange}
isPassive={isPassive} />
+);
export default Page;
diff --git a/src/pages/Upstream/components/Step1.tsx
b/src/pages/Upstream/components/Step1.tsx
index cfbf2b4..0e5e3a5 100644
--- a/src/pages/Upstream/components/Step1.tsx
+++ b/src/pages/Upstream/components/Step1.tsx
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import React from 'react';
-import { Form, Input, Row, Col, InputNumber, Select } from 'antd';
+import { Form, Input, Row, Col, InputNumber, Select, Switch, notification }
from 'antd';
import { FormInstance } from 'antd/lib/form';
import { useIntl } from 'umi';
@@ -27,10 +27,14 @@ import {
HASH_KEY_LIST,
HASH_ON_LIST,
} from '@/pages/Upstream/constants';
+import { PanelSection } from '@api7-dashboard/ui';
type Props = {
form: FormInstance;
disabled?: boolean;
+ isActive: boolean;
+ isPassive: boolean;
+ onChange(checkActive: boolean, checkPassive: boolean): void;
};
const initialValues = {
@@ -43,9 +47,38 @@ const initialValues = {
send: 6000,
read: 6000,
},
+ active: false,
+ passive: false,
+ checks: {
+ active: {
+ timeout: 5,
+ http_path: '',
+ host: '',
+ healthy: {
+ interval: 2,
+ successes: 1,
+ },
+ unhealthy: {
+ interval: 1,
+ http_failures: 2,
+ },
+ req_headers: [''],
+ },
+ passive: {
+ healthy: {
+ http_statuses: [undefined],
+ successes: 3,
+ },
+ unhealthy: {
+ http_statuses: [undefined],
+ http_failures: 3,
+ tcp_failures: 3,
+ },
+ },
+ },
};
-const Step1: React.FC<Props> = ({ form, disabled }) => {
+const Step1: React.FC<Props> = ({ form, disabled, isActive, onChange,
isPassive }) => {
const { formatMessage } = useIntl();
const renderUpstreamMeta = () => (
@@ -171,6 +204,390 @@ const Step1: React.FC<Props> = ({ form, disabled }) => {
const renderTimeUnit = () => <span style={{ margin: '0 8px' }}>ms</span>;
+ const handleActiveChange = () => {
+ if (isActive) {
+ onChange(!isActive, false);
+ form.setFieldsValue({ ...form.getFieldsValue(), passive: false });
+ return;
+ }
+ onChange(!isActive, isPassive);
+ form.setFieldsValue({ ...form.getFieldsValue(), active: !isActive });
+ };
+ const handlePassiveChange = () => {
+ if (!isActive) {
+ notification.warning({
+ message: formatMessage({ id:
'upstream.notificationMessage.enableHealthCheckFirst' }),
+ });
+ form.setFieldsValue({ ...form.getFieldsValue(), passive: isPassive });
+ return;
+ }
+ onChange(isActive, !isPassive);
+ form.setFieldsValue({ ...form.getFieldsValue(), passive: !isPassive });
+ };
+
+ const renderPassiveHealthyCheck = () => (
+ <>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.healthy' })} />
+ <Form.List name={['checks', 'passive', 'healthy', 'http_statuses']}>
+ {(fields, { add, remove }) => (
+ <>
+ {fields.map((field, index) => (
+ <Form.Item
+ required
+ key={field.key}
+ {...(index === 0 ? FORM_ITEM_LAYOUT : FORM_ITEM_WITHOUT_LABEL)}
+ label={
+ index === 0
+ ? formatMessage({ id:
'upstream.step.healthy.checks.passive.http_statuses' })
+ : ''
+ }
+ >
+ <Row style={{ marginBottom: '10px' }} gutter={16}>
+ <Col span={4}>
+ <Form.Item style={{ marginBottom: 0 }} name={[field.name]}>
+ <InputNumber
+ placeholder={formatMessage({
+ id:
'upstream.step.input.healthy.checks.passive.http_statuses',
+ })}
+ disabled={disabled}
+ />
+ </Form.Item>
+ </Col>
+ <Col
+ style={{
+ marginLeft: -10,
+ display: 'flex',
+ alignItems: 'center',
+ }}
+ >
+ {!disabled &&
+ (fields.length > 1 ? (
+ <MinusCircleOutlined
+ style={{ margin: '0 8px' }}
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ ) : null)}
+ </Col>
+ </Row>
+ </Form.Item>
+ ))}
+ {!disabled && (
+ <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+ <Button
+ type="dashed"
+ onClick={() => {
+ add();
+ }}
+ >
+ <PlusOutlined />
+ {formatMessage({ id: 'upstream.step.create' })}
+ </Button>
+ </Form.Item>
+ )}
+ </>
+ )}
+ </Form.List>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.successes' })} required>
+ <Form.Item
+ name={['checks', 'passive', 'healthy', 'successes']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.receive.timeout' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} max={254} />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.unhealthy' })} />
+ <Form.List name={['checks', 'passive', 'unhealthy', 'http_statuses']}>
+ {(fields, { add, remove }) => (
+ <>
+ {fields.map((field, index) => (
+ <Form.Item
+ required
+ key={field.key}
+ {...(index === 0 ? FORM_ITEM_LAYOUT : FORM_ITEM_WITHOUT_LABEL)}
+ label={
+ index === 0
+ ? formatMessage({ id:
'upstream.step.healthy.checks.passive.http_statuses' })
+ : ''
+ }
+ >
+ <Row style={{ marginBottom: '10px' }} gutter={16}>
+ <Col span={4}>
+ <Form.Item style={{ marginBottom: 0 }} name={[field.name]}>
+ <InputNumber
+ placeholder={formatMessage({
+ id:
'upstream.step.input.healthy.checks.passive.http_statuses',
+ })}
+ disabled={disabled}
+ max={599}
+ />
+ </Form.Item>
+ </Col>
+ <Col
+ style={{
+ marginLeft: -10,
+ display: 'flex',
+ alignItems: 'center',
+ }}
+ >
+ {!disabled &&
+ (fields.length > 1 ? (
+ <MinusCircleOutlined
+ style={{ margin: '0 8px' }}
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ ) : null)}
+ </Col>
+ </Row>
+ </Form.Item>
+ ))}
+ {!disabled && (
+ <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+ <Button
+ type="dashed"
+ onClick={() => {
+ add();
+ }}
+ >
+ <PlusOutlined />
+ {formatMessage({ id: 'upstream.step.create' })}
+ </Button>
+ </Form.Item>
+ )}
+ </>
+ )}
+ </Form.List>
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.http_failures' })}
+ required
+ >
+ <Form.Item
+ name={['checks', 'passive', 'unhealthy', 'http_failures']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.http_failures' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} max={254} />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.passive.tcp_failures' })}
+ required
+ >
+ <Form.Item
+ name={['checks', 'passive', 'unhealthy', 'tcp_failures']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({
+ id: 'upstream.step.input.healthy.checks.passive.tcp_failures',
+ }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} max={254} />
+ </Form.Item>
+ </Form.Item>
+ </>
+ );
+
+ const renderActiveHealthyCheck = () => (
+ <>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.active.timeout' })}>
+ <Form.Item name={['checks', 'active', 'timeout']} noStyle>
+ <InputNumber disabled={disabled} />
+ </Form.Item>
+ <span style={{ margin: '0 8px' }}>s</span>
+ </Form.Item>
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.active.http_path' })}
+ required
+ >
+ <Form.Item
+ name={['checks', 'active', 'http_path']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.active.http_path' }),
+ },
+ ]}
+ >
+ <Input
+ disabled={disabled}
+ placeholder={formatMessage({
+ id: 'upstream.step.input.healthy.checks.active.http_path',
+ })}
+ />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.active.host' })} required>
+ <Form.Item
+ style={{ marginBottom: 0 }}
+ name={['checks', 'active', 'host']}
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.active.host' }),
+ },
+ {
+ pattern: new RegExp(
+
/(^([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(\.(25[0-5]|1\d{2}|2[0-4]\d|[1-9]?\d)){3}$|^(?![0-9.]+$)([a-zA-Z0-9_-]+)(\.[a-zA-Z0-9_-]+){0,}$)/,
+ 'g',
+ ),
+ message: formatMessage({ id:
'upstream.step.domain.name.or.ip.rule' }),
+ },
+ ]}
+ >
+ <Input
+ placeholder={formatMessage({ id:
'upstream.step.input.healthy.checks.active.host' })}
+ disabled={disabled}
+ />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.healthy' })} />
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.active.interval' })}
+ required
+ >
+ <Form.Item
+ style={{ marginBottom: 0 }}
+ name={['checks', 'active', 'healthy', 'interval']}
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.active.interval' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.successes' })} required>
+ <Form.Item
+ name={['checks', 'active', 'healthy', 'successes']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.successes' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} max={254} />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item label={formatMessage({ id:
'upstream.step.healthy.checks.unhealthy' })} />
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.active.interval' })}
+ required
+ >
+ <Form.Item
+ name={['checks', 'active', 'unhealthy', 'interval']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.active.interval' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} />
+ </Form.Item>
+ </Form.Item>
+ <Form.Item
+ label={formatMessage({ id:
'upstream.step.healthy.checks.http_failures' })}
+ required
+ >
+ <Form.Item
+ name={['checks', 'active', 'unhealthy', 'http_failures']}
+ noStyle
+ rules={[
+ {
+ required: true,
+ message: formatMessage({ id:
'upstream.step.input.healthy.checks.http_failures' }),
+ },
+ ]}
+ >
+ <InputNumber disabled={disabled} min={1} max={254} />
+ </Form.Item>
+ </Form.Item>
+ <Form.List name={['checks', 'active', 'req_headers']}>
+ {(fields, { add, remove }) => (
+ <>
+ {fields.map((field, index) => (
+ <Form.Item
+ key={field.key}
+ {...(index === 0 ? FORM_ITEM_LAYOUT : FORM_ITEM_WITHOUT_LABEL)}
+ label={
+ index === 0
+ ? formatMessage({ id:
'upstream.step.healthy.checks.active.req_headers' })
+ : ''
+ }
+ >
+ <Row style={{ marginBottom: '10px' }} gutter={16}>
+ <Col span={10}>
+ <Form.Item style={{ marginBottom: 0 }} name={[field.name]}>
+ <Input
+ placeholder={formatMessage({
+ id:
'upstream.step.input.healthy.checks.active.req_headers',
+ })}
+ disabled={disabled}
+ />
+ </Form.Item>
+ </Col>
+ <Col
+ style={{
+ marginLeft: -10,
+ display: 'flex',
+ alignItems: 'center',
+ }}
+ >
+ {!disabled &&
+ (fields.length > 1 ? (
+ <MinusCircleOutlined
+ style={{ margin: '0 8px' }}
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ ) : null)}
+ </Col>
+ </Row>
+ </Form.Item>
+ ))}
+ {!disabled && (
+ <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+ <Button
+ type="dashed"
+ onClick={() => {
+ add();
+ }}
+ >
+ <PlusOutlined />
+ {formatMessage({ id: 'upstream.step.create' })}
+ </Button>
+ </Form.Item>
+ )}
+ </>
+ )}
+ </Form.List>
+ </>
+ );
return (
<Form {...FORM_ITEM_LAYOUT} form={form} initialValues={initialValues}>
<Form.Item
@@ -272,6 +689,24 @@ const Step1: React.FC<Props> = ({ form, disabled }) => {
</Form.Item>
{renderTimeUnit()}
</Form.Item>
+ <PanelSection title={formatMessage({ id: 'upstream.step.healthy.check'
})}>
+ <Form.Item
+ label={formatMessage({ id: 'upstream.step.healthy.checks.active' })}
+ name="active"
+ valuePropName="checked"
+ >
+ <Switch disabled={disabled} onChange={handleActiveChange} />
+ </Form.Item>
+ {isActive && renderActiveHealthyCheck()}
+ <Form.Item
+ label={formatMessage({ id: 'upstream.step.healthy.checks.passive' })}
+ name="passive"
+ valuePropName="checked"
+ >
+ <Switch disabled={disabled} onChange={handlePassiveChange} />
+ </Form.Item>
+ {isPassive && renderPassiveHealthyCheck()}
+ </PanelSection>
</Form>
);
};
diff --git a/src/pages/Upstream/locales/en-US.ts
b/src/pages/Upstream/locales/en-US.ts
index a56bf10..fe91f40 100644
--- a/src/pages/Upstream/locales/en-US.ts
+++ b/src/pages/Upstream/locales/en-US.ts
@@ -38,6 +38,30 @@ export default {
'upstream.step.input.send.timeout': 'Please input send timeout',
'upstream.step.receive.timeout': 'Receive Timeout',
'upstream.step.input.receive.timeout': 'Please input receive timeout',
+ 'upstream.step.healthy.check': 'Upstream Healthy Check',
+ 'upstream.step.healthy.checks.healthy': 'Healthy',
+ 'upstream.step.healthy.checks.unhealthy': 'Unhealthy',
+ 'upstream.step.healthy.checks.active': 'Upstream Healthy Check Active',
+ 'upstream.step.healthy.checks.active.timeout': 'Timeout',
+ 'upstream.step.input.healthy.checks.active.timeout': 'Please input timeout',
+ 'upstream.step.healthy.checks.active.http_path': 'HttpPath',
+ 'upstream.step.input.healthy.checks.active.http_path': 'HttpPath',
+ 'upstream.step.healthy.checks.active.host': 'Host',
+ 'upstream.step.input.healthy.checks.active.host': 'Please input Host',
+ 'upstream.step.healthy.checks.active.interval': 'Interval',
+ 'upstream.step.input.healthy.checks.active.interval': 'Please input
Interval',
+ 'upstream.step.healthy.checks.successes': 'Successes',
+ 'upstream.step.input.healthy.checks.successes': 'Please input successes',
+ 'upstream.step.healthy.checks.http_failures': 'HttpFailures',
+ 'upstream.step.input.healthy.checks.http_failures': 'Please input
httpFailures',
+ 'upstream.step.healthy.checks.active.req_headers': 'req_headers',
+ 'upstream.step.input.healthy.checks.active.req_headers': 'Please input
req_headers',
+ 'upstream.step.healthy.checks.passive': 'Passive',
+ 'upstream.step.healthy.checks.passive.http_statuses': 'http_statuses',
+ 'upstream.step.input.healthy.checks.passive.http_statuses': 'Please input
http_statuses',
+ 'upstream.step.healthy.checks.passive.tcp_failures': 'tcp_failures',
+ 'upstream.step.input.healthy.checks.passive.tcp_failures': 'Please input
tcp_failures',
+ 'upstream.notificationMessage.enableHealthCheckFirst': 'Please enable health
check first.',
'upstream.create.edit': 'Edit',
'upstream.create.create': 'Create',
diff --git a/src/pages/Upstream/locales/zh-CN.ts
b/src/pages/Upstream/locales/zh-CN.ts
index 5bb175e..1e24469 100644
--- a/src/pages/Upstream/locales/zh-CN.ts
+++ b/src/pages/Upstream/locales/zh-CN.ts
@@ -38,6 +38,30 @@ export default {
'upstream.step.input.send.timeout': '请输入发送超时时间',
'upstream.step.receive.timeout': '接收超时',
'upstream.step.input.receive.timeout': '请输入接收超时时间',
+ 'upstream.step.healthy.check': '上游健康检查',
+ 'upstream.step.healthy.checks.healthy': '健康',
+ 'upstream.step.healthy.checks.unhealthy': '不健康',
+ 'upstream.step.healthy.checks.active': '探活健康检查',
+ 'upstream.step.healthy.checks.active.timeout': '超时时间',
+ 'upstream.step.input.healthy.checks.active.timeout': '请输入超时时间',
+ 'upstream.step.healthy.checks.active.http_path': '路径',
+ 'upstream.step.input.healthy.checks.active.http_path': '请输入路径',
+ 'upstream.step.healthy.checks.active.host': '域名',
+ 'upstream.step.input.healthy.checks.active.host': '请输入域名',
+ 'upstream.step.healthy.checks.active.interval': '间隔',
+ 'upstream.step.input.healthy.checks.active.interval': '请输入间隔',
+ 'upstream.step.healthy.checks.successes': '成功次数',
+ 'upstream.step.input.healthy.checks.successes': '请输入成功次数',
+ 'upstream.step.healthy.checks.http_failures': '失败次数',
+ 'upstream.step.input.healthy.checks.http_failures': '请输入失败次数',
+ 'upstream.step.healthy.checks.active.req_headers': '请求头',
+ 'upstream.step.input.healthy.checks.active.req_headers': '请输入请求头',
+ 'upstream.step.healthy.checks.passive': '被动健康检查',
+ 'upstream.step.healthy.checks.passive.http_statuses': '状态码',
+ 'upstream.step.input.healthy.checks.passive.http_statuses': '请输入状态码',
+ 'upstream.step.healthy.checks.passive.tcp_failures': 'tcp失败次数',
+ 'upstream.step.input.healthy.checks.passive.tcp_failures': '请输入tcp失败次数',
+ 'upstream.notificationMessage.enableHealthCheckFirst': '请先启用探活健康检查。',
'upstream.create.edit': '编辑',
'upstream.create.create': '创建',
diff --git a/src/pages/Upstream/transform.ts b/src/pages/Upstream/transform.ts
index 5a67c2c..5d7d077 100644
--- a/src/pages/Upstream/transform.ts
+++ b/src/pages/Upstream/transform.ts
@@ -35,17 +35,26 @@ export const transformCreate = (props:
UpstreamModule.Body): UpstreamModule.Enti
props.upstreamHostList.forEach((node) => {
nodes[`${node.host}:${node.port}`] = node.weight;
});
-
return {
- ...omit(props, 'upstreamHostList'),
+ ...omit(props, 'upstreamHostList', 'active', 'passive'),
nodes,
};
};
export const transformFetch = (props: UpstreamModule.Entity) => {
const upstreamHostList = transformUpstreamNodes(props.nodes);
+ let active = false;
+ let passive = false;
+ if (props.checks) {
+ active = true;
+ if (props.checks.passive) {
+ passive = true;
+ }
+ }
return {
...omit(props, 'nodes'),
upstreamHostList,
+ active,
+ passive,
};
};
diff --git a/src/pages/Upstream/typing.d.ts b/src/pages/Upstream/typing.d.ts
index 8206345..25603d3 100644
--- a/src/pages/Upstream/typing.d.ts
+++ b/src/pages/Upstream/typing.d.ts
@@ -30,6 +30,33 @@ declare namespace UpstreamModule {
};
type: 'roundrobin' | 'chash';
description: string;
+ checks: {
+ active: {
+ timeout?: number;
+ http_path: string;
+ host: string;
+ healthy: {
+ interval: number;
+ successes: number;
+ };
+ unhealthy: {
+ interval: number;
+ http_failures: number;
+ };
+ req_headers?: string[];
+ };
+ passive: {
+ healthy: {
+ http_statuses: number[];
+ successes: number;
+ };
+ unhealthy: {
+ http_statuses: number[];
+ http_failures: number;
+ tcp_failures: number;
+ };
+ };
+ };
};
type Entity = Base & {