feat: show action logs of a zun container
Show action logs of a zun container Change-Id: Icd660776a220941b05511c4f2eef3547b7f952dc
This commit is contained in:
parent
4ccb380ff4
commit
88d877cde2
@ -71,6 +71,11 @@ export class ZunClient extends Base {
|
|||||||
{
|
{
|
||||||
key: 'stats',
|
key: 'stats',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'actions',
|
||||||
|
key: 'container_actions',
|
||||||
|
responseKey: 'containerAction',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
52
src/components/Popover/PopActionEvent.jsx
Normal file
52
src/components/Popover/PopActionEvent.jsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { getLocalTimeStr } from 'utils/time';
|
||||||
|
import IPopover from './Popover';
|
||||||
|
|
||||||
|
export default function PopActionEvent({ id, requestId, store, actionEvent }) {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: t('Operation Name'),
|
||||||
|
dataIndex: 'event',
|
||||||
|
key: 'event',
|
||||||
|
render: (value) => actionEvent[value] || value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Start Time'),
|
||||||
|
dataIndex: 'start_time',
|
||||||
|
key: 'start_time',
|
||||||
|
render: (value) => getLocalTimeStr(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('End Time'),
|
||||||
|
dataIndex: 'finish_time',
|
||||||
|
key: 'finish_time',
|
||||||
|
render: (value) => (value ? getLocalTimeStr(value) : '-'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Execution Result'),
|
||||||
|
dataIndex: 'result',
|
||||||
|
key: 'result',
|
||||||
|
render: (value) => (value === 'Success' ? t('Success') : '-'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const getData = async () => {
|
||||||
|
const detail = (await store.fetchDetail({ id, requestId })) || {};
|
||||||
|
const { events = [] } = detail;
|
||||||
|
return events.slice().reverse();
|
||||||
|
};
|
||||||
|
return <IPopover columns={columns} getData={getData} />;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import Base from 'containers/List';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import { ActionsLogStore } from 'src/stores/zun/action-log';
|
||||||
|
import { actionColumn } from 'resources/zun/actions';
|
||||||
|
|
||||||
|
export class ActionLogs extends Base {
|
||||||
|
init() {
|
||||||
|
this.store = new ActionsLogStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('Action Logs');
|
||||||
|
}
|
||||||
|
|
||||||
|
get policy() {
|
||||||
|
return 'container:actions';
|
||||||
|
}
|
||||||
|
|
||||||
|
getColumns = () => actionColumn(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(ActionLogs));
|
@ -16,6 +16,7 @@ import globalContainersStore from 'src/stores/zun/containers';
|
|||||||
import { containerStatus } from 'resources/zun/container';
|
import { containerStatus } from 'resources/zun/container';
|
||||||
import actionConfigs from '../actions';
|
import actionConfigs from '../actions';
|
||||||
import BaseDetail from './BaseDetail';
|
import BaseDetail from './BaseDetail';
|
||||||
|
import ActionLogs from './ActionLogs';
|
||||||
|
|
||||||
export class ContainerDetail extends Base {
|
export class ContainerDetail extends Base {
|
||||||
init() {
|
init() {
|
||||||
@ -62,6 +63,11 @@ export class ContainerDetail extends Base {
|
|||||||
key: 'general_info',
|
key: 'general_info',
|
||||||
component: BaseDetail,
|
component: BaseDetail,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('Action Logs'),
|
||||||
|
key: 'action_logs',
|
||||||
|
component: ActionLogs,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import ImageType from 'components/ImageType';
|
import ImageType from 'components/ImageType';
|
||||||
import { getLocalTimeStr } from 'utils/time';
|
import { Tag, Tooltip } from 'antd';
|
||||||
import { Table, Popover, Tag, Tooltip } from 'antd';
|
import { ActionLogStore } from 'stores/nova/action-log';
|
||||||
import globalActionLogStore from 'stores/nova/action-log';
|
|
||||||
import { ironicOriginEndpoint } from 'client/client/constants';
|
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||||
import { projectTagsColors } from 'src/utils/constants';
|
import { projectTagsColors } from 'src/utils/constants';
|
||||||
|
import PopActionEvent from 'src/components/Popover/PopActionEvent';
|
||||||
import lockSvg from 'asset/image/lock.svg';
|
import lockSvg from 'asset/image/lock.svg';
|
||||||
import unlockSvg from 'asset/image/unlock.svg';
|
import unlockSvg from 'asset/image/unlock.svg';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
@ -506,64 +505,6 @@ export const actionEvent = {
|
|||||||
compute_reboot_instance: t('Compute Reboot Instance'),
|
compute_reboot_instance: t('Compute Reboot Instance'),
|
||||||
};
|
};
|
||||||
|
|
||||||
function PopUpContent({ id, requestId }) {
|
|
||||||
const [event, setEvent] = useState([]);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let timeout = null;
|
|
||||||
(async function () {
|
|
||||||
setLoading(true);
|
|
||||||
const cb = await globalActionLogStore.fetchDetail({ id, requestId });
|
|
||||||
const { events = [] } = cb;
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
setLoading(false);
|
|
||||||
setEvent(events.slice().reverse());
|
|
||||||
}, 200);
|
|
||||||
})();
|
|
||||||
return () => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: t('Operation Name'),
|
|
||||||
dataIndex: 'event',
|
|
||||||
key: 'event',
|
|
||||||
render: (value) => actionEvent[value],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('Start Time'),
|
|
||||||
dataIndex: 'start_time',
|
|
||||||
key: 'start_time',
|
|
||||||
render: (value) => getLocalTimeStr(value),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('End Time'),
|
|
||||||
dataIndex: 'finish_time',
|
|
||||||
key: 'finish_time',
|
|
||||||
render: (value) => (value ? getLocalTimeStr(value) : '-'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('Execution Result'),
|
|
||||||
dataIndex: 'result',
|
|
||||||
key: 'result',
|
|
||||||
render: (value) => (value === 'Success' ? t('Success') : '-'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const table = (
|
|
||||||
<Table
|
|
||||||
columns={columns}
|
|
||||||
dataSource={event}
|
|
||||||
pagination={false}
|
|
||||||
loading={loading}
|
|
||||||
size="small"
|
|
||||||
rowKey="event"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const actionColumn = (self) => {
|
export const actionColumn = (self) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -586,20 +527,17 @@ export const actionColumn = (self) => {
|
|||||||
title: t('Request ID'),
|
title: t('Request ID'),
|
||||||
dataIndex: 'request_id',
|
dataIndex: 'request_id',
|
||||||
isHideable: true,
|
isHideable: true,
|
||||||
render: (value, record) => {
|
render: (value, record) => (
|
||||||
const content = (
|
<>
|
||||||
<PopUpContent id={record.instance_uuid} requestId={value} />
|
<span>{value}</span>
|
||||||
);
|
<PopActionEvent
|
||||||
return (
|
id={record.instance_uuid}
|
||||||
<>
|
requestId={value}
|
||||||
{value && (
|
store={new ActionLogStore()}
|
||||||
<Popover content={content} destroyTooltipOnHide trigger="click">
|
actionEvent={actionEvent}
|
||||||
<span className="link-class">{value}</span>
|
/>
|
||||||
</Popover>
|
</>
|
||||||
)}
|
),
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('User ID'),
|
title: t('User ID'),
|
||||||
|
90
src/resources/zun/actions.jsx
Normal file
90
src/resources/zun/actions.jsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { ActionsLogStore } from 'src/stores/zun/action-log';
|
||||||
|
import PopActionEvent from 'src/components/Popover/PopActionEvent';
|
||||||
|
|
||||||
|
export const actionEvent = {
|
||||||
|
compute__do_container_start: t('Start Container'),
|
||||||
|
compute__do_container_create: t('Create Container'),
|
||||||
|
compute__do_container_stop: t('Stop Container'),
|
||||||
|
compute__do_container_reboot: t('Reboot Container'),
|
||||||
|
compute__do_container_restart: t('Restart Container'),
|
||||||
|
compute__do_container_pause: t('Pause Container'),
|
||||||
|
compute__do_container_unpause: t('Unpause Container'),
|
||||||
|
compute__do_container_resize: t('Resize Container'),
|
||||||
|
compute__do_container_rebuild: t('Rebuild Container'),
|
||||||
|
compute__do_container_kill: t('Kill Container'),
|
||||||
|
compute__do_container_delete: t('Delete Container'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actionMap = {
|
||||||
|
create: t('Create'),
|
||||||
|
stop: t('Stop'),
|
||||||
|
reboot: t('Reboot'),
|
||||||
|
start: t('Start'),
|
||||||
|
restart: t('Restart'),
|
||||||
|
pause: t('Pause'),
|
||||||
|
unpause: t('Unpause'),
|
||||||
|
resize: t('Resize'),
|
||||||
|
rebuild: t('Rebuild'),
|
||||||
|
kill: t('Kill'),
|
||||||
|
delete: t('Delete'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actionColumn = (self) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t('Operation Name'),
|
||||||
|
dataIndex: 'action',
|
||||||
|
render: (value) => actionMap[value] || value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Project ID/Name'),
|
||||||
|
dataIndex: 'project_name',
|
||||||
|
isHideable: true,
|
||||||
|
hidden: !self.isAdminPage,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Operation Time'),
|
||||||
|
dataIndex: 'start_time',
|
||||||
|
valueRender: 'toLocalTimeMoment',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Request ID'),
|
||||||
|
dataIndex: 'request_id',
|
||||||
|
isHideable: true,
|
||||||
|
render: (value, record) => (
|
||||||
|
<>
|
||||||
|
<span>{value}</span>
|
||||||
|
<PopActionEvent
|
||||||
|
id={record.container_uuid}
|
||||||
|
requestId={value}
|
||||||
|
store={new ActionsLogStore()}
|
||||||
|
actionEvent={actionEvent}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('User ID'),
|
||||||
|
dataIndex: 'user_id',
|
||||||
|
isHideable: true,
|
||||||
|
hidden: !self.isAdminPage,
|
||||||
|
render: (value) =>
|
||||||
|
self.getLinkRender('userDetail', value, { id: value }, null),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
45
src/stores/zun/action-log.js
Normal file
45
src/stores/zun/action-log.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import Base from 'stores/base';
|
||||||
|
import client from 'client';
|
||||||
|
|
||||||
|
export class ActionsLogStore extends Base {
|
||||||
|
get client() {
|
||||||
|
return client.zun.containers.actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isSubResource() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get paramsFunc() {
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get mapper() {
|
||||||
|
return (data) => ({
|
||||||
|
...data,
|
||||||
|
id: data.request_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
detailFetchByClient(resourceParams) {
|
||||||
|
const { id, requestId } = resourceParams;
|
||||||
|
return this.client.show(id, requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalActionsLogStore = new ActionsLogStore();
|
||||||
|
export default globalActionsLogStore;
|
Loading…
Reference in New Issue
Block a user