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 & {

Reply via email to