1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
<template>
<Generic :item="item">
<template #content>
<p class="title is-4">{{ item.name }}</p>
<p class="subtitle is-6">
<template v-if="item.subtitle">
{{ item.subtitle }}
</template>
<template v-else-if="vms">
<div v-if="loading">
<strong>Loading...</strong>
</div>
<div v-else-if="error">
<strong class="danger">Error loading info</strong>
</div>
<div v-else class="metrics">
<span>VMs: <span class="is-number"><strong>{{ vms.running }}</strong>/{{vms.total}}</span></span>
<span>Disk: <strong class="is-number" :class="statusClass(diskUsed)">{{ diskUsed }}%</strong></span>
<span>Mem: <strong class="is-number" :class="statusClass(memoryUsed)">{{ memoryUsed }}%</strong></span>
<span>CPU: <strong class="is-number" :class="statusClass(cpuUsed)">{{ cpuUsed }}%</strong></span>
</div>
</template>
</p>
</template>
<template #indicator>
<i v-if="loading" class="fa fa-circle-notch fa-spin fa-2xl"></i>
<i v-if="error" class="fa fa-exclamation-circle fa-2xl danger"></i>
</template>
</Generic>
</template>
<script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue";
export default {
name: "Proxmox",
mixins: [service],
props: {
item: Object,
},
components: {
Generic,
},
data: () => ({
vms: {
total: 0,
running: 0
},
memoryUsed: 0,
diskUsed: 0,
cpuUsed: 0,
error: false,
loading: true
}),
created() {
this.fetchStatus();
},
methods: {
statusClass(value) {
if (value > this.item.danger_value) return 'danger';
if (value > this.item.warning_value) return 'warning';
return 'healthy'
},
fetchStatus: async function () {
try {
const options = {
headers: {
"Authorization": this.item.api_token
}
}
const status = await this.fetch(`/api2/json/nodes/${this.item.node}/status`, options);
// main metrics:
this.memoryUsed = ( (status.data.memory.used * 100) / status.data.memory.total ).toFixed(1);
this.diskUsed = ( (status.data.rootfs.used * 100) / status.data.rootfs.total ).toFixed(1);
this.cpuUsed = (status.data.cpu * 100).toFixed(1);
// vms:
const vms = await this.fetch(`/api2/json/nodes/${this.item.node}/qemu`, options);
this.vms.total += vms.data.length;
this.vms.running += vms.data.filter( i => i.status === 'running' ).length;
this.error = false;
} catch(err) {
console.log(err);
this.error = true;
}
this.loading = false;
},
},
};
</script>
<style scoped lang="scss">
.is-number {
font-family: "Lato"
}
.healthy {
color: green
}
.warning {
color: orange
}
.danger {
color: red
}
.metrics {
display: flex;
justify-content: space-between;
}
</style>
|