当前位置: 首页 > news >正文

巴中城乡和住房建设厅网站/代推广平台

巴中城乡和住房建设厅网站,代推广平台,带音乐网站模板,温州企业做网站k8s 管理系统项目[前端部分–工作负载-Deployment] 1. 代码部分 1.1 准备工作 由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改. 替换Deployment为Pod替换Deploy为Pod替换deployment为pod替换deploy为pod禁用新增的按钮,删除新增方法,表…

k8s 管理系统项目[前端部分–工作负载-Deployment]

1. 代码部分

1.1 准备工作

由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改.

  1. 替换Deployment为Pod
  2. 替换Deploy为Pod
  3. 替换deployment为pod
  4. 替换deploy为pod
  5. 禁用新增的按钮,删除新增方法,表单
  6. 删除扩容和重启的按钮,方法,抽屉

1.2 Pod前端代码

src/views/workload/Pod.vue

<template><div class="pod"><el-row><!-- 头部1 --><el-col :span="24"><div><el-card class="pod-head-card" shadow="never" :body-style="{padding:'10px'}"><el-row><el-col :span="6"><div><span>命名空间: </span><el-select v-model="namespaceValue" filterable placeholder="请选择"><el-optionv-for="(item, index) in namespaceList":key="index":label="item.metadata.name":value="item.metadata.name"></el-option></el-select></div></el-col><el-col :span="2" :offset="16"><div><el-button style="border-radius:2px;" icon="Refresh" plain @click="getPods()">刷新</el-button></div></el-col></el-row></el-card></div></el-col><!-- 头部2 --><el-col :span="24"><div><el-card class="pod-head-card" shadow="never" :body-style="{padding:'10px'}"><el-row><el-col :span="2"><div><el-button disabled style="border-radius:2px;" icon="Edit" type="primary">创建</el-button></div></el-col><el-col :span="6"><div><el-input class="pod-head-search" clearable placeholder="请输入" v-model="searchInput"></el-input><el-button style="border-radius:2px;" icon="Search" type="primary" plain @click="getPods()">搜索</el-button></div></el-col></el-row></el-card></div></el-col><!-- 数据表格 --><el-col :span="24"><div><el-card class="pod-body-card" shadow="never" :body-style="{padding:'5px'}"><!-- 数据表格 --><!-- row-key 用来定义行数据的key,结合expand-row-keys使用,往expandKeys中增加key来展开行 --><!-- expand-row-keys 展开的行的key数组 --><!-- expand-change 展开触发时,调用这个方法 --><el-tablestyle="width:100%;font-size:12px;margin-bottom:10px;":data="podList"v-loading="appLoading":row-key="getRowKeys":expand-row-keys="expandKeys"@expand-change="expandChange"><el-table-column width="10"></el-table-column><!-- 展开 --><el-table-column type="expand"><!-- 插槽,里面是展开的内容,props标识展开的行的数据 --><template #default="props"><el-tabs v-model="activeName" type="card"><!-- tab容器标签页 --><el-tab-pane label="容器" name="container"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><!-- 嵌套数据表格 --><el-tablestyle="width:100%;font-size:12px;":data="props.row.spec.containers"><el-table-column align=left prop="name" label="容器名"></el-table-column><el-table-column align=left prop="image" label="镜像"></el-table-column><el-table-column align=center label="Pod IP"><span>{{ props.row.status.podIP }}</span></el-table-column><el-table-column align=center prop="args" label="启动命令"></el-table-column><el-table-column align=center label="环境变量"><template v-slot="scope"><!-- 气泡弹出框,内容是所有的环境变量 --><el-popover :width="500" placement="left" trigger="hover"><el-table style="width:100%;font-size:12px;" size="mini" :show-header="false" :data="scope.row.env"><el-table-column property="name" label="名称"></el-table-column><el-table-column property="value" label="值"></el-table-column></el-table><template #reference><el-button size="small">此处查看</el-button></template></el-popover></template></el-table-column></el-table></el-card></el-tab-pane><!-- tab日志标签页 --><el-tab-pane label="日志" name="log"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><el-row :gutter="10"><el-col :span="3"><!-- 容器选择框 --><el-select size="small" v-model="containerValue" placeholder="请选择"><el-option v-for="item in containerList" :key="item" :value="item"></el-option></el-select></el-col><el-col :span="2"><!-- 查看日志按钮 --><el-button style="border-radius:2px;" size="small" type="primary" @click="getPodLog(props.row.metadata.name)">查看</el-button></el-col><el-col :span="24" style="margin-top: 5px"><!-- 显示日志内容 --><el-card shadow="never" class="pod-body-log-card" :body-style="{padding:'5px'}"><span class="pod-body-log-span">{{ logContent }}</span></el-card></el-col></el-row></el-card></el-tab-pane><!-- tab终端标签页 --><el-tab-pane label="终端" name="shell"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><el-row :gutter="10"><el-col :span="3"><!-- 容器选择框 --><el-select size="small" v-model="containerValue" placeholder="请选择"><el-option v-for="item in containerList" :key="item" :value="item"></el-option></el-select></el-col><el-col :span="1"><!-- 连接按钮 --><el-button style="border-radius:2px;" size="small" type="primary" @click="initSocket(props.row)">连接</el-button></el-col><el-col :span="1"><!-- 关闭连接按钮 --><el-button style="border-radius:2px;" size="small" type="danger" @click="closeSocket()">关闭</el-button></el-col><el-col :span="24" style="margin-top: 5px"><el-card shadow="never" class="pod-body-shell-card" :body-style="{padding:'5px'}"><!-- xterm虚拟终端 --><div id="xterm"></div></el-card></el-col></el-row></el-card></el-tab-pane></el-tabs></template></el-table-column><el-table-column align=left label="Pod名"><template v-slot="scope"><!-- 三元运算:expandMap[scope.row.metadata.name]为1则触发关闭(expandedRows为空数组),为0则触发展开expandedRows有值 --><a class="pod-body-podname" @click="expandMap[scope.row.metadata.name] ? expandChange(scope.row, []) : expandChange(scope.row, [scope.row])">{{ scope.row.metadata.name }}</a></template></el-table-column><el-table-column align=center min-width="150" label="节点"><template v-slot="scope"><el-tag v-if="scope.row.spec.nodeName !== undefined" type="warning">{{ scope.row.spec.nodeName }}</el-tag></template></el-table-column><el-table-column align=center label="状态"><template v-slot="scope"><div :class="{'success-dot':scope.row.status.phase == 'Running' || scope.row.status.phase == 'Succeeded', 'warning-dot':scope.row.status.phase == 'Pending', 'error-dot':scope.row.status.phase != 'Running' && scope.row.status.phase != 'Pending' && scope.row.status.phase != 'Succeeded'}"></div><span :class="{'success-status':scope.row.status.phase == 'Running' || scope.row.status.phase == 'Succeeded', 'warning-status':scope.row.status.phase == 'Pending', 'error-status':scope.row.status.phase != 'Running' && scope.row.status.phase != 'Pending' && scope.row.status.phase != 'Succeeded'}">{{ scope.row.status.phase }} </span></template></el-table-column><el-table-column align=center label="重启数"><template v-slot="scope"><span>{{ restartTotal(scope) }} </span></template></el-table-column><el-table-column align=center min-width="100" label="创建时间"><template v-slot="scope"><el-tag type="info">{{ timeTrans(scope.row.metadata.creationTimestamp) }} </el-tag></template></el-table-column><el-table-column align=center label="操作" width="200"><template v-slot="scope"><el-button size="small" style="border-radius:2px;" icon="Edit" type="primary" plain @click="getPodDetail(scope)">YAML</el-button><el-button size="small" style="border-radius:2px;" icon="Delete" type="danger" @click="handleConfirm(scope, '删除', delPod)">删除</el-button></template></el-table-column></el-table><el-paginationclass="pod-body-pagination"background@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="pagesizeList":page-size="pagesize"layout="total, sizes, prev, pager, next, jumper":total="podTotal"></el-pagination></el-card></div></el-col></el-row><!-- 展示YAML信息的弹框 --><el-dialog title="YAML信息" v-model="yamlDialog" width="45%" top="5%"><codemirror:value="contentYaml"border:options="cmOptions"height="500"style="font-size:14px;"@change="onChange"></codemirror><template #footer><span class="dialog-footer"><el-button @click="yamlDialog = false">取 消</el-button><el-button type="primary" @click="updatePod()">更 新</el-button></span></template></el-dialog></div>
</template><script>
import common from "../common/Config";
import httpClient from '../../utils/request';
//引入xterm终端依赖
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';
import 'xterm/lib/xterm.js';
import yaml2obj from 'js-yaml';
import json2yaml from 'json2yaml';
export default {data() {return {//编辑器配置cmOptions: common.cmOptions,contentYaml: '',//分页currentPage: 1,pagesize: 10,pagesizeList: [10, 20, 30],//searchInput: '',namespaceValue: 'default',namespaceList: [],namespaceListUrl: common.k8sNamespaceList,appLoading: false,podList: [],podTotal: 0,getPodsData: {url: common.k8sPodList,params: {filter_name: '',namespace: '',page: '',limit: '',}},//详情podDetail: {},getPodDetailData: {url: common.k8sPodDetail,params: {pod_name: '',namespace: ''}},//yaml更新yamlDialog: false,updatePodData: {url: common.k8sPodUpdate,params: {namespace: '',content: ''}},//删除delPodData: {url: common.k8sPodDel,params: {pod_name: '',namespace: ''}},//expand扩展activeName: 'container',expandKeys: [],expandMap: {},//日志containerList: {},containerValue: '',getPodContainerData: {url: common.k8sPodContainer,params: {pod_name: '',namespace: ''}},logContent: '',getPodLogData: {url: common.k8sPodLog,params: {container_name: '',pod_name: '',namespace: ''}},//terminalterm: null,socket: null}},methods: {transYaml(content) {return json2yaml.stringify(content)},transObj(content) {return yaml2obj.load(content)},onChange(val) {this.contentYaml = val},handleSizeChange(size) {this.pagesize = size;this.getPods()},handleCurrentChange(currentPage) {this.currentPage = currentPage;this.getPods()},handleClose(done) {this.$confirm('确认关闭?').then(() => {done();}).catch(() => {});},ellipsis(value) {return value.length>15?value.substring(0,15)+'...':value},timeTrans(timestamp) {let date = new Date(new Date(timestamp).getTime() + 8 * 3600 * 1000)date = date.toJSON();date = date.substring(0, 19).replace('T', ' ')return date},restartTotal(e) {let index, sum = 0let containerStatuses = e.row.status.containerStatusesfor ( index in containerStatuses) {sum = sum + containerStatuses[index].restartCount}return sum},getNamespaces() {httpClient.get(this.namespaceListUrl).then(res => {this.namespaceList = res.data.items}).catch(res => {this.$message.error({message: res.msg})})},getPods() {this.appLoading = truethis.getPodsData.params.filter_name = this.searchInputthis.getPodsData.params.namespace = this.namespaceValuethis.getPodsData.params.page = this.currentPagethis.getPodsData.params.limit = this.pagesizehttpClient.get(this.getPodsData.url, {params: this.getPodsData.params}).then(res => {this.podList = res.data.itemsthis.podTotal = res.data.total}).catch(res => {this.$message.error({message: res.msg})})this.appLoading = false},getPodDetail(e) {this.getPodDetailData.params.pod_name = e.row.metadata.namethis.getPodDetailData.params.namespace = this.namespaceValuehttpClient.get(this.getPodDetailData.url, {params: this.getPodDetailData.params}).then(res => {this.podDetail = res.datathis.contentYaml = this.transYaml(this.podDetail)this.yamlDialog = true}).catch(res => {this.$message.error({message: res.msg})})},updatePod() {let content = JSON.stringify(this.transObj(this.contentYaml))this.updatePodData.params.namespace = this.namespaceValuethis.updatePodData.params.content = contenthttpClient.put(this.updatePodData.url, this.updatePodData.params).then(res => {this.$message.success({message: res.msg})}).catch(res => {this.$message.error({message: res.msg})})this.yamlDialog = false},delPod(e) {this.delPodData.params.pod_name = e.row.metadata.namethis.delPodData.params.namespace = this.namespaceValuehttpClient.delete(this.delPodData.url, {data: this.delPodData.params}).then(res => {this.getPods()this.$message.success({message: res.msg})}).catch(res => {this.$message.error({message: res.msg})})},handleConfirm(obj, operateName, fn) {this.confirmContent = '确认继续 ' + operateName + ' 操作吗?'this.$confirm(this.confirmContent,'提示',{confirmButtonText: '确定',cancelButtonText: '取消',}).then(() => {fn(obj)}).catch(() => {this.$message.info({message: '已取消操作'})})},getRowKeys(row) {return row.metadata.name},//row,展开的当前行的数据//expandedRows,展开的所有行的数据组成的数组,但是这里用法是只会有一行,也就是数组长度永远为1expandChange(row, expandedRows) {//初始化变量//清空expandKeys,代表关闭所有展开的行this.expandKeys = []//清空日志内容this.logContent= ''//清空containervalue,展开时不显示上次的值this.containerValue = ''//将tab标签页顶部页面调成容器this.activeName = 'container'//expandedRows.length == 1表示展开,expandedRows.length == 0 表示关闭if (expandedRows.length > 0) {//expandMap key表示展开过的行的key,值为1表示展开标记,值为0表示关闭标记//expandMap用于数据表格点击name的展开,用于判断这一行是展开还是关闭的行为this.expandMap[row.metadata.name] = 1//将expandMap除了row.metadata.name,其他key的值都置为0this.setExpandMap(row.metadata.name)//这里才是真正的展开,将row.metadata.name添加到expandKeys数组中展开,然后执行方法获取containerthis.expandKeys.push(row.metadata.name)this. getPodContainer(row)} else {//关闭标记this.expandMap[row.metadata.name] = 0}},//匹配expandMap中podName,不相等的全都置为0,意为除了podName这行,其他全都标记关闭setExpandMap(podName) {let keyfor ( key in this.expandMap ) {key !== podName ? this.expandMap[key] = 0 : ''}},getPodContainer(row) {this.getPodContainerData.params.pod_name = row.metadata.namethis.getPodContainerData.params.namespace = this.namespaceValuehttpClient.get(this.getPodContainerData.url, {params: this.getPodContainerData.params}).then(res => {this.containerList = res.datathis.containerValue = this.containerList[0]}).catch(res => {this.$message.error({message: res.msg})})},getPodLog(podName) {this.getPodLogData.params.pod_name = podNamethis.getPodLogData.params.container_name = this.containerValuethis.getPodLogData.params.namespace = this.namespaceValuehttpClient.get(this.getPodLogData.url, {params: this.getPodLogData.params}).then(res => {this.logContent = res.data}).catch(res => {this.$message.error({message: res.msg})})},initTerm() {//初始化xterm实例this.term = new Terminal({rendererType: 'canvas', //渲染类型rows: 30, //行数cols: 110,convertEol: false, //启用时,光标将设置为下一行的开头scrollback: 10, //终端中的回滚量disableStdin: false, //是否应禁用输入cursorStyle: 'underline', //光标样式cursorBlink: true, //光标闪烁theme: {foreground: 'white', //字体background: '#060101', //背景色cursor: 'help' //设置光标}});//绑定domthis.term.open(document.getElementById('xterm'))//终端适应父元素大小const fitAddon = new FitAddon()this.term.loadAddon(fitAddon)fitAddon.fit();//获取终端的焦点this.term.focus();let _this = this; //一定要重新定义一个this,不然this指向会出问题//onData方法用于定义输入的动作this.term.onData(function (key) {// 这里key值是输入的值,数据格式就是后端定义的 {"operation":"stdin","data":"ls"}let msgOrder = {operation: 'stdin',data: key,};//发送数据_this.socket.send(JSON.stringify(msgOrder));});//发送resize请求let msgOrder2 = {operation: 'resize',cols: this.term.cols,rows: this.term.rows,};this.socket.send(JSON.stringify(msgOrder2))},//初始化websocketinitSocket(row) {//定义websocket连接地址let terminalWsUrl = common.k8sTerminalWs + "?pod_name=" + row.metadata.name + "&container_name=" + this.containerValue + "&namespace=" + this.namespaceValue//实例化this.socket = new WebSocket(terminalWsUrl);//关闭连接时的方法this.socketOnClose();//建立连接时的方法this.socketOnOpen();//接收消息的方法this.socketOnMessage();//报错时的方法this.socketOnError();},socketOnOpen() {this.socket.onopen = () => {//简历连接成功后,初始化虚拟终端this.initTerm()}},socketOnMessage() {this.socket.onmessage = (msg) => {//接收到消息后将字符串转为对象,输出data内容let content = JSON.parse(msg.data)this.term.write(content.data)}},socketOnClose() {this.socket.onclose = () => {//关闭连接后打印在终端里this.term.write("链接已关闭")}},socketOnError() {this.socket.onerror = () => {console.log('socket 链接失败')}},//关闭连接closeSocket() {//若没有实例化,则不需要关闭if (this.socket === null) {return}this.term.write("链接关闭中。。。")this.socket.close()}},watch: {namespaceValue: {handler() {localStorage.setItem('namespace', this.namespaceValue)this.currentPage = 1this.getPods()}},//若tab标签页切到日志,则重新加载日志内容activeName: {handler() {if ( this.activeName == 'log' ) {this.expandKeys.length == 1 ? this.getPodLog(this.expandKeys[0]) : ''}}}},beforeMount() {if (localStorage.getItem('namespace') !== undefined && localStorage.getItem('namespace') !== null) {this.namespaceValue = localStorage.getItem('namespace')}this.getNamespaces()this.getPods()},beforeUnmount() {//若websocket连接没有关闭,则在改生命周期关闭if ( this.socket !== null ) {this.socket.close()}},
}
</script><style scoped>
.pod-head-card,.pod-body-card {border-radius: 1px;margin-bottom: 5px;
}
.pod-head-search {width:160px;margin-right:10px;
}
.pod-body-podname {color: #4795EE;
}
.pod-body-podname:hover {color: rgb(84, 138, 238);cursor: pointer;font-weight: bold;
}
/* pod状态栏圆点的css实现 */
.success-dot{display:inline-block;width: 7px;height:7px;background: rgb(27, 202, 21);border-radius:50%;border:1px solid rgb(27, 202, 21);margin-right: 10px;
}
.warning-dot{display:inline-block;width: 7px;height:7px;background: rgb(233, 200, 16);border-radius:50%;border:1px solid rgb(233, 200, 16);margin-right: 10px;
}
.error-dot{display:inline-block;width: 7px;height:7px;background: rgb(226, 23, 23);border-radius:50%;border:1px solid rgb(226, 23, 23);margin-right: 10px;
}
.success-status {color: rgb(27, 202, 21);
}
.warning-status {color: rgb(233, 200, 16);
}
.error-status {color: rgb(226, 23, 23);
}
/deep/ .el-tabs__item {font-size: 12px;
}
/deep/ .el-tabs__header {margin-bottom: 8px;
}
.pod-body-log-card, .pod-body-shell-card {border-radius:1px;height:600px;overflow:auto;background-color: #060101;
}
.pod-body-log-card {color: aliceblue;
}
.pod-body-log-span {white-space:pre;
}
</style>

2. 功能测试

2.1 获取pod清单和分页

请添加图片描述
请添加图片描述

2.2 获取pod详细信息

2.2.1 pod详情

请添加图片描述

2.2.2 Pod环境变量

请添加图片描述

2.2.2 Pod日志

请添加图片描述

2.2.4 控制台

请添加图片描述

2.3 Yaml

请添加图片描述

2.4 删除Pod

请添加图片描述

请添加图片描述

请添加图片描述

3. 两个小bug

3.1 router错误

之前写后端路由时/api/k8s/pod/detail写成了/api/k8s/pods/detail

造成获取yaml时无法获得消息.

尝试用api调用发现问题,修改了router下的路由问题解决

3.2 翻页的问题

之前后端GetPods中取total写成了

	filtered := selectableData.Filter()// 排序和分页data := filtered.Sort().Paginate()total := len(data.GenericDataList)

改了下问题解决

	filtered := selectableData.Filter()total := len(filtered.GenericDataList)// 排序和分页data := filtered.Sort().Paginate()
http://www.jmfq.cn/news/5076901.html

相关文章:

  • 网站备案变更 委托书/爱站网备案查询
  • WordPress注册无需发送邮件/深圳网站关键词优化公司
  • 如何用cms做网站/口碑营销公司
  • 请柬网站开发/推广产品
  • winscp怎么做网站/长沙seo招聘
  • 网站销售的优势/兰州seo
  • 专业外包网站建设公司排名/抖音seo推广外包公司好做吗
  • 高青县住房和城乡建设局网站/seo学校
  • 易派客网站是谁做的/怎么做平台推广
  • 西宁做网站多少钱/代做百度首页排名价格
  • 免费做外贸的网站/北京网站优化专家
  • 做网站公司长沙/一个新手怎么做推广
  • 专业的企业网站优化公司/全网线报 实时更新
  • 做网站现在用什么语言/成都培训机构排名前十
  • python是什么意思/网站优化的主要内容
  • 上海松江区建设局官方网站/双桥seo排名优化培训
  • 建网站中企动力优/2345网址导航 中国最
  • 便宜的网站设计企业/百度网络营销app
  • 眉山 网站开发/西安排名seo公司
  • 域名备案通过后怎么做网站/nba最新排行
  • 花钱做网站/优化关键词步骤
  • 蓝色企业网站/什么是电商平台推广
  • 如何开通网站/windows优化大师和鲁大师
  • 网站建设论团/ip域名查询网站入口
  • 做网站主播要什么条件/如何免费做视频二维码永久
  • 如何做网站友情链接/百度手机卫士下载安装
  • 做网站需要服务器和什么软件/windows优化大师提供的
  • 如何判断一个网站是否用织梦建设的/搜狗站长平台验证网站
  • asp网站中停止后面代码的运行/山西百度查关键词排名
  • 服装行业网站开发/国内seo工具