forked from JointCloud/JCC-RIP
kubex 20210123
This commit is contained in:
parent
8c7630daa2
commit
a872acc16c
|
@ -2,4 +2,4 @@
|
|||
ENV = 'development'
|
||||
|
||||
# base api
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
VUE_APP_BASE_API = '/'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "vue-element-admin",
|
||||
"name": "kubex",
|
||||
"version": "4.4.0",
|
||||
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||
"author": "Pan <panfree23@gmail.com>",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import request from '@/utils/request'
|
||||
const qs = require('qs')
|
||||
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/vue-element-admin/user/login',
|
||||
url: '/oauth/token',
|
||||
method: 'post',
|
||||
data
|
||||
data: qs.stringify(data)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ export default {
|
|||
const first = matched[0]
|
||||
|
||||
if (!this.isDashboard(first)) {
|
||||
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
|
||||
matched = [{ path: '/', meta: { title: 'KUBEX' }}].concat(matched)
|
||||
}
|
||||
|
||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<el-card class="chartCard" style="height: 150px">
|
||||
<el-table style="padding:20px 0" :data="clusterMessage">
|
||||
<el-table-column prop="agent" label="服务商" width="140" />
|
||||
<el-table-column prop="version" label="KubeX版本" width="140" />
|
||||
<el-table-column prop="visible" label="集群可见性" width="140" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ClusterMessage',
|
||||
data() {
|
||||
return {
|
||||
clusterMessage: [
|
||||
{ agent: 'KubeX', version: 'v0.1', visible: '部分可见' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-table::before{
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<el-card class="chartCard" style="height: 150px">
|
||||
<el-table style="padding:20px 0" :data="componentStatus">
|
||||
<el-table-column prop="apiRequest" label="API每秒请求数" width="140" />
|
||||
<el-table-column prop="delay" label="API请求延迟" width="140" />
|
||||
<el-table-column prop="schedulerTimes" label="调度器调度次数" width="140" />
|
||||
<el-table-column prop="schedulingPods" label="调度失败的容器组" width="140" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ComponentStatus',
|
||||
data() {
|
||||
return {
|
||||
componentStatus: [
|
||||
{
|
||||
apiRequest: '15.483 times/s',
|
||||
delay: '2.41 ms',
|
||||
schedulerTimes: '71',
|
||||
schedulingPods: '2'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<el-card class="chartCard">
|
||||
<el-table style="padding:20px 0" :data="nodeMessage">
|
||||
<el-table-column prop="node" label="节点" width="200" />
|
||||
<el-table-column prop="CPU" label="CPU使用率" width="120" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NodeMessage',
|
||||
data() {
|
||||
return {
|
||||
nodeMessage: [
|
||||
{ node: 'master 192.168.12.10', CPU: '16%' },
|
||||
{ node: 'node1 192.168.12.11', CPU: '12%' },
|
||||
{ node: 'node2 192.168.12.12', CPU: '7%' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<el-card class="chartCard">
|
||||
<p>节点详细信息</p>
|
||||
<el-table :data="nodeStatus">
|
||||
<el-table-column prop="name" label="名称" width="140" />
|
||||
<el-table-column prop="status" label="状态" width="140" />
|
||||
<el-table-column prop="role" label="角色" width="140" />
|
||||
<el-table-column prop="cpu" label="CPU" width="140" />
|
||||
<el-table-column prop="ram" label="内存" width="140" />
|
||||
<el-table-column prop="pod" label="Pods" width="140" />
|
||||
<el-table-column prop="allocatedCPU" label="已分配CPU" width="180" />
|
||||
<el-table-column prop="allocatedRAM" label="已分配内存" width="180s" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NodeStatus',
|
||||
data() {
|
||||
return {
|
||||
nodeStatus: [
|
||||
{
|
||||
name: 'master', status: '运行中', role: 'master, worker', cpu: '17%', ram: '48%', pod: '50%', allocatedCPU: '2.877 Core (79%)', allocatedRAM: '2.177 Gi (30%)'
|
||||
},
|
||||
{
|
||||
name: 'node1', status: '运行中', role: 'worker', cpu: '13%', ram: '31%', pod: '25%', allocatedCPU: '1.612 Core (44%)', allocatedRAM: '2.06 Gi (29%)'
|
||||
},
|
||||
{
|
||||
name: 'node2', status: '运行中', role: 'worker', cpu: '9%', ram: '50%', pod: '23%', allocatedCPU: '1.752 Core (48%)', allocatedRAM: '4.703 Gi (66%)'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<el-card class="chartCard" style="height: 450px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-col :span="6" class="center">
|
||||
<el-progress type="circle" :percentage="80" style="width:130px;margin-top: 20px" />
|
||||
</el-col>
|
||||
<el-col :span="18" class="center">
|
||||
<el-card style="height: 75px;margin-top: 10px;padding:10px">
|
||||
<el-col :span="6">
|
||||
<el-progress type="circle" :percentage="12" :width="75" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-col :span="8">
|
||||
<p>12%</p>
|
||||
<p>CPU</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>1.49 core</p>
|
||||
<p>已使用</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>12 core</p>
|
||||
<p>总计</p>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card style="height: 75px;margin-top: 10px;padding:10px">
|
||||
<el-col :span="6">
|
||||
<el-progress type="circle" :percentage="39" :width="75" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-col :span="8">
|
||||
<p>39%</p>
|
||||
<p>内存</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>9.18 Gi</p>
|
||||
<p>已使用</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>23.39 Gi</p>
|
||||
<p>总计</p>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card style="height: 75px;margin-top: 10px;padding:10px">
|
||||
<el-col :span="6">
|
||||
<el-progress type="circle" :percentage="31" :width="75" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-col :span="8">
|
||||
<p>31%</p>
|
||||
<p>Pods</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>102</p>
|
||||
<p>已使用</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>330</p>
|
||||
<p>总计</p>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card style="height: 75px;margin-top: 10px;padding:10px">
|
||||
<el-col :span="6">
|
||||
<el-progress type="circle" :percentage="86" :width="75" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-col :span="8">
|
||||
<p>86%</p>
|
||||
<p>本地存储</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>54.12 GB</p>
|
||||
<p>已使用</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<p>63 GB</p>
|
||||
<p>总计</p>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ResourceUsage'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -28,10 +28,10 @@ import * as filters from './filters' // global filters
|
|||
* Currently MockJs will be used in the production environment,
|
||||
* please remove it before going online ! ! !
|
||||
*/
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const { mockXHR } = require('../mock')
|
||||
mockXHR()
|
||||
}
|
||||
// if (process.env.NODE_ENV !== 'production') {
|
||||
// const { mockXHR } = require('../mock')
|
||||
// mockXHR()
|
||||
// }
|
||||
|
||||
Vue.use(Element, {
|
||||
size: Cookies.get('size') || 'small' // set element-ui default size
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import router from './router'
|
||||
import store from './store'
|
||||
import { Message } from 'element-ui'
|
||||
// import store from './store'
|
||||
// import { Message } from 'element-ui'
|
||||
import NProgress from 'nprogress' // progress bar
|
||||
import 'nprogress/nprogress.css' // progress bar style
|
||||
import { getToken } from '@/utils/auth' // get token from cookie
|
||||
|
@ -26,33 +26,34 @@ router.beforeEach(async(to, from, next) => {
|
|||
next({ path: '/' })
|
||||
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
|
||||
} else {
|
||||
// determine whether the user has obtained his permission roles through getInfo
|
||||
const hasRoles = store.getters.roles && store.getters.roles.length > 0
|
||||
if (hasRoles) {
|
||||
next()
|
||||
} else {
|
||||
try {
|
||||
// get user info
|
||||
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
|
||||
const { roles } = await store.dispatch('user/getInfo')
|
||||
// determine whether the user has obtained his permission roles through getInfo
|
||||
// const hasRoles = store.getters.roles && store.getters.roles.length > 0
|
||||
// if (hasRoles) {
|
||||
// next()
|
||||
// } else {
|
||||
// try {
|
||||
// // get user info
|
||||
// // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
|
||||
// const { roles } = await store.dispatch('user/getInfo')
|
||||
|
||||
// generate accessible routes map based on roles
|
||||
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
|
||||
// // generate accessible routes map based on roles
|
||||
// const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
|
||||
|
||||
// dynamically add accessible routes
|
||||
router.addRoutes(accessRoutes)
|
||||
// // dynamically add accessible routes
|
||||
// router.addRoutes(accessRoutes)
|
||||
|
||||
// hack method to ensure that addRoutes is complete
|
||||
// set the replace: true, so the navigation will not leave a history record
|
||||
next({ ...to, replace: true })
|
||||
} catch (error) {
|
||||
// remove token and go to login page to re-login
|
||||
await store.dispatch('user/resetToken')
|
||||
Message.error(error || 'Has Error')
|
||||
next(`/login?redirect=${to.path}`)
|
||||
NProgress.done()
|
||||
}
|
||||
}
|
||||
// // hack method to ensure that addRoutes is complete
|
||||
// // set the replace: true, so the navigation will not leave a history record
|
||||
// next({ ...to, replace: true })
|
||||
// } catch (error) {
|
||||
// // remove token and go to login page to re-login
|
||||
// await store.dispatch('user/resetToken')
|
||||
// Message.error(error || 'Has Error')
|
||||
// next(`/login?redirect=${to.path}`)
|
||||
// NProgress.done()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
/* has no token*/
|
||||
|
|
|
@ -70,19 +70,74 @@ export const constantRoutes = [
|
|||
component: () => import('@/views/error-page/401'),
|
||||
hidden: true
|
||||
},
|
||||
// {
|
||||
// path: '/',
|
||||
// component: Layout,
|
||||
// redirect: '/dashboard',
|
||||
// children: [
|
||||
// {
|
||||
// path: 'dashboard',
|
||||
// component: () => import('@/views/dashboard/index'),
|
||||
// name: 'Dashboard',
|
||||
// meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
redirect: 'overview',
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: () => import('@/views/dashboard/index'),
|
||||
name: 'Dashboard',
|
||||
meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
|
||||
path: 'overview',
|
||||
component: () => import('@/views/overview/index'),
|
||||
name: 'Overview',
|
||||
meta: { title: '概览', icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/nodeManagement',
|
||||
component: Layout,
|
||||
redirect: 'nodeManagement',
|
||||
children: [
|
||||
{
|
||||
path: 'nodeManagement',
|
||||
component: () => import('@/views/nodeManagement/index'),
|
||||
name: 'NodeManagement',
|
||||
meta: { title: '节点管理', icon: 'el-icon-s-management', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/projectManagement',
|
||||
component: Layout,
|
||||
redirect: 'projectManagement',
|
||||
children: [
|
||||
{
|
||||
path: 'projectManagement',
|
||||
component: () => import('@/views/projectManagement/index'),
|
||||
name: 'ProjectManagement',
|
||||
meta: { title: '项目管理', icon: 'el-icon-s-management', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/storageManagement',
|
||||
component: Layout,
|
||||
redirect: 'storageManagement',
|
||||
children: [
|
||||
{
|
||||
path: 'storageManagement',
|
||||
component: () => import('@/views/storageManagement/index'),
|
||||
name: 'StorageManagement',
|
||||
meta: { title: '存储管理', icon: 'el-icon-s-management', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: '/documentation',
|
||||
// component: Layout,
|
||||
|
|
|
@ -5,7 +5,7 @@ module.exports = {
|
|||
* @type {boolean} true | false
|
||||
* @description Whether show the settings right-panel
|
||||
*/
|
||||
showSettings: true,
|
||||
showSettings: false,
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { login, logout, getInfo } from '@/api/user'
|
||||
import { login, getInfo } from '@/api/user'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import router, { resetRouter } from '@/router'
|
||||
|
||||
|
@ -33,10 +33,10 @@ const actions = {
|
|||
login({ commit }, userInfo) {
|
||||
const { username, password } = userInfo
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ username: username.trim(), password: password }).then(response => {
|
||||
const { data } = response
|
||||
commit('SET_TOKEN', data.token)
|
||||
setToken(data.token)
|
||||
login({ 'grant_type': 'password', 'username': username.trim(), 'password': password }).then(response => {
|
||||
console.log(response)
|
||||
commit('SET_TOKEN', response.access_token)
|
||||
setToken(response.access_token)
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
@ -75,7 +75,7 @@ const actions = {
|
|||
// user logout
|
||||
logout({ commit, state, dispatch }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token).then(() => {
|
||||
// logout(state.token).then(() => {
|
||||
commit('SET_TOKEN', '')
|
||||
commit('SET_ROLES', [])
|
||||
removeToken()
|
||||
|
@ -86,9 +86,9 @@ const actions = {
|
|||
dispatch('tagsView/delAllViews', null, { root: true })
|
||||
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
// }).catch(error => {
|
||||
// reject(error)
|
||||
// })
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ html {
|
|||
|
||||
#app {
|
||||
height: 100%;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
*,
|
||||
|
@ -189,3 +190,19 @@ aside {
|
|||
.multiselect--active {
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
span.tips {
|
||||
display: block;
|
||||
line-height: 1em;
|
||||
margin-top: 5px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.chartCard .el-card__body {
|
||||
padding: 0 20px;
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background: #F5F7FA;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Cookies from 'js-cookie'
|
||||
|
||||
const TokenKey = 'Admin-Token'
|
||||
const TokenKey = 'access_token'
|
||||
|
||||
export function getToken() {
|
||||
return Cookies.get(TokenKey)
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import axios from 'axios'
|
||||
import { MessageBox, Message } from 'element-ui'
|
||||
import { Message } from 'element-ui'
|
||||
import store from '@/store'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
// create an axios instance
|
||||
const service = axios.create({
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
|
||||
// withCredentials: true, // send cookies when cross-domain requests
|
||||
timeout: 5000 // request timeout
|
||||
|
@ -16,10 +19,7 @@ service.interceptors.request.use(
|
|||
// do something before request is sent
|
||||
|
||||
if (store.getters.token) {
|
||||
// let each request carry token
|
||||
// ['X-Token'] is a custom headers key
|
||||
// please modify it according to the actual situation
|
||||
config.headers['X-Token'] = getToken()
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
return config
|
||||
},
|
||||
|
@ -46,7 +46,7 @@ service.interceptors.response.use(
|
|||
const res = response.data
|
||||
|
||||
// if the custom code is not 20000, it is judged as an error.
|
||||
if (res.code !== 20000) {
|
||||
if (response.status !== 200) {
|
||||
Message({
|
||||
message: res.message || 'Error',
|
||||
type: 'error',
|
||||
|
@ -54,18 +54,18 @@ service.interceptors.response.use(
|
|||
})
|
||||
|
||||
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
|
||||
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
|
||||
// to re-login
|
||||
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
|
||||
confirmButtonText: 'Re-Login',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
store.dispatch('user/resetToken').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
})
|
||||
}
|
||||
// if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
|
||||
// // to re-login
|
||||
// MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
|
||||
// confirmButtonText: 'Re-Login',
|
||||
// cancelButtonText: 'Cancel',
|
||||
// type: 'warning'
|
||||
// }).then(() => {
|
||||
// store.dispatch('user/resetToken').then(() => {
|
||||
// location.reload()
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
return Promise.reject(new Error(res.message || 'Error'))
|
||||
} else {
|
||||
return res
|
||||
|
|
|
@ -10,27 +10,19 @@
|
|||
</h1>
|
||||
gif来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面
|
||||
<h2>你没有权限去该页面</h2>
|
||||
<h6>如有不满请联系你领导</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li>或者你可以去:</li>
|
||||
<li class="link-type">
|
||||
<router-link to="/dashboard">
|
||||
<router-link to="/overview">
|
||||
回首页
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="link-type">
|
||||
<a href="https://www.taobao.com/">随便看看</a>
|
||||
</li>
|
||||
<li><a href="#" @click.prevent="dialogVisible=true">点我看图</a></li>
|
||||
</ul>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream.">
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-dialog :visible.sync="dialogVisible" title="随便看">
|
||||
<img :src="ewizardClap" class="pan-img">
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -47,42 +47,20 @@
|
|||
|
||||
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
|
||||
|
||||
<div style="position:relative">
|
||||
<div class="tips">
|
||||
<span>Username : admin</span>
|
||||
<span>Password : any</span>
|
||||
</div>
|
||||
<div class="tips">
|
||||
<span style="margin-right:18px;">Username : editor</span>
|
||||
<span>Password : any</span>
|
||||
</div>
|
||||
|
||||
<el-button class="thirdparty-button" type="primary" @click="showDialog=true">
|
||||
Or connect with
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<el-dialog title="Or connect with" :visible.sync="showDialog">
|
||||
Can not be simulated on local, so please combine you own business simulation! ! !
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<social-sign />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { validUsername } from '@/utils/validate'
|
||||
import SocialSign from './components/SocialSignin'
|
||||
import { isString } from '@/utils/validate'
|
||||
// import SocialSign from './components/SocialSignin'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
components: { SocialSign },
|
||||
// components: { SocialSign },
|
||||
data() {
|
||||
const validateUsername = (rule, value, callback) => {
|
||||
if (!validUsername(value)) {
|
||||
if (!isString(value)) {
|
||||
callback(new Error('Please enter the correct user name'))
|
||||
} else {
|
||||
callback()
|
||||
|
@ -98,7 +76,7 @@ export default {
|
|||
return {
|
||||
loginForm: {
|
||||
username: 'admin',
|
||||
password: '111111'
|
||||
password: 'P@88w0rd'
|
||||
},
|
||||
loginRules: {
|
||||
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
||||
|
@ -158,6 +136,7 @@ export default {
|
|||
this.loading = true
|
||||
this.$store.dispatch('user/login', this.loginForm)
|
||||
.then(() => {
|
||||
this.$message.success('登录成功')
|
||||
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
||||
this.loading = false
|
||||
})
|
||||
|
@ -178,24 +157,6 @@ export default {
|
|||
return acc
|
||||
}, {})
|
||||
}
|
||||
// afterQRScan() {
|
||||
// if (e.key === 'x-admin-oauth-code') {
|
||||
// const code = getQueryObject(e.newValue)
|
||||
// const codeMap = {
|
||||
// wechat: 'code',
|
||||
// tencent: 'code'
|
||||
// }
|
||||
// const type = codeMap[this.auth_type]
|
||||
// const codeName = code[type]
|
||||
// if (codeName) {
|
||||
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
|
||||
// this.$router.push({ path: this.redirect || '/' })
|
||||
// })
|
||||
// } else {
|
||||
// alert('第三方登录失败')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card class="chartCard">
|
||||
<h4>
|
||||
集群节点
|
||||
</h4>
|
||||
<span class="tips">集群节点提供了当前集群下节点的运行状态,以及可以编辑删除节点</span>
|
||||
<el-collapse v-model="activeName" accordion>
|
||||
<el-collapse-item title="集群节点的类型?" name="1">
|
||||
<div>节点分为主控 (Master) 节点和工作 (Worker) 节点</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="什么是节点污点?" name="2">
|
||||
<div>节点污点 (Taints) 可以阻止某些容器组 (Pod) 副本部署至该节点中,
|
||||
与容忍度 (Tolerations) 一起工作确保容器组不会被调度到不合适的节点上</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-card>
|
||||
<el-card class="chartCard" style="height:150px;width:600px">
|
||||
<el-table style="margin-top:25px" :data="nodeReliefMessage">
|
||||
<el-table-column prop="totalNumber" label="节点数量" />
|
||||
<el-table-column prop="masterNumber" label="控制节点数量" />
|
||||
<el-table-column prop="nodeNumber" label="工作节点数量" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
<NodeStatus />
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NodeStatus from '@/components/ClusterManagement/nodeStatus.vue'
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
components: { NodeStatus },
|
||||
data() {
|
||||
return {
|
||||
activeName: '1',
|
||||
nodeReliefMessage: [
|
||||
{ totalNumber: '3', masterNumber: '1', nodeNumber: '3' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.chartCard{
|
||||
text-align: left;
|
||||
span{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<h4>hostHost 集群 </h4>
|
||||
<span class="tips">
|
||||
Automatically created by KubeX, we encourage you to use host cluster for clusters management only, deploy workloads to member clusters.</span>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<h5>集群信息</h5>
|
||||
<ClusterMessage />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<h5>KubeX组件状态</h5>
|
||||
<ComponentStatus />
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<h5>集群资源使用情况</h5>
|
||||
<ResourceUsage />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<h5>节点用量 Top3</h5>
|
||||
<NodeMessage />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ClusterMessage from '@/components/ClusterManagement/clusterMessage'
|
||||
import ComponentStatus from '@/components/ClusterManagement/componentStatus'
|
||||
import NodeMessage from '@/components/ClusterManagement/nodeMessage'
|
||||
import ResourceUsage from '@/components/ClusterManagement/resourceUsage'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ClusterMessage, ComponentStatus, NodeMessage, ResourceUsage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
key: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<div class="projectInfo">
|
||||
<el-card class="chartCard" style="height:100px">
|
||||
<h4>
|
||||
项目
|
||||
</h4>
|
||||
<span class="tips">将根据项目资源进行分组, 可以按项目对资源进行查看管理</span>
|
||||
</el-card>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="用户项目">
|
||||
<el-table :data="nodeStatus">
|
||||
<el-table-column prop="name" label="名称" width="140" />
|
||||
<el-table-column prop="status" label="状态" width="140" />
|
||||
<el-table-column prop="space" label="企业空间" width="140" />
|
||||
<el-table-column prop="cpu" label="CPU使用量" width="140" />
|
||||
<el-table-column prop="ram" label="内存使用量" width="140" />
|
||||
<el-table-column prop="pod" label="Pods数量" width="140" />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="系统项目">
|
||||
<el-table :data="nodeStatus">
|
||||
<el-table-column prop="name" label="名称" width="140" />
|
||||
<el-table-column prop="status" label="状态" width="140" />
|
||||
<el-table-column prop="space" label="企业空间" width="140" />
|
||||
<el-table-column prop="cpu" label="CPU使用量" width="140" />
|
||||
<el-table-column prop="ram" label="内存使用量" width="140" />
|
||||
<el-table-column prop="pod" label="Pods数量" width="140" />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ProjectForm',
|
||||
data() {
|
||||
return {
|
||||
nodeStatus: [
|
||||
{
|
||||
name: 'a111', status: '活跃', space: '', cpu: '0 m', ram: '0 Bytes', pod: '0'
|
||||
},
|
||||
{
|
||||
name: 'node1', status: '活跃', space: 'demo', cpu: '30 m', ram: '1.63 Gi', pod: '33'
|
||||
},
|
||||
{
|
||||
name: 'aba', status: '活跃', space: 'demo', cpu: '0 m', ram: '0 Bytes', pod: '0'
|
||||
},
|
||||
{
|
||||
name: 'cert-manager', status: '活跃', space: '', cpu: '10 m', ram: '105.65 Mi', pod: '3'
|
||||
},
|
||||
{
|
||||
name: 'a111', status: '活跃', space: '', cpu: '0 m', ram: '0 Bytes', pod: '0'
|
||||
},
|
||||
{
|
||||
name: 'node1', status: '活跃', space: 'demo', cpu: '30 m', ram: '1.63 Gi', pod: '33'
|
||||
},
|
||||
{
|
||||
name: 'aba', status: '活跃', space: 'demo', cpu: '0 m', ram: '0 Bytes', pod: '0'
|
||||
},
|
||||
{
|
||||
name: 'cert-manager', status: '活跃', space: '', cpu: '10 m', ram: '105.65 Mi', pod: '3'
|
||||
},
|
||||
{
|
||||
name: 'aba', status: '活跃', space: 'demo', cpu: '0 m', ram: '0 Bytes', pod: '0'
|
||||
},
|
||||
{
|
||||
name: 'cert-manager', status: '活跃', space: '', cpu: '10 m', ram: '105.65 Mi', pod: '3'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.projectInfo{
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,68 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card class="chartCard">
|
||||
<h4>
|
||||
存储卷信息
|
||||
</h4>
|
||||
<span class="tips" style="margin-bottom:10px">存储卷供用户创建的工作负载使用,是将工作负载数据持久化的一种资源对象。</span>
|
||||
<el-collapse v-model="activeName" accordion>
|
||||
<el-collapse-item title="什么是存储卷类型?" name="1">
|
||||
<div>存储卷类型 (StorageClass) 是由集群管理员配置存储服务端的参数,并按类型提供存储给集群用户使用。</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="什么是本地存储卷 (Local Volume) ?" name="2">
|
||||
<div>本地存储卷表示挂载的本地存储设备,如磁盘、分区或目录。</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-card>
|
||||
<el-card class="chartCard" style="height: 700px; padding:20px 0">
|
||||
<el-table :data="nodeStatus">
|
||||
<el-table-column prop="name" label="名称" width="300" />
|
||||
<el-table-column prop="status" label="状态" width="140" />
|
||||
<el-table-column prop="mode" label="访问模式" width="200" />
|
||||
<el-table-column prop="mount" label="挂载" width="140" />
|
||||
<el-table-column prop="createtime" label="创建时间" width="140" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'StorageForm',
|
||||
data() {
|
||||
return {
|
||||
activeName: '1',
|
||||
nodeStatus: [
|
||||
{
|
||||
name: 'minio-87dz96', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2021-01-07 13:49'
|
||||
},
|
||||
{
|
||||
name: 'data-postgre-ux292w-postgresql-0', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2021-01-05 12:09'
|
||||
},
|
||||
{
|
||||
name: 'db-data-mongodb-5gupv8-0', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2021-01-04 09:59'
|
||||
},
|
||||
{
|
||||
name: 'ks-jenkins', status: '准备就绪', mode: 'ReadWriteOnce', mount: '未挂载', createtime: '2020-12-09 20:23'
|
||||
},
|
||||
{
|
||||
name: 'harbor-hrypxk-harbor-registry', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2020-11-22 03:00'
|
||||
},
|
||||
{
|
||||
name: 'harbor-hrypxk-harbor-jobservice', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2020-11-22 03:00'
|
||||
},
|
||||
{
|
||||
name: 'harbor-hrypxk-harbor-chartmuseum', status: '准备就绪', mode: 'ReadWriteOnce', mount: '已挂载', createtime: '2020-11-22 03:00'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.chartCard{
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
|
@ -36,7 +36,14 @@ module.exports = {
|
|||
warnings: false,
|
||||
errors: true
|
||||
},
|
||||
before: require('./mock/mock-server.js')
|
||||
proxy: {
|
||||
'/': {
|
||||
ws: false,
|
||||
target: 'http://192.168.0.86:30881/',
|
||||
// changeOrigin: true,
|
||||
},
|
||||
},
|
||||
// before: require('./mock/mock-server.js')
|
||||
},
|
||||
configureWebpack: {
|
||||
// provide the app's title in webpack's name field, so that
|
||||
|
|
Loading…
Reference in New Issue