feat: update edit health monitor

1. refactor listener detail and actions code to optimize requests
2. fix remove health monitor
3. hide admin_state_up form item when disable health monitor in the lb step create page
4. support updating admin_state_up when editing health monitor
5. support admin_state_up info in the health monitor card in the lisenter detail page

Change-Id: Id1a9c32ddae09b1ae3dfb613bd7468a372aa5478
This commit is contained in:
zhangjingwei 2023-11-15 10:47:27 +08:00
parent 73653da708
commit b2801a7913
14 changed files with 157 additions and 118 deletions

View File

@ -0,0 +1,10 @@
---
features:
- |
Update editing health monitor for load balancer:
* Fix remove health monitor.
* Support editing admin_state_up when editing health monitor.
* Support display admin_state_up info in the heath monitor info card in the listener detail page.

View File

@ -998,7 +998,6 @@
"Fingerprint": "Fingerprint",
"Finish Resize": "Finish Resize",
"Finland": "Finland",
"First time edit automatically creates health monitor When pool does not have a health monitor": "First time edit automatically creates health monitor When pool does not have a health monitor",
"Fixed IP": "Fixed IP",
"Fixed IP Address": "Fixed IP Address",
"Fixed IPs": "Fixed IPs",

View File

@ -998,7 +998,6 @@
"Fingerprint": "",
"Finish Resize": "Resize 완료",
"Finland": "",
"First time edit automatically creates health monitor When pool does not have a health monitor": "Pool에 Heath monitor가 없을 때 처음 편집하면 Heath monitor가 자동으로 생성됩니다.",
"Fixed IP": "고정 IP",
"Fixed IP Address": "고정 IP 주소",
"Fixed IPs": "고정 IP",

View File

@ -998,7 +998,6 @@
"Fingerprint": "指纹",
"Finish Resize": "完成调整",
"Finland": "芬兰",
"First time edit automatically creates health monitor When pool does not have a health monitor": "资源池无健康检查器时,首次编辑会自动创建健康检查器",
"Fixed IP": "内网IP",
"Fixed IP Address": "内网IP地址",
"Fixed IPs": "内网IP",

View File

@ -40,7 +40,8 @@ export class CreatePool extends ModalAction {
static policy = 'os_load-balancer_api:pool:post';
static allowed = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}

View File

@ -40,7 +40,8 @@ export default class DeleteAction extends ConfirmAction {
policy = 'os_load-balancer_api:listener:delete';
allowed = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}

View File

@ -40,7 +40,8 @@ export default class DeletePoolAction extends ConfirmAction {
policy = 'os_load-balancer_api:pool:delete';
allowedCheckFunc = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}

View File

@ -31,7 +31,8 @@ export class Edit extends Base {
static policy = 'os_load-balancer_api:listener:put';
static allowed = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}

View File

