feat: Update certificate
1. Add certificate id in listener 2. SNI certificate change to multiple select 3. TERMINATED_HTTPS change to HTTPS 4. Change validator of certificate content and keypair 5. Hide domain name if in CA certificate Change-Id: Id613f5c2c7795a477257ec5f71443378ac686007
This commit is contained in:
parent
eae1e27256
commit
1d5c1acb1f
@ -1069,7 +1069,7 @@
|
||||
"If OS is Linux, system will reset root password, if OS is Windows, system will reset Administrator password.": "如果操作系统是Linux,系统会修改root用户密码,如果是Windows,系统会修改Administrator用户密码。",
|
||||
"If an instance is using this flavor, deleting it will cause the instance's flavor data to be missing. Are you sure to delete {name}?": "若有云主机正在使用此 flavor,删除会导致云主机的 flavor 数据缺失,确定删除 {name} ?",
|
||||
"If checked, the network will be enable.": "如果选中,那么网络将被启用。",
|
||||
"If it is an SNI type certificate, a domain name needs to be specified": "如果是 SNI 类型证书,需制定域名",
|
||||
"If it is an SNI type certificate, a domain name needs to be specified": "如果是 SNI 类型证书,需指定域名",
|
||||
"If no gateway is specified, the first IP address will be defaulted.": "如果不指定网关IP,默认是第一个地址。",
|
||||
"If not provided, the roles assigned to the application credential will be the same as the roles in the current token.": "如果不选择,那么分配给应用凭证的角色将与当前用户的角色相同。",
|
||||
"If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.": "如果计算节点上的nova-compute被禁用,将禁止其作为目标节点。",
|
||||
|
@ -20,7 +20,6 @@ import globalContainersStore, {
|
||||
import { checkPolicyRule } from 'resources/skyline/policy';
|
||||
import globalSecretsStore, { SecretsStore } from 'stores/barbican/secrets';
|
||||
import { certificateMode, certificateStatus } from 'resources/octavia/lb';
|
||||
import { getOptions } from 'utils/index';
|
||||
import { parse } from 'qs';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
@ -90,16 +89,20 @@ export class Certificate extends Base {
|
||||
title: t('Certificate Type'),
|
||||
dataIndex: 'mode',
|
||||
render: (value) => certificateMode[value] || value,
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Expires At'),
|
||||
dataIndex: 'expiration',
|
||||
valueRender: 'toLocalTime',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Domain Name'),
|
||||
dataIndex: 'algorithm',
|
||||
render: (value) => value || '-',
|
||||
hidden: this.currentMode === 'CA',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
@ -110,6 +113,7 @@ export class Certificate extends Base {
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created',
|
||||
valueRender: 'toLocalTime',
|
||||
isHideable: true,
|
||||
},
|
||||
];
|
||||
return columns;
|
||||
@ -121,11 +125,6 @@ export class Certificate extends Base {
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
label: t('Certificate Type'),
|
||||
name: 'mode',
|
||||
options: getOptions(certificateMode),
|
||||
},
|
||||
];
|
||||
return ret;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ export class Detail extends Base {
|
||||
get tabs() {
|
||||
return [
|
||||
{
|
||||
title: t('Detail Info'),
|
||||
title: t('BaseDetail'),
|
||||
key: 'detail_info',
|
||||
component: BaseDetail,
|
||||
},
|
||||
|
@ -50,7 +50,7 @@ export class Detail extends Base {
|
||||
get tabs() {
|
||||
return [
|
||||
{
|
||||
title: t('Detail Info'),
|
||||
title: t('BaseDetail'),
|
||||
key: 'detail_info',
|
||||
component: BaseDetail,
|
||||
},
|
||||
|
@ -73,18 +73,11 @@ export class CreateAction extends ModalAction {
|
||||
validateCertificateContent = (rule, value) => {
|
||||
if (!value) return Promise.reject();
|
||||
const keys = value.split(/\n/g);
|
||||
const start = keys.shift();
|
||||
const end = keys.pop();
|
||||
const middleCorrect = keys.every((it, index) => {
|
||||
if (index === keys.length - 1) {
|
||||
return it.length <= 64;
|
||||
}
|
||||
return it.length === 64;
|
||||
});
|
||||
const start = keys[0];
|
||||
const end = keys[keys.length - 1] || keys[keys.length - 2]; // Compatible with last blank line
|
||||
if (
|
||||
start === '-----BEGIN CERTIFICATE-----' &&
|
||||
end === '-----END CERTIFICATE-----' &&
|
||||
middleCorrect
|
||||
end === '-----END CERTIFICATE-----'
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@ -98,18 +91,11 @@ export class CreateAction extends ModalAction {
|
||||
validateCertificateKeyPair = (rule, value) => {
|
||||
if (!value) return Promise.reject();
|
||||
const keys = value.split(/\n/g);
|
||||
const start = keys.shift();
|
||||
const end = keys.pop();
|
||||
const middleCorrect = keys.every((it, index) => {
|
||||
if (index === keys.length - 1) {
|
||||
return it.length <= 64;
|
||||
}
|
||||
return it.length === 64;
|
||||
});
|
||||
const start = keys[0];
|
||||
const end = keys[keys.length - 1] || keys[keys.length - 2];
|
||||
if (
|
||||
start === '-----BEGIN RSA PRIVATE KEY-----' &&
|
||||
end === '-----END RSA PRIVATE KEY-----' &&
|
||||
middleCorrect
|
||||
end === '-----END RSA PRIVATE KEY-----'
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -150,7 +150,9 @@ export class Create extends ModalAction {
|
||||
name: 'name',
|
||||
},
|
||||
],
|
||||
columns: certificateColumns,
|
||||
columns: certificateColumns.filter(
|
||||
(it) => it.dataIndex !== 'algorithm'
|
||||
),
|
||||
display:
|
||||
protocol === 'TERMINATED_HTTPS' && ssl_parsing_method === 'two-way',
|
||||
},
|
||||
@ -167,7 +169,7 @@ export class Create extends ModalAction {
|
||||
required: true,
|
||||
data: this.SNICertificate,
|
||||
isLoading: this.containersStore.list.isLoading,
|
||||
isMulti: false,
|
||||
isMulti: true,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
@ -217,9 +219,9 @@ export class Create extends ModalAction {
|
||||
data.client_authentication = 'MANDATORY';
|
||||
}
|
||||
if (sni_container_refs) {
|
||||
data.sni_container_refs = [
|
||||
sni_container_refs.selectedRows[0].container_ref,
|
||||
];
|
||||
data.sni_container_refs = sni_container_refs.selectedRows.map(
|
||||
(it) => it.container_ref
|
||||
);
|
||||
}
|
||||
return this.store.create(data);
|
||||
};
|
||||
|
@ -46,6 +46,10 @@ export class BaseDetail extends Base {
|
||||
return [this.PoolInfo, this.healthMonitor];
|
||||
}
|
||||
|
||||
get rightCards() {
|
||||
return [this.certificateInfo];
|
||||
}
|
||||
|
||||
get PoolInfo() {
|
||||
const { default_pool = {} } = this.detailData || {};
|
||||
const { name, protocol, lb_algorithm, description } = default_pool;
|
||||
@ -106,6 +110,67 @@ export class BaseDetail extends Base {
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get certificateInfo() {
|
||||
const options = [
|
||||
{
|
||||
label: t('Server Certificate'),
|
||||
dataIndex: 'serverCertificateId',
|
||||
render: (value) => {
|
||||
return value
|
||||
? this.getLinkRender(
|
||||
'certificateContainerDetail',
|
||||
value,
|
||||
{
|
||||
id: value,
|
||||
},
|
||||
null
|
||||
)
|
||||
: '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('CA Certificate'),
|
||||
dataIndex: 'caCertificateId',
|
||||
render: (value) => {
|
||||
return value
|
||||
? this.getLinkRender(
|
||||
'certificateSecretDetail',
|
||||
value,
|
||||
{
|
||||
id: value,
|
||||
},
|
||||
null
|
||||
)
|
||||
: '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('SNI Certificate'),
|
||||
dataIndex: 'sniCertificateId',
|
||||
render: (value) => {
|
||||
return value.length
|
||||
? value.map(
|
||||
(it, index) =>
|
||||
this.getLinkRender(
|
||||
'certificateContainerDetail',
|
||||
`${it}${index === value.length - 1 ? '' : ' , '}`,
|
||||
{
|
||||
id: it,
|
||||
}
|
||||
),
|
||||
null
|
||||
)
|
||||
: '-';
|
||||
},
|
||||
},
|
||||
];
|
||||
return {
|
||||
title: t('certificate'),
|
||||
options,
|
||||
labelCol: 4,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(BaseDetail));
|
||||
|
@ -120,9 +120,10 @@ export class StepCreate extends StepAction {
|
||||
listenerData.client_authentication = 'MANDATORY';
|
||||
}
|
||||
if (listener_sni_enabled && listener_sni_container_refs) {
|
||||
listenerData.sni_container_refs = [
|
||||
listener_sni_container_refs.selectedRows[0].container_ref,
|
||||
];
|
||||
listenerData.sni_container_refs =
|
||||
listener_sni_container_refs.selectedRows.map(
|
||||
(it) => it.container_ref
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,9 @@ export class ListenerStep extends Base {
|
||||
name: 'name',
|
||||
},
|
||||
],
|
||||
columns: certificateColumns,
|
||||
columns: certificateColumns.filter(
|
||||
(it) => it.dataIndex !== 'algorithm'
|
||||
),
|
||||
display:
|
||||
listener_protocol === 'TERMINATED_HTTPS' &&
|
||||
listener_ssl_parsing_method === 'two-way',
|
||||
@ -170,7 +172,7 @@ export class ListenerStep extends Base {
|
||||
required: true,
|
||||
data: this.SNISecrets,
|
||||
isLoading: false,
|
||||
isMulti: false,
|
||||
isMulti: true,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
|
@ -79,7 +79,7 @@ export const listenerProtocols = [
|
||||
value: 'TCP',
|
||||
},
|
||||
{
|
||||
label: 'TERMINATED_HTTPS',
|
||||
label: 'HTTPS',
|
||||
value: 'TERMINATED_HTTPS',
|
||||
},
|
||||
{
|
||||
|
@ -47,7 +47,23 @@ export class ListenerStore extends Base {
|
||||
// }
|
||||
|
||||
async detailDidFetch(item) {
|
||||
const { default_pool_id } = item;
|
||||
const {
|
||||
default_pool_id,
|
||||
default_tls_container_ref = '',
|
||||
client_ca_tls_container_ref = '',
|
||||
sni_container_refs = [],
|
||||
} = item;
|
||||
const [, serverId] = default_tls_container_ref.split('/containers/');
|
||||
const [, caId] = client_ca_tls_container_ref.split('/secrets/');
|
||||
const sniId = sni_container_refs.map((it) => {
|
||||
const [, ssid] = it.split('/containers/');
|
||||
return ssid;
|
||||
});
|
||||
Object.assign(item, {
|
||||
serverCertificateId: serverId,
|
||||
caCertificateId: caId,
|
||||
sniCertificateId: sniId,
|
||||
});
|
||||
if (default_pool_id) {
|
||||
// pool attach listener or loadbalancer ?
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user