feat: support insert_headers for listener
support insert_headers for lb's listener when creating lb, creating listener, editin listener Change-Id: Id9892add8545ec019413bff07ecbdffcfe3dc8d5
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Support insert_headers for lb's listener:
|
||||
|
||||
* Support set insert_headers for listener when creating lb.
|
||||
|
||||
* Support set insert_headers when creating lb's listener.
|
||||
|
||||
* Support update insert_headers when editing lb's listener.
|
||||
|
||||
* Support insert_headers card in the listener detail page.
|
@@ -603,6 +603,7 @@
|
||||
"Current Storage Backend": "Current Storage Backend",
|
||||
"Current data downloaded.": "Current data downloaded.",
|
||||
"Custom": "Custom",
|
||||
"Custom Headers": "Custom Headers",
|
||||
"Custom ICMP Rule": "Custom ICMP Rule",
|
||||
"Custom Metadata": "Custom Metadata",
|
||||
"Custom Properties Info": "Custom Properties Info",
|
||||
@@ -901,7 +902,7 @@
|
||||
"Enable Domain": "Enable Domain",
|
||||
"Enable Floating IP": "Enable Floating IP",
|
||||
"Enable Health Check": "Enable Health Check",
|
||||
"Enable HealthMonitor": "Enable HealthMonitor",
|
||||
"Enable Health Monitor": "Enable Health Monitor",
|
||||
"Enable Load Balancer": "Enable Load Balancer",
|
||||
"Enable Neutron Agent": "Enable Neutron Agent",
|
||||
"Enable Project": "Enable Project",
|
||||
@@ -1104,6 +1105,7 @@
|
||||
"Health Check Retries": "Health Check Retries",
|
||||
"Health Check Timeout": "Health Check Timeout",
|
||||
"Health Checking Log": "Health Checking Log",
|
||||
"Health Monitor": "Health Monitor",
|
||||
"Health Monitor Delay": "Health Monitor Delay",
|
||||
"Health Monitor Detail": "Health Monitor Detail",
|
||||
"Health Monitor Max Retries": "Health Monitor Max Retries",
|
||||
@@ -1111,7 +1113,6 @@
|
||||
"Health Monitor Timeout": "Health Monitor Timeout",
|
||||
"Health Monitor Type": "Health Monitor Type",
|
||||
"Health Status": "Health Status",
|
||||
"HealthMonitor": "HealthMonitor",
|
||||
"HealthMonitor Type": "HealthMonitor Type",
|
||||
"Healthy": "Healthy",
|
||||
"Heartbeat Timestamp": "Heartbeat Timestamp",
|
||||
@@ -2298,6 +2299,8 @@
|
||||
"Specification": "Specification",
|
||||
"Specify Physical Node": "Specify Physical Node",
|
||||
"Specify mount point.": "Specify mount point.",
|
||||
"Specify the client IP address": "Specify the client IP address",
|
||||
"Specify the listener port": "Specify the listener port",
|
||||
"Specify whether future replicated instances will be created on the same hypervisor (affinity) or on different hypervisors (anti-affinity). This value is ignored if the instance to be launched is a replica.": "Specify whether future replicated instances will be created on the same hypervisor (affinity) or on different hypervisors (anti-affinity). This value is ignored if the instance to be launched is a replica.",
|
||||
"Specs": "Specs",
|
||||
"Sri Lanka": "Sri Lanka",
|
||||
@@ -2483,6 +2486,7 @@
|
||||
"The number of allowed key pairs for each user.": "The number of allowed key pairs for each user.",
|
||||
"The number of vCPU cores should not exceed the maximum number of CPU cores of the physical node. Otherwise it will cause fail to schedule to any physical node when creating instance.": "The number of vCPU cores should not exceed the maximum number of CPU cores of the physical node. Otherwise it will cause fail to schedule to any physical node when creating instance.",
|
||||
"The number of virtual cpu for this container": "The number of virtual cpu for this container",
|
||||
"The optional headers to insert into the request before it is sent to the backend member.": "The optional headers to insert into the request before it is sent to the backend member.",
|
||||
"The password must not be the same as the previous": "The password must not be the same as the previous",
|
||||
"The password must not be the same as the previous two": "The password must not be the same as the previous two",
|
||||
"The password must not be the same as the previous {num}": "The password must not be the same as the previous {num}",
|
||||
|
@@ -603,6 +603,7 @@
|
||||
"Current Storage Backend": "현재 스토리지 백엔드",
|
||||
"Current data downloaded.": "현재 데이터가 다운로드되었습니다.",
|
||||
"Custom": "사용자 정의",
|
||||
"Custom Headers": "맞춤 헤더",
|
||||
"Custom ICMP Rule": "사용자 ICMP 규칙",
|
||||
"Custom Metadata": "사용자 정의 메타데이터",
|
||||
"Custom Properties Info": "사용자 정의 속성 정보",
|
||||
@@ -901,7 +902,7 @@
|
||||
"Enable Domain": "Domain 활성화",
|
||||
"Enable Floating IP": "Floating IP 활성화",
|
||||
"Enable Health Check": "Health Check 활성화",
|
||||
"Enable HealthMonitor": "HealthMonitor 활성화",
|
||||
"Enable Health Monitor": "Health Monitor 활성화",
|
||||
"Enable Load Balancer": "Load Balancer 활성화",
|
||||
"Enable Neutron Agent": "Neutron Agent 활성화",
|
||||
"Enable Project": "Project 활성화",
|
||||
@@ -1104,6 +1105,7 @@
|
||||
"Health Check Retries": "Health Check 재시도",
|
||||
"Health Check Timeout": "Health Check 타임아웃",
|
||||
"Health Checking Log": "Health Check 로그",
|
||||
"Health Monitor": "Health Monitor",
|
||||
"Health Monitor Delay": "Health Monitor 지연시간",
|
||||
"Health Monitor Detail": "Health Monitor 세부 정보",
|
||||
"Health Monitor Max Retries": "Health Monitor 최대 재시도 횟수",
|
||||
@@ -1111,7 +1113,6 @@
|
||||
"Health Monitor Timeout": "Health Monitor 타임아웃",
|
||||
"Health Monitor Type": "Health Monitor 타입",
|
||||
"Health Status": "",
|
||||
"HealthMonitor": "",
|
||||
"HealthMonitor Type": "HealthMonitor 타입",
|
||||
"Healthy": "정상",
|
||||
"Heartbeat Timestamp": "Heartbeat 타임스템프",
|
||||
@@ -2298,6 +2299,8 @@
|
||||
"Specification": "",
|
||||
"Specify Physical Node": "",
|
||||
"Specify mount point.": "",
|
||||
"Specify the client IP address": "클라이언트 IP 주소 지정",
|
||||
"Specify the listener port": "리스너 포트 지정",
|
||||
"Specify whether future replicated instances will be created on the same hypervisor (affinity) or on different hypervisors (anti-affinity). This value is ignored if the instance to be launched is a replica.": "",
|
||||
"Specs": "",
|
||||
"Sri Lanka": "",
|
||||
@@ -2483,6 +2486,7 @@
|
||||
"The number of allowed key pairs for each user.": "각 사용자별 허용되는 키 쌍(key pair) 수입니다.",
|
||||
"The number of vCPU cores should not exceed the maximum number of CPU cores of the physical node. Otherwise it will cause fail to schedule to any physical node when creating instance.": "vCPU 코어의 수는 물리적 노드의 최대 CPU 코어 수를 초과해서는 안 됩니다. 그렇지 않으면 인스턴스 생성 시 어떤 물리적 노드에도 스케줄링할 수 없는 문제가 발생합니다.",
|
||||
"The number of virtual cpu for this container": "이 컨테이너의 가상 CPU 수",
|
||||
"The optional headers to insert into the request before it is sent to the backend member.": "백엔드 멤버에게 전송되기 전에 요청에 삽입할 선택적 헤더입니다.",
|
||||
"The password must not be the same as the previous": "이전 비밀번호와 중복되지 않아야 합니다.",
|
||||
"The password must not be the same as the previous two": "이전 두 개의 비밀번호와 중복되지 않아야 합니다.",
|
||||
"The password must not be the same as the previous {num}": "이전 {num}개의 비밀번호와 중복되지 않아야 합니다.",
|
||||
|
@@ -603,6 +603,7 @@
|
||||
"Current Storage Backend": "当前存储后端",
|
||||
"Current data downloaded.": "当前数据已完成下载。",
|
||||
"Custom": "自定义",
|
||||
"Custom Headers": "自定义标头",
|
||||
"Custom ICMP Rule": "定制ICMP规则",
|
||||
"Custom Metadata": "自定义元数据",
|
||||
"Custom Properties Info": "自定义属性",
|
||||
@@ -901,7 +902,7 @@
|
||||
"Enable Domain": "启用域",
|
||||
"Enable Floating IP": "使用浮动IP",
|
||||
"Enable Health Check": "启用健康检查",
|
||||
"Enable HealthMonitor": "启用健康检查",
|
||||
"Enable Health Monitor": "启用健康检查",
|
||||
"Enable Load Balancer": "启用负载均衡",
|
||||
"Enable Neutron Agent": "启用网络服务",
|
||||
"Enable Project": "启用项目",
|
||||
@@ -1104,14 +1105,14 @@
|
||||
"Health Check Retries": "健康检查重试次数",
|
||||
"Health Check Timeout": "健康检查超时时间",
|
||||
"Health Checking Log": "健康检查日志",
|
||||
"Health Monitor": "健康检查器",
|
||||
"Health Monitor Delay": "检查间隔(秒)",
|
||||
"Health Monitor Detail": "健康检查器详情",
|
||||
"Health Monitor Max Retries": "最大重试次数",
|
||||
"Health Monitor Name": "名称",
|
||||
"Health Monitor Name": "健康检查器名称",
|
||||
"Health Monitor Timeout": "检查超时时间(秒)",
|
||||
"Health Monitor Type": "健康检查器类型",
|
||||
"Health Status": "健康状况",
|
||||
"HealthMonitor": "健康检查器",
|
||||
"HealthMonitor Type": "健康检查类型",
|
||||
"Healthy": "健康",
|
||||
"Heartbeat Timestamp": "心跳时间戳",
|
||||
@@ -2298,6 +2299,8 @@
|
||||
"Specification": "规格",
|
||||
"Specify Physical Node": "指定物理节点",
|
||||
"Specify mount point.": "指定挂载点",
|
||||
"Specify the client IP address": "指定客户端 IP 地址",
|
||||
"Specify the listener port": "指定监听器端口",
|
||||
"Specify whether future replicated instances will be created on the same hypervisor (affinity) or on different hypervisors (anti-affinity). This value is ignored if the instance to be launched is a replica.": "指定未来的复制实例是在相同的管理程序(亲和)上创建还是在不同的管理程序(反亲和)上创建。如果要启动的实例是副本,则忽略此值。",
|
||||
"Specs": "规格",
|
||||
"Sri Lanka": "斯里兰卡",
|
||||
@@ -2483,6 +2486,7 @@
|
||||
"The number of allowed key pairs for each user.": "每个用户允许创建的密钥数量",
|
||||
"The number of vCPU cores should not exceed the maximum number of CPU cores of the physical node. Otherwise it will cause fail to schedule to any physical node when creating instance.": "vCPU核数不应该超过物理节点的最大CPU核数,否则会导致云主机创建时无法调度到任何物理节点。",
|
||||
"The number of virtual cpu for this container": "容器的虚拟 CPU 数量",
|
||||
"The optional headers to insert into the request before it is sent to the backend member.": "在将请求发送到后端成员之前插入到请求中的可选标头。",
|
||||
"The password must not be the same as the previous": "新密码不能与以前的密码相同",
|
||||
"The password must not be the same as the previous two": "用户新密码不能与重置前的密码一致",
|
||||
"The password must not be the same as the previous {num}": "用户新密码不能与前{num}次密码相同",
|
||||
|
@@ -19,6 +19,8 @@ import { ContainersStore } from 'stores/barbican/containers';
|
||||
import { SecretsStore } from 'stores/barbican/secrets';
|
||||
import {
|
||||
getCertificateColumns,
|
||||
getInsertHeadersValueFromForm,
|
||||
getListenerInsertHeadersFormItem,
|
||||
listenerProtocols,
|
||||
sslParseMethod,
|
||||
} from 'resources/octavia/lb';
|
||||
@@ -96,6 +98,8 @@ export class Create extends ModalAction {
|
||||
get formItems() {
|
||||
const { protocol, ssl_parsing_method, sni_enabled } = this.state;
|
||||
|
||||
const insertHeaderFormItem = getListenerInsertHeadersFormItem();
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
@@ -199,6 +203,7 @@ export class Create extends ModalAction {
|
||||
extra: t('-1 means no connection limit'),
|
||||
required: true,
|
||||
},
|
||||
insertHeaderFormItem,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -209,12 +214,17 @@ export class Create extends ModalAction {
|
||||
default_tls_container_ref,
|
||||
client_ca_tls_container_ref,
|
||||
sni_container_refs,
|
||||
insert_headers,
|
||||
...rest
|
||||
} = values;
|
||||
const data = {
|
||||
...rest,
|
||||
loadbalancer_id: this.containerProps.detail.id,
|
||||
};
|
||||
const insertHeaders = getInsertHeadersValueFromForm(insert_headers);
|
||||
if (insertHeaders) {
|
||||
data.insert_headers = insertHeaders;
|
||||
}
|
||||
if (default_tls_container_ref) {
|
||||
data.default_tls_container_ref =
|
||||
default_tls_container_ref.selectedRows[0].container_ref;
|
||||
|
@@ -15,6 +15,10 @@
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import globalListenerStore from 'stores/octavia/listener';
|
||||
import globalLbaasStore from 'stores/octavia/loadbalancer';
|
||||
import {
|
||||
getInsertHeadersFormValueFromListener,
|
||||
getInsertHeadersValueFromForm,
|
||||
} from 'resources/octavia/lb';
|
||||
import { Create as Base } from './CreateListener';
|
||||
|
||||
export class Edit extends Base {
|
||||
@@ -53,6 +57,7 @@ export class Edit extends Base {
|
||||
protocol: item.protocol,
|
||||
protocol_port: item.protocol_port,
|
||||
connection_limit: item.connection_limit,
|
||||
insert_headers: getInsertHeadersFormValueFromListener(item),
|
||||
};
|
||||
if (item.protocol === 'TERMINATED_HTTPS') {
|
||||
if (item.default_tls_container_ref) {
|
||||
@@ -115,11 +120,16 @@ export class Edit extends Base {
|
||||
default_tls_container_ref,
|
||||
client_ca_tls_container_ref,
|
||||
sni_container_refs,
|
||||
insert_headers,
|
||||
...rest
|
||||
} = values;
|
||||
const data = {
|
||||
...rest,
|
||||
};
|
||||
const insertHeaders = getInsertHeadersValueFromForm(insert_headers);
|
||||
if (insertHeaders) {
|
||||
data.insert_headers = insertHeaders;
|
||||
}
|
||||
if (protocol === 'TERMINATED_HTTPS') {
|
||||
if (default_tls_container_ref) {
|
||||
data.default_tls_container_ref =
|
||||
|
@@ -122,7 +122,7 @@ export class EditHealthMonitor extends ModalAction {
|
||||
return [
|
||||
{
|
||||
name: 'admin_state_up',
|
||||
label: t('Enable HealthMonitor'),
|
||||
label: t('Enable Health Monitor'),
|
||||
type: 'radio',
|
||||
required: true,
|
||||
// onlyRadio: true,
|
||||
|
@@ -16,6 +16,8 @@ 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 'src/resources/octavia/lb';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
export class BaseDetail extends Base {
|
||||
componentDidMount() {
|
||||
@@ -43,7 +45,12 @@ export class BaseDetail extends Base {
|
||||
};
|
||||
|
||||
get leftCards() {
|
||||
return [this.PoolInfo, this.healthMonitor];
|
||||
const cards = [this.PoolInfo, this.healthMonitor];
|
||||
const { insert_headers = {} } = this.detailData;
|
||||
if (isEmpty(insert_headers)) {
|
||||
return cards;
|
||||
}
|
||||
return [...cards, this.customHeaders];
|
||||
}
|
||||
|
||||
get rightCards() {
|
||||
@@ -81,16 +88,21 @@ export class BaseDetail extends Base {
|
||||
};
|
||||
}
|
||||
|
||||
get customHeaders() {
|
||||
const { insert_headers = {} } = this.detailData || {};
|
||||
return getInsertHeaderCard(insert_headers || {});
|
||||
}
|
||||
|
||||
get healthMonitor() {
|
||||
const healthmonitor = this.healthmonitorStore.detail || {};
|
||||
const { admin_state_up, type, delay, timeout, max_retries } = healthmonitor;
|
||||
const options = [
|
||||
{
|
||||
label: t('Enable HealthMonitor'),
|
||||
label: t('Enable Health Monitor'),
|
||||
content: admin_state_up ? t('Yes') : t('No'),
|
||||
},
|
||||
{
|
||||
label: t('HealthMonitor Type'),
|
||||
label: t('Health Monitor Type'),
|
||||
content: admin_state_up ? type : '-',
|
||||
},
|
||||
{
|
||||
@@ -110,7 +122,7 @@ export class BaseDetail extends Base {
|
||||
options[0].content = '-';
|
||||
}
|
||||
return {
|
||||
title: t('HealthMonitor'),
|
||||
title: t('Health Monitor'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { StepAction } from 'containers/Action';
|
||||
import globalLbaasStore from 'stores/octavia/loadbalancer';
|
||||
import { getInsertHeadersValueFromForm } from 'resources/octavia/lb';
|
||||
import BaseStep from './BaseStep';
|
||||
import ListenerStep from '../../../StepCreateComponents/ListenerStep';
|
||||
import PoolStep from '../../../StepCreateComponents/PoolStep';
|
||||
@@ -93,6 +94,7 @@ export class StepCreate extends StepAction {
|
||||
listener_admin_state_up,
|
||||
pool_admin_state_up,
|
||||
monitor_admin_state_up,
|
||||
insert_headers,
|
||||
...rest
|
||||
} = values;
|
||||
const data = {
|
||||
@@ -112,6 +114,11 @@ export class StepCreate extends StepAction {
|
||||
protocol: listener_protocol,
|
||||
};
|
||||
|
||||
const insertHeaders = getInsertHeadersValueFromForm(insert_headers);
|
||||
if (insertHeaders) {
|
||||
listenerData.insert_headers = insertHeaders;
|
||||
}
|
||||
|
||||
if (listener_protocol === 'TERMINATED_HTTPS') {
|
||||
if (listener_default_tls_container_ref) {
|
||||
listenerData.default_tls_container_ref =
|
||||
|
@@ -48,12 +48,11 @@ export class HealthMonitorStep extends Base {
|
||||
allowed = () => Promise.resolve();
|
||||
|
||||
get formItems() {
|
||||
const {health_delay, enableHealthMonitor} =
|
||||
this.state;
|
||||
const { health_delay, enableHealthMonitor } = this.state;
|
||||
return [
|
||||
{
|
||||
name: 'enableHealthMonitor',
|
||||
label: t('Enable HealthMonitor'),
|
||||
label: t('Enable Health Monitor'),
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
|
@@ -16,6 +16,7 @@ import { inject, observer } from 'mobx-react';
|
||||
import Base from 'components/Form';
|
||||
import {
|
||||
getCertificateColumns,
|
||||
getListenerInsertHeadersFormItem,
|
||||
listenerProtocols,
|
||||
sslParseMethod,
|
||||
} from 'resources/octavia/lb';
|
||||
@@ -87,6 +88,8 @@ export class ListenerStep extends Base {
|
||||
listener_ssl_parsing_method,
|
||||
listener_sni_enabled,
|
||||
} = this.state;
|
||||
|
||||
const insertHeadersFormItem = getListenerInsertHeadersFormItem();
|
||||
return [
|
||||
{
|
||||
name: 'listener_name',
|
||||
@@ -202,6 +205,7 @@ export class ListenerStep extends Base {
|
||||
type: 'switch',
|
||||
tip: t('Defines the admin state of the listener.'),
|
||||
},
|
||||
insertHeadersFormItem,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { isEmpty } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
export const operatingStatusCodes = {
|
||||
@@ -154,3 +155,82 @@ export const healthProtocols = [
|
||||
value: 'UDP-CONNECT',
|
||||
},
|
||||
];
|
||||
|
||||
export const INSERT_HEADERS = {
|
||||
'X-Forwarded-For': t('Specify the client IP address'),
|
||||
'X-Forwarded-Port': t('Specify the listener port'),
|
||||
};
|
||||
|
||||
export const insertHeaderOptions = Object.keys(INSERT_HEADERS).map((key) => ({
|
||||
label: key,
|
||||
value: key,
|
||||
}));
|
||||
|
||||
export const insertHeaderTips = (
|
||||
<>
|
||||
{Object.keys(INSERT_HEADERS).map((key) => {
|
||||
return (
|
||||
<p key={key}>
|
||||
{key}: {INSERT_HEADERS[key]}
|
||||
</p>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
export const insertHeaderDesc = t(
|
||||
'The optional headers to insert into the request before it is sent to the backend member.'
|
||||
);
|
||||
|
||||
export const getListenerInsertHeadersFormItem = () => {
|
||||
return {
|
||||
name: 'insert_headers',
|
||||
label: t('Custom Headers'),
|
||||
type: 'check-group',
|
||||
extra: insertHeaderDesc,
|
||||
tip: insertHeaderTips,
|
||||
options: insertHeaderOptions,
|
||||
};
|
||||
};
|
||||
|
||||
export const getInsertHeadersValueFromForm = (values) => {
|
||||
if (!values) {
|
||||
return null;
|
||||
}
|
||||
const result = {};
|
||||
Object.keys(INSERT_HEADERS).forEach((key) => {
|
||||
if (values[key]) {
|
||||
result[key] = 'true';
|
||||
}
|
||||
});
|
||||
return isEmpty(result) ? null : result;
|
||||
};
|
||||
|
||||
export const getInsertHeadersFormValueFromListener = (listener) => {
|
||||
const { insert_headers } = listener || {};
|
||||
const result = {};
|
||||
Object.keys(INSERT_HEADERS).forEach((key) => {
|
||||
if (insert_headers[key]) {
|
||||
result[key] = insert_headers[key] === 'true';
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getInsertHeaderCard = (data) => {
|
||||
const options = [];
|
||||
Object.keys(INSERT_HEADERS).forEach((key) => {
|
||||
if (data[key]) {
|
||||
options.push({
|
||||
label: key,
|
||||
content: data[key],
|
||||
tooltip: INSERT_HEADERS[key],
|
||||
});
|
||||
}
|
||||
});
|
||||
return {
|
||||
title: t('Custom Headers'),
|
||||
titleHelp: insertHeaderDesc,
|
||||
options,
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user