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