feature: support ip address, ports and networks in list and detail

1. show ip address, ports and networks in zun containers list
2. show ip address and subnets into zun containers detail

Change-Id: Ic53c2eb28ad392736d0f78b23eafd13e4c5d88dd
This commit is contained in:
xusongfu 2023-01-11 16:27:49 +08:00
parent 317a81acc4
commit a347c373a4
5 changed files with 114 additions and 27 deletions

View File

@ -1025,7 +1025,7 @@
"Gibraltar": "直布罗陀",
"Given IP": "指定IP",
"Glance": "",
"Glance Image": "本地镜像(Glance)",
"Glance Image": "本地镜像",
"Global Setting": "平台配置",
"GlusterFS": "",
"Grant Databases Access": "设置数据库访问",

View File

@ -19,6 +19,7 @@ import {
containerStatus,
imageDrivers,
exitPolicies,
containerTaskStatus,
} from 'resources/zun/container';
import { stringifyContent } from 'utils/content';
import { isEmpty } from 'lodash';
@ -67,6 +68,7 @@ export class BaseDetail extends Base {
{
label: t('Task State'),
dataIndex: 'task_state',
valueMap: containerTaskStatus,
},
];
@ -202,6 +204,19 @@ export class BaseDetail extends Base {
dataIndex: 'addresses',
render: stringifyContent,
},
{
label: t('IP Address'),
dataIndex: 'addrs',
render: (value = []) => (
<>
{value.length
? value.map((it) => {
return <div key={it.addr}>{it.addr}</div>;
})
: '-'}
</>
),
},
{
label: t('Networks'),
dataIndex: 'networks',
@ -218,6 +233,23 @@ export class BaseDetail extends Base {
</>
),
},
{
label: t('Subnets'),
dataIndex: 'subnets',
render: (value = []) => (
<>
{value.length
? value.map((it) => {
const link = this.getLinkRender('subnetDetail', it.subnet, {
networkId: it.network,
id: it.subnet,
});
return <div key={it.subnet}>{link}</div>;
})
: '-'}
</>
),
},
{
label: t('Ports'),
dataIndex: 'ports',
@ -225,10 +257,7 @@ export class BaseDetail extends Base {
<>
{value.length
? value.map((it) => {
const link = this.getLinkRender('portDetail', it, {
id: it,
});
return <div key={it}>{link}</div>;
return <div key={it}>{it}</div>;
})
: '-'}
</>

View File

@ -51,7 +51,7 @@ export class ContainerDetail extends Base {
dataIndex: 'name',
},
{
title: t('Status'),
title: t('Container Status'),
dataIndex: 'status',
valueMap: containerStatus,
},

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import React from 'react';
import Base from 'containers/List';
import { inject, observer } from 'mobx-react';
import globalContainersStore from 'src/stores/zun/containers';
@ -60,7 +61,52 @@ export class Containers extends Base {
valueMap: imageDrivers,
},
{
title: t('Status'),
title: t('IP Address'),
isHideable: true,
dataIndex: 'addrs',
render: (value = []) => (
<>
{value.length
? value.map((it) => {
return <div key={it.addr}>{it.addr}</div>;
})
: '-'}
</>
),
},
{
title: t('Ports'),
isHideable: true,
dataIndex: 'ports',
render: (value = []) => (
<>
{value.length
? value.map((it) => {
return <div key={it}>{it}</div>;
})
: '-'}
</>
),
},
{
title: t('Networks'),
isHideable: true,
dataIndex: 'networks',
render: (value = []) => (
<>
{value.length
? value.map((it) => {
const link = this.getLinkRender('networkDetail', it, {
id: it,
});
return <div key={it}>{link}</div>;
})
: '-'}
</>
),
},
{
title: t('Container Status'),
isHideable: true,
dataIndex: 'status',
valueMap: containerStatus,
@ -80,6 +126,11 @@ export class Containers extends Base {
label: t('Name'),
name: 'name',
},
{
label: t('Image Driver'),
name: 'image_driver',
options: getOptions(imageDrivers),
},
{
label: t('Status'),
name: 'status',

View File

@ -15,7 +15,6 @@
import Base from 'stores/base';
import client from 'client';
import { action } from 'mobx';
import { isEmpty } from 'lodash';
export class ContainersStore extends Base {
get client() {
@ -27,11 +26,27 @@ export class ContainersStore extends Base {
}
get mapper() {
return (data) => ({
...data,
id: data.uuid,
task_state: data.task_state === null ? 'free' : data.task_state,
});
return (data) => {
const { addresses = {} } = data;
const networks = Object.keys(addresses);
const addrs = [];
const subnets = [];
Object.entries(addresses).forEach(([key, val]) => {
(val || []).forEach((v) => {
addrs.push({ network: key, addr: v.addr });
subnets.push({ network: key, subnet: v.subnet_id });
});
});
return {
...data,
id: data.uuid,
task_state: data.task_state === null ? 'free' : data.task_state,
networks,
addrs,
subnets,
};
};
}
@action
@ -90,26 +105,18 @@ export class ContainersStore extends Base {
}
async detailDidFetch(item) {
const { uuid, status, addresses = {}, image_driver, image } = item;
const { uuid, status, image_driver, image } = item;
let stats = {};
if (status === 'Running') {
stats = (await this.client.stats.list(uuid)) || {};
}
const networks = Object.keys(addresses);
let { ports = [] } = item;
if (isEmpty(ports)) {
ports = Object.values(addresses)
.reduce((ret, cur) => {
ret = ret.concat(cur);
return ret;
}, [])
.map((it) => it.port);
}
if (image_driver === 'glance') {
const info = await this.imageClient.show(image);
item.imageInfo = info;
try {
const info = await this.imageClient.show(image);
item.imageInfo = info;
} catch (error) {}
}
return { ...item, stats, networks, ports };
return { ...item, stats };
}
async fetchLogs(id) {