You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by we...@apache.org on 2021/04/15 04:29:45 UTC

[apisix-dashboard] branch master updated: feat: added default values & missing fields to Upstream (#1764)

This is an automated email from the ASF dual-hosted git repository.

wenming 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 4b86ef2  feat: added default values & missing fields to Upstream (#1764)
4b86ef2 is described below

commit 4b86ef2ae8841fda6386cd24a071030dc5a43db9
Author: 琚致远 <ju...@apache.org>
AuthorDate: Thu Apr 15 12:29:39 2021 +0800

    feat: added default values & missing fields to Upstream (#1764)
---
 web/cypress/fixtures/data.json                     |   2 +
 web/cypress/fixtures/selector.json                 |  18 +--
 .../create-plugin-template-with-route.spec.js      |   2 +
 ...an-skip-upstream-when-select-service-id.spec.js |   2 +
 .../create-edit-duplicate-delete-route.spec.js     |   2 +
 .../create-route-with-api-breaker-form.spec.js     |   2 +
 .../route/create-route-with-cors-form.spec.js      |   2 +
 .../route/create-route-with-limit-req-form.spec.js |   2 +
 .../create-route-with-proxy-mirror-form.spec.js    |   4 +-
 .../create-route-with-proxy-rewrite-plugin.spec.js |   2 +
 ...ate-route-with-referer-restriction-form.spec.js |   2 +
 .../route/create-route-with-upstream.spec.js       |   6 +
 .../integration/route/import_export_route.spec.js  |   2 +
 web/cypress/integration/route/search-route.spec.js |   2 +
 .../service/create-edit-delete-service.spec.js     |   2 +
 .../service/edit-service-with-upstream.spec.js     |   4 +
 .../upstream/create_and_delete_upstream.spec.js    |   6 +-
 web/src/components/Upstream/UpstreamForm.tsx       | 129 +++++++++++++--------
 .../components/{Retries.tsx => DiscoveryType.tsx}  |  17 +--
 web/src/components/Upstream/components/Nodes.tsx   |   2 +-
 .../components/Upstream/components/PassHost.tsx    |   1 +
 web/src/components/Upstream/components/Retries.tsx |   3 +-
 web/src/components/Upstream/components/Scheme.tsx  |   5 +-
 .../components/{Retries.tsx => ServiceName.tsx}    |  17 +--
 web/src/components/Upstream/components/TLS.tsx     |  93 +++++++++++++++
 web/src/components/Upstream/components/Timeout.tsx |   5 +-
 web/src/components/Upstream/components/Type.tsx    |  80 +++++--------
 .../active-check/{Timeout.tsx => Concurrency.tsx}  |  10 +-
 .../{Unhealthy => Healthy}/HttpStatuses.tsx        |   5 +-
 .../components/active-check/Healthy/Interval.tsx   |   5 +-
 .../components/active-check/Healthy/Successes.tsx  |   7 +-
 .../components/active-check/Healthy/index.ts       |   4 +-
 .../Upstream/components/active-check/Host.tsx      |  14 +--
 .../Upstream/components/active-check/HttpPath.tsx  |   9 +-
 .../HttpsVerifyCertificate.tsx}                    |  17 +--
 .../Upstream/components/active-check/Port.tsx      |   6 +-
 .../components/active-check/ReqHeaders.tsx         |   5 +-
 .../Upstream/components/active-check/Timeout.tsx   |   2 +-
 .../Upstream/components/active-check/Type.tsx      |  38 +++---
 .../active-check/Unhealthy/HttpFailures.tsx        |   7 +-
 .../active-check/Unhealthy/HttpStatuses.tsx        |   2 +-
 .../components/active-check/Unhealthy/Interval.tsx |   5 +-
 .../Unhealthy/TCPFailures.tsx}                     |  17 ++-
 .../components/active-check/Unhealthy/Timeouts.tsx |  26 +++--
 .../components/active-check/Unhealthy/index.ts     |   4 +-
 .../Upstream/components/active-check/index.ts      |   6 +-
 .../passive-check/Healthy/HttpStatuses.tsx         |   4 +-
 .../components/passive-check/Healthy/Successes.tsx |   7 +-
 .../Upstream/components/passive-check/Type.tsx     |  66 ++++++-----
 .../passive-check/Unhealthy/HttpFailures.tsx       |   5 +-
 .../passive-check/Unhealthy/HttpStatuses.tsx       |   2 +-
 .../passive-check/Unhealthy/TcpFailures.tsx        |   1 +
 .../passive-check/Unhealthy/Timeouts.tsx           |  26 +++--
 web/src/components/Upstream/constant.ts            | 109 +++++++----------
 web/src/components/Upstream/locales/en-US.ts       |  91 +++++++++++++++
 web/src/components/Upstream/locales/zh-CN.ts       |  96 +++++++++++++++
 .../Unhealthy/Timeouts.tsx => service.ts}          |  44 ++++---
 web/src/components/Upstream/typings.d.ts           |  67 +++++++++++
 web/src/locales/en-US.ts                           |   4 +-
 web/src/locales/en-US/component.ts                 |   1 +
 web/src/locales/zh-CN.ts                           |   4 +-
 web/src/locales/zh-CN/component.ts                 |   1 +
 web/src/pages/Route/Create.tsx                     |   9 +-
 web/src/pages/Service/Create.tsx                   |   8 +-
 web/src/pages/Upstream/Create.tsx                  |   5 +-
 web/src/pages/Upstream/components/Step1.tsx        |   4 +-
 web/src/pages/Upstream/locales/en-US.ts            |  22 +---
 web/src/pages/Upstream/locales/zh-CN.ts            |  32 +----
 web/src/pages/Upstream/transform.ts                |   4 +
 web/src/pages/Upstream/typing.d.ts                 |   3 +
 70 files changed, 795 insertions(+), 423 deletions(-)

diff --git a/web/cypress/fixtures/data.json b/web/cypress/fixtures/data.json
index 1ea7bcd..9c14e98 100644
--- a/web/cypress/fixtures/data.json
+++ b/web/cypress/fixtures/data.json
@@ -20,6 +20,8 @@
   "host1": "11.11.11.11",
   "host2": "12.12.12.12",
   "host3": "10.10.10.10",
+  "port": "80",
+  "weight": 1,
   "description": "desc_by_autotest",
   "description2": "description2",
   "grafanaAddress": "Grafana Address",
diff --git a/web/cypress/fixtures/selector.json b/web/cypress/fixtures/selector.json
index b903e0f..f075bc0 100644
--- a/web/cypress/fixtures/selector.json
+++ b/web/cypress/fixtures/selector.json
@@ -1,7 +1,6 @@
 {
   "codeMirror": ".CodeMirror",
   "username": "#username",
-
   "languageSwitcher": ".ant-space-align-center",
   "dropdown": ".rc-virtual-list",
   "notification": ".ant-notification-notice-message",
@@ -9,12 +8,10 @@
   "notificationCloseIcon": ".ant-notification-close-icon",
   "notificationDesc": ".ant-notification-notice-description",
   "errorNotification:": ".ant-notification-notice-error",
-
   "pluginCard": ".ant-card",
   "pluginCardBordered": ".ant-card-bordered",
   "pageContent": ".ant-pro-page-container",
-
-  "tableBody":".ant-table-tbody",
+  "tableBody": ".ant-table-tbody",
   "tableCell": ".ant-table-cell",
   "empty": ".ant-empty-normal",
   "refresh": ".anticon-reload",
@@ -22,16 +19,15 @@
   "disabledSwitcher": "#disable",
   "checkedSwitcher": ".ant-switch-checked",
   "deleteButton": ".ant-btn-dangerous",
-
   "name": "#name",
   "nodes_0_host": "#nodes_0_host",
   "nodes_0_port": "#nodes_0_port",
+  "nodes_0_weight": "#nodes_0_weight",
   "upstream_id": "#upstream_id",
   "input": ":input",
   "nameSelector": "[title=Name]",
   "serviceSelector": "[title=test_service]",
   "nameSearch": "[title=Name]",
-
   "description": "#desc",
   "upstreamSelector": "[data-cy=upstream_selector]",
   "addHost": "[data-cy=addHost]",
@@ -43,27 +39,21 @@
   "ruleCard": ".ant-modal",
   "operator": "#operator",
   "value": "#value",
-
   "fileSelector": "[type=file]",
   "fileTypeRadio": "[type=radio]",
   "fileSelectorClose": ".ant-modal-close",
-
   "debugUri": "#debugUri",
-
   "hosts_0": "#hosts_0",
   "labels_0_labelKey": "#labels_0_labelKey",
   "labels_0_labelValue": "#labels_0_labelValue",
   "labelSelector": "[title=Labels]",
   "labelSelect_0": ".ant-select-selection-overflow",
-
   "pageContainer": ".ant-pro-page-container",
   "notificationMessage": ".ant-notification-notice-message",
   "avatar": ".ant-space-align-center",
   "grafanaURL": "#grafanaURL",
   "explain": ".ant-form-item-explain",
-
   "upstreamType": ".ant-select-item-option-content",
-
   "errorExplain": ".ant-form-item-explain",
   "usernameInput": "#control-ref_username",
   "passwordInput": "#control-ref_password",
@@ -76,7 +66,6 @@
   "notificationClose": ".anticon-close",
   "redirectURIInput": "#redirectURI",
   "redirectCodeSelector": "#ret_code",
-
   "paginationOptions": ".ant-pagination-options",
   "fiftyPerPage": "[title=\"50 / page\"]",
   "twentyPerPage": "[title=\"20 / page\"]",
@@ -85,7 +74,6 @@
   "pageTwoActived": ".ant-pagination-item-2.ant-pagination-item-active",
   "selectDropdown": ".ant-select-dropdown",
   "codeMirrorMode": "[data-cy='code-mirror-mode']",
-  "selectJSON":".ant-select-dropdown [label=JSON]",
-
+  "selectJSON": ".ant-select-dropdown [label=JSON]",
   "deleteAlert": ".ant-modal-body"
 }
