Merge "Add Zun UI to Skyline-Console"
This commit is contained in:
commit
4dc1baba0d
@ -33,6 +33,7 @@ export const endpointVersionMap = {
|
|||||||
trove: 'v1.0',
|
trove: 'v1.0',
|
||||||
manilav2: 'v2',
|
manilav2: 'v2',
|
||||||
barbican: 'v1',
|
barbican: 'v1',
|
||||||
|
zun: 'v1',
|
||||||
magnum : 'v1',
|
magnum : 'v1',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ export const swiftBase = () => getOpenstackEndpoint('swift');
|
|||||||
export const troveBase = () => getOpenstackEndpoint('trove');
|
export const troveBase = () => getOpenstackEndpoint('trove');
|
||||||
export const manilaBase = () => getOpenstackEndpoint('manilav2');
|
export const manilaBase = () => getOpenstackEndpoint('manilav2');
|
||||||
export const barbicanBase = () => getOpenstackEndpoint('barbican');
|
export const barbicanBase = () => getOpenstackEndpoint('barbican');
|
||||||
|
export const zunBase = () => getOpenstackEndpoint('zun');
|
||||||
export const magnumBase = () => getOpenstackEndpoint('magnum');
|
export const magnumBase = () => getOpenstackEndpoint('magnum');
|
||||||
|
|
||||||
export const ironicOriginEndpoint = () => getOriginEndpoint('ironic');
|
export const ironicOriginEndpoint = () => getOriginEndpoint('ironic');
|
||||||
|
@ -26,6 +26,7 @@ import swift from './swift';
|
|||||||
import trove from './trove';
|
import trove from './trove';
|
||||||
import manila from './manila';
|
import manila from './manila';
|
||||||
import barbican from './barbican';
|
import barbican from './barbican';
|
||||||
|
import zun from './zun';
|
||||||
import magnum from './magnum';
|
import magnum from './magnum';
|
||||||
|
|
||||||
const client = {
|
const client = {
|
||||||
@ -43,6 +44,7 @@ const client = {
|
|||||||
trove,
|
trove,
|
||||||
manila,
|
manila,
|
||||||
barbican,
|
barbican,
|
||||||
|
zun,
|
||||||
magnum
|
magnum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
62
src/client/zun/index.js
Normal file
62
src/client/zun/index.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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 { zunBase } from 'client/client/constants';
|
||||||
|
import Base from '../client/base';
|
||||||
|
|
||||||
|
class ZunClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return zunBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'capsules',
|
||||||
|
key: 'capsules',
|
||||||
|
responseKey: 'capsule',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'containers',
|
||||||
|
key: 'containers',
|
||||||
|
responseKey: 'container',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'start',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'stop',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'pause',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'reboot',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'unpause',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const zunClient = new ZunClient();
|
||||||
|
export default zunClient;
|
169
src/components/FormItem/ZunVolume/index.jsx
Normal file
169
src/components/FormItem/ZunVolume/index.jsx
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// 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 { Select, Row, Col, Form, Input } from 'antd';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import styles from './index.less';
|
||||||
|
import InputInt from '../InputInt';
|
||||||
|
|
||||||
|
export default class ZunVolume extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
value: PropTypes.any,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
type: [],
|
||||||
|
source: [],
|
||||||
|
destination: "",
|
||||||
|
cinderVolumeSize: 0,
|
||||||
|
isCinderVolume: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(nextProps, prevState) {
|
||||||
|
const { type, source, cinderVolumeSize, destination } = nextProps.value || {};
|
||||||
|
if (type !== prevState.type || source !== prevState.source || cinderVolumeSize !== prevState.cinderVolumeSize || destination !== prevState.destination) {
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
source,
|
||||||
|
cinderVolumeSize,
|
||||||
|
destination,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (value) => {
|
||||||
|
const { onChange } = this.props;
|
||||||
|
if (onChange) {
|
||||||
|
onChange(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onTypeChange = (value) => {
|
||||||
|
if (value === "cinder-new") {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
isCinderVolume: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (value === "cinder-available") {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
isCinderVolume: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.onChange({
|
||||||
|
...this.state,
|
||||||
|
type: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onSourceChange = (value) => {
|
||||||
|
this.onChange({
|
||||||
|
...this.state,
|
||||||
|
source: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onCinderVolumeSizeChange = (e) => {
|
||||||
|
this.onChange({
|
||||||
|
...this.state,
|
||||||
|
cinderVolumeSize: e
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onDestinationChange = (e) => {
|
||||||
|
this.onChange({
|
||||||
|
...this.state,
|
||||||
|
destination: e.target.value
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
source,
|
||||||
|
destination,
|
||||||
|
cinderVolumeSize,
|
||||||
|
isCinderVolume
|
||||||
|
} = this.state;
|
||||||
|
const { name } = this.props;
|
||||||
|
const selectType = (
|
||||||
|
<Select
|
||||||
|
value={type}
|
||||||
|
options={this.props.optionsType}
|
||||||
|
onChange={this.onTypeChange}
|
||||||
|
className={styles.select}
|
||||||
|
placeholder={t('Please select type')}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const selectSource = (
|
||||||
|
<Select
|
||||||
|
value={source}
|
||||||
|
options={this.props.optionsSource}
|
||||||
|
onChange={this.onSourceChange}
|
||||||
|
className={styles.select}
|
||||||
|
placeholder={t('Please select source')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const inputSize = (
|
||||||
|
<InputInt
|
||||||
|
value={cinderVolumeSize}
|
||||||
|
onChange={this.onCinderVolumeSizeChange}
|
||||||
|
style={{ maxWidth: '40%' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const inputDestination = (
|
||||||
|
<Input
|
||||||
|
value={destination}
|
||||||
|
onChange={this.onDestinationChange}
|
||||||
|
style={{ maxWidth: '60%' }}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
className={styles['zun-volume']}
|
||||||
|
name={name}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={8}>
|
||||||
|
<span className={styles.label}>{t('Type')}</span>
|
||||||
|
{selectType}
|
||||||
|
</Col>
|
||||||
|
<Col span={8} hidden={isCinderVolume}>
|
||||||
|
<span className={styles.label}>{t('Source')}</span>
|
||||||
|
{selectSource}
|
||||||
|
</Col>
|
||||||
|
<Col span={8} hidden={!isCinderVolume}>
|
||||||
|
<span className={styles.label}>{t('Size(GB)')}</span>
|
||||||
|
{inputSize}
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<span className={styles.label}>{t('Destination')}</span>
|
||||||
|
{inputDestination}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
13
src/components/FormItem/ZunVolume/index.less
Normal file
13
src/components/FormItem/ZunVolume/index.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.zun-volume {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-right: 10px;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
@ -582,11 +582,47 @@ const renderMenu = (t) => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/container-infra',
|
path: '/container',
|
||||||
name: t('Container Infra'),
|
name: t('Container'),
|
||||||
key: 'containerInfra',
|
key: 'container',
|
||||||
icon: <ContainerOutlined />,
|
icon: <ContainerOutlined />,
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: '/container/containers',
|
||||||
|
name: t('Containers'),
|
||||||
|
key: 'containers',
|
||||||
|
level: 1,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/container/containers/create',
|
||||||
|
name: t('Create Container'),
|
||||||
|
key: 'containersCreateContainer',
|
||||||
|
level: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: /^\/container\/containers\/detail\/.[^/]+$/,
|
||||||
|
name: t('Containers Detail'),
|
||||||
|
key: 'containersDetail',
|
||||||
|
level: 2,
|
||||||
|
routePath: '/container/containers/detail/:id',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/container/capsules',
|
||||||
|
name: t('Capsules'),
|
||||||
|
key: 'capsules',
|
||||||
|
level: 1,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: /^\/container\/capsules\/detail\/.[^/]+$/,
|
||||||
|
name: t('Capsules Detail'),
|
||||||
|
key: 'capsulesDetail',
|
||||||
|
level: 2,
|
||||||
|
routePath: '/container/capsules/detail/:id',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/container-infra/clusters',
|
path: '/container-infra/clusters',
|
||||||
name: t('Clusters'),
|
name: t('Clusters'),
|
||||||
|
@ -53,6 +53,9 @@ const Share = lazy(() =>
|
|||||||
const ContainerInfra = lazy(() =>
|
const ContainerInfra = lazy(() =>
|
||||||
import(/* webpackChunkName: "container-infra" */ 'pages/container-infra/App')
|
import(/* webpackChunkName: "container-infra" */ 'pages/container-infra/App')
|
||||||
);
|
);
|
||||||
|
const Containers = lazy(() =>
|
||||||
|
import(/* webpackChunkName: "Container" */ 'pages/container-service/App')
|
||||||
|
);
|
||||||
const E404 = lazy(() =>
|
const E404 = lazy(() =>
|
||||||
import(/* webpackChunkName: "E404" */ 'pages/base/containers/404')
|
import(/* webpackChunkName: "E404" */ 'pages/base/containers/404')
|
||||||
);
|
);
|
||||||
@ -109,6 +112,10 @@ export default [
|
|||||||
path: `/container-infra`,
|
path: `/container-infra`,
|
||||||
component: ContainerInfra,
|
component: ContainerInfra,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: `/container`,
|
||||||
|
component: Containers,
|
||||||
|
},
|
||||||
{ path: '*', component: E404 },
|
{ path: '*', component: E404 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
21
src/pages/container-service/App.jsx
Normal file
21
src/pages/container-service/App.jsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// 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 renderRoutes from 'utils/RouterConfig';
|
||||||
|
|
||||||
|
import routes from './routes';
|
||||||
|
|
||||||
|
const App = (props) => renderRoutes(routes, props);
|
||||||
|
|
||||||
|
export default App;
|
@ -0,0 +1,136 @@
|
|||||||
|
// 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/BaseDetail';
|
||||||
|
import React from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
|
||||||
|
export class BaseDetail extends Base {
|
||||||
|
get leftCards() {
|
||||||
|
const cards = [this.baseInfoCard, this.containersCard];
|
||||||
|
return cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rightCards() {
|
||||||
|
return [this.specCard];
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseInfoCard() {
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('ID'),
|
||||||
|
dataIndex: 'uuid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
dataIndex: 'meta_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status'),
|
||||||
|
dataIndex: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status Reason'),
|
||||||
|
dataIndex: 'status_reason',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Created'),
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Updated'),
|
||||||
|
dataIndex: 'updated_at',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Project ID'),
|
||||||
|
dataIndex: 'project_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('User ID'),
|
||||||
|
dataIndex: 'user_id',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Cluster Type'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get containersCard() {
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('Containers'),
|
||||||
|
dataIndex: 'containers',
|
||||||
|
render: (value) =>
|
||||||
|
value.map((it) => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<b>Name</b> : {it.name} <br /> <b>Container ID</b> : {it.uuid}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Containers'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get specCard() {
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('CPU'),
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Memory'),
|
||||||
|
dataIndex: 'memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Restart Policy'),
|
||||||
|
dataIndex: 'restart_policy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Labels'),
|
||||||
|
dataIndex: 'labels',
|
||||||
|
render: (value) => value || ' - ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Links'),
|
||||||
|
dataIndex: 'links',
|
||||||
|
render: (value) =>
|
||||||
|
value.map((it) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{it.href} : {it.rel}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Addresses'),
|
||||||
|
dataIndex: 'addresses',
|
||||||
|
render: (value) => (value.length != null ? value : '-'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Spec'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(BaseDetail))
|
@ -0,0 +1,57 @@
|
|||||||
|
// 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 { inject, observer } from 'mobx-react';
|
||||||
|
import Base from 'containers/TabDetail';
|
||||||
|
import BaseDetail from './BaseDetail';
|
||||||
|
import globalCapsulesStore from 'src/stores/zun/capsules';
|
||||||
|
|
||||||
|
export class CapsulesDetail extends Base {
|
||||||
|
init() {
|
||||||
|
this.store = globalCapsulesStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('Cluster Template Detail');
|
||||||
|
}
|
||||||
|
|
||||||
|
get listUrl() {
|
||||||
|
return this.getRoutePath('capsules');
|
||||||
|
}
|
||||||
|
|
||||||
|
get policy() {
|
||||||
|
return 'container:capsule:get_one_all_projects';
|
||||||
|
}
|
||||||
|
|
||||||
|
get detailInfos() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t('Name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get tabs() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t('General Info'),
|
||||||
|
key: 'general_info',
|
||||||
|
component: BaseDetail,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(CapsulesDetail))
|
@ -0,0 +1,79 @@
|
|||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Unles //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 { inject, observer } from 'mobx-react';
|
||||||
|
import { ModalAction } from 'src/containers/Action';
|
||||||
|
import { getYaml } from 'src/resources/heat/stack';
|
||||||
|
import globalCapsulesStore from 'src/stores/zun/capsules';
|
||||||
|
|
||||||
|
export class Create extends ModalAction {
|
||||||
|
static id = 'create-capsules';
|
||||||
|
|
||||||
|
static title = t('Create Capsule');
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.store = globalCapsulesStore;
|
||||||
|
this.maxSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static allowed = () => Promise.resolve(true);
|
||||||
|
|
||||||
|
static buttonText = t('Create Capsule');
|
||||||
|
|
||||||
|
static get modalSize() {
|
||||||
|
return 'middle';
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('Create Capsules');
|
||||||
|
}
|
||||||
|
|
||||||
|
static policy = 'container:capsule:create';
|
||||||
|
|
||||||
|
sizeValidate = (rule, value) => {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject(t('Please select a file'));
|
||||||
|
}
|
||||||
|
const { size } = value;
|
||||||
|
if (size <= this.maxSize * 1024 * 1024 * 1024) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return Promise.reject(
|
||||||
|
t(
|
||||||
|
'Please upload files smaller than { size }G on the page. It is recommended to upload files over { size }G using API.',
|
||||||
|
{ size: this.maxSize }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'template_file',
|
||||||
|
label: t('Load Template from a file'),
|
||||||
|
type: 'textarea-from-file',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit = (values) => {
|
||||||
|
const y = getYaml(values.template_file);
|
||||||
|
|
||||||
|
return this.store.create({
|
||||||
|
template: y,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(Create))
|
@ -0,0 +1,41 @@
|
|||||||
|
// 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 { inject, observer } from 'mobx-react';
|
||||||
|
import { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalCapsulesStore from 'src/stores/zun/capsules';
|
||||||
|
|
||||||
|
export class DeleteCapsules extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Delete Capsules');
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Delete Capsules');
|
||||||
|
}
|
||||||
|
|
||||||
|
get buttonType() {
|
||||||
|
return 'danger';
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:capsule:delete';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalCapsulesStore.delete({ id: data.uuid });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(DeleteCapsules))
|
@ -0,0 +1,25 @@
|
|||||||
|
// 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 Create from './Create';
|
||||||
|
import DeleteCapsules from './Delete';
|
||||||
|
|
||||||
|
const actionConfigs = {
|
||||||
|
rowActions: {
|
||||||
|
firstAction: DeleteCapsules,
|
||||||
|
},
|
||||||
|
batchActions: [DeleteCapsules],
|
||||||
|
primaryActions: [Create],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actionConfigs;
|
64
src/pages/container-service/containers/Capsules/index.jsx
Normal file
64
src/pages/container-service/containers/Capsules/index.jsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// 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 actionConfigs from './actions';
|
||||||
|
import globalCapsulesStore from 'src/stores/zun/capsules';
|
||||||
|
|
||||||
|
export class Capsules extends Base {
|
||||||
|
init() {
|
||||||
|
this.store = globalCapsulesStore;
|
||||||
|
this.downloadStore = globalCapsulesStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('capsules');
|
||||||
|
}
|
||||||
|
|
||||||
|
get policy() {
|
||||||
|
return 'container:capsule:get_all';
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionConfigs() {
|
||||||
|
return actionConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
getColumns = () => [
|
||||||
|
{
|
||||||
|
title: t('ID/Name'),
|
||||||
|
dataIndex: 'meta_name',
|
||||||
|
isLink: true,
|
||||||
|
routeName: this.getRouteName('capsulesDetail'),
|
||||||
|
idKey: 'uuid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Status'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('CPU'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Memory'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'memory',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(Capsules))
|
@ -0,0 +1,183 @@
|
|||||||
|
// 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/BaseDetail';
|
||||||
|
import React from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
|
||||||
|
export class BaseDetail extends Base {
|
||||||
|
get leftCards() {
|
||||||
|
const cards = [this.baseInfoCard, this.miscellaneousCard];
|
||||||
|
return cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rightCards() {
|
||||||
|
return [this.specCard];
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseInfoCard() {
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('ID'),
|
||||||
|
dataIndex: 'uuid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status'),
|
||||||
|
dataIndex: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status Detail'),
|
||||||
|
dataIndex: 'status_detail',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status Reason'),
|
||||||
|
dataIndex: 'status_reason',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Task State'),
|
||||||
|
dataIndex: 'task_state',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Command'),
|
||||||
|
dataIndex: 'command',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Base Info'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get miscellaneousCard() {
|
||||||
|
const content = (
|
||||||
|
<div>
|
||||||
|
<pre>{JSON.stringify(this.detailData.environment, null, 4)}</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('Host'),
|
||||||
|
dataIndex: 'host',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Workdir'),
|
||||||
|
dataIndex: 'workdir',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Environment'),
|
||||||
|
dataIndex: 'environment',
|
||||||
|
content
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Interactive'),
|
||||||
|
dataIndex: 'interactive',
|
||||||
|
valueRender: 'yesNo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Labels'),
|
||||||
|
dataIndex: 'labels',
|
||||||
|
render: (value) => value['cloud-shell'] || '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Links'),
|
||||||
|
dataIndex: 'links',
|
||||||
|
render: (value) => <div> <pre>{JSON.stringify(value, null, 4)}</pre> </div>
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Miscellaneous'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get specCard() {
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: t('Image'),
|
||||||
|
dataIndex: 'image',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Image Driver'),
|
||||||
|
dataIndex: 'image_driver',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Image Pull Policy'),
|
||||||
|
dataIndex: 'image_pull_policy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Hostname'),
|
||||||
|
dataIndex: 'hostname',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Runtime'),
|
||||||
|
dataIndex: 'runtime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('CPU'),
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Memory'),
|
||||||
|
dataIndex: 'memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Disk'),
|
||||||
|
dataIndex: 'disk',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Restart Policy'),
|
||||||
|
dataIndex: 'restart_policy',
|
||||||
|
render: (value) => <div> <pre>{JSON.stringify(value, null, 4)}</pre> </div>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Auto Remove'),
|
||||||
|
dataIndex: 'auto_remove',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Auto Heal'),
|
||||||
|
dataIndex: 'auto_heal',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Addresses'),
|
||||||
|
dataIndex: 'addresses',
|
||||||
|
render: (value) => <div> <pre>{JSON.stringify(value, null, 4)}</pre> </div>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Ports'),
|
||||||
|
dataIndex: 'ports',
|
||||||
|
render: (value) => <div> <pre>{JSON.stringify(value, null, 4)}</pre> </div>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Security Groups'),
|
||||||
|
dataIndex: 'security_groups',
|
||||||
|
render: (value) => <div> <pre>{JSON.stringify(value, null, 4)}</pre> </div>
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('Spec'),
|
||||||
|
labelCol: 4,
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(BaseDetail))
|
@ -0,0 +1,55 @@
|
|||||||
|
// 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 { inject, observer } from 'mobx-react';
|
||||||
|
import Base from 'containers/TabDetail';
|
||||||
|
import BaseDetail from './BaseDetail';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export class ContainersDetail extends Base {
|
||||||
|
init() {
|
||||||
|
this.store = globalContainersStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('Containers Detail');
|
||||||
|
}
|
||||||
|
|
||||||
|
get listUrl() {
|
||||||
|
return this.getRoutePath('containers');
|
||||||
|
}
|
||||||
|
|
||||||
|
get policy() {
|
||||||
|
return 'container:container:get_one';
|
||||||
|
}
|
||||||
|
|
||||||
|
get detailInfos() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t('Name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get tabs() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t('General Info'),
|
||||||
|
key: 'general_info',
|
||||||
|
component: BaseDetail,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(ContainersDetail))
|
@ -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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class DeleteContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Delete Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Delete Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
get buttonType() {
|
||||||
|
return 'danger';
|
||||||
|
}
|
||||||
|
|
||||||
|
get buttonText() {
|
||||||
|
return t('Delete');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:delete';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) =>
|
||||||
|
globalContainersStore.delete({ id: data.uuid });
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
// 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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class PauseContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'pause';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Pause Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Pause Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:pause';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalContainersStore.pause({ id: data.uuid });
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
// 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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class RebootContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'reboot';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Reboot Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Reboot Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:reboot';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalContainersStore.reboot({ id: data.uuid });
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
// 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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class StartContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'start';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Start Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Start Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:start';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalContainersStore.start({ id: data.uuid });
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
// 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 "components/Form";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
|
||||||
|
export class StepInfo extends Base {
|
||||||
|
get title() {
|
||||||
|
return t("Info")
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t("Info")
|
||||||
|
}
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "clusterName",
|
||||||
|
label: t("Cluster Name"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("Cluster Name"),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "image",
|
||||||
|
label: t("Image"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("Name or ID og the container image"),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "imageDriver",
|
||||||
|
label: t("Image Driver"),
|
||||||
|
placeholder: t("Image Driver"),
|
||||||
|
type: "select",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: t("Docker"),
|
||||||
|
value: "docker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("Glance"),
|
||||||
|
value: "glance"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
allowClear: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "command",
|
||||||
|
label: t("Command"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("A command that will be sent to the container"),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepInfo));
|
@ -0,0 +1,71 @@
|
|||||||
|
// 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 "components/Form";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import KeyValueInput from 'components/FormItem/KeyValueInput';
|
||||||
|
|
||||||
|
export class StepMiscellaneous extends Base {
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t("Miscellaneous")
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t("Miscellaneous")
|
||||||
|
}
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "workingDirectory",
|
||||||
|
label: t("Working Directory"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("The working directory for commands to run in")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "environmentVariables",
|
||||||
|
label: t("Environment Variables"),
|
||||||
|
type: 'add-select',
|
||||||
|
itemComponent: KeyValueInput,
|
||||||
|
addText: t('Add Environment Variable'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "enableInteractiveMode",
|
||||||
|
label: t("Enable interactive mode"),
|
||||||
|
type: "check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "divider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "labels",
|
||||||
|
label: t("Labels"),
|
||||||
|
type: 'add-select',
|
||||||
|
itemComponent: KeyValueInput,
|
||||||
|
addText: t('Add Label'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "divider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hints",
|
||||||
|
label: t("Scheduler Hints"),
|
||||||
|
type: "select",
|
||||||
|
mode: "tags",
|
||||||
|
placeholder: t("Type to Scheduler Hints and press enter")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepMiscellaneous));
|
@ -0,0 +1,80 @@
|
|||||||
|
// 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 { SecurityGroupStore } from 'stores/neutron/security-group';
|
||||||
|
import { VirtualAdapterStore } from 'stores/neutron/virtual-adapter';
|
||||||
|
import Base from "components/Form";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import globalNetworkStore from 'src/stores/neutron/network';
|
||||||
|
import { portColumns, portFilters } from 'src/resources/neutron/port';
|
||||||
|
import { securityGroupColumns, securityGroupFilter } from 'src/resources/neutron/security-group';
|
||||||
|
|
||||||
|
export class StepNetworks extends Base {
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.getNetworkStore();
|
||||||
|
this.portStore = new VirtualAdapterStore();
|
||||||
|
this.securityGroupStore = new SecurityGroupStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t("Networks")
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t("Networks")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getNetworkStore() {
|
||||||
|
await globalNetworkStore.fetchList({ project_id: this.currentProjectId });
|
||||||
|
}
|
||||||
|
|
||||||
|
get networking() {
|
||||||
|
return (globalNetworkStore.list.data || []).map((it) => ({
|
||||||
|
label: it.name,
|
||||||
|
value: it.id,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'networkSelect',
|
||||||
|
label: t('Networks'),
|
||||||
|
type: 'network-select-table',
|
||||||
|
isMulti: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ports',
|
||||||
|
type: 'select-table',
|
||||||
|
label: t('Ports'),
|
||||||
|
isMulti: true,
|
||||||
|
columns: portColumns,
|
||||||
|
filterParams: portFilters,
|
||||||
|
backendPageStore: this.portStore,
|
||||||
|
extraParams: { project_id: this.currentProjectId, device_owner: [''], admin_state_up: [true] }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'securityGroup',
|
||||||
|
label: t('Security Group'),
|
||||||
|
type: 'select-table',
|
||||||
|
backendPageStore: this.securityGroupStore,
|
||||||
|
extraParams: { project_id: this.currentProjectId },
|
||||||
|
columns: securityGroupColumns,
|
||||||
|
filterParams: securityGroupFilter,
|
||||||
|
isMulti: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepNetworks));
|
@ -0,0 +1,136 @@
|
|||||||
|
// 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 "components/Form";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import globalAvailabilityZoneStore from "src/stores/nova/zone";
|
||||||
|
|
||||||
|
export class StepSpec extends Base {
|
||||||
|
init() {
|
||||||
|
this.getAvailabilityZones();
|
||||||
|
this.state.isMaxRetry = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t("Spec");
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t("Spec");
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAvailabilityZones() {
|
||||||
|
await globalAvailabilityZoneStore.fetchListWithoutDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
get getAvailabilityZoneList() {
|
||||||
|
return (globalAvailabilityZoneStore.list.data || []).filter((it) => it.zoneState.available)
|
||||||
|
.map((it) => ({
|
||||||
|
value: it.zoneName,
|
||||||
|
label: it.zoneName,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
onExitPolicyChange(value) {
|
||||||
|
this.setState({ isMaxRetry: value === "on-failure" ? false : true })
|
||||||
|
}
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "hostname",
|
||||||
|
label: t("Hostname"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("The host name of this container"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "runtime",
|
||||||
|
label: t("Runtime"),
|
||||||
|
type: "input",
|
||||||
|
placeholder: t("The runtime to create container with"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cpu",
|
||||||
|
label: t("CPU"),
|
||||||
|
type: "input-number",
|
||||||
|
placeholder: t("The number of virtual cpu for this container"),
|
||||||
|
min: 1,
|
||||||
|
width: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "memory",
|
||||||
|
label: t("Memory"),
|
||||||
|
type: "input-number",
|
||||||
|
placeholder: t("The container memory size in MiB"),
|
||||||
|
min: 4,
|
||||||
|
width: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "disk",
|
||||||
|
label: t("Disk"),
|
||||||
|
type: "input-number",
|
||||||
|
placeholder: t("The disk size in GİB for per container"),
|
||||||
|
min: 1,
|
||||||
|
width: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "availableZone",
|
||||||
|
label: t("Availability Zone"),
|
||||||
|
type: "select",
|
||||||
|
options: this.getAvailabilityZoneList,
|
||||||
|
allowClear: true,
|
||||||
|
showSearch: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "exitPolicy",
|
||||||
|
label: t("Exit Policy"),
|
||||||
|
type: "select",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: t("No"),
|
||||||
|
value: "no"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("On failure"),
|
||||||
|
value: "on-failure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("Always"),
|
||||||
|
value: "always"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("Unless Stopped"),
|
||||||
|
value: "unless-stopped"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onChange: (val) => this.onExitPolicyChange(val),
|
||||||
|
allowClear: true,
|
||||||
|
showSearch: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "maxRetry",
|
||||||
|
label: t("Max Retry"),
|
||||||
|
type: "input-number",
|
||||||
|
placeholder: t("Retry times for 'Restart on failure' policy"),
|
||||||
|
min: 1,
|
||||||
|
disabled: this.state.isMaxRetry
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "enableAutoHeal",
|
||||||
|
label: t("Enable auto heal"),
|
||||||
|
type: "check"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepSpec));
|
@ -0,0 +1,52 @@
|
|||||||
|
// 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 "components/Form";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import ZunVolume from "src/components/FormItem/ZunVolume";
|
||||||
|
import globalVolumeStore from "src/stores/cinder/volume";
|
||||||
|
|
||||||
|
export class StepVolumes extends Base {
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.globalVolumeStore = globalVolumeStore;
|
||||||
|
this.getVolumeStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
get cinderVolume() {
|
||||||
|
return (this.globalVolumeStore.list.data || [])
|
||||||
|
.filter((it) => it.status === 'available')
|
||||||
|
.map((it) => ({
|
||||||
|
value: it.id,
|
||||||
|
label: it.name === '' ? it.id : it.name,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
getVolumeStore() {
|
||||||
|
this.globalVolumeStore.fetchList();
|
||||||
|
}
|
||||||
|
|
||||||
|
get formItems() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "mounts",
|
||||||
|
label: t("Type"),
|
||||||
|
type: 'add-select',
|
||||||
|
optionsType: [{ label: "Existing Cinder Volume", value: "cinder-available" }, { label: "New Cinder Volume", value: "cinder-new" }],
|
||||||
|
optionsSource: this.cinderVolume,
|
||||||
|
itemComponent: ZunVolume,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepVolumes));
|
@ -0,0 +1,153 @@
|
|||||||
|
// 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 StepInfo from './StepInfo';
|
||||||
|
import StepSpec from './StepSpec';
|
||||||
|
import StepVolumes from './StepVolumes';
|
||||||
|
import StepNetworks from './StepNetworks';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import StepMiscellaneous from './StepMiscellaneous';
|
||||||
|
import { StepAction } from 'src/containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export class StepCreate extends StepAction {
|
||||||
|
init() {
|
||||||
|
this.store = globalContainersStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
static id = "create-container";
|
||||||
|
|
||||||
|
static title = t("Create Container (Step)");
|
||||||
|
|
||||||
|
static path = "/container/containers/create";
|
||||||
|
|
||||||
|
static policy = "container:container:create";
|
||||||
|
|
||||||
|
static allowed() {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t("Create Container");
|
||||||
|
}
|
||||||
|
|
||||||
|
get listUrl() {
|
||||||
|
return this.getRoutePath("containers");
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasConfirmStep() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get steps() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t("Info"),
|
||||||
|
component: StepInfo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("Spec"),
|
||||||
|
component: StepSpec
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("Volumes"),
|
||||||
|
component: StepVolumes
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("Network Config"),
|
||||||
|
component: StepNetworks
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("Miscellaneous"),
|
||||||
|
component: StepMiscellaneous
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit = (values) => {
|
||||||
|
const { environmentVariables, labels, mounts } = values
|
||||||
|
|
||||||
|
const requestEnviranment = {};
|
||||||
|
const requestLabels = {};
|
||||||
|
const requestValumes = [];
|
||||||
|
|
||||||
|
environmentVariables !== null ? environmentVariables.forEach((item) => {
|
||||||
|
const labelKey = item.value.key.toLowerCase().trim();
|
||||||
|
const labelValue = item.value.value.toLowerCase().trim();
|
||||||
|
requestEnviranment[labelKey] = labelValue;
|
||||||
|
}) : null;
|
||||||
|
|
||||||
|
labels !== null ? labels.forEach((item) => {
|
||||||
|
const key = item.value.key.toLowerCase().trim();
|
||||||
|
const value = item.value.value.toLowerCase().trim();
|
||||||
|
requestLabels[key] = value;
|
||||||
|
}) : null;
|
||||||
|
|
||||||
|
mounts !== null ? mounts.forEach((item) => {
|
||||||
|
const destination = item.value.destination;
|
||||||
|
const source = item.value.source;
|
||||||
|
const type = item.value.type;
|
||||||
|
const cinderVolumeSize = item.value.cinderVolumeSize;
|
||||||
|
item.value.isCinderVolume !== true ? requestValumes.push({
|
||||||
|
destination: destination,
|
||||||
|
source: source,
|
||||||
|
type: type
|
||||||
|
}) : requestValumes.push({
|
||||||
|
destination: destination,
|
||||||
|
cinderVolumeSize: cinderVolumeSize,
|
||||||
|
type: type
|
||||||
|
})
|
||||||
|
}) : null;
|
||||||
|
|
||||||
|
const networks = [];
|
||||||
|
const securityGroups = [];
|
||||||
|
|
||||||
|
values.networkSelect.selectedRowKeys.forEach((item) => {
|
||||||
|
networks.push({ network: item })
|
||||||
|
})
|
||||||
|
|
||||||
|
values.ports.selectedRowKeys.forEach((item) => {
|
||||||
|
networks.push({ port: item })
|
||||||
|
})
|
||||||
|
|
||||||
|
values.securityGroup.selectedRowKeys.forEach((item) => {
|
||||||
|
securityGroups.push(item)
|
||||||
|
})
|
||||||
|
|
||||||
|
return this.store.create({
|
||||||
|
name: values.clusterName,
|
||||||
|
image: values.image,
|
||||||
|
command: values.command,
|
||||||
|
cpu: values.cpu,
|
||||||
|
memory: values.memory,
|
||||||
|
workdir: values.workingDirectory,
|
||||||
|
labels: requestLabels,
|
||||||
|
environment: requestEnviranment,
|
||||||
|
restart_policy: {
|
||||||
|
Name: values.exitPolicy === null ? 'no' : values.exitPolicy,
|
||||||
|
MaximumRetryCount: values.maxRetry === null ? 0 : values.maxRetry,
|
||||||
|
},
|
||||||
|
interactive: values.enableInteractiveMode,
|
||||||
|
image_driver: values.imageDriver,
|
||||||
|
security_groups: securityGroups,
|
||||||
|
nets: networks,
|
||||||
|
runtime: values.runtime,
|
||||||
|
hostname: values.hostname,
|
||||||
|
auto_heal: values.enableAutoHeal,
|
||||||
|
availability_zone: values.availableZone,
|
||||||
|
hints: values.hints,
|
||||||
|
mounts: values.mounts,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('rootStore')(observer(StepCreate));
|
@ -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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class StopContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'start';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Stop Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Stop Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:stop';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalContainersStore.stop({ id: data.uuid });
|
||||||
|
}
|
@ -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 { ConfirmAction } from 'containers/Action';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export default class UnpauseContainers extends ConfirmAction {
|
||||||
|
get id() {
|
||||||
|
return 'Unpause';
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return t('Unpause Container')
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionName() {
|
||||||
|
return t('Unpause Container');
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = 'container:container:unpause';
|
||||||
|
|
||||||
|
allowedCheckFunc = () => true;
|
||||||
|
|
||||||
|
onSubmit = (data) => globalContainersStore.unpause({ id: data.uuid });
|
||||||
|
}
|
@ -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 CreateStep from './StepCreate';
|
||||||
|
import DeleteContainer from './Delete';
|
||||||
|
import PauseContainer from './Pause';
|
||||||
|
import RebootContainer from './Reboot';
|
||||||
|
import StartContainer from './Start';
|
||||||
|
import StopContainer from './Stop';
|
||||||
|
import UnpauseContainer from './Unpause';
|
||||||
|
|
||||||
|
const actionConfigs = {
|
||||||
|
rowActions: {
|
||||||
|
moreActions: [
|
||||||
|
{ action: StartContainer },
|
||||||
|
{ action: DeleteContainer },
|
||||||
|
{ action: StopContainer },
|
||||||
|
{ action: PauseContainer },
|
||||||
|
{ action: RebootContainer },
|
||||||
|
{ action: UnpauseContainer },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
batchActions: [DeleteContainer],
|
||||||
|
primaryActions: [CreateStep],
|
||||||
|
};
|
||||||
|
export default actionConfigs;
|
68
src/pages/container-service/containers/Containers/index.jsx
Normal file
68
src/pages/container-service/containers/Containers/index.jsx
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// 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 actionConfigs from './actions';
|
||||||
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
|
|
||||||
|
export class Containers extends Base {
|
||||||
|
init() {
|
||||||
|
this.store = globalContainersStore;
|
||||||
|
this.downloadStore = globalContainersStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return t('containers');
|
||||||
|
}
|
||||||
|
|
||||||
|
get policy() {
|
||||||
|
return 'container:container:get_all';
|
||||||
|
}
|
||||||
|
|
||||||
|
get actionConfigs() {
|
||||||
|
return actionConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rowKey() {
|
||||||
|
return 'uuid';
|
||||||
|
}
|
||||||
|
|
||||||
|
getColumns = () => [
|
||||||
|
{
|
||||||
|
title: t('ID/Name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
isLink: true,
|
||||||
|
routeName: this.getRouteName('containerDetail'),
|
||||||
|
idKey: 'uuid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Status'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Image'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'image',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Task State'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'task_state',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject("rootStore")(observer(Containers))
|
51
src/pages/container-service/routes/index.js
Normal file
51
src/pages/container-service/routes/index.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// 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 BaseLayout from 'layouts/Basic';
|
||||||
|
import E404 from 'pages/base/containers/404';
|
||||||
|
import Containers from '../containers/Containers';
|
||||||
|
import Capsules from '../containers/Capsules';
|
||||||
|
import ContainersDetail from '../containers/Containers/Detail';
|
||||||
|
import CapsulesDetail from '../containers/Capsules/Detail';
|
||||||
|
import StepCreateContainer from '../containers/Containers/actions/StepCreate';
|
||||||
|
|
||||||
|
const PATH = '/container';
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
path: PATH,
|
||||||
|
component: BaseLayout,
|
||||||
|
routes: [
|
||||||
|
// Containers
|
||||||
|
{ path: `${PATH}/containers`, component: Containers, exact: true },
|
||||||
|
{ path: `${PATH}/containers/create`, component: StepCreateContainer, exact: true },
|
||||||
|
{
|
||||||
|
path: `${PATH}/containers/detail/:id`,
|
||||||
|
component: ContainersDetail,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `${PATH}/capsules`,
|
||||||
|
component: Capsules,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `${PATH}/capsules/detail/:id`,
|
||||||
|
component: CapsulesDetail,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
// All
|
||||||
|
{ path: '*', component: E404 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
36
src/stores/zun/capsules.js
Normal file
36
src/stores/zun/capsules.js
Normal file
@ -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 'stores/base';
|
||||||
|
import client from 'client';
|
||||||
|
import { action } from 'mobx';
|
||||||
|
|
||||||
|
export class CapsulesStore extends Base {
|
||||||
|
get client() {
|
||||||
|
return client.zun.capsules;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async create(newbody) {
|
||||||
|
return this.client.create(newbody);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async delete({ id }) {
|
||||||
|
return this.client.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalCapsulesStore = new CapsulesStore();
|
||||||
|
export default globalCapsulesStore;
|
61
src/stores/zun/containers.js
Normal file
61
src/stores/zun/containers.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// 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';
|
||||||
|
import { action } from 'mobx';
|
||||||
|
|
||||||
|
export class ContainersStore extends Base {
|
||||||
|
get client() {
|
||||||
|
return client.zun.containers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async create(newbody) {
|
||||||
|
return this.submitting(this.client.create(newbody));
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async delete({ id }) {
|
||||||
|
return this.client.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async start({ id }) {
|
||||||
|
return this.client.start(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async stop({ id }) {
|
||||||
|
return this.client.stop(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async pause({ id }) {
|
||||||
|
return this.client.pause(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async reboot({ id }) {
|
||||||
|
return this.client.reboot(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async unpause({ id }) {
|
||||||
|
return this.client.unpause(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalContainersStore = new ContainersStore();
|
||||||
|
export default globalContainersStore;
|
Loading…
x
Reference in New Issue
Block a user