@ -20,14 +20,17 @@ import globalHealthMonitorStore, {
import { healthProtocols } from 'resources/octavia/lb';
import { PoolStore } from 'stores/octavia/pool';
import globalLbaasStore from 'stores/octavia/loadbalancer';
import { ListenerStore } from 'stores/octavia/listener';
export class EditHealthMonitor extends ModalAction {
init() {
this.store = new HealthMonitorStore();
this.listenerStore = new ListenerStore();
this.poolStore = new PoolStore();
this.state = {
defaultData: true,
admin_state_up: false,
enableHealthMonitor: false,
dataLoading: true,
healthMonitor: null,
};
}
@ -58,31 +61,40 @@ export class EditHealthMonitor extends ModalAction {
}
get defaultValue() {
const { operating_status, type, delay, timeout, max_retries } =
this.store.detail;
const { defaultData, admin_state_up } = this.state;
if (defaultData && operating_status && this.formRef.current) {
this.formRef.current.setFieldsValue({
admin_state_up,
operating_status,
type,
delay,
timeout,
max_retries,
});
this.setState({ defaultData: false });
const { healthMonitor } = this.state;
if (!healthMonitor) {
return {
delay: 5,
timeout: 3,
max_retries: 3,
enableHealthMonitor: false,
admin_state_up: true,
};
}
const {
admin_state_up,
operating_status,
type,
delay,
timeout,
max_retries,
} = healthMonitor;
return {
delay: 5,
timeout: 3,
max_retries: 3,
enableHealthMonitor: true,
admin_state_up,
operating_status,
type,
delay,
timeout,
max_retries,
};
}
static policy = 'os_load-balancer_api:healthmonitor:put';
static allowed = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}
@ -94,52 +106,45 @@ export class EditHealthMonitor extends ModalAction {
};
async getHealthMonitor() {
const { default_pool_id } = this.item;
const pool = await this.poolStore.fetchDetail({ id: default_pool_id });
const { healthmonitor_id } = pool;
if (healthmonitor_id) {
const { admin_state_up } = await this.store.fetchDetail({
id: healthmonitor_id,
});
this.setState({ admin_state_up });
this.formRef.current.setFieldsValue({ admin_state_up });
}
}
get tips() {
const { healthmonitor_id } = this.poolStore.detail || {};
if (!healthmonitor_id) {
return t(
'First time edit automatically creates health monitor When pool does not have a health monitor'
);
}
return '';
const detail = await this.listenerStore.fetchDetail(this.item);
const { healthMonitor } = detail;
this.setState(
{
healthMonitor,
enableHealthMonitor: !!healthMonitor,
dataLoading: false,
},
() => {
this.updateDefaultValue();
}
);
}
get formItems() {
const { admin_state_up } = this.state;
const { healthmonitor_id } = this.poolStore.detail || {};
const { enableHealthMonitor, dataLoading, healthMonitor } = this.state;
if (dataLoading) {
return [
{
name: 'loading',
type: 'loading',
},
];
}
return [
{
name: 'admin_state_up',
name: 'enableHealthMonitor',
label: t('Enable Health Monitor'),
type: 'radio',
required: true,
// onlyRadio: true,
// isWrappedValue: true,
options: [
{
label: t('Yes'),
value: true,
},
...(healthmonitor_id
? [
{
label: t('No'),
value: false,
},
]
: []),
{
label: t('No'),
value: false,
},
],
},
{
@ -147,9 +152,9 @@ export class EditHealthMonitor extends ModalAction {
label: t('HealthMonitor Type'),
type: 'select',
options: this.filteredProtocolOptions,
hidden: !admin_state_up && healthmonitor_id,
hidden: !enableHealthMonitor,
required: true,
disabled: !!healthmonitor_id,
disabled: !!healthMonitor,
},
{
name: 'delay',
@ -157,7 +162,7 @@ export class EditHealthMonitor extends ModalAction {
type: 'input-int',
min: 0,
extra: t('Maximum interval time for each health check response'),
hidden: !admin_state_up && healthmonitor_id,
hidden: !enableHealthMonitor,
required: true,
},
{
@ -168,7 +173,7 @@ export class EditHealthMonitor extends ModalAction {
extra: t(
'The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure'
),
hidden: !admin_state_up && healthmonitor_id,
hidden: !enableHealthMonitor,
required: true,
},
{
@ -179,21 +184,39 @@ export class EditHealthMonitor extends ModalAction {
extra: t(
'That is, after how many consecutive failures of the health check, the health check status of the back-end cloud server is changed from normal to abnormal'
),
hidden: !admin_state_up && healthmonitor_id,
hidden: !enableHealthMonitor,
required: true,
},
{
name: 'admin_state_up',
label: t('Admin State Up'),
type: 'switch',
tip: t('Defines the admin state of the health monitor.'),
hidden: !enableHealthMonitor,
},
];
}
onSubmit = (values) => {
const { default_pool_id } = this.item;
const { healthmonitor_id: id } = this.poolStore.detail || {};
const { healthMonitor } = this.state;
const { id } = healthMonitor || {};
const { enableHealthMonitor, type, ...others } = values;
if (id) {
const { type, ...others } = values;
if (!enableHealthMonitor) {
return globalHealthMonitorStore.delete({ id });
}
return globalHealthMonitorStore.edit({ id }, others);
}
values.pool_id = default_pool_id;
return globalHealthMonitorStore.create(values);
if (!enableHealthMonitor) {
return Promise.resolve();
}
const data = {
type,
...others,
pool_id: default_pool_id,
};
return globalHealthMonitorStore.create(data);
};
}

View File

@ -63,7 +63,8 @@ export class EditPoolInfo extends ModalAction {
static policy = 'os_load-balancer_api:pool:put';
static allowed = async (item, containerProps) => {
let { detail: lbDetail } = containerProps || {};
const { detail } = containerProps || {};
let lbDetail = item.loadBalancer || detail;
if (!lbDetail) {
lbDetail = await globalLbaasStore.pureFetchDetail(item.loadbalancers[0]);
}

View File

@ -13,38 +13,12 @@
// limitations under the License.
import { inject, observer } from 'mobx-react';
import globalListenerStore from 'stores/octavia/listener';
import Base from 'containers/BaseDetail';
import { HealthMonitorStore } from 'stores/octavia/health-monitor';
import { getInsertHeaderCard } from 'resources/octavia/lb';
import { isEmpty } from 'lodash';
import { algorithmDict } from 'resources/octavia/pool';
export class BaseDetail extends Base {
componentDidMount() {
this.fetchData();
const { default_pool: { healthmonitor_id } = {} } = this.detailData;
if (healthmonitor_id) {
this.fetchHealthMonitor();
}
}
get shouldFetchDetail() {
return true;
}
init() {
this.store = globalListenerStore;
this.healthmonitorStore = new HealthMonitorStore();
}
fetchHealthMonitor = async () => {
const {
default_pool: { healthmonitor_id },
} = this.detailData;
await this.healthmonitorStore.fetchDetail({ id: healthmonitor_id });
};
get leftCards() {
const cards = [this.PoolInfo, this.healthMonitor];
const { insert_headers = {} } = this.detailData;
@ -100,32 +74,39 @@ export class BaseDetail extends Base {
}
get healthMonitor() {
const healthmonitor = this.healthmonitorStore.detail || {};
const { admin_state_up, type, delay, timeout, max_retries } = healthmonitor;
const healthMonitor = this.detailData.healthMonitor || {};
const { type, delay, timeout, max_retries, admin_state_up } = healthMonitor;
const options = [
{
label: t('Enable Health Monitor'),
content: admin_state_up ? t('Yes') : t('No'),
},
{
label: t('Health Monitor Type'),
content: admin_state_up ? type : '-',
},
{
label: t('Delay Interval(s)'),
content: admin_state_up ? delay : '-',
},
{
label: t('Timeout(s)'),
content: admin_state_up ? timeout : '-',
},
{
label: t('Max Retries'),
content: admin_state_up ? max_retries : '-',
content: !isEmpty(healthMonitor) ? t('Yes') : t('No'),
},
];
if (Object.keys(healthmonitor).length === 0) {
options[0].content = '-';
if (!isEmpty(healthMonitor)) {
options.push(
...[
{
label: t('Health Monitor Type'),
content: type,
},
{
label: t('Delay Interval(s)'),
content: delay,
},
{
label: t('Timeout(s)'),
content: timeout,
},
{
label: t('Max Retries'),
content: max_retries,
},
{
label: t('Admin State Up'),
content: admin_state_up ? t('On') : t('Off'),
},
]
);
}
return {
title: t('Health Monitor'),

View File

@ -78,6 +78,10 @@ export class ListenerDetail extends Base {
];
}
get forceLoadingTabs() {
return ['detail'];
}
get tabs() {
const tabs = [
{

View File

@ -122,6 +122,7 @@ export class HealthMonitorStep extends Base {
label: t('Admin State Up'),
type: 'switch',
tip: t('Defines the admin state of the health monitor.'),
hidden: !enableHealthMonitor,
},
];
}

View File

@ -24,6 +24,14 @@ export class ListenerStore extends Base {
return client.octavia.pools;
}
get healthMonitorClient() {
return client.octavia.healthMonitors;
}
get lbClient() {
return client.octavia.loadbalancers;
}
get listFilterByProject() {
return true;
}
@ -66,11 +74,21 @@ export class ListenerStore extends Base {
caCertificateId: caId,
sniCertificateId: sniId,
});
const { loadbalancers = [] } = item;
const { loadbalancer } = await this.lbClient.show(loadbalancers[0].id);
item.loadBalancer = loadbalancer;
if (default_pool_id) {
// pool attach listener or loadbalancer
try {
const res = await this.poolClient.show(default_pool_id);
item.default_pool = res.pool;
const { pool } = await this.poolClient.show(default_pool_id);
item.default_pool = pool;
const { healthmonitor_id } = pool;
if (healthmonitor_id) {
const { healthmonitor } = await this.healthMonitorClient.show(
healthmonitor_id
);
item.healthMonitor = healthmonitor;
}
return item;
} catch (err) {
return item;