Skip to content

Commit 5f1216b

Browse files
committed
fix(pods): pod 列表区别显示
1 parent ff5dd98 commit 5f1216b

File tree

3 files changed

+300
-93
lines changed

3 files changed

+300
-93
lines changed

web/dashboard/src/business/cluster/nodes/detail/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
<br>
181181
<el-tabs type="border-card" v-if="Object.keys(item.metadata).length > 0">
182182
<el-tab-pane label="Pods" v-has-permissions="{scope:'namespace',apiGroup:'',resource:'pods',verb:'list'}">
183-
<ko-detail-pods :cluster="cluster" :allocatable="item.status.allocatable" :field-selector="'spec.nodeName='+item.metadata.name"></ko-detail-pods>
183+
<ko-detail-node-pods :cluster="cluster" :allocatable="item.status.allocatable" :field-selector="'spec.nodeName='+item.metadata.name"></ko-detail-node-pods>
184184
</el-tab-pane>
185185
<el-tab-pane :label="$t('business.pod.image')">
186186
<table style="width: 90%" class="myTable">
@@ -255,13 +255,13 @@ import LayoutContent from "@/components/layout/LayoutContent"
255255
import { getNode } from "@/api/nodes"
256256
import { listPodsWithNsSelector } from "@/api/pods"
257257
import YamlEditor from "@/components/yaml-editor"
258-
import KoDetailPods from "@/components/detail/detail-pods"
258+
import KoDetailNodePods from "@/components/detail/detail-node-pods"
259259
import KoDetailBasic from "@/components/detail/detail-basic"
260260
import { checkPermissions } from "@/utils/permission"
261261
262262
export default {
263263
name: "NodeDetail",
264-
components: { KoDetailBasic, KoDetailPods, YamlEditor, LayoutContent },
264+
components: { KoDetailBasic, KoDetailNodePods, YamlEditor, LayoutContent },
265265
props: {
266266
name: String,
267267
},
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
<template>
2+
<div>
3+
<complex-table :data="pods" v-loading="loading" @search="search">
4+
<el-table-column :label="$t('commons.table.status')" min-width="45">
5+
<template v-slot:default="{row}">
6+
<el-button v-if="row.status.phase === 'Running' || row.status.phase === 'Succeeded'" type="success"
7+
size="mini" plain round>
8+
{{ row.status.phase }}
9+
</el-button>
10+
<el-button v-if="row.status.phase !== 'Running' && row.status.phase !== 'Succeeded'" type="warning"
11+
size="mini" plain round>
12+
{{ row.status.phase }}
13+
</el-button>
14+
</template>
15+
</el-table-column>
16+
<el-table-column :label="$t('commons.table.name')" prop="name" min-width="80" show-overflow-tooltip>
17+
<template v-slot:default="{row}">
18+
<span class="span-link" @click="openDetail(row)">{{ row.metadata.name }}</span>
19+
</template>
20+
</el-table-column>
21+
<el-table-column :label="$t('business.namespace.namespace')" min-width="40" prop="metadata.namespace"
22+
show-overflow-tooltip/>
23+
<el-table-column :label="'CPU ' + $t('business.workload.reservation')" min-width="45">
24+
<template v-slot:default="{row}">
25+
{{ row.cpuRequest }}
26+
</template>
27+
</el-table-column>
28+
<el-table-column :label="'CPU ' + $t('business.workload.limit')" min-width="45">
29+
<template v-slot:default="{row}">
30+
{{ row.cpuLimit }}
31+
</template>
32+
</el-table-column>
33+
<el-table-column :label="$t('business.workload.memory') + $t('business.workload.reservation')" min-width="50">
34+
<template v-slot:default="{row}">
35+
{{ row.memoryRequest }}
36+
</template>
37+
</el-table-column>
38+
<el-table-column :label="$t('business.workload.memory') + $t('business.workload.limit')" min-width="45">
39+
<template v-slot:default="{row}">
40+
{{ row.memoryLimit }}
41+
</template>
42+
</el-table-column>
43+
<el-table-column :label="$t('commons.table.created_time')" min-width="40" prop="metadata.creationTimestamp" show-overflow-tooltip fix>
44+
<template v-slot:default="{row}">
45+
{{ row.metadata.creationTimestamp | age }}
46+
</template>
47+
</el-table-column>
48+
<ko-table-operations :buttons="buttons" :label="$t('commons.table.action')"></ko-table-operations>
49+
</complex-table>
50+
51+
<el-dialog :title="'Pod ' + $t('business.pod.eviction')" width="30%" :visible.sync="evictionDialogVisible">
52+
<div style="margin-left: 50px">
53+
<p>{{ $t("business.pod.eviction_confirm") }}</p>
54+
<ul>{{ $t("business.pod.eviction_help1") }}</ul>
55+
<ul>{{ $t("business.pod.eviction_help2") }}</ul>
56+
<ul>{{ $t("business.pod.eviction_help3") }}</ul>
57+
</div>
58+
<div slot="footer" class="dialog-footer">
59+
<el-button size="small" @click="evictionDialogVisible = false">{{ $t("commons.button.cancel") }}</el-button>
60+
<el-button size="small" @click="submitEviction">{{ $t("commons.button.confirm") }}</el-button>
61+
</div>
62+
</el-dialog>
63+
64+
</div>
65+
</template>
66+
67+
<script>
68+
import ComplexTable from "@/components/complex-table"
69+
import KoTableOperations from "@/components/ko-table-operations"
70+
import {listPodsWithNsSelector, evictionPod} from "@/api/pods"
71+
import {cordonNode} from "@/api/nodes"
72+
import {checkPermissions} from "@/utils/permission"
73+
import { cpuUnitConvert, memoryUnitConvert } from "@/utils/unitConvert"
74+
75+
export default {
76+
name: "KoDetailNodePods",
77+
components: { ComplexTable, KoTableOperations },
78+
props: {
79+
cluster: String,
80+
namespace: String,
81+
selector: String,
82+
fieldSelector: String,
83+
allocatable: Object,
84+
},
85+
watch: {
86+
selector: {
87+
handler (newSelector) {
88+
if (newSelector) {
89+
this.search()
90+
}
91+
},
92+
immediate: true,
93+
},
94+
fieldSelector: {
95+
handler (newSelector) {
96+
if (newSelector) {
97+
this.search()
98+
}
99+
},
100+
immediate: true,
101+
},
102+
},
103+
data () {
104+
return {
105+
buttons: [
106+
{
107+
label: this.$t("commons.button.terminal"),
108+
icon: "iconfont iconline-terminalzhongduan",
109+
click: (row) => {
110+
this.openTerminal(row)
111+
},
112+
},
113+
{
114+
label: this.$t("commons.button.logs"),
115+
icon: "el-icon-tickets",
116+
click: (row) => {
117+
this.openTerminalLogs(row)
118+
},
119+
},
120+
{
121+
label: this.$t("business.node.drain"),
122+
icon: "el-icon-delete",
123+
click: (row) => {
124+
this.openEviction(row)
125+
},
126+
},
127+
],
128+
loading: false,
129+
evictionDialogVisible: false,
130+
pods: [],
131+
podItem: {},
132+
}
133+
},
134+
methods: {
135+
search (resetPage) {
136+
this.loading = true
137+
if (resetPage) {
138+
this.paginationConfig.currentPage = 1
139+
}
140+
if (!checkPermissions({ scope: "namespace", apiGroup: "", resource: "pods", verb: "list" })) {
141+
return
142+
}
143+
listPodsWithNsSelector(this.cluster, this.namespace, this.selector, this.fieldSelector).then((res) => {
144+
this.pods = res.items
145+
for (const item of this.pods) {
146+
let cpuLimit = 0
147+
let memoryLimit = 0
148+
let cpuRequest = 0
149+
let memoryRequest = 0
150+
for (const c of item.spec.containers) {
151+
if(c.resources?.limits?.cpu) {
152+
cpuLimit += cpuUnitConvert(c.resources.limits.cpu)
153+
}
154+
if(c.resources?.limits?.memory) {
155+
memoryLimit += memoryUnitConvert(c.resources.limits.memory)
156+
}
157+
if(c.resources?.requests?.cpu) {
158+
cpuRequest += cpuUnitConvert(c.resources.requests.cpu)
159+
}
160+
if(c.resources?.requests?.memory) {
161+
memoryRequest += memoryUnitConvert(c.resources.requests.memory)
162+
}
163+
}
164+
item.cpuLimit = cpuLimit !== 0 ? (cpuLimit + "m (" + (Math.floor(cpuLimit / cpuUnitConvert(this.allocatable.cpu) * 100)) + "%)") : 0
165+
item.memoryLimit = memoryLimit !== 0 ? (memoryLimit + "Mi (" + (Math.floor(memoryLimit / memoryUnitConvert(this.allocatable.memory) * 100)) + "%)") : 0
166+
item.cpuRequest = cpuRequest !== 0 ? (cpuRequest + "m (" + (Math.floor(cpuRequest / cpuUnitConvert(this.allocatable.cpu) * 100)) + "%)") : 0
167+
item.memoryRequest = memoryRequest !== 0 ? (memoryRequest + "Mi (" + (Math.floor(memoryRequest / memoryUnitConvert(this.allocatable.memory) * 100)) + "%)") : 0
168+
}
169+
this.loading = false
170+
})
171+
},
172+
openEviction(row) {
173+
this.evictionDialogVisible = true
174+
this.podItem = row
175+
},
176+
submitEviction() {
177+
let data = { spec: { unschedulable: true } }
178+
cordonNode(this.cluster, this.podItem.spec.nodeName, data).then(() => {
179+
const rmPod = {
180+
apiVersion: "policy/v1beta1",
181+
kind: "Eviction",
182+
metadata: {
183+
name: this.podItem.metadata.name,
184+
namespace: this.podItem.metadata.namespace,
185+
creationTimestamp: null,
186+
},
187+
deleteOptions: {},
188+
}
189+
evictionPod(this.cluster, this.podItem.metadata.namespace, this.podItem.metadata.name, rmPod).then(() => {
190+
let data = { spec: { unschedulable: false } }
191+
cordonNode(this.cluster, this.podItem.spec.nodeName, data).then(() => {
192+
this.$message({
193+
type: "success",
194+
message: this.$t("business.pod.drain_success"),
195+
})
196+
this.evictionDialogVisible = false
197+
})
198+
})
199+
})
200+
},
201+
openDetail (row) {
202+
this.$router.push({
203+
name: "PodDetail",
204+
params: { namespace: row.metadata.namespace, name: row.metadata.name },
205+
query: { yamlShow: false },
206+
})
207+
},
208+
openTerminal (row) {
209+
let c = row.spec.containers[0].name
210+
let routeUrl = this.$router.resolve({
211+
path: "/terminal",
212+
query: {
213+
cluster: this.cluster,
214+
namespace: row.metadata.namespace,
215+
pod: row.metadata.name,
216+
container: c,
217+
type: "terminal"
218+
}
219+
})
220+
window.open(routeUrl.href, "_blank")
221+
},
222+
openTerminalLogs (row) {
223+
let c = row.spec.containers[0].name
224+
let routeUrl = this.$router.resolve({
225+
path: "/terminal",
226+
query: {
227+
cluster: this.cluster,
228+
namespace: row.metadata.namespace,
229+
pod: row.metadata.name,
230+
container: c,
231+
type: "log"
232+
}
233+
})
234+
window.open(routeUrl.href, "_blank")
235+
},
236+
},
237+
}
238+
</script>
239+
240+
<style scoped>
241+
.btnSize {
242+
width: 28px;
243+
height: 28px;
244+
}
245+
</style>

0 commit comments

Comments
 (0)