mirror of https://github.com/bastienwirtz/homer
Adds custom service for Proxmox
parent
fdf6d4284d
commit
10f4cca67a
|
@ -21,6 +21,7 @@ within Homer:
|
||||||
+ [Tautulli](#tautulli)
|
+ [Tautulli](#tautulli)
|
||||||
+ [Mealie](#mealie)
|
+ [Mealie](#mealie)
|
||||||
+ [Healthchecks](#healthchecks)
|
+ [Healthchecks](#healthchecks)
|
||||||
|
+ [Proxmox](#proxmox)
|
||||||
|
|
||||||
If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
|
If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
|
||||||
|
|
||||||
|
@ -244,3 +245,20 @@ Two lines are needed in the config.yml :
|
||||||
|
|
||||||
The url must be the root url of the Healthchecks application.
|
The url must be the root url of the Healthchecks application.
|
||||||
The Healthchecks API key can be found in Settings > API Access > API key (read-only). The key is needed to access Healthchecks API.
|
The Healthchecks API key can be found in Settings > API Access > API key (read-only). The key is needed to access Healthchecks API.
|
||||||
|
|
||||||
|
## Proxmox
|
||||||
|
|
||||||
|
This service displays status information of a Proxmox node (VMs running and disk, memory and cpu used). It uses the proxmox API and [API Tokens](https://pve.proxmox.com/pve-docs/pveum-plain.html) for authorization so you need to generate one to set in the yaml config. You can set it up in Proxmox under Permissions > API Tokens. You also need to know the realm the user of the API Token is assigned to (by default pam).
|
||||||
|
|
||||||
|
Configuration example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: "Proxmox - Node"
|
||||||
|
logo: "https://www.google.com/url?sa=i&url=https%3A%2F%2Fgithub.com%2FandOTP%2FandOTP%2Fissues%2F337&psig=AOvVaw2YKVuEUIBeTUikr7kAjm8D&ust=1665323538747000&source=images&cd=vfe&ved=0CAkQjRxqFwoTCPCTruLj0PoCFQAAAAAdAAAAABAN"
|
||||||
|
type: "Proxmox"
|
||||||
|
url: "https://your.proxmox.server"
|
||||||
|
node: "your-node-name"
|
||||||
|
warning_value: 50
|
||||||
|
danger_value: 80
|
||||||
|
api_token: "PVEAPIToken=root@pam!your-api-token-name=your-api-token-key"
|
||||||
|
```
|
|
@ -0,0 +1,101 @@
|
||||||
|
<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="error">
|
||||||
|
<strong class="danger">Error loading info!</strong>
|
||||||
|
</div>
|
||||||
|
<div v-else class="metrics">
|
||||||
|
<span>VMs: <strong class="is-number">{{ vms.running }}</strong></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>
|
||||||
|
</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
|
||||||
|
}),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</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>
|
||||||
|
|
Loading…
Reference in New Issue