]>
Commit | Line | Data |
---|---|---|
10f4cca6 | 1 | <template> |
24b6dedb BW |
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 | |
17 | v-else | |
18 | class="metrics" | |
19 | :class="{ | |
20 | 'is-size-7-mobile': item.small_font_on_small_screens, | |
21 | 'is-small': item.small_font_on_desktop, | |
22 | }" | |
23 | > | |
24 | <span v-if="isValueShown('vms')" class="margined" | |
25 | >VMs: | |
26 | <span class="is-number" | |
27 | ><span class="has-text-weight-bold">{{ vms.running }}</span | |
28 | ><span v-if="isValueShown('vms_total')" | |
29 | >/{{ vms.total }}</span | |
30 | ></span | |
31 | ></span | |
32 | > | |
33 | <span v-if="isValueShown('lxcs')" class="margined" | |
34 | >LXCs: | |
35 | <span class="is-number" | |
36 | ><span class="has-text-weight-bold">{{ lxcs.running }}</span | |
37 | ><span v-if="isValueShown('lxcs_total')" | |
38 | >/{{ lxcs.total }}</span | |
39 | ></span | |
40 | ></span | |
41 | > | |
42 | <span v-if="isValueShown('disk')" class="margined" | |
43 | >Disk: | |
44 | <span | |
45 | class="has-text-weight-bold is-number" | |
46 | :class="statusClass(diskUsed)" | |
47 | >{{ diskUsed }}%</span | |
48 | ></span | |
49 | > | |
50 | <span v-if="isValueShown('mem')" class="margined" | |
51 | >Mem: | |
52 | <span | |
53 | class="has-text-weight-bold is-number" | |
54 | :class="statusClass(memoryUsed)" | |
55 | >{{ memoryUsed }}%</span | |
56 | ></span | |
57 | > | |
58 | <span v-if="isValueShown('cpu')" class="margined" | |
59 | >CPU: | |
60 | <span | |
61 | class="has-text-weight-bold is-number" | |
62 | :class="statusClass(cpuUsed)" | |
63 | >{{ cpuUsed }}%</span | |
64 | ></span | |
65 | > | |
66 | </div> | |
67 | </template> | |
68 | </p> | |
69 | </template> | |
70 | <template #indicator> | |
71 | <i v-if="loading" class="fa fa-circle-notch fa-spin fa-2xl"></i> | |
72 | <i v-if="error" class="fa fa-exclamation-circle fa-2xl danger"></i> | |
73 | </template> | |
74 | </Generic> | |
75 | </template> | |
76 | ||
77 | <script> | |
78 | import service from "@/mixins/service.js"; | |
79 | import Generic from "./Generic.vue"; | |
80 | ||
81 | export default { | |
82 | name: "Proxmox", | |
83 | mixins: [service], | |
84 | props: { | |
85 | item: Object, | |
86 | }, | |
87 | components: { | |
88 | Generic, | |
89 | }, | |
90 | data: () => ({ | |
91 | vms: { | |
92 | total: 0, | |
93 | running: 0, | |
10f4cca6 | 94 | }, |
24b6dedb BW |
95 | lxcs: { |
96 | total: 0, | |
97 | running: 0, | |
10f4cca6 | 98 | }, |
24b6dedb BW |
99 | memoryUsed: 0, |
100 | diskUsed: 0, | |
101 | cpuUsed: 0, | |
102 | hide: [], | |
103 | error: false, | |
104 | loading: true, | |
105 | }), | |
106 | created() { | |
107 | if (this.item.hide) this.hide = this.item.hide; | |
108 | this.fetchStatus(); | |
109 | }, | |
110 | methods: { | |
111 | statusClass(value) { | |
112 | if (value > this.item.danger_value) return "danger"; | |
113 | if (value > this.item.warning_value) return "warning"; | |
114 | return "healthy"; | |
10f4cca6 | 115 | }, |
24b6dedb BW |
116 | fetchStatus: async function () { |
117 | try { | |
118 | const options = { | |
119 | headers: { | |
120 | Authorization: this.item.api_token, | |
121 | }, | |
122 | }; | |
123 | const status = await this.fetch( | |
124 | `/api2/json/nodes/${this.item.node}/status`, | |
125 | options | |
126 | ); | |
127 | // main metrics: | |
128 | const decimalsToShow = this.item.hide_decimals ? 0 : 1; | |
129 | this.memoryUsed = ( | |
130 | (status.data.memory.used * 100) / | |
131 | status.data.memory.total | |
132 | ).toFixed(decimalsToShow); | |
133 | this.diskUsed = ( | |
134 | (status.data.rootfs.used * 100) / | |
135 | status.data.rootfs.total | |
136 | ).toFixed(decimalsToShow); | |
137 | this.cpuUsed = (status.data.cpu * 100).toFixed(decimalsToShow); | |
138 | // vms: | |
139 | if (this.isValueShown("vms")) { | |
140 | const vms = await this.fetch( | |
141 | `/api2/json/nodes/${this.item.node}/qemu`, | |
142 | options | |
143 | ); | |
144 | this.parseVMsAndLXCs(vms, this.vms); | |
10f4cca6 | 145 | } |
24b6dedb BW |
146 | // lxc containers: |
147 | if (this.isValueShown("lxcs")) { | |
148 | const lxcs = await this.fetch( | |
149 | `/api2/json/nodes/${this.item.node}/lxc`, | |
150 | options | |
151 | ); | |
152 | this.parseVMsAndLXCs(lxcs, this.lxcs); | |
153 | } | |
154 | this.error = false; | |
155 | } catch (err) { | |
156 | console.log(err); | |
157 | this.error = true; | |
d32f7f64 | 158 | } |
24b6dedb BW |
159 | this.loading = false; |
160 | }, | |
161 | parseVMsAndLXCs(items, value) { | |
162 | value.total += items.data.length; | |
163 | value.running += items.data.filter((i) => i.status === "running").length; | |
164 | // if no vms, hide this value: | |
165 | if (value.total == 0) this.hide.push("lxcs"); | |
166 | }, | |
167 | isValueShown(value) { | |
168 | return this.hide.indexOf(value) == -1; | |
10f4cca6 | 169 | }, |
24b6dedb BW |
170 | }, |
171 | }; | |
172 | </script> | |
173 | ||
174 | <style scoped lang="scss"> | |
175 | .is-number { | |
176 | font-family: "Lato"; | |
177 | } | |
178 | .healthy { | |
179 | color: green; | |
180 | } | |
181 | .warning { | |
182 | color: orange; | |
183 | } | |
184 | .danger { | |
185 | color: red; | |
186 | } | |
187 | .metrics .margined:not(:first-child) { | |
188 | margin-left: 0.3rem; | |
189 | } | |
190 | .is-small { | |
191 | font-size: small; | |
192 | } | |
193 | </style> |