Added Portainer custom service

This commit is contained in:
Evan Steinkerchner 2022-03-01 20:55:45 -05:00
parent ba2c7c5c57
commit a1a70d4a3c
2 changed files with 138 additions and 0 deletions

View File

@ -125,3 +125,19 @@ For Prometheus you need to set the type to Prometheus and provide a url.
url: "http://192.168.0.151/"
# subtitle: "Monitor data server"
```
## Portainer
This service displays info about the total number of containers managed by your Portainer instance.
In order to use it, you must be using Portainer version 1.11 or later. Generate an access token from the UI and pass
it to the apikey field.
See https://docs.portainer.io/v/ce-2.11/user/account-settings#access-tokens
```yaml
- name: "Portainer"
logo: "assets/tools/sample.png"
url: "http://192.168.0.151/"
type: "Portainer"
apikey: "MY-SUPER-SECRET-API-KEY"
```

View File

@ -0,0 +1,122 @@
<template>
<Generic :item="item">
<template #indicator>
<div class="notifs">
<strong v-if="running > 0" class="notif running" title="Running">
{{ running }}
</strong>
<strong v-if="dead > 0" class="notif dead" title="Dead">
{{ dead }}
</strong>
<strong v-if="misc > 0" class="notif misc" title="Other (creating, paused, exited, etc.)">
{{ misc }}
</strong>
</div>
</template>
</Generic>
</template>
<script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue";
export default {
name: "Portainer",
mixins: [service],
props: {
item: Object,
},
components: {
Generic,
},
data: () => ({
endpoints: null,
containers: null,
}),
computed: {
running: function () {
if (!this.containers) {
return "";
}
return this.containers.filter((container) => {
return container.State.toLowerCase() === "running";
}).length;
},
dead: function () {
if (!this.containers) {
return "";
}
return this.containers.filter((container) => {
return container.State.toLowerCase() === "dead";
}).length || 1;
},
misc: function () {
if (!this.containers) {
return "";
}
return this.containers.filter((container) => {
return container.State.toLowerCase() !== "running" && container.State.toLowerCase() !== "dead";
}).length;
},
},
created() {
this.fetchStatus();
},
methods: {
fetchStatus: async function () {
const headers = {
"X-Api-Key": this.item.apikey,
};
this.endpoints = await this.fetch("/api/endpoints", { headers })
.catch((e) => {
console.error(e);
});
let containers = [];
for (let endpoint of this.endpoints) {
const uri = `/api/endpoints/${endpoint.Id}/docker/containers/json?all=1`;
const endpointContainers = await this.fetch(uri, { headers })
.catch((e) => {
console.error(e);
});
containers = containers.concat(endpointContainers);
}
this.containers = containers;
},
},
};
</script>
<style scoped lang="scss">
.notifs {
position: absolute;
color: white;
font-family: sans-serif;
top: 0.3em;
right: 0.5em;
.notif {
display: inline-block;
padding: 0.2em 0.35em;
border-radius: 0.25em;
position: relative;
margin-left: 0.3em;
font-size: 0.8em;
&.running {
background-color: #4fd671;
}
&.dead {
background-color: #e51111;
}
&.misc {
background-color: #2ed0c8;
}
}
}
</style>