diff --git a/web/cypress/integration/pluginTemplate/create-plugin-template-with-route.spec.js b/web/cypress/integration/pluginTemplate/create-plugin-template-with-route.spec.js
index 8be0f49..4a3b703 100644
--- a/web/cypress/integration/pluginTemplate/create-plugin-template-with-route.spec.js
+++ b/web/cypress/integration/pluginTemplate/create-plugin-template-with-route.spec.js
@@ -46,6 +46,8 @@ context('Create PluginTemplate Binding To Route', () => {
     cy.get(this.domSelector.name).type(this.data.routeName);
     cy.contains('Next').click();
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
     cy.contains('Custom').should('be.visible');
     cy.get(this.domSelector.customSelector).click();
diff --git a/web/cypress/integration/route/can-skip-upstream-when-select-service-id.spec.js b/web/cypress/integration/route/can-skip-upstream-when-select-service-id.spec.js
index 0ca5d28..d62cd87 100644
--- a/web/cypress/integration/route/can-skip-upstream-when-select-service-id.spec.js
+++ b/web/cypress/integration/route/can-skip-upstream-when-select-service-id.spec.js
@@ -31,6 +31,8 @@ context('Can select service_id skip upstream in route', () => {
 
     cy.get(this.domSelector.name).type(this.data.upstreamName);
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
+    cy.get(this.domSelector.nodes_0_port).clear().type('7000');
+    cy.get(this.domSelector.nodes_0_weight).clear().type(1);
     cy.contains('Next').click();
     cy.contains('Submit').click();
     cy.get(this.domSelector.notification).should('contain', this.data.createUpstreamSuccess);
diff --git a/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
index 6e16a7e..5919048 100644
--- a/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
+++ b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
@@ -65,6 +65,8 @@ context('Create and Delete Route', () => {
 
     cy.contains('Next').click();
     cy.get(this.domSelector.nodes_0_host).type(this.data.host2);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
 
     // redirect plugin should not display in route step3
diff --git a/web/cypress/integration/route/create-route-with-api-breaker-form.spec.js b/web/cypress/integration/route/create-route-with-api-breaker-form.spec.js
index 8437d9d..93e3e2a 100644
--- a/web/cypress/integration/route/create-route-with-api-breaker-form.spec.js
+++ b/web/cypress/integration/route/create-route-with-api-breaker-form.spec.js
@@ -40,6 +40,8 @@ context('Create and delete route with api-breaker form', () => {
     cy.contains('Next').click();
 
     cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
 
     // config api-breaker plugin
diff --git a/web/cypress/integration/route/create-route-with-cors-form.spec.js b/web/cypress/integration/route/create-route-with-cors-form.spec.js
index 915effb..beabccc 100644
--- a/web/cypress/integration/route/create-route-with-cors-form.spec.js
+++ b/web/cypress/integration/route/create-route-with-cors-form.spec.js
@@ -40,6 +40,8 @@ context('Create and delete route with cors form', () => {
     cy.contains('Next').click();
 
     cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
 
     // config cors plugin
diff --git a/web/cypress/integration/route/create-route-with-limit-req-form.spec.js b/web/cypress/integration/route/create-route-with-limit-req-form.spec.js
index 8609d04..e215163 100644
--- a/web/cypress/integration/route/create-route-with-limit-req-form.spec.js
+++ b/web/cypress/integration/route/create-route-with-limit-req-form.spec.js
@@ -42,6 +42,8 @@ context('Create and delete route with limit-req form', () => {
     cy.contains('Next').click();
 
     cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
 
     // config limit-req plugin
diff --git a/web/cypress/integration/route/create-route-with-proxy-mirror-form.spec.js b/web/cypress/integration/route/create-route-with-proxy-mirror-form.spec.js
index 7637568..87ac24d 100644
--- a/web/cypress/integration/route/create-route-with-proxy-mirror-form.spec.js
+++ b/web/cypress/integration/route/create-route-with-proxy-mirror-form.spec.js
@@ -40,6 +40,8 @@ context('Create and delete route with proxy-mirror form', () => {
     cy.contains('Next').click();
 
     cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
 
     // config proxy-mirror plugin
@@ -100,6 +102,6 @@ context('Create and delete route with proxy-mirror form', () => {
       cy.contains('OK').click();
     });
     cy.get(domSelector.notification).should('contain', data.deleteRouteSuccess);
-    cy.get(domSelector.notificationCloseIcon).click();
+    cy.get(domSelector.notificationCloseIcon).click({ multiple: true });
   });
 });
diff --git a/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js b/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js
index 1d8173d..5ce18fd 100644
--- a/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js
+++ b/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js
@@ -90,6 +90,8 @@ context('create route with proxy-rewrite plugin', () => {
 
     cy.contains('Next').click();
     cy.get(this.domSelector.nodes_0_host).type(this.data.host2);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
 
     // should not see proxy-rewrite plugin in the step3
diff --git a/web/cypress/integration/route/create-route-with-referer-restriction-form.spec.js b/web/cypress/integration/route/create-route-with-referer-restriction-form.spec.js
index 39e13a3..4987d16 100644
--- a/web/cypress/integration/route/create-route-with-referer-restriction-form.spec.js
+++ b/web/cypress/integration/route/create-route-with-referer-restriction-form.spec.js
@@ -40,6 +40,8 @@ context('Create and delete route with referer-restriction form', () => {
     cy.contains('Next').click();
 
     cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+    cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
     cy.contains('Next').click();
 
     // config referer-restriction plugin
diff --git a/web/cypress/integration/route/create-route-with-upstream.spec.js b/web/cypress/integration/route/create-route-with-upstream.spec.js
index a6cf351..2a976b8 100644
--- a/web/cypress/integration/route/create-route-with-upstream.spec.js
+++ b/web/cypress/integration/route/create-route-with-upstream.spec.js
@@ -32,6 +32,8 @@ context('Create Route with Upstream', () => {
     cy.get(this.domSelector.name).type(this.data.upstreamName);
     cy.get(this.domSelector.description).type(this.data.description);
     cy.get(this.domSelector.nodes_0_host).type(this.data.host1);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
     cy.contains('Submit').click();
   });
@@ -56,6 +58,8 @@ context('Create Route with Upstream', () => {
     cy.get(this.domSelector.input).should('not.be.disabled');
 
     cy.get(this.domSelector.nodes_0_host).clear().type(this.data.ip1);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
     cy.contains('Next').click();
     cy.contains('Submit').click();
@@ -87,6 +91,8 @@ context('Create Route with Upstream', () => {
     cy.get(this.domSelector.input).should('not.be.disabled');
 
     cy.get(this.domSelector.nodes_0_host).clear().type(this.data.ip2);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
     cy.contains('Next').click();
     cy.contains('Submit').click();
diff --git a/web/cypress/integration/route/import_export_route.spec.js b/web/cypress/integration/route/import_export_route.spec.js
index c327c58..ea877f3 100644
--- a/web/cypress/integration/route/import_export_route.spec.js
+++ b/web/cypress/integration/route/import_export_route.spec.js
@@ -66,6 +66,8 @@ context('import and export routes', () => {
       cy.contains(actionBarUS['component.actionbar.button.nextStep']).click();
       // input nodes_0_host, click Next
       cy.get(this.domSelector.nodes_0_host).type(data[`upstream_node0_host_${i}`]);
+      cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+      cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
       cy.contains(actionBarUS['component.actionbar.button.nextStep']).click();
       // do not config plugins, click Next
       cy.contains(actionBarUS['component.actionbar.button.nextStep']).click();
diff --git a/web/cypress/integration/route/search-route.spec.js b/web/cypress/integration/route/search-route.spec.js
index 381b9fe..37bae68 100644
--- a/web/cypress/integration/route/search-route.spec.js
+++ b/web/cypress/integration/route/search-route.spec.js
@@ -63,6 +63,8 @@ context('Create and Search Route', () => {
       cy.get(this.domSelector.nodes_0_host).type(this.data.host2, {
         timeout,
       });
+      cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+      cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
       cy.contains('Next').click();
       cy.contains('Next').click();
       cy.contains('Submit').click();
diff --git a/web/cypress/integration/service/create-edit-delete-service.spec.js b/web/cypress/integration/service/create-edit-delete-service.spec.js
index 8c7fa0a..5551629 100644
--- a/web/cypress/integration/service/create-edit-delete-service.spec.js
+++ b/web/cypress/integration/service/create-edit-delete-service.spec.js
@@ -35,6 +35,8 @@ context('Create and Delete Service ', () => {
     cy.get(this.domSelector.description).type(this.data.description);
     cy.get(this.domSelector.nodes_0_host).click();
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
+    cy.get(this.domSelector.nodes_0_port).clear().type('7000');
+    cy.get(this.domSelector.nodes_0_weight).clear().type(1);
 
     cy.contains('Next').click();
 
diff --git a/web/cypress/integration/service/edit-service-with-upstream.spec.js b/web/cypress/integration/service/edit-service-with-upstream.spec.js
index 1d89ee3..87be509 100644
--- a/web/cypress/integration/service/edit-service-with-upstream.spec.js
+++ b/web/cypress/integration/service/edit-service-with-upstream.spec.js
@@ -30,6 +30,8 @@ context('Edit Service with Upstream', () => {
     cy.contains('Create').click();
     cy.get(this.domSelector.name).type(this.data.upstreamName);
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
+    cy.get(this.domSelector.nodes_0_port).clear().type('7000');
+    cy.get(this.domSelector.nodes_0_weight).clear().type(1);
     cy.contains('Next').click();
     cy.contains('Submit').click();
     cy.get(this.domSelector.notification).should('contain', this.data.createUpstreamSuccess);
@@ -66,6 +68,8 @@ context('Edit Service with Upstream', () => {
     cy.get(this.domSelector.upstreamSelector).click();
     cy.contains('Custom').click();
     cy.get(this.domSelector.nodes_0_host).should('not.be.disabled').clear().type(this.data.ip2);
+    cy.get(this.domSelector.nodes_0_port).type(this.data.port);
+    cy.get(this.domSelector.nodes_0_weight).type(this.data.weight);
     cy.contains('Next').click();
     cy.contains('Next').click();
     cy.contains('Submit').click();
diff --git a/web/cypress/integration/upstream/create_and_delete_upstream.spec.js b/web/cypress/integration/upstream/create_and_delete_upstream.spec.js
index a8063eb..4f2c0fa 100644
--- a/web/cypress/integration/upstream/create_and_delete_upstream.spec.js
+++ b/web/cypress/integration/upstream/create_and_delete_upstream.spec.js
@@ -34,6 +34,7 @@ context('Create and Delete Upstream', () => {
 
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
     cy.get(this.domSelector.nodes_0_port).clear().type('7000');
+    cy.get(this.domSelector.nodes_0_weight).clear().type(1);
     cy.contains('Next').click();
     cy.contains('Submit').click();
     cy.get(this.domSelector.notification).should('contain', this.data.createUpstreamSuccess);
@@ -78,11 +79,11 @@ context('Create and Delete Upstream', () => {
     cy.get(this.domSelector.upstreamType).within(() => {
       cy.contains('CHash').click();
     });
-    cy.get('#hash_on').click();
+    cy.get('#hash_on').click({ force: true });
     cy.get(this.domSelector.upstreamType).within(() => {
       cy.contains('vars').click();
     });
-    cy.get('#key').click();
+    cy.get('#key').click({ force: true });
     cy.get(this.domSelector.upstreamType).within(() => {
       cy.contains('remote_addr').click();
     });
@@ -90,6 +91,7 @@ context('Create and Delete Upstream', () => {
     // add first upstream node
     cy.get(this.domSelector.nodes_0_host).type(this.data.ip1);
     cy.get(this.domSelector.nodes_0_port).clear().type('7000');
+    cy.get(this.domSelector.nodes_0_weight).clear().type(1);
 
     // add second upstream node
     cy.get('.ant-btn-dashed').click();
diff --git a/web/src/components/Upstream/UpstreamForm.tsx b/web/src/components/Upstream/UpstreamForm.tsx
index 7fade14..42d7144 100644
--- a/web/src/components/Upstream/UpstreamForm.tsx
+++ b/web/src/components/Upstream/UpstreamForm.tsx
@@ -21,7 +21,6 @@ import type { FormInstance } from 'antd/es/form';
 
 import { PanelSection } from '@api7-dashboard/ui';
 import { transformRequest } from '@/pages/Upstream/transform';
-import { DEFAULT_UPSTREAM } from './constant';
 import PassiveCheck from './components/passive-check';
 import ActiveCheck from './components/active-check'
 import Nodes from './components/Nodes'
@@ -31,6 +30,8 @@ import Type from './components/Type';
 import UpstreamSelector from './components/UpstreamSelector';
 import Retries from './components/Retries';
 import PassHost from './components/PassHost';
+import TLSComponent from './components/TLS';
+import { transformUpstreamDataFromRequest } from './service';
 
 type Upstream = {
   name?: string;
@@ -86,14 +87,18 @@ const UpstreamForm: React.FC<Props> = forwardRef(
         if (required) {
           requestAnimationFrame(() => {
             form.resetFields();
-            form.setFieldsValue(DEFAULT_UPSTREAM);
             setHiddenForm(false);
           });
         }
       } else {
         if (upstream_id) {
           requestAnimationFrame(() => {
-            form.setFieldsValue(list.find((item) => item.id === upstream_id));
+            const targetData = list.find((item) => item.id === upstream_id) as UpstreamComponent.ResponseData
+            if (targetData) {
+              form.setFieldsValue(transformUpstreamDataFromRequest(targetData));
+            } else {
+              // TODO: 提示 upstream_id 找不到想要的数据
+            }
           });
         }
         if (!required && !Object.keys(formData).length) {
@@ -106,15 +111,24 @@ const UpstreamForm: React.FC<Props> = forwardRef(
       setReadonly(Boolean(upstream_id) || disabled);
     }, [list]);
 
-
-
     const ActiveHealthCheck = () => (
       <React.Fragment>
         <ActiveCheck.Type readonly={readonly} />
+        <Form.Item noStyle shouldUpdate={(prev, next) => prev.checks.active.type !== next.checks.active.type}>
+          {() => {
+            const type = form.getFieldValue(['checks', 'active', 'type'])
+            if (['https'].includes(type)) {
+              return <ActiveCheck.HttpsVerifyCertificate readonly={readonly} />
+            }
+            return null
+          }}
+        </Form.Item>
         <ActiveCheck.Timeout readonly={readonly} />
+        <ActiveCheck.Concurrency readonly={readonly} />
         <ActiveCheck.Host readonly={readonly} />
         <ActiveCheck.Port readonly={readonly} />
         <ActiveCheck.HttpPath readonly={readonly} />
+        <ActiveCheck.ReqHeaders readonly={readonly} />
 
         <Divider orientation="left" plain>
           {formatMessage({ id: 'page.upstream.step.healthyCheck.healthy.status' })}
@@ -122,6 +136,7 @@ const UpstreamForm: React.FC<Props> = forwardRef(
 
         <ActiveCheck.Healthy.Interval readonly={readonly} />
         <ActiveCheck.Healthy.Successes readonly={readonly} />
+        <ActiveCheck.Healthy.HttpStatuses readonly={readonly} />
 
         <Divider orientation="left" plain>
           {formatMessage({ id: 'page.upstream.step.healthyCheck.unhealthyStatus' })}
@@ -131,14 +146,11 @@ const UpstreamForm: React.FC<Props> = forwardRef(
         <ActiveCheck.Unhealthy.Interval readonly={readonly} />
         <ActiveCheck.Unhealthy.HttpStatuses readonly={readonly} />
         <ActiveCheck.Unhealthy.HttpFailures readonly={readonly} />
-
-        <Divider orientation="left" plain>Others</Divider>
-
-        <ActiveCheck.ReqHeaders readonly={readonly} />
+        <ActiveCheck.Unhealthy.TCPFailures readonly={readonly} />
       </React.Fragment>
     );
 
-    const InActiveHealthCheck = () => (
+    const PassiveHealthCheck = () => (
       <React.Fragment>
         <PassiveCheck.Type readonly={readonly} />
 
@@ -161,55 +173,54 @@ const UpstreamForm: React.FC<Props> = forwardRef(
     );
 
     const HealthCheckComponent = () => {
-      const options = [
-        {
-          label: formatMessage({ id: 'page.upstream.step.healthyCheck.active' }),
-          name: ['checks', 'active'],
-          component: (
-            <>
-              <ActiveHealthCheck />
-              <Divider orientation="left" plain />
-            </>
-          ),
-        },
-        {
-          label: formatMessage({ id: 'page.upstream.step.healthyCheck.passive' }),
-          name: ['checks', 'passive'],
-          component: <InActiveHealthCheck />,
-        },
-      ]
-
       return (
         <PanelSection
           title={formatMessage({ id: 'page.upstream.step.healthyCheck.healthy.check' })}
         >
-          {options.map(({ label, name, component }) => (
-            <div key={label}>
-              <Form.Item label={label} name={name} valuePropName="checked" key={label}>
-                <Switch disabled={readonly} />
-              </Form.Item>
-              <Form.Item shouldUpdate noStyle>
-                {() => {
-                  if (form.getFieldValue(name)) {
-                    return component;
-                  }
-                  return null;
-                }}
-              </Form.Item>
-            </div>
-          ))}
+          <Form.Item label={formatMessage({ id: 'page.upstream.step.healthyCheck.active' })} name={['custom', 'checks', 'active']} valuePropName="checked">
+            <Switch disabled={readonly} />
+          </Form.Item>
+          <Form.Item shouldUpdate noStyle>
+            {
+              () => {
+                const active = form.getFieldValue(['custom', 'checks', 'active'])
+                if (active) {
+                  return (
+                    <ActiveHealthCheck />
+                  )
+                }
+                return null
+              }
+            }
+          </Form.Item>
+          <Divider orientation="left" plain />
+          <Form.Item label={formatMessage({ id: 'page.upstream.step.healthyCheck.passive' })} name={['custom', 'checks', 'passive']} valuePropName="checked">
+            <Switch disabled={readonly} />
+          </Form.Item>
+          <Form.Item shouldUpdate noStyle>
+            {
+              () => {
+                const passive = form.getFieldValue(['custom', 'checks', 'passive'])
+                if (passive) {
+                  /*
+                  * When enable passive check, we should enable active check, too.
+                  * When we use form.setFieldsValue to enable active check, error throws.
+                  * We choose to alert users first, and need users to enable active check manually.
+                  */
+                  return <PassiveHealthCheck />
+                }
+                return null
+              }
+            }
+          </Form.Item>
         </PanelSection>
       )
     }
 
-
     return (
       <Form
         form={form}
         labelCol={{ span: 3 }}
-        initialValues={{
-          pass_host: 'pass',
-        }}
       >
         {showSelector && (
           <UpstreamSelector
@@ -221,7 +232,10 @@ const UpstreamForm: React.FC<Props> = forwardRef(
               if (prev.upstream_id !== next.upstream_id) {
                 const id = next.upstream_id;
                 if (id) {
-                  form.setFieldsValue(list.find((item) => item.id === id));
+                  const targetData = list.find((item) => item.id === id) as UpstreamComponent.ResponseData
+                  if (targetData) {
+                    form.setFieldsValue(transformUpstreamDataFromRequest(targetData));
+                  }
                   form.setFieldsValue({
                     upstream_id: id,
                   });
@@ -232,10 +246,12 @@ const UpstreamForm: React.FC<Props> = forwardRef(
             onChange={(upstream_id) => {
               setReadonly(Boolean(upstream_id));
               setHiddenForm(Boolean(upstream_id === 'None'));
-              form.setFieldsValue(list.find((item) => item.id === upstream_id));
+              const targetData = list.find((item) => item.id === upstream_id) as UpstreamComponent.ResponseData
+              if (targetData) {
+                form.setFieldsValue(transformUpstreamDataFromRequest(targetData));
+              }
               if (upstream_id === '') {
                 form.resetFields();
-                form.setFieldsValue(DEFAULT_UPSTREAM);
               }
             }}
           />
@@ -248,7 +264,20 @@ const UpstreamForm: React.FC<Props> = forwardRef(
 
             <PassHost form={form} readonly={readonly} />
             <Retries readonly={readonly} />
+
             <Scheme readonly={readonly} />
+            <Form.Item noStyle shouldUpdate={(prev, next) => prev.scheme !== next.scheme}>
+              {
+                () => {
+                  const scheme = form.getFieldValue("scheme") as string
+                  if (["https", "grpcs"].includes(scheme)) {
+                    return <TLSComponent form={form} readonly={readonly} />
+                  }
+                  return null
+                }
+              }
+            </Form.Item>
+
             {timeoutFields.map((item, index) => (
               <Timeout key={index} {...item} readonly={readonly} />
             ))}
diff --git a/web/src/components/Upstream/components/Retries.tsx b/web/src/components/Upstream/components/DiscoveryType.tsx
similarity index 66%
copy from web/src/components/Upstream/components/Retries.tsx
copy to web/src/components/Upstream/components/DiscoveryType.tsx
index a77ecef..031de33 100644
--- a/web/src/components/Upstream/components/Retries.tsx
+++ b/web/src/components/Upstream/components/DiscoveryType.tsx
@@ -15,25 +15,20 @@
  * limitations under the License.
  */
 import React from 'react'
-import { Form, InputNumber } from 'antd'
+import { Form, Input } from 'antd'
 import { useIntl } from 'umi'
 
 type Props = {
-  readonly?: boolean
+  readonly?: boolean;
 }
 
-const Component: React.FC<Props> = ({ readonly }) => {
+const DiscoveryType: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
-    <Form.Item
-      label={formatMessage({ id: 'page.upstream.retries' })}
-      name="retries"
-    >
-      <InputNumber
-        disabled={readonly}
-      />
+    <Form.Item name="discovery_type" label={formatMessage({ id: 'component.upstream.fields.discovery_type' })} tooltip={formatMessage({ id: 'component.upstream.fields.discovery_type.tooltip' })}>
+      <Input disabled={readonly} placeholder={formatMessage({ id: 'component.upstream.fields.discovery_type.placeholder' })} />
     </Form.Item>
   )
 }
 
-export default Component
+export default DiscoveryType
diff --git a/web/src/components/Upstream/components/Nodes.tsx b/web/src/components/Upstream/components/Nodes.tsx
index 2a92d48..eaaa3a4 100644
--- a/web/src/components/Upstream/components/Nodes.tsx
+++ b/web/src/components/Upstream/components/Nodes.tsx
@@ -29,7 +29,7 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
-    <Form.List name="nodes">
+    <Form.List name="nodes" initialValue={[{ host: undefined, port: undefined, weight: undefined }]}>
       {(fields, { add, remove }) => (
         <>
           <Form.Item label={formatMessage({ id: 'page.upstream.form.item-label.node.domain.or.ip' })} style={{ marginBottom: 0 }}>
diff --git a/web/src/components/Upstream/components/PassHost.tsx b/web/src/components/Upstream/components/PassHost.tsx
index 6102076..a2f7e45 100644
--- a/web/src/components/Upstream/components/PassHost.tsx
+++ b/web/src/components/Upstream/components/PassHost.tsx
@@ -46,6 +46,7 @@ const Component: React.FC<Props> = ({ form, readonly }) => {
       <Form.Item
         label={formatMessage({ id: 'page.upstream.step.pass-host' })}
         name="pass_host"
+        initialValue="pass"
       >
         <Select disabled={readonly}>
           {options.map(item => (
diff --git a/web/src/components/Upstream/components/Retries.tsx b/web/src/components/Upstream/components/Retries.tsx
index a77ecef..51d346e 100644
--- a/web/src/components/Upstream/components/Retries.tsx
+++ b/web/src/components/Upstream/components/Retries.tsx
@@ -26,7 +26,8 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.retries' })}
+      label={formatMessage({ id: 'component.upstream.fields.retries' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.retries.tooltip' })}
       name="retries"
     >
       <InputNumber
diff --git a/web/src/components/Upstream/components/Scheme.tsx b/web/src/components/Upstream/components/Scheme.tsx
index 840d5e6..c289e28 100644
--- a/web/src/components/Upstream/components/Scheme.tsx
+++ b/web/src/components/Upstream/components/Scheme.tsx
@@ -38,13 +38,14 @@ type Props = {
   readonly?: boolean
 }
 
-const Component: React.FC<Props> = ({ readonly }) => {
+const Scheme: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
       label={formatMessage({ id: 'page.upstream.scheme' })}
       name="scheme"
       rules={[{ required: true }]}
+      initialValue="http"
     >
       <Select disabled={readonly}>
         {options.map(item => {
@@ -59,4 +60,4 @@ const Component: React.FC<Props> = ({ readonly }) => {
   )
 }
 
-export default Component
+export default Scheme
diff --git a/web/src/components/Upstream/components/Retries.tsx b/web/src/components/Upstream/components/ServiceName.tsx
similarity index 67%
copy from web/src/components/Upstream/components/Retries.tsx
copy to web/src/components/Upstream/components/ServiceName.tsx
index a77ecef..b0ef62c 100644
--- a/web/src/components/Upstream/components/Retries.tsx
+++ b/web/src/components/Upstream/components/ServiceName.tsx
@@ -15,25 +15,20 @@
  * limitations under the License.
  */
 import React from 'react'
-import { Form, InputNumber } from 'antd'
+import { Form, Input } from 'antd'
 import { useIntl } from 'umi'
 
 type Props = {
-  readonly?: boolean
+  readonly?: boolean;
 }
 
-const Component: React.FC<Props> = ({ readonly }) => {
+const ServiceName: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
-    <Form.Item
-      label={formatMessage({ id: 'page.upstream.retries' })}
-      name="retries"
-    >
-      <InputNumber
-        disabled={readonly}
-      />
+    <Form.Item name="service_name" label={formatMessage({ id: 'component.upstream.fields.service_name' })} tooltip={formatMessage({ id: 'component.upstream.fields.service_name.tooltip' })}>
+      <Input disabled={readonly} placeholder={formatMessage({ id: 'component.upstream.fields.service_name.placeholder' })} />
     </Form.Item>
   )
 }
 
-export default Component
+export default ServiceName
diff --git a/web/src/components/Upstream/components/TLS.tsx b/web/src/components/Upstream/components/TLS.tsx
new file mode 100644
index 0000000..2d4feee
--- /dev/null
+++ b/web/src/components/Upstream/components/TLS.tsx
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react'
+import { Form, Row, Col, Select, FormInstance, Input } from 'antd'
+import { useIntl } from 'umi'
+
+type Props = {
+  form: FormInstance;
+  readonly?: boolean;
+}
+
+const TLSComponent: React.FC<Props> = ({ form, readonly }) => {
+  const { formatMessage } = useIntl()
+
+  return (
+    <React.Fragment>
+      <Form.Item
+        label={formatMessage({ id: 'component.upstream.fields.tls' })}
+        tooltip={formatMessage({ id: 'component.upstream.fields.tls.tooltip' })}
+        style={{ marginBottom: 0 }}
+      >
+        <Row>
+          <Col span={5}>
+            <Form.Item
+              name={["custom", "tls"]}
+              initialValue="disable"
+            >
+              <Select disabled={readonly}>
+                {
+                  ["disable", "enable"].map(item => (
+                    <Select.Option value={item} key={item}>
+                      {formatMessage({ id: `component.global.${item}` })}
+                    </Select.Option>
+                  ))
+                }
+              </Select>
+            </Form.Item>
+          </Col>
+        </Row>
+      </Form.Item>
+      <Form.Item
+        noStyle
+        shouldUpdate={(prev, next) => {
+          return prev.custom.tls !== next.custom.tls
+        }}
+      >
+        {
+          () => {
+            if (form.getFieldValue(["custom", "tls"]) === 'enable') {
+              return (
+                <React.Fragment>
+                  <Form.Item
+                    label={formatMessage({ id: 'component.upstream.fields.tls.client_cert' })}
+                    name={["tls", "client_cert"]}
+                    required
+                    rules={[{ required: true, message: "" }, { max: 64 * 1024 }, { min: 128 }]}
+                  >
+                    <Input.TextArea disabled={readonly} minLength={128} maxLength={64 * 1024} rows={5} placeholder="请输入客户端证书" />
+                  </Form.Item>
+                  <Form.Item
+                    label={formatMessage({ id: 'component.upstream.fields.tls.client_key' })}
+                    name={["tls", "client_key"]}
+                    required
+                    rules={[{ required: true, message: "" }, { max: 64 * 1024 }, { min: 128 }]}
+                  >
+                    <Input.TextArea disabled={readonly} minLength={128} maxLength={64 * 1024} rows={5} placeholder="请输入客户端私钥" />
+                  </Form.Item>
+                </React.Fragment>
+              )
+            }
+            return null
+          }
+        }
+      </Form.Item>
+    </React.Fragment>
+  )
+}
+
+export default TLSComponent
diff --git a/web/src/components/Upstream/components/Timeout.tsx b/web/src/components/Upstream/components/Timeout.tsx
index 059b63a..8eefdf0 100644
--- a/web/src/components/Upstream/components/Timeout.tsx
+++ b/web/src/components/Upstream/components/Timeout.tsx
@@ -20,7 +20,7 @@ import { useIntl } from 'umi'
 
 import TimeUnit from './TimeUnit'
 
-const Component: React.FC<{
+const Timeout: React.FC<{
   label: string;
   desc: string;
   name: string[];
@@ -38,6 +38,7 @@ const Component: React.FC<{
             message: formatMessage({ id: `page.upstream.step.input.${name[1]}.timeout` }),
           },
         ]}
+        initialValue={6}
       >
         <InputNumber disabled={readonly} />
       </Form.Item>
@@ -46,4 +47,4 @@ const Component: React.FC<{
   )
 }
 
-export default Component
+export default Timeout
diff --git a/web/src/components/Upstream/components/Type.tsx b/web/src/components/Upstream/components/Type.tsx
index 0a7ce25..8788ebb 100644
--- a/web/src/components/Upstream/components/Type.tsx
+++ b/web/src/components/Upstream/components/Type.tsx
@@ -19,63 +19,38 @@ import { Form, Select } from 'antd'
 import { useIntl } from 'umi'
 import type { FormInstance } from 'antd/es/form'
 
-enum Type {
-  roundrobin = 'roundrobin',
-  chash = 'chash',
-  ewma = 'ewma',
-  // TODO: new type
-  // least_conn = 'least_conn'
-}
-
-enum HashOn {
-  vars = 'vars',
-  header = 'header',
-  cookie = 'cookie',
-  consumer = 'consumer',
-  // TODO: new hash_on key
-  // vars_combinations = 'vars_combinations'
-}
-
-enum HashKey {
-  remote_addr = 'remote_addr',
-  host = 'host',
-  uri = 'uri',
-  server_name = 'server_name',
-  server_addr = 'server_addr',
-  request_uri = 'request_uri',
-  query_string = 'query_string',
-  remote_port = 'remote_port',
-  hostname = 'hostname',
-  arg_id = 'arg_id',
-}
+import { HashOnEnum, CommonHashKeyEnum, AlgorithmEnum } from '../constant'
 
 type Props = {
   readonly?: boolean
   form: FormInstance
 }
 
-const CHash: React.FC<Pick<Props, 'readonly'>> = ({ readonly }) => (
-  <>
-    <Form.Item label="Hash On" name="hash_on" rules={[{ required: true }]}>
-      <Select disabled={readonly}>
-        {Object.entries(HashOn).map(([label, value]) => (
-          <Select.Option value={value} key={value}>
-            {label}
-          </Select.Option>
-        ))}
-      </Select>
-    </Form.Item>
-    <Form.Item label="Key" name="key" rules={[{ required: true }]}>
-      <Select disabled={readonly}>
-        {Object.entries(HashKey).map(([label, value]) => (
-          <Select.Option value={value} key={value}>
-            {label}
-          </Select.Option>
-        ))}
-      </Select>
-    </Form.Item>
-  </>
-);
+const CHash: React.FC<Pick<Props, 'readonly'>> = ({ readonly }) => {
+  const { formatMessage } = useIntl()
+  return (
+    <React.Fragment>
+      <Form.Item name="hash_on" rules={[{ required: true }]} label={formatMessage({ id: 'component.upstream.fields.hash_on' })} tooltip={formatMessage({ id: 'component.upstream.fields.hash_on.tooltip' })} initialValue="vars">
+        <Select disabled={readonly}>
+          {Object.entries(HashOnEnum).map(([label, value]) => (
+            <Select.Option value={value} key={value}>
+              {label}
+            </Select.Option>
+          ))}
+        </Select>
+      </Form.Item>
+      <Form.Item name="key" rules={[{ required: true }]} label={formatMessage({ id: 'component.upstream.fields.key' })} tooltip={formatMessage({ id: 'component.upstream.fields.key.tooltip' })} initialValue="remote_addr">
+        <Select disabled={readonly}>
+          {Object.entries(CommonHashKeyEnum).map(([label, value]) => (
+            <Select.Option value={value} key={value}>
+              {label}
+            </Select.Option>
+          ))}
+        </Select>
+      </Form.Item>
+    </React.Fragment>
+  )
+};
 
 const Component: React.FC<Props> = ({ readonly, form }) => {
   const { formatMessage } = useIntl()
@@ -86,9 +61,10 @@ const Component: React.FC<Props> = ({ readonly, form }) => {
         label={formatMessage({ id: 'page.upstream.step.type' })}
         name="type"
         rules={[{ required: true }]}
+        initialValue="roundrobin"
       >
         <Select disabled={readonly}>
-          {Object.entries(Type).map(([label, value]) => {
+          {Object.entries(AlgorithmEnum).map(([label, value]) => {
             return (
               <Select.Option value={value} key={value}>
                 {formatMessage({ id: `page.upstream.type.${label}` })}
diff --git a/web/src/components/Upstream/components/active-check/Timeout.tsx b/web/src/components/Upstream/components/active-check/Concurrency.tsx
similarity index 72%
copy from web/src/components/Upstream/components/active-check/Timeout.tsx
copy to web/src/components/Upstream/components/active-check/Concurrency.tsx
index 4d294b7..8ef19d3 100644
--- a/web/src/components/Upstream/components/active-check/Timeout.tsx
+++ b/web/src/components/Upstream/components/active-check/Concurrency.tsx
@@ -17,23 +17,21 @@
 import React from 'react'
 import { Form, InputNumber } from 'antd'
 import { useIntl } from 'umi'
-import TimeUnit from '../TimeUnit'
 
 type Props = {
   readonly?: boolean
 }
 
-const ActiveCheckTimeoutComponent: React.FC<Props> = ({ readonly }) => {
+const ConcurrencyComponent: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
-    <Form.Item label={formatMessage({ id: 'page.upstream.step.healthyCheck.active.timeout' })} tooltip={formatMessage({ id: 'page.upstream.checks.active.timeout.description' })}>
-      <Form.Item name={['checks', 'active', 'timeout']} noStyle>
+    <Form.Item label={formatMessage({ id: 'component.upstream.fields.checks.active.concurrency' })} tooltip={formatMessage({ id: "component.upstream.fields.checks.active.concurrency.tooltip" })}>
+      <Form.Item name={['checks', 'active', 'concurrency']} noStyle initialValue={10}>
         <InputNumber disabled={readonly} min={0} />
       </Form.Item>
-      <TimeUnit />
     </Form.Item>
   )
 }
 
-export default ActiveCheckTimeoutComponent
+export default ConcurrencyComponent
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx b/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx
similarity index 88%
copy from web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx
copy to web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx
index 0cdad52..5357ef7 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx
+++ b/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx
@@ -29,13 +29,14 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
-    <Form.List name={['checks', 'active', 'unhealthy', 'http_statuses']}>
+    <Form.List name={['checks', 'active', 'healthy', 'http_statuses']} initialValue={[200, 302]}>
       {(fields, { add, remove }) => (
         <>
           <Form.Item
             required
-            label={formatMessage({ id: 'page.upstream.step.healthyCheck.passive.http_statuses' })}
+            label={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.http_statuses' })}
             style={{ marginBottom: 0 }}
+            tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.http_statuses.tooltip' })}
           >
             {fields.map((field, index) => (
               <Row style={{ marginBottom: 10 }} key={index}>
diff --git a/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx b/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx
index 47ca56e..0a4e3c8 100644
--- a/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx
+++ b/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx
@@ -27,9 +27,9 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.activeInterval' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.interval' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.active.healthy.interval.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.interval.tooltip' })}
     >
       <Form.Item
         noStyle
@@ -43,6 +43,7 @@ const Component: React.FC<Props> = ({ readonly }) => {
             }),
           },
         ]}
+        initialValue={1}
       >
         <InputNumber disabled={readonly} min={1} />
       </Form.Item>
diff --git a/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx b/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx
index 84fbccf..a096cdf 100644
--- a/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx
+++ b/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx
@@ -27,9 +27,9 @@ const Component: React.FC<Props> = ({ readonly }) => {
 
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.successes' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.successes' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.active.healthy.successes.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.healthy.successes.tooltip' })}
     >
       <Form.Item
         name={['checks', 'active', 'healthy', 'successes']}
@@ -37,9 +37,10 @@ const Component: React.FC<Props> = ({ readonly }) => {
         rules={[
           {
             required: true,
-            message: formatMessage({ id: 'page.upstream.step.input.healthyCheck.successes' }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.active.healthy.successes.required' }),
           },
         ]}
+        initialValue={2}
       >
         <InputNumber disabled={readonly} min={1} max={254} />
       </Form.Item>
diff --git a/web/src/components/Upstream/components/active-check/Healthy/index.ts b/web/src/components/Upstream/components/active-check/Healthy/index.ts
index cef27c1..f803f58 100644
--- a/web/src/components/Upstream/components/active-check/Healthy/index.ts
+++ b/web/src/components/Upstream/components/active-check/Healthy/index.ts
@@ -16,8 +16,10 @@
  */
 import Interval from './Interval'
 import Successes from './Successes'
+import HttpStatuses from './HttpStatuses'
 
 export default {
   Interval,
-  Successes
+  Successes,
+  HttpStatuses
 }
diff --git a/web/src/components/Upstream/components/active-check/Host.tsx b/web/src/components/Upstream/components/active-check/Host.tsx
index 871000b..f21a76b 100644
--- a/web/src/components/Upstream/components/active-check/Host.tsx
+++ b/web/src/components/Upstream/components/active-check/Host.tsx
@@ -26,30 +26,30 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.activeHost' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.host' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.active.host.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.host.tooltip' })}
+      style={{ marginBottom: 0 }}
     >
       <Form.Item
-        style={{ marginBottom: 0 }}
         name={['checks', 'active', 'host']}
         rules={[
           {
             required: true,
-            message: formatMessage({ id: 'page.upstream.step.input.healthyCheck.activeHost' }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.active.host.required' }),
           },
           {
             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,}$)/,
+              /^\\*?[0-9a-zA-Z-._]+$/,
               'g',
             ),
-            message: formatMessage({ id: 'page.upstream.step.domain.name.or.ip.rule' }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.active.host.scope' }),
           },
         ]}
       >
         <Input
           placeholder={formatMessage({
-            id: 'page.upstream.step.input.healthyCheck.activeHost',
+            id: 'component.upstream.fields.checks.active.host.required',
           })}
           disabled={readonly}
         />
diff --git a/web/src/components/Upstream/components/active-check/HttpPath.tsx b/web/src/components/Upstream/components/active-check/HttpPath.tsx
index 4914a49..db5c2b6 100644
--- a/web/src/components/Upstream/components/active-check/HttpPath.tsx
+++ b/web/src/components/Upstream/components/active-check/HttpPath.tsx
@@ -27,10 +27,10 @@ const Component: React.FC<Props> = ({ readonly }) => {
 
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.active.http_path' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.http_path' })}
       required
       tooltip={formatMessage({
-        id: 'page.upstream.step.input.healthyCheck.active.http_path',
+        id: 'component.upstream.fields.checks.active.http_path.tooltip',
       })}
     >
       <Form.Item
@@ -39,13 +39,14 @@ const Component: React.FC<Props> = ({ readonly }) => {
         rules={[
           {
             required: true,
-            message: formatMessage({ id: 'page.upstream.checks.active.http_path.placeholder' }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.active.http_path.placeholder' }),
           },
         ]}
+        initialValue="/"
       >
         <Input
           disabled={readonly}
-          placeholder={formatMessage({ id: 'page.upstream.checks.active.http_path.placeholder' })}
+          placeholder={formatMessage({ id: 'component.upstream.fields.checks.active.http_path.placeholder' })}
         />
       </Form.Item>
     </Form.Item>
diff --git a/web/src/components/Upstream/components/Retries.tsx b/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx
similarity index 66%
copy from web/src/components/Upstream/components/Retries.tsx
copy to web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx
index a77ecef..901c509 100644
--- a/web/src/components/Upstream/components/Retries.tsx
+++ b/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx
@@ -15,25 +15,26 @@
  * limitations under the License.
  */
 import React from 'react'
-import { Form, InputNumber } from 'antd'
+import { Form, Switch } from 'antd'
 import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
 }
 
-const Component: React.FC<Props> = ({ readonly }) => {
+const HttpsVerifyCertificateComponent: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.retries' })}
-      name="retries"
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.https_verify_certificate' })}
+      name="https_verify_certificate"
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.https_verify_certificate.tooltip' })}
+      initialValue={true}
+      valuePropName="checked"
     >
-      <InputNumber
-        disabled={readonly}
-      />
+      <Switch disabled={readonly} />
     </Form.Item>
   )
 }
 
-export default Component
+export default HttpsVerifyCertificateComponent
diff --git a/web/src/components/Upstream/components/active-check/Port.tsx b/web/src/components/Upstream/components/active-check/Port.tsx
index 3d04e07..8ca857b 100644
--- a/web/src/components/Upstream/components/active-check/Port.tsx
+++ b/web/src/components/Upstream/components/active-check/Port.tsx
@@ -25,11 +25,11 @@ type Props = {
 const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
-    <Form.Item label={formatMessage({ id: 'page.upstream.step.healthyCheck.activePort' })}>
-      <Form.Item name={['checks', 'active', 'port']} noStyle>
+    <Form.Item label={formatMessage({ id: 'component.upstream.fields.checks.active.port' })} required>
+      <Form.Item name={['checks', 'active', 'port']} noStyle initialValue={80} rules={[{ required: true, message: formatMessage({ id: "component.upstream.fields.checks.active.port.required" }) }]}>
         <InputNumber
           placeholder={formatMessage({
-            id: 'page.upstream.step.input.healthyCheck.activePort',
+            id: 'component.upstream.fields.checks.active.port',
           })}
           disabled={readonly}
           min={1}
diff --git a/web/src/components/Upstream/components/active-check/ReqHeaders.tsx b/web/src/components/Upstream/components/active-check/ReqHeaders.tsx
index 25fb8d6..9280ed4 100644
--- a/web/src/components/Upstream/components/active-check/ReqHeaders.tsx
+++ b/web/src/components/Upstream/components/active-check/ReqHeaders.tsx
@@ -34,8 +34,9 @@ const Component: React.FC<Props> = ({ readonly }) => {
         <>
           <Form.Item
             label={
-              formatMessage({ id: 'page.upstream.step.healthyCheck.active.req_headers' })
+              formatMessage({ id: 'component.upstream.fields.checks.active.req_headers' })
             }
+            tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.req_headers.tooltip' })}
             style={{ marginBottom: 0 }}
           >
             {fields.map((field, index) => (
@@ -51,7 +52,7 @@ const Component: React.FC<Props> = ({ readonly }) => {
                   </Form.Item>
                 </Col>
                 <Col style={{ ...removeBtnStyle, marginLeft: 0 }}>
-                  {!readonly && fields.length > 1 && (
+                  {!readonly && fields.length > 0 && (
                     <MinusCircleOutlined
                       onClick={() => {
                         remove(field.name);
diff --git a/web/src/components/Upstream/components/active-check/Timeout.tsx b/web/src/components/Upstream/components/active-check/Timeout.tsx
index 4d294b7..f2b6bdc 100644
--- a/web/src/components/Upstream/components/active-check/Timeout.tsx
+++ b/web/src/components/Upstream/components/active-check/Timeout.tsx
@@ -28,7 +28,7 @@ const ActiveCheckTimeoutComponent: React.FC<Props> = ({ readonly }) => {
 
   return (
     <Form.Item label={formatMessage({ id: 'page.upstream.step.healthyCheck.active.timeout' })} tooltip={formatMessage({ id: 'page.upstream.checks.active.timeout.description' })}>
-      <Form.Item name={['checks', 'active', 'timeout']} noStyle>
+      <Form.Item name={['checks', 'active', 'timeout']} noStyle initialValue={1}>
         <InputNumber disabled={readonly} min={0} />
       </Form.Item>
       <TimeUnit />
diff --git a/web/src/components/Upstream/components/active-check/Type.tsx b/web/src/components/Upstream/components/active-check/Type.tsx
index e8b95c6..067bf96 100644
--- a/web/src/components/Upstream/components/active-check/Type.tsx
+++ b/web/src/components/Upstream/components/active-check/Type.tsx
@@ -15,7 +15,8 @@
  * limitations under the License.
  */
 import React from 'react'
-import { Form, Select } from 'antd'
+import { Form, Select, Row, Col } from 'antd'
+import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
@@ -35,21 +36,32 @@ const options = [
 ]
 
 const ActiveCheckTypeComponent: React.FC<Props> = ({ readonly }) => {
+  const { formatMessage } = useIntl()
+
   return (
     <Form.Item
-      label="Type"
-      name={['checks', 'active', 'type']}
-      rules={[{ required: true }]}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.type' })}
+      style={{ marginBottom: 0 }}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.type.tooltip' })}
     >
-      <Select disabled={readonly}>
-        {options.map(item => {
-          return (
-            <Select.Option value={item.value} key={item.value}>
-              {item.label}
-            </Select.Option>
-          );
-        })}
-      </Select>
+      <Row>
+        <Col span={5}>
+          <Form.Item
+            name={['checks', 'active', 'type']}
+            initialValue="http"
+          >
+            <Select disabled={readonly}>
+              {options.map(item => {
+                return (
+                  <Select.Option value={item.value} key={item.value}>
+                    {item.label}
+                  </Select.Option>
+                );
+              })}
+            </Select>
+          </Form.Item>
+        </Col>
+      </Row>
     </Form.Item>
   )
 }
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/HttpFailures.tsx b/web/src/components/Upstream/components/active-check/Unhealthy/HttpFailures.tsx
index dbd4118..953e785 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/HttpFailures.tsx
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/HttpFailures.tsx
@@ -27,9 +27,9 @@ const Component: React.FC<Props> = ({ readonly }) => {
 
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.http_failures' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.http_failures' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.active.unhealthy.http_failures.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip' })}
     >
       <Form.Item
         name={['checks', 'active', 'unhealthy', 'http_failures']}
@@ -38,10 +38,11 @@ const Component: React.FC<Props> = ({ readonly }) => {
           {
             required: true,
             message: formatMessage({
-              id: 'page.upstream.step.input.healthyCheck.http_failures',
+              id: 'component.upstream.fields.checks.active.unhealthy.http_failures.required',
             }),
           },
         ]}
+        initialValue={5}
       >
         <InputNumber disabled={readonly} min={1} max={254} />
       </Form.Item>
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx b/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx
index 0cdad52..3e5830c 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/HttpStatuses.tsx
@@ -29,7 +29,7 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
-    <Form.List name={['checks', 'active', 'unhealthy', 'http_statuses']}>
+    <Form.List name={['checks', 'active', 'unhealthy', 'http_statuses']} initialValue={[429, 404, 500, 501, 502, 503, 504, 505]}>
       {(fields, { add, remove }) => (
         <>
           <Form.Item
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/Interval.tsx b/web/src/components/Upstream/components/active-check/Unhealthy/Interval.tsx
index 8052808..5b41aa0 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/Interval.tsx
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/Interval.tsx
@@ -28,13 +28,14 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.activeInterval' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.interval' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.active.unhealthy.interval.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.interval.tooltip' })}
     >
       <Form.Item
         name={['checks', 'active', 'unhealthy', 'interval']}
         noStyle
+        initialValue={1}
         rules={[
           {
             required: true,
diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx b/web/src/components/Upstream/components/active-check/Unhealthy/TCPFailures.tsx
similarity index 71%
copy from web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx
copy to web/src/components/Upstream/components/active-check/Unhealthy/TCPFailures.tsx
index 3ba6154..20011b7 100644
--- a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/TCPFailures.tsx
@@ -14,34 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React from 'react'
 import { Form, InputNumber } from 'antd'
+import React from 'react'
 import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
 }
 
-const Component: React.FC<Props> = ({ readonly }) => {
+const TCPFailures: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.http_failures' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.tcp_failures' })}
       required
-      tooltip={formatMessage({ id: 'page.upstream.checks.passive.unhealthy.http_failures.description' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip' })}
     >
       <Form.Item
-        name={['checks', 'passive', 'unhealthy', 'http_failures']}
+        name={['checks', 'active', 'unhealthy', 'tcp_Failures']}
         noStyle
         rules={[
           {
             required: true,
-            message: formatMessage({
-              id: 'page.upstream.step.input.healthyCheck.http_failures',
-            }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.tcp_failures.required' }),
           },
         ]}
+        initialValue={2}
       >
         <InputNumber disabled={readonly} min={1} max={254} />
       </Form.Item>
@@ -49,4 +48,4 @@ const Component: React.FC<Props> = ({ readonly }) => {
   )
 }
 
-export default Component
+export default TCPFailures
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx b/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx
index 2f5af5f..c1faa1e 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx
@@ -16,23 +16,29 @@
  */
 import React from 'react'
 import { Form, InputNumber } from 'antd'
+import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
 }
 
-const Component: React.FC<Props> = ({ readonly }) => (
-  <Form.Item
-    label="Timeouts"
-    required
-  >
+const Component: React.FC<Props> = ({ readonly }) => {
+  const { formatMessage } = useIntl()
+  return (
     <Form.Item
-      name={['checks', 'active', 'unhealthy', 'timeouts']}
-      noStyle
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.timeouts' })}
+      required
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip' })}
     >
-      <InputNumber disabled={readonly} min={1} max={254} />
+      <Form.Item
+        name={['checks', 'active', 'unhealthy', 'timeouts']}
+        noStyle
+        initialValue={3}
+      >
+        <InputNumber disabled={readonly} min={1} max={254} />
+      </Form.Item>
     </Form.Item>
-  </Form.Item>
-)
+  )
+}
 
 export default Component
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/index.ts b/web/src/components/Upstream/components/active-check/Unhealthy/index.ts
index bb9b869..6dde012 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/index.ts
+++ b/web/src/components/Upstream/components/active-check/Unhealthy/index.ts
@@ -18,10 +18,12 @@ import Timeouts from './Timeouts'
 import Interval from './Interval'
 import HttpStatuses from './HttpStatuses'
 import HttpFailures from './HttpFailures'
+import TCPFailures from './TCPFailures'
 
 export default {
   Timeouts,
   Interval,
   HttpStatuses,
-  HttpFailures
+  HttpFailures,
+  TCPFailures
 }
diff --git a/web/src/components/Upstream/components/active-check/index.ts b/web/src/components/Upstream/components/active-check/index.ts
index efc3046..0a99290 100644
--- a/web/src/components/Upstream/components/active-check/index.ts
+++ b/web/src/components/Upstream/components/active-check/index.ts
@@ -23,6 +23,8 @@ import ReqHeaders from './ReqHeaders'
 import Host from './Host'
 import Port from './Port'
 import HttpPath from './HttpPath'
+import Concurrency from './Concurrency'
+import HttpsVerifyCertificate from './HttpsVerifyCertificate'
 
 export default {
   Unhealthy,
@@ -32,5 +34,7 @@ export default {
   ReqHeaders,
   Host,
   Port,
-  HttpPath
+  HttpPath,
+  Concurrency,
+  HttpsVerifyCertificate
 }
diff --git a/web/src/components/Upstream/components/passive-check/Healthy/HttpStatuses.tsx b/web/src/components/Upstream/components/passive-check/Healthy/HttpStatuses.tsx
index f1b06d2..8ac8ecb 100644
--- a/web/src/components/Upstream/components/passive-check/Healthy/HttpStatuses.tsx
+++ b/web/src/components/Upstream/components/passive-check/Healthy/HttpStatuses.tsx
@@ -29,7 +29,9 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
 
   return (
-    <Form.List name={['checks', 'passive', 'healthy', 'http_statuses']}>
+    <Form.List name={['checks', 'passive', 'healthy', 'http_statuses']} initialValue={[200, 201, 202, 203, 204, 205, 206, 207,
+      208, 226, 300, 301, 302, 303, 304, 305,
+      306, 307, 308]}>
       {(fields, { add, remove }) => (
         <>
           <Form.Item
diff --git a/web/src/components/Upstream/components/passive-check/Healthy/Successes.tsx b/web/src/components/Upstream/components/passive-check/Healthy/Successes.tsx
index 2ee3590..a85a69f 100644
--- a/web/src/components/Upstream/components/passive-check/Healthy/Successes.tsx
+++ b/web/src/components/Upstream/components/passive-check/Healthy/Successes.tsx
@@ -26,17 +26,18 @@ const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.successes' })}
-      tooltip={formatMessage({ id: 'page.upstream.checks.passive.healthy.successes.description' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.passive.healthy.successes' })}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.passive.healthy.successes.tooltip' })}
       required
     >
       <Form.Item
         name={['checks', 'passive', 'healthy', 'successes']}
         noStyle
+        initialValue={5}
         rules={[
           {
             required: true,
-            message: formatMessage({ id: 'page.upstream.step.input.healthyCheck.successes' }),
+            message: formatMessage({ id: 'component.upstream.fields.checks.passive.healthy.successes.required' }),
           },
         ]}
       >
diff --git a/web/src/components/Upstream/components/passive-check/Type.tsx b/web/src/components/Upstream/components/passive-check/Type.tsx
index d3401ee..f43f445 100644
--- a/web/src/components/Upstream/components/passive-check/Type.tsx
+++ b/web/src/components/Upstream/components/passive-check/Type.tsx
@@ -15,43 +15,55 @@
  * limitations under the License.
  */
 import React from 'react'
-import { Form, Select } from 'antd'
+import { Form, Select, Row, Col } from 'antd'
+import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
 }
 
-const PassiveCheckTypeComponent: React.FC<Props> = ({ readonly }) => {
-  const options = [
-    {
-      label: "HTTP",
-      value: "http"
-    }, {
-      label: "HTTPs",
-      value: "https"
-    }, {
-      label: "TCP",
-      value: "tcp"
-    }
-  ]
+const options = [
+  {
+    label: "HTTP",
+    value: "http"
+  }, {
+    label: "HTTPs",
+    value: "https"
+  }, {
+    label: "TCP",
+    value: "tcp"
+  }
+]
+
+const ActiveCheckTypeComponent: React.FC<Props> = ({ readonly }) => {
+  const { formatMessage } = useIntl()
 
   return (
     <Form.Item
-      label="Type"
-      name={['checks', 'passive', 'type']}
-      rules={[{ required: true }]}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.type' })}
+      style={{ marginBottom: 0 }}
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.active.type.tooltip' })}
     >
-      <Select disabled={readonly}>
-        {options.map(item => {
-          return (
-            <Select.Option value={item.value} key={item.value}>
-              {item.label}
-            </Select.Option>
-          );
-        })}
-      </Select>
+      <Row>
+        <Col span={5}>
+          <Form.Item
+            name={['checks', 'passive', 'type']}
+            initialValue="http"
+          >
+            <Select disabled={readonly}>
+              {options.map(item => {
+                return (
+                  <Select.Option value={item.value} key={item.value}>
+                    {item.label}
+                  </Select.Option>
+                );
+              })}
+            </Select>
+          </Form.Item>
+        </Col>
+      </Row>
     </Form.Item>
   )
 }
 
-export default PassiveCheckTypeComponent
+export default ActiveCheckTypeComponent
diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx
index 3ba6154..be282b7 100644
--- a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx
+++ b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx
@@ -27,18 +27,19 @@ const Component: React.FC<Props> = ({ readonly }) => {
 
   return (
     <Form.Item
-      label={formatMessage({ id: 'page.upstream.step.healthyCheck.http_failures' })}
+      label={formatMessage({ id: 'component.upstream.fields.checks.active.unhealthy.http_failures' })}
       required
       tooltip={formatMessage({ id: 'page.upstream.checks.passive.unhealthy.http_failures.description' })}
     >
       <Form.Item
         name={['checks', 'passive', 'unhealthy', 'http_failures']}
         noStyle
+        initialValue={2}
         rules={[
           {
             required: true,
             message: formatMessage({
-              id: 'page.upstream.step.input.healthyCheck.http_failures',
+              id: 'component.upstream.fields.checks.active.unhealthy.http_failures.required',
             }),
           },
         ]}
diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx
index ba9ba75..2127c05 100644
--- a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx
+++ b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx
@@ -28,7 +28,7 @@ type Props = {
 const Component: React.FC<Props> = ({ readonly }) => {
   const { formatMessage } = useIntl()
   return (
-    <Form.List name={['checks', 'passive', 'unhealthy', 'http_statuses']}>
+    <Form.List name={['checks', 'passive', 'unhealthy', 'http_statuses']} initialValue={[429, 500, 503]}>
       {(fields, { add, remove }) => (
         <>
           <Form.Item
diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx
index 175d22f..7828cb2 100644
--- a/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx
+++ b/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx
@@ -33,6 +33,7 @@ const Component: React.FC<Props> = ({ readonly }) => {
       <Form.Item
         name={['checks', 'passive', 'unhealthy', 'tcp_failures']}
         noStyle
+        initialValue={2}
         rules={[
           {
             required: true,
diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx
index 91b7b4f..6eff53a 100644
--- a/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx
+++ b/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx
@@ -16,23 +16,29 @@
  */
 import React from 'react'
 import { Form, InputNumber } from 'antd'
+import { useIntl } from 'umi'
 
 type Props = {
   readonly?: boolean
 }
 
-const Component: React.FC<Props> = ({ readonly }) => (
-  <Form.Item
-    label="Timeouts"
-    required
-  >
+const Component: React.FC<Props> = ({ readonly }) => {
+  const { formatMessage } = useIntl()
+  return (
     <Form.Item
-      name={['checks', 'passive', 'unhealthy', 'timeouts']}
-      noStyle
+      label={formatMessage({ id: 'component.upstream.fields.checks.passive.unhealthy.timeouts' })}
+      required
+      tooltip={formatMessage({ id: 'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip' })}
     >
-      <InputNumber disabled={readonly} min={1} max={254} />
+      <Form.Item
+        name={['checks', 'passive', 'unhealthy', 'timeouts']}
+        noStyle
+        initialValue={7}
+      >
+        <InputNumber disabled={readonly} min={1} max={254} />
+      </Form.Item>
     </Form.Item>
-  </Form.Item>
-)
+  )
+}
 
 export default Component
diff --git a/web/src/components/Upstream/constant.ts b/web/src/components/Upstream/constant.ts
index d4f243b..66ddc45 100644
--- a/web/src/components/Upstream/constant.ts
+++ b/web/src/components/Upstream/constant.ts
@@ -14,77 +14,50 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-export const DEFAULT_UPSTREAM = {
-  upstream_id: '',
-  // NOTE: the following fields are the default configurations
-  // https://github.com/apache/apisix/blob/master/apisix/schema_def.lua#L325
-  nodes: [
-    {
-      host: '',
-      port: 80,
-      weight: 1
-    }
-  ],
-  retries: 0,
-  timeout: {
-    connect: 6,
-    send: 6,
-    read: 6,
-  },
-  type: 'roundrobin',
-  checks: {},
-  scheme: "http",
-  pass_host: "pass",
-  name: "",
-  desc: ""
-};
-
-// NOTE: checks.active
-// https://github.com/apache/apisix/blob/master/apisix/schema_def.lua#L40
-export const DEFAULT_HEALTH_CHECK_ACTIVE = {
-  type: "http",
-  timeout: 1,
-  concurrency: 10,
-  host: "",
-  port: 80,
-  http_path: "",
-  https_verify_certificate: true,
-  healthy: {
-    interval: 1,
-    http_statuses: [200, 302],
-    successes: 2
-  },
-  unhealthy: {
-    interval: 1,
-    http_statuses: [429, 404, 500, 501, 502, 503, 504, 505],
-    http_failures: 5,
-    tcp_failures: 2,
-    timeouts: 3
-  },
-  req_headers: []
-}
-
-// NOTE: checks.passive
-export const DEFAULT_HEALTH_CHECK_PASSIVE = {
-  type: "http",
-  healthy: {
-    http_statuses: [
-      200, 201, 202, 203, 204, 205, 206, 207,
-      208, 226, 300, 301, 302, 303, 304, 305,
-      306, 307, 308
-    ],
-    successes: 5
-  },
-  unhealthy: {
-    http_statuses: [429, 500, 503],
-    tcp_failures: 2,
-    timeouts: 7,
-    http_failures: 5
-  }
-}
 
 export const removeBtnStyle = {
   marginLeft: 20,
   display: 'flex',
   alignItems: 'center',
 };
+
+export enum AlgorithmEnum {
+  chash = "chash",
+  roundrobin = "roundrobin",
+  ewma = "ewma",
+  least_conn = "least_conn"
+}
+
+export enum HashOnEnum {
+  vars = 'vars',
+  header = 'header',
+  cookie = 'cookie',
+  consumer = 'consumer',
+  vars_combinations = 'vars_combinations'
+}
+
+export enum CommonHashKeyEnum {
+  remote_addr = 'remote_addr',
+  host = 'host',
+  uri = 'uri',
+  server_name = 'server_name',
+  server_addr = 'server_addr',
+  request_uri = 'request_uri',
+  query_string = 'query_string',
+  remote_port = 'remote_port',
+  hostname = 'hostname',
+  arg_id = 'arg_id',
+}
+
+export enum SchemeEnum {
+  grpc = "grpc",
+  grpcs = "grpcs",
+  http = "http",
+  https = "https"
+}
+
+export enum PassHostEnum {
+  pass = "pass",
+  node = "node",
+  rewrite = "rewrite"
+}
diff --git a/web/src/components/Upstream/locales/en-US.ts b/web/src/components/Upstream/locales/en-US.ts
new file mode 100644
index 0000000..585fb66
--- /dev/null
+++ b/web/src/components/Upstream/locales/en-US.ts
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export default {
+  'component.upstream.fields.tls.client_key': 'Client Key',
+  'component.upstream.fields.tls.client_cert': 'Client Cert',
+
+  'component.upstream.fields.discovery_type': 'Discovery Type',
+  'component.upstream.fields.discovery_type.tooltip': 'Discovery Type',
+  'component.upstream.fields.discovery_type.placeholder': 'Please enter the discovery type',
+
+  'component.upstream.fields.service_name': 'Service Name',
+  'component.upstream.fields.service_name.tooltip': 'Service Name',
+  'component.upstream.fields.service_name.placeholder': 'Please enter the service name',
+
+  'component.upstream.fields.tls': 'TLS',
+  'component.upstream.fields.tls.tooltip': 'TLS Certificate',
+
+  'component.upstream.fields.hash_on': 'Hash on',
+  'component.upstream.fields.hash_on.tooltip': 'What to use as hashing input',
+
+  'component.upstream.fields.key': 'Key',
+  'component.upstream.fields.key.tooltip': 'Key as hashing input',
+
+  'component.upstream.fields.retries': 'Retries',
+  'component.upstream.fields.retries.tooltip': 'The retry mechanism sends the request to the next upstream node. A value of 0 disables the retry mechanism and leaves the table empty to use the number of available backend nodes.',
+
+  'component.upstream.fields.checks.active.type': 'Type',
+  'component.upstream.fields.checks.active.type.tooltip': 'Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection.',
+
+  'component.upstream.fields.checks.active.concurrency': 'Concurrency',
+  'component.upstream.fields.checks.active.concurrency.tooltip': 'Number of targets to check concurrently in active health checks.',
+
+  'component.upstream.fields.checks.active.host': 'Host',
+  'component.upstream.fields.checks.active.host.required': 'Please enter the hostname',
+  'component.upstream.fields.checks.active.host.tooltip': 'The hostname of the HTTP request used to perform the active health check',
+  'component.upstream.fields.checks.active.host.scope': 'Only letters, numbers and . are supported',
+
+  'component.upstream.fields.checks.active.port': 'Port',
+  'component.upstream.fields.checks.active.port.required': 'Please enter the port',
+
+  'component.upstream.fields.checks.active.http_path': 'HTTP Path',
+  'component.upstream.fields.checks.active.http_path.tooltip': 'The path that should be used when issuing the HTTP GET request to the target. The default value is /.',
+
+  'component.upstream.fields.checks.active.https_verify_certificate': 'Verify HTTPs Certificate',
+  'component.upstream.fields.checks.active.https_verify_certificate.tooltip': 'Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS.',
+
+  'component.upstream.fields.checks.active.req_headers': 'Request Headers',
+  'component.upstream.fields.checks.active.req_headers.tooltip': 'Additional request headers, example: User-Agent: curl/7.29.0',
+
+  'component.upstream.fields.checks.active.healthy.interval': 'Interval',
+  'component.upstream.fields.checks.active.healthy.interval.tooltip': 'Interval between checks for healthy targets (in seconds)',
+
+  'component.upstream.fields.checks.active.healthy.successes': 'Successes',
+  'component.upstream.fields.checks.active.healthy.successes.tooltip': 'Number of successes to consider a target healthy',
+  'component.upstream.fields.checks.active.healthy.successes.required': 'Please enter successes number',
+
+  'component.upstream.fields.checks.active.healthy.http_statuses': 'HTTP Statuses',
+  'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': 'An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks.',
+
+  'component.upstream.fields.checks.active.unhealthy.timeouts': 'Timeouts',
+  'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': 'Number of timeouts in active probes to consider a target unhealthy.',
+
+  'component.upstream.fields.checks.active.unhealthy.http_failures': 'HTTP Failures',
+  'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': 'Number of HTTP failures to consider a target unhealthy',
+  'component.upstream.fields.checks.active.unhealthy.http_failures.required': 'Please enter the HTTP failures',
+
+  'component.upstream.fields.checks.active.unhealthy.interval': 'Interval',
+  'component.upstream.fields.checks.active.unhealthy.interval.tooltip': 'Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed.',
+  'component.upstream.fields.checks.active.unhealthy.required': 'Please enter the unhelthy interval',
+
+  'component.upstream.fields.checks.passive.healthy.successes': 'Successes',
+  'component.upstream.fields.checks.passive.healthy.successes.tooltip': 'Number of successes to consider a target healthy',
+  'component.upstream.fields.checks.passive.healthy.successes.required': 'Please enter the successes number',
+
+  'component.upstream.fields.checks.passive.unhealthy.timeouts': 'Timeouts',
+  'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': 'Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks.',
+}
diff --git a/web/src/components/Upstream/locales/zh-CN.ts b/web/src/components/Upstream/locales/zh-CN.ts
new file mode 100644
index 0000000..62925e6
--- /dev/null
+++ b/web/src/components/Upstream/locales/zh-CN.ts
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export default {
+  'component.upstream.fields.tls.client_key': '客户端私钥',
+  'component.upstream.fields.tls.client_cert': '客户端证书',
+
+  'component.upstream.fields.discovery_type': '服务发现类型',
+  'component.upstream.fields.discovery_type.tooltip': '服务发现类型',
+  'component.upstream.fields.discovery_type.placeholder': '请输入服务发现类型',
+
+  'component.upstream.fields.service_name': '服务名称',
+  'component.upstream.fields.service_name.tooltip': '服务名称',
+  'component.upstream.fields.service_name.placeholder': '请输入服务名称',
+
+  'component.upstream.fields.tls': 'TLS',
+  'component.upstream.fields.tls.tooltip': 'TLS 证书',
+
+  'component.upstream.fields.hash_on': '哈希位置',
+  'component.upstream.fields.hash_on.tooltip': '哈希的输入的位置(Hash On)',
+
+  'component.upstream.fields.key': 'Key',
+  'component.upstream.fields.key.tooltip': '哈希键(Hash Key)',
+
+  'component.upstream.fields.retries': '重试次数',
+  'component.upstream.fields.retries.tooltip': '重试机制将请求发到下一个上游节点。值为 0 表示禁用重试机制,留空表是使用可用后端节点的数量。',
+
+  'component.upstream.fields.checks.active.type': '类型',
+  'component.upstream.fields.checks.active.type.tooltip': '是使用 HTTP 或 HTTPS 进行主动健康检查,还是只尝试 TCP 连接。',
+
+  'component.upstream.fields.checks.active.concurrency': '并行数量',
+  'component.upstream.fields.checks.active.concurrency.tooltip': '在主动健康检查中同时检查的目标数量。',
+
+  'component.upstream.fields.checks.active.host': '主机名',
+  'component.upstream.fields.checks.active.host.required': '请输入主机名',
+  'component.upstream.fields.checks.active.host.tooltip': '进行主动健康检查时使用的 HTTP 请求主机名',
+  'component.upstream.fields.checks.active.host.scope': '仅支持字母、数字和 . ',
+
+  'component.upstream.fields.checks.active.port': '端口',
+  'component.upstream.fields.checks.active.port.required': '请输入端口',
+
+  'component.upstream.fields.checks.active.http_path': '请求路径',
+  'component.upstream.fields.checks.active.http_path.tooltip': '向目标节点发出 HTTP GET 请求时应使用的路径。',
+  'component.upstream.fields.checks.active.http_path.placeholder': '请输入 HTTP 请求路径',
+
+  'component.upstream.fields.checks.active.https_verify_certificate': '验证证书',
+  'component.upstream.fields.checks.active.https_verify_certificate.tooltip': '在使用 HTTPS 执行主动健康检查时,是否检查远程主机的 SSL 证书的有效性。',
+
+  'component.upstream.fields.checks.active.req_headers': '请求头',
+  'component.upstream.fields.checks.active.req_headers.tooltip': '额外的请求头,示例:User-Agent: curl/7.29.0',
+
+  'component.upstream.fields.checks.active.healthy.interval': '间隔时间',
+  'component.upstream.fields.checks.active.healthy.interval.tooltip': '对健康的上游服务目标节点进行主动健康检查的间隔时间(以秒为单位)。数值为0表示对健康节点不进行主动健康检查。',
+
+  'component.upstream.fields.checks.active.healthy.successes': '成功次数',
+  'component.upstream.fields.checks.active.healthy.successes.tooltip': '主动健康检查的 HTTP 成功次数,若达到此值,表示上游服务目标节点是健康的。',
+  'component.upstream.fields.checks.active.healthy.successes.required': '请输入成功次数',
+
+  'component.upstream.fields.checks.active.healthy.http_statuses': '状态码',
+  'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': 'HTTP 状态码列表,当探针在主动健康检查中返回时,视为健康。',
+
+  'component.upstream.fields.checks.active.unhealthy.timeouts': '超时时间',
+  'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': '活动探针中认为目标不健康的超时次数。',
+
+  'component.upstream.fields.checks.active.unhealthy.interval': '间隔时间',
+  'component.upstream.fields.checks.active.unhealthy.interval.tooltip': '对不健康目标的主动健康检查之间的间隔(以秒为单位)。数值为0表示不应该对健康目标进行主动探查。',
+  'component.upstream.fields.checks.active.unhealthy.required': '请输入间隔时间',
+
+  'component.upstream.fields.checks.active.unhealthy.http_failures': 'HTTP 失败次数',
+  'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': '主动健康检查的 HTTP 失败次数,默认值为0。若达到此值,表示上游服务目标节点是不健康的。',
+  'component.upstream.fields.checks.active.unhealthy.http_failures.required': '请输入 HTTP 失败次数',
+
+  'component.upstream.fields.checks.active.unhealthy.tcp_failures': 'TCP 失败次数',
+  'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip': '主动探测中 TCP 失败次数超过该值时,认为目标不健康。',
+  'component.upstream.fields.checks.active.unhealthy.tcp_failures.required': '请输入 TCP 失败次数',
+
+  'component.upstream.fields.checks.passive.healthy.successes': '成功次数',
+  'component.upstream.fields.checks.passive.healthy.successes.tooltip': '通过被动健康检查观察到的正常代理流量的成功次数。如果达到该值,上游服务目标节点将被视为健康。',
+  'component.upstream.fields.checks.passive.healthy.successes.required': '请输入成功次数',
+
+  'component.upstream.fields.checks.passive.unhealthy.timeouts': '超时时间',
+  'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': '根据被动健康检查的观察,在代理中认为目标不健康的超时次数。',
+}
diff --git a/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx b/web/src/components/Upstream/service.ts
similarity index 54%
copy from web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx
copy to web/src/components/Upstream/service.ts
index 2f5af5f..2642100 100644
--- a/web/src/components/Upstream/components/active-check/Unhealthy/Timeouts.tsx
+++ b/web/src/components/Upstream/service.ts
@@ -14,25 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React from 'react'
-import { Form, InputNumber } from 'antd'
+import cloneDeep from 'lodash/cloneDeep'
 
-type Props = {
-  readonly?: boolean
-}
+/**
+ * Because we have some `custom` field in Upstream Form, like custom.tls/custom.checks.active etc,
+ * we need to transform data that doesn't have `custom` field to data contains `custom` field
+*/
+export const transformUpstreamDataFromRequest = (originData: UpstreamComponent.ResponseData) => {
+  const data = cloneDeep(originData)
+  data.custom = {}
+
+  if (data.checks) {
+    data.custom.checks = {}
+
+    if (data.checks.active) {
+      data.custom.checks.active = true
+    }
 
-const Component: React.FC<Props> = ({ readonly }) => (
-  <Form.Item
-    label="Timeouts"
-    required
-  >
-    <Form.Item
-      name={['checks', 'active', 'unhealthy', 'timeouts']}
-      noStyle
-    >
-      <InputNumber disabled={readonly} min={1} max={254} />
-    </Form.Item>
-  </Form.Item>
-)
+    if (data.checks.passive) {
+      data.custom.checks.passive = true
+    }
+  }
 
-export default Component
+  if (data.tls) {
+    data.custom.tls = "enable"
+  }
+
+  return data
+}
diff --git a/web/src/components/Upstream/typings.d.ts b/web/src/components/Upstream/typings.d.ts
new file mode 100644
index 0000000..bbe22d3
--- /dev/null
+++ b/web/src/components/Upstream/typings.d.ts
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Schema: https://github.com/apache/apisix/blob/master/apisix/schema_def.lua#L335
+*/
+declare namespace UpstreamComponent {
+  type ActiveCheck = {}
+
+  type PassiveCheck = {}
+
+  type TLS = {
+    client_cert: string;
+    client_key: string
+  }
+
+  type Node = {
+    host: string;
+    port: number;
+    weight: number;
+    priority?: number;
+  }
+
+  type Timeout = {
+    connect: number;
+    send: number;
+    read: number;
+  }
+
+  type ResponseData = {
+    nodes: Node[];
+    retries?: number;
+    timeout?: Timeout;
+    tls?: TLS;
+    type?: string;
+    checks?: {
+      active?: ActiveCheck;
+      passive?: PassiveCheck;
+    }
+    hash_on?: string;
+    key?: string;
+    scheme?: string;
+    discovery_type?: string;
+    pass_host?: string;
+    upstream_host?: string;
+    name?: string;
+    desc?: string;
+    service_name?: string;
+    id?: string;
+    // NOTE: custom field
+    custom?: Record<string, any>;
+  }
+}
diff --git a/web/src/locales/en-US.ts b/web/src/locales/en-US.ts
index 19c348a..e4773a6 100644
--- a/web/src/locales/en-US.ts
+++ b/web/src/locales/en-US.ts
@@ -26,6 +26,7 @@ import other from './en-US/other'
 import PluginOrchestration from '../components/PluginOrchestration/locales/en-US';
 import Plugin from '../components/Plugin/locales/en-US';
 import RawDataEditor from '../components/RawDataEditor/locales/en-US';
+import UpstreamComponent from '../components/Upstream/locales/en-US'
 
 export default {
   'navBar.lang': 'Languages',
@@ -43,5 +44,6 @@ export default {
   ...ActionBarEnUS,
   ...PluginOrchestration,
   ...Plugin,
-  ...RawDataEditor
+  ...RawDataEditor,
+  ...UpstreamComponent
 };
diff --git a/web/src/locales/en-US/component.ts b/web/src/locales/en-US/component.ts
index fe9e2ea..a5d6356 100644
--- a/web/src/locales/en-US/component.ts
+++ b/web/src/locales/en-US/component.ts
@@ -24,6 +24,7 @@ export default {
   'component.global.format': 'Format',
   'component.global.document': 'Document',
   'component.global.enable': 'Enable',
+  'component.global.disable': 'Disable',
   'component.global.scope': 'Scope',
   'component.global.data.editor': 'Raw Data Editor',
   'component.global.delete': 'Delete',
diff --git a/web/src/locales/zh-CN.ts b/web/src/locales/zh-CN.ts
index 0c80375..4d89580 100644
--- a/web/src/locales/zh-CN.ts
+++ b/web/src/locales/zh-CN.ts
@@ -26,6 +26,7 @@ import settings from './zh-CN/setting';
 import PluginOrchestration from '../components/PluginOrchestration/locales/zh-CN';
 import Plugin from '../components/Plugin/locales/zh-CN';
 import RawDataEditor from '../components/RawDataEditor/locales/zh-CN';
+import UpstreamComponent from '../components/Upstream/locales/zh-CN'
 
 export default {
   'navBar.lang': '语言',
@@ -43,5 +44,6 @@ export default {
   ...ActionBarZhCN,
   ...PluginOrchestration,
   ...Plugin,
-  ...RawDataEditor
+  ...RawDataEditor,
+  ...UpstreamComponent
 };
diff --git a/web/src/locales/zh-CN/component.ts b/web/src/locales/zh-CN/component.ts
index bf5ee19..df60e7f 100644
--- a/web/src/locales/zh-CN/component.ts
+++ b/web/src/locales/zh-CN/component.ts
@@ -24,6 +24,7 @@ export default {
   'component.global.format': '格式化',
   'component.global.document': '文档',
   'component.global.enable': '启用',
+  'component.global.disable': '禁用',
   'component.global.scope': '作用域',
   'component.global.data.editor': '数据编辑器',
   'component.global.delete': '删除',
diff --git a/web/src/pages/Route/Create.tsx b/web/src/pages/Route/Create.tsx
index 648546f..8c478d1 100644
--- a/web/src/pages/Route/Create.tsx
+++ b/web/src/pages/Route/Create.tsx
@@ -21,7 +21,6 @@ import { history, useIntl } from 'umi';
 import { isEmpty } from 'lodash';
 
 import ActionBar from '@/components/ActionBar';
-import { DEFAULT_UPSTREAM } from '@/components/Upstream';
 
 import { transformer as chartTransformer } from '@/components/PluginOrchestration';
 import { create, fetchItem, update, checkUniqueName, checkHostWithSSL } from './service';
@@ -83,7 +82,6 @@ const Page: React.FC<Props> = (props) => {
     setAdvancedMatchingRules([]);
     setStep3Data(DEFAULT_STEP_3_DATA);
     form1.setFieldsValue(DEFAULT_STEP_1_DATA);
-    form2.setFieldsValue(DEFAULT_UPSTREAM);
     setStep(1);
   };
 
@@ -95,7 +93,7 @@ const Page: React.FC<Props> = (props) => {
     }
   }, []);
 
-  const getProxyRewriteEnable =() => {
+  const getProxyRewriteEnable = () => {
     return !isEmpty(transformProxyRewrite2Plugin(form1.getFieldValue('proxyRewrite')));
   }
 
@@ -269,9 +267,8 @@ const Page: React.FC<Props> = (props) => {
   return (
     <>
       <PageHeaderWrapper
-        title={`${
-          formatMessage({ id: `component.global.${props.route.path.split('/').slice(-1)[0]}`})
-        } ${formatMessage({ id: 'menu.routes' })}`}
+        title={`${formatMessage({ id: `component.global.${props.route.path.split('/').slice(-1)[0]}` })
+          } ${formatMessage({ id: 'menu.routes' })}`}
       >
         <Card bordered={false}>
           <Steps current={step - 1} className={styles.steps}>
diff --git a/web/src/pages/Service/Create.tsx b/web/src/pages/Service/Create.tsx
index cb3d667..4d1dbc2 100644
--- a/web/src/pages/Service/Create.tsx
+++ b/web/src/pages/Service/Create.tsx
@@ -22,7 +22,6 @@ import { omit } from 'lodash';
 
 import ActionBar from '@/components/ActionBar';
 import PluginPage from '@/components/Plugin';
-import { DEFAULT_UPSTREAM } from '@/components/Upstream';
 import Preview from './components/Preview';
 import Step1 from './components/Step1';
 import { create, update, fetchItem } from './service';
@@ -46,9 +45,6 @@ const Page: React.FC = (props) => {
   const [step, setStep] = useState(1);
 
   useEffect(() => {
-    // init upstream default value
-    upstreamForm.setFieldsValue(DEFAULT_UPSTREAM);
-
     const { serviceId } = (props as any).match.params;
     if (serviceId) {
       fetchItem(serviceId).then(({ data }) => {
@@ -82,8 +78,8 @@ const Page: React.FC = (props) => {
       .then(() => {
         notification.success({
           message: `${serviceId
-            ? formatMessage({ id: 'component.global.edit' })
-            : formatMessage({ id: 'component.global.create' })
+              ? formatMessage({ id: 'component.global.edit' })
+              : formatMessage({ id: 'component.global.create' })
             } ${formatMessage({ id: 'menu.service' })} ${formatMessage({
               id: 'component.status.success',
             })}`,
diff --git a/web/src/pages/Upstream/Create.tsx b/web/src/pages/Upstream/Create.tsx
index 0e068c7..993e20a 100644
--- a/web/src/pages/Upstream/Create.tsx
+++ b/web/src/pages/Upstream/Create.tsx
@@ -21,6 +21,7 @@ import { history, useIntl } from 'umi';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 
 import ActionBar from '@/components/ActionBar';
+import { transformUpstreamDataFromRequest } from '@/components/Upstream/service';
 
 import Step1 from './components/Step1';
 import { fetchOne, create, update } from './service';
@@ -35,8 +36,8 @@ const Page: React.FC = (props) => {
     const { id } = (props as any).match.params;
 
     if (id) {
-      fetchOne(id).then((data) => {
-        form1.setFieldsValue(data.data);
+      fetchOne(id).then(({ data }) => {
+        form1.setFieldsValue(transformUpstreamDataFromRequest(data));
       });
     }
   }, []);
diff --git a/web/src/pages/Upstream/components/Step1.tsx b/web/src/pages/Upstream/components/Step1.tsx
index 182ffbc..40f3c31 100644
--- a/web/src/pages/Upstream/components/Step1.tsx
+++ b/web/src/pages/Upstream/components/Step1.tsx
@@ -19,7 +19,7 @@ import { Form, Input } from 'antd';
 import type { FormInstance } from 'antd/lib/form';
 import { useIntl } from 'umi';
 
-import UpstreamForm, { DEFAULT_UPSTREAM } from '@/components/Upstream';
+import UpstreamForm from '@/components/Upstream';
 import { fetchList } from '../service';
 
 type Props = {
@@ -38,7 +38,7 @@ const Step1: React.FC<Props> = ({ form, disabled, upstreamRef }) => {
 
   return (
     <>
-      <Form labelCol={{ span: 3 }} form={form} initialValues={DEFAULT_UPSTREAM}>
+      <Form labelCol={{ span: 3 }} form={form}>
         <Form.Item
           label={formatMessage({ id: 'page.upstream.step.name' })}
           name="name"
diff --git a/web/src/pages/Upstream/locales/en-US.ts b/web/src/pages/Upstream/locales/en-US.ts
index bc078e2..503c6cd 100644
--- a/web/src/pages/Upstream/locales/en-US.ts
+++ b/web/src/pages/Upstream/locales/en-US.ts
@@ -19,7 +19,6 @@ export default {
   'page.upstream.step.select.upstream.select.option': 'Custom',
   'page.upstream.form.item-label.node.domain.or.ip': 'Targets',
   'page.upstream.step.input.domain.name.or.ip': 'Please enter domain or IP',
-  'page.upstream.step.domain.name.or.ip.rule': 'Only letters, numbers and . are supported',
   'page.upstream.step.domain.name.or.ip': 'Hostname or IP',
   'page.upstream.step.input.port': 'Please enter port number',
   'page.upstream.step.port': 'Port',
@@ -54,18 +53,7 @@ export default {
   'page.upstream.step.healthyCheck.active': 'Active',
   'page.upstream.step.healthyCheck.active.timeout': 'Timeout',
   'page.upstream.step.input.healthyCheck.active.timeout': 'Please enter timeout',
-  'page.upstream.step.healthyCheck.active.http_path': 'HTTP Path',
-  'page.upstream.step.healthyCheck.activePort': 'Port',
-  'page.upstream.step.input.healthyCheck.activePort': 'Port',
-  'page.upstream.step.healthyCheck.activeHost': 'Host',
-  'page.upstream.step.input.healthyCheck.activeHost': 'Please enter HTTP Request Host',
-  'page.upstream.step.healthyCheck.activeInterval': 'Interval',
   'page.upstream.step.input.healthyCheck.activeInterval': 'Please enter interval',
-  'page.upstream.step.healthyCheck.successes': 'Successes',
-  'page.upstream.step.input.healthyCheck.successes': 'Please enter successes',
-  'page.upstream.step.healthyCheck.http_failures': 'HTTP Failures',
-  'page.upstream.step.input.healthyCheck.http_failures': 'Please enter http failures',
-  'page.upstream.step.healthyCheck.active.req_headers': 'Request Headers',
   'page.upstream.step.input.healthyCheck.active.req_headers': 'Please enter request headers',
   'page.upstream.step.healthyCheck.passive': 'Passive',
   'page.upstream.step.healthyCheck.passive.http_statuses': 'HTTP Status',
@@ -100,21 +88,13 @@ export default {
   'page.upstream.type.roundrobin': 'Round Robin',
   'page.upstream.type.chash': 'CHash',
   'page.upstream.type.ewma': 'EWMA',
+  'page.upstream.type.least_conn': 'Least conn',
 
   'page.upstream.list.content': 'The upstream list contains the created upstream services (i.e., backend services) and allows load balancing and health checking of multiple target nodes of the upstream services.',
 
-  'page.upstream.retries': 'Retries',
-
-  'page.upstream.checks.active.http_path.placeholder': 'Please enter HTTP request path',
-  'page.upstream.step.input.healthyCheck.active.http_path': 'Path to use in GET HTTP request to run on active checks',
   'page.upstream.checks.active.timeout.description': 'Socket timeout for active checks (in seconds)',
-  'page.upstream.checks.active.host.description': 'The hostname of the HTTP request used to perform the active health check',
-  'page.upstream.checks.active.healthy.interval.description': 'Interval between checks for healthy targets (in seconds)',
-  'page.upstream.checks.active.healthy.successes.description': 'Number of successes to consider a target healthy',
   'page.upstream.checks.active.unhealthy.interval.description': 'Interval between checks for unhealthy targets (in seconds)',
-  'page.upstream.checks.active.unhealthy.http_failures.description': 'Number of HTTP failures to consider a target unhealthy',
   'page.upstream.checks.passive.healthy.http_statuses.description': 'Which HTTP statuses to consider a failure',
-  'page.upstream.checks.passive.healthy.successes.description': 'Number of successes to consider a target healthy',
   'page.upstream.checks.passive.unhealthy.http_statuses.description': 'Which HTTP statuses to consider a success',
   'page.upstream.checks.passive.unhealthy.http_failures.description': 'Number of HTTP failures to consider a target unhealthy',
   'page.upstream.checks.passive.unhealthy.tcp_failures.description': 'Number of TCP failures to consider a target unhealthy',
diff --git a/web/src/pages/Upstream/locales/zh-CN.ts b/web/src/pages/Upstream/locales/zh-CN.ts
index 58620ba..7a0d648 100644
--- a/web/src/pages/Upstream/locales/zh-CN.ts
+++ b/web/src/pages/Upstream/locales/zh-CN.ts
@@ -19,9 +19,8 @@ export default {
   'page.upstream.step.select.upstream.select.option': '手动填写',
   'page.upstream.form.item-label.node.domain.or.ip': '目标节点',
   'page.upstream.step.input.domain.name.or.ip': '请输入域名或 IP',
-  'page.upstream.step.domain.name.or.ip.rule': '仅支持字母、数字和 . ',
   'page.upstream.step.domain.name.or.ip': '主机名或 IP',
-  'page.upstream.step.input.port': '请输入端口',
+  'page.upstream.step.input.port': '请输入',
   'page.upstream.step.port': '端口',
   'page.upstream.step.input.weight': '请输入权重',
   'page.upstream.step.weight': '权重',
@@ -33,10 +32,10 @@ export default {
   'page.upstream.step.input.description': '请输入上游服务的描述',
   'page.upstream.step.type': '负载均衡算法',
   'page.upstream.step.pass-host': 'Host 请求头',
-  'page.upstream.step.pass-host.pass': '保持与客户端请求一致的 Host 请求头',
-  'page.upstream.step.pass-host.node': '使用上游节点列表中的域名或 IP',
+  'page.upstream.step.pass-host.pass': '保持与客户端请求一致的主机名',
+  'page.upstream.step.pass-host.node': '使用上游节点列表中的主机名或 IP',
   'page.upstream.step.pass-host.rewrite': '自定义 Host 请求头(即将废弃)',
-  'page.upstream.step.pass-host.upstream_host': '自定义 Host 请求头',
+  'page.upstream.step.pass-host.upstream_host': '自定义主机名',
   'page.upstream.step.connect.timeout': '连接超时',
   'page.upstream.step.connect.timeout.desc': '建立从请求到上游服务器的连接的超时时间',
   'page.upstream.step.input.connect.timeout': '请输入连接超时时间',
@@ -54,18 +53,7 @@ export default {
   'page.upstream.step.healthyCheck.active': '主动检查',
   'page.upstream.step.healthyCheck.active.timeout': '超时时间',
   'page.upstream.step.input.healthyCheck.active.timeout': '请输入超时时间',
-  'page.upstream.step.healthyCheck.active.http_path': '路径',
-  'page.upstream.step.healthyCheck.activePort': '端口',
-  'page.upstream.step.input.healthyCheck.activePort': '端口',
-  'page.upstream.step.healthyCheck.activeHost': '域名',
-  'page.upstream.step.input.healthyCheck.activeHost': '请输入 HTTP 请求域名',
-  'page.upstream.step.healthyCheck.activeInterval': '间隔时间',
   'page.upstream.step.input.healthyCheck.activeInterval': '请输入间隔时间',
-  'page.upstream.step.healthyCheck.successes': '成功次数',
-  'page.upstream.step.input.healthyCheck.successes': '请输入成功次数',
-  'page.upstream.step.healthyCheck.http_failures': '失败次数',
-  'page.upstream.step.input.healthyCheck.http_failures': '请输入失败次数',
-  'page.upstream.step.healthyCheck.active.req_headers': '请求头',
   'page.upstream.step.input.healthyCheck.active.req_headers': '请输入请求头',
   'page.upstream.step.healthyCheck.passive': '被动检查',
   'page.upstream.step.healthyCheck.passive.http_statuses': '状态码',
@@ -97,24 +85,16 @@ export default {
   'page.upstream.list.input': '请输入',
   'page.upstream.list.create': '创建',
 
-  'page.upstream.type.roundrobin': '轮询调度(Round Robin)',
+  'page.upstream.type.roundrobin': '带权轮询(Round Robin)',
   'page.upstream.type.chash': '一致性哈希(CHash)',
   'page.upstream.type.ewma': '指数加权移动平均法(EWMA)',
+  'page.upstream.type.least_conn': '最小连接数(least_conn)',
 
   'page.upstream.list.content': '上游列表包含了已创建的上游服务(即后端服务),可以对上游服务的多个目标节点进行负载均衡和健康检查。',
 
-  'page.upstream.retries': '重试次数',
-
-  'page.upstream.checks.active.http_path.placeholder': '请输入 HTTP 请求路径',
-  'page.upstream.step.input.healthyCheck.active.http_path': '进行主动健康检查时使用的 HTTP 请求路径(默认为 /)',
   'page.upstream.checks.active.timeout.description': '主动健康检查的套接字的超时时间',
-  'page.upstream.checks.active.host.description': '进行主动健康检查时使用的 HTTP 请求主机名',
-  'page.upstream.checks.active.healthy.interval.description': '对健康的上游服务目标节点进行主动健康检查的间隔时间,默认值为0,表示对健康节点不进行主动健康检查。',
-  'page.upstream.checks.active.healthy.successes.description': '主动健康检查的 HTTP 成功次数,默认值为0。若达到此值,表示上游服务目标节点是健康的。',
   'page.upstream.checks.active.unhealthy.interval.description': '对不健康的上游服务目标节点进行主动健康检查的间隔时间,默认值为0,表示对不健康节点不进行主动健康检查。',
-  'page.upstream.checks.active.unhealthy.http_failures.description': '主动健康检查的 HTTP 失败次数,默认值为0。若达到此值,表示上游服务目标节点是不健康的。',
   'page.upstream.checks.passive.healthy.http_statuses.description': '当被动健康检查的探针返回值是 HTTP 状态码列表的某一个值时,代表健康状态是由代理流量产生的。',
-  'page.upstream.checks.passive.healthy.successes.description': '通过被动健康检查观察到的正常代理流量的成功次数。如果达到该值,上游服务目标节点将被视为健康。',
   'page.upstream.checks.passive.unhealthy.http_statuses.description': '当被动健康检查的探针返回值是 HTTP 状态码列表的某一个值时,代表不健康状态是由代理流量产生的。',
   'page.upstream.checks.passive.unhealthy.http_failures.description': '由被动健康检查所观察,代理流量中 HTTP 失败的次数。如果达到此值,则认为上游服务目标节点是不健康的。',
   'page.upstream.checks.passive.unhealthy.tcp_failures.description': '被动健康检查所观察到的代理流量中 TCP 失败的次数。如果达到此值,则认为上游服务目标节点是不健康的。',
diff --git a/web/src/pages/Upstream/transform.ts b/web/src/pages/Upstream/transform.ts
index efe0f17..0b520f2 100644
--- a/web/src/pages/Upstream/transform.ts
+++ b/web/src/pages/Upstream/transform.ts
@@ -20,6 +20,9 @@ export const transformRequest = (
   formData: UpstreamModule.RequestBody,
 ): UpstreamModule.RequestBody | undefined | { upstream_id: string } => {
   let data = pickBy(formData, identity) as UpstreamModule.RequestBody;
+
+  data = omit(data, 'custom')
+
   const {
     type,
     hash_on,
@@ -30,6 +33,7 @@ export const transformRequest = (
     upstream_host,
     upstream_id,
   } = data;
+
   data.checks = pickBy(data.checks || {}, identity);
   if (data.checks.active) {
     data.checks.active = pickBy(
diff --git a/web/src/pages/Upstream/typing.d.ts b/web/src/pages/Upstream/typing.d.ts
index 39ae372..a262ba1 100644
--- a/web/src/pages/Upstream/typing.d.ts
+++ b/web/src/pages/Upstream/typing.d.ts
@@ -79,6 +79,9 @@ declare namespace UpstreamModule {
     desc?: string;
     pass_host?: 'pass' | 'node' | 'rewrite';
     upstream_host: UpstreamHost[];
+
+    // Custom Fields that need to be omitted
+    custom?: {};
   };
 
   // TODO: typing