fix: certificate expired change

1. Use metadata to instead of actual expired time
2. Delete disabled if the certificate was used for a listener

Change-Id: I8a16c4c1cc6f104c85835906405aba7ae9a3bf02
This commit is contained in:
xusongfu 2022-06-08 18:45:51 +08:00
parent d133705f6f
commit efaeac8453
10 changed files with 151 additions and 35 deletions

View File

@ -94,11 +94,29 @@ export class Certificate extends Base {
},
{
title: t('Domain Name'),
dataIndex: 'algorithm',
dataIndex: 'domain',
render: (value) => value || '-',
hidden: this.currentMode === 'CA',
isHideable: true,
},
{
title: t('Listener'),
dataIndex: 'listener',
render: (value) => {
return value
? this.getLinkRender(
'lbListenerDetail',
value.name,
{
loadBalancerId: value.lb,
id: value.id,
},
null
)
: '-';
},
isHideable: true,
},
{
title: t('Status'),
dataIndex: 'status',

View File

@ -15,7 +15,7 @@
import { inject, observer } from 'mobx-react';
import Base from 'containers/TabDetail';
import { ContainersStore } from 'stores/barbican/containers';
import { certificateColumns } from 'resources/octavia/lb';
import { getCertificateColumns } from 'resources/octavia/lb';
import BaseDetail from './BaseDetail';
import actionConfigs from '../../actions';
@ -41,7 +41,7 @@ export class Detail extends Base {
}
get detailInfos() {
return certificateColumns;
return getCertificateColumns(this);
}
get tabs() {

View File

@ -15,7 +15,7 @@
import { inject, observer } from 'mobx-react';
import Base from 'containers/TabDetail';
import { SecretsStore } from 'stores/barbican/secrets';
import { certificateColumns } from 'resources/octavia/lb';
import { getCertificateColumns } from 'resources/octavia/lb';
import BaseDetail from './BaseDetail';
import actionConfigs from '../../actions';
@ -41,7 +41,9 @@ export class Detail extends Base {
}
get detailInfos() {
return certificateColumns.filter((it) => it.dataIndex !== 'algorithm');
return getCertificateColumns(this).filter(
(it) => it.dataIndex !== 'domain'
);
}
get tabs() {

View File

@ -38,7 +38,7 @@ export default class DeleteAction extends ConfirmAction {
policy = ['barbican:secret:delete', 'barbican:container:delete'];
allowedCheckFunc = () => true;
allowedCheckFunc = (item) => !item.listener;
onSubmit = (data) => {
return globalContainersStore.delete(data);

View File

@ -38,7 +38,7 @@ export default class DeleteAction extends ConfirmAction {
policy = 'barbican:secret:delete';
allowedCheckFunc = () => true;
allowedCheckFunc = (item) => !item.listener;
onSubmit = (data) => {
return globalSecretsStore.delete(data);

View File

@ -18,7 +18,7 @@ import { ListenerStore } from 'stores/octavia/listener';
import { ContainersStore } from 'stores/barbican/containers';
import { SecretsStore } from 'stores/barbican/secrets';
import {
certificateColumns,
getCertificateColumns,
listenerProtocols,
sslParseMethod,
} from 'resources/octavia/lb';
@ -74,9 +74,7 @@ export class Create extends ModalAction {
}
get SNICertificate() {
return (this.containersStore.list.data || []).filter(
(it) => !!it.algorithm
);
return (this.containersStore.list.data || []).filter((it) => !!it.domain);
}
get isEdit() {
@ -140,7 +138,7 @@ export class Create extends ModalAction {
name: 'name',
},
],
columns: certificateColumns,
columns: getCertificateColumns(this),
display: protocol === 'TERMINATED_HTTPS',
},
{
@ -157,8 +155,8 @@ export class Create extends ModalAction {
name: 'name',
},
],
columns: certificateColumns.filter(
(it) => it.dataIndex !== 'algorithm'
columns: getCertificateColumns(this).filter(
(it) => it.dataIndex !== 'domain'
),
display:
protocol === 'TERMINATED_HTTPS' && ssl_parsing_method === 'two-way',
@ -183,7 +181,7 @@ export class Create extends ModalAction {
name: 'name',
},
],
columns: certificateColumns,
columns: getCertificateColumns(this),
display: protocol === 'TERMINATED_HTTPS' && sni_enabled,
},
{

View File

@ -15,7 +15,7 @@
import { inject, observer } from 'mobx-react';
import Base from 'components/Form';
import {
certificateColumns,
getCertificateColumns,
listenerProtocols,
sslParseMethod,
} from 'resources/octavia/lb';
@ -59,9 +59,7 @@ export class ListenerStep extends Base {
}
get SNISecrets() {
return (this.containersStore.list.data || []).filter(
(it) => !!it.algorithm
);
return (this.containersStore.list.data || []).filter((it) => !!it.domain);
}
get defaultValue() {
@ -135,7 +133,7 @@ export class ListenerStep extends Base {
name: 'name',
},
],
columns: certificateColumns,
columns: getCertificateColumns(this),
display: listener_protocol === 'TERMINATED_HTTPS',
},
{
@ -152,8 +150,8 @@ export class ListenerStep extends Base {
name: 'name',
},
],
columns: certificateColumns.filter(
(it) => it.dataIndex !== 'algorithm'
columns: getCertificateColumns(this).filter(
(it) => it.dataIndex !== 'domain'
),
display:
listener_protocol === 'TERMINATED_HTTPS' &&
@ -179,7 +177,7 @@ export class ListenerStep extends Base {
name: 'name',
},
],
columns: certificateColumns,
columns: getCertificateColumns(this),
display:
listener_protocol === 'TERMINATED_HTTPS' && listener_sni_enabled,
},

View File

@ -26,7 +26,7 @@ export const certificateStatus = {
ERROR: t('Error'),
};
export const certificateColumns = [
export const getCertificateColumns = (self) => [
{
title: t('Name'),
dataIndex: 'name',
@ -43,9 +43,26 @@ export const certificateColumns = [
},
{
title: t('Domain Name'),
dataIndex: 'algorithm',
dataIndex: 'domain',
render: (value) => value || '-',
},
{
title: t('Listener'),
dataIndex: 'listener',
render: (value) => {
return value
? self.getLinkRender(
'lbListenerDetail',
value.name,
{
loadBalancerId: value.lb,
id: value.id,
},
null
)
: '-';
},
},
{
title: t('Status'),
dataIndex: 'status',

View File

@ -16,6 +16,7 @@ import Base from 'stores/base';
import client from 'client';
import { action } from 'mobx';
import { SecretsStore } from './secrets';
import globalListenerStore from '../octavia/listener';
export class ContainersStore extends Base {
get client() {
@ -42,11 +43,14 @@ export class ContainersStore extends Base {
get mapper() {
return (data) => {
const { container_ref } = data;
const { container_ref, algorithm } = data;
const [, uuid] = container_ref.split('/containers/');
const { domain, expiration } = algorithm ? JSON.parse(algorithm) : {};
return {
...data,
id: uuid,
domain,
expiration,
};
};
}
@ -67,9 +71,32 @@ export class ContainersStore extends Base {
return data;
}
updateItem(item, listeners) {
const { container_ref } = item;
const enabledLs = listeners.find((ls) => {
const refs = [
ls.default_tls_container_ref,
ls.client_ca_tls_container_ref,
...ls.sni_container_refs,
];
return refs.includes(container_ref);
});
if (enabledLs) {
item.listener = {
id: enabledLs.id,
name: enabledLs.name,
lb: enabledLs.lbIds[0],
};
}
return item;
}
async listDidFetch(items) {
if (items.length === 0) return items;
const secrets = await this.secretStore.fetchList({ mode: 'SERVER' });
const [secrets, listeners] = await Promise.all([
this.secretStore.fetchList({ mode: 'SERVER' }),
globalListenerStore.fetchList(),
]);
const newItems = items.map((it) => {
const { secret_refs = [] } = it;
if (secret_refs.length === 0) {
@ -85,12 +112,13 @@ export class ContainersStore extends Base {
Object.assign(it, {
algorithm: theSecret.algorithm,
mode: theSecret.mode,
expiration: theSecret.expiration,
});
} else {
it.hidden = true;
}
});
// Determine if the certificate is used in the listener
this.updateItem(it, listeners);
}
return {
...it,
@ -101,7 +129,10 @@ export class ContainersStore extends Base {
async detailDidFetch(item) {
const { secret_refs = [] } = item;
const secrets = await this.secretStore.fetchList({ mode: 'SERVER' });
const [secrets, listeners] = await Promise.all([
this.secretStore.fetchList({ mode: 'SERVER' }),
globalListenerStore.fetchList(),
]);
const secretIds = [];
// Filter available secrets
secret_refs.forEach(async (secret) => {
@ -114,10 +145,11 @@ export class ContainersStore extends Base {
Object.assign(item, {
algorithm: theSecret.algorithm,
mode: theSecret.mode,
expiration: theSecret.expiration,
});
}
});
// Determine if the certificate is used in the listener
this.updateItem(item, listeners);
// Fetch secrets payload
const payloads = await Promise.all(
secretIds.map((id) =>
@ -138,8 +170,10 @@ export class ContainersStore extends Base {
mode: values.mode,
payload_content_type: 'text/plain',
secret_type: 'certificate',
algorithm: JSON.stringify({
domain: values.domain,
expiration: values.expiration,
algorithm: values.domain,
}),
};
const contentData = {
...commonData,

View File

@ -15,6 +15,7 @@
import Base from 'stores/base';
import client from 'client';
import { action } from 'mobx';
import globalListenerStore from '../octavia/listener';
export class SecretsStore extends Base {
get client() {
@ -42,11 +43,14 @@ export class SecretsStore extends Base {
get mapper() {
return (data) => {
const { secret_ref } = data;
const { secret_ref, algorithm } = data;
const [, uuid] = secret_ref.split('/secrets/');
const { domain, expiration } = algorithm ? JSON.parse(algorithm) : {};
return {
...data,
id: uuid,
domain,
expiration,
};
};
}
@ -67,25 +71,70 @@ export class SecretsStore extends Base {
return data;
}
updateItem(item, listeners) {
const { secret_ref } = item;
const enabledLs = listeners.find((ls) => {
const refs = [
ls.default_tls_container_ref,
ls.client_ca_tls_container_ref,
...ls.sni_container_refs,
];
return refs.includes(secret_ref);
});
if (enabledLs) {
item.listener = {
id: enabledLs.id,
name: enabledLs.name,
lb: enabledLs.lbIds[0],
};
}
return item;
}
@action
async fetchDetail({ id, silent }) {
if (!silent) {
this.isLoading = true;
}
const [item, payload] = await Promise.all([
const [item, payload, listeners] = await Promise.all([
this.client.show(id, {}, { headers: { Accept: 'application/json' } }),
this.payloadClient.list(id, {}, { headers: { Accept: 'text/plain' } }),
globalListenerStore.fetchList(),
]);
item.payload = payload;
// Determine if the certificate is used in the listener
this.updateItem(item, listeners);
const detail = this.mapper(item || {});
this.detail = detail;
this.isLoading = false;
return detail;
}
async listDidFetch(items) {
if (items.length === 0) return items;
const listeners = await globalListenerStore.fetchList();
return items.map((it) => {
// Determine if the certificate is used in the listener
this.updateItem(it, listeners);
return {
...it,
};
});
}
@action
async create(data) {
return this.client.create(data);
const { expiration, domain, algorithm, ...rest } = data;
const body = {
...rest,
algorithm:
algorithm ||
JSON.stringify({
domain,
expiration,
}),
};
return this.client.create(body);
}
}