mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-27 16:54:04 +00:00
Compare commits
3 commits
641c58597c
...
51fc1b997c
Author | SHA1 | Date | |
---|---|---|---|
|
51fc1b997c | ||
|
6899603eb7 | ||
|
bd719d9987 |
6 changed files with 79 additions and 7 deletions
|
@ -23,7 +23,7 @@ It is a temporary live demo, all data will be deleted after 10 minutes. Sponsore
|
|||
|
||||
## ⭐ Features
|
||||
|
||||
- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
|
||||
- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers / Docker Services
|
||||
- Fancy, Reactive, Fast UI/UX
|
||||
- Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
|
||||
- 20-second intervals
|
||||
|
|
11
db/knex_migrations/2024-10-17-0000-add-docker-service.js
Normal file
11
db/knex_migrations/2024-10-17-0000-add-docker-service.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
exports.up = function (knex) {
|
||||
return knex.schema.alterTable("monitor", function (table) {
|
||||
table.string("docker_service", 255);
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema.alterTable("monitor", function (table) {
|
||||
table.dropColumn("docker_service");
|
||||
});
|
||||
};
|
|
@ -120,6 +120,7 @@ class Monitor extends BeanModel {
|
|||
dns_resolve_server: this.dns_resolve_server,
|
||||
dns_last_result: this.dns_last_result,
|
||||
docker_container: this.docker_container,
|
||||
docker_service: this.docker_service,
|
||||
docker_host: this.docker_host,
|
||||
proxyId: this.proxy_id,
|
||||
notificationIDList: preloadData.notifications.get(this.id) || {},
|
||||
|
@ -757,6 +758,54 @@ class Monitor extends BeanModel {
|
|||
} else {
|
||||
throw Error("Container State is " + res.data.State.Status);
|
||||
}
|
||||
} else if (this.type === "docker-service-availability") { // TODO: add a service-health to count running vs desired (needs services api)
|
||||
log.debug("monitor", `[${this.name}] Prepare Options for Axios`);
|
||||
|
||||
const options = {
|
||||
url: `/tasks?filters={"service":{"${this.docker_service}":true}}`,
|
||||
timeout: this.interval * 1000 * 0.8,
|
||||
headers: {
|
||||
"Accept": "*/*",
|
||||
},
|
||||
httpsAgent: new https.Agent({
|
||||
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
|
||||
rejectUnauthorized: !this.getIgnoreTls(),
|
||||
secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
|
||||
}),
|
||||
httpAgent: new http.Agent({
|
||||
maxCachedSessions: 0,
|
||||
}),
|
||||
};
|
||||
|
||||
const dockerHost = await R.load("docker_host", this.docker_host);
|
||||
|
||||
if (!dockerHost) {
|
||||
throw new Error("Failed to load docker host config");
|
||||
}
|
||||
|
||||
if (dockerHost._dockerType === "socket") {
|
||||
options.socketPath = dockerHost._dockerDaemon;
|
||||
} else if (dockerHost._dockerType === "tcp") {
|
||||
options.baseURL = DockerHost.patchDockerURL(dockerHost._dockerDaemon);
|
||||
options.httpsAgent = new https.Agent(
|
||||
DockerHost.getHttpsAgentOptions(dockerHost._dockerType, options.baseURL)
|
||||
);
|
||||
}
|
||||
|
||||
log.debug("monitor", `[${this.name}] Axios Request (get service tasks)`);
|
||||
let res = await axios.request(options);
|
||||
|
||||
if (res.data.message) {
|
||||
throw Error(res.data.message);
|
||||
}
|
||||
|
||||
if (res.data.filter((task) => task.Status.State === "running").length) {
|
||||
bean.status = UP;
|
||||
bean.msg = `Service: ${this.docker_service} is available`;
|
||||
} else {
|
||||
bean.status = DOWN;
|
||||
bean.msg = `Service: ${this.docker_service} is Down. No replicas available`;
|
||||
}
|
||||
} else if (this.type === "sqlserver") {
|
||||
let startTime = dayjs().valueOf();
|
||||
|
||||
|
|
|
@ -828,6 +828,7 @@ let needSetup = false;
|
|||
bean.dns_resolve_server = monitor.dns_resolve_server;
|
||||
bean.pushToken = monitor.pushToken;
|
||||
bean.docker_container = monitor.docker_container;
|
||||
bean.docker_service = monitor.docker_service;
|
||||
bean.docker_host = monitor.docker_host;
|
||||
bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null;
|
||||
bean.mqttUsername = monitor.mqttUsername;
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="sendgrid-from-email" class="form-label">{{ $t("From Email") }}</label>
|
||||
<input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="email" class="form-control" required>
|
||||
<input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="sendgrid-to-email" class="form-label">{{ $t("To Email") }}</label>
|
||||
<input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="email" class="form-control" required>
|
||||
<input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="sendgrid-cc-email" class="form-label">{{ $t("smtpCC") }}</label>
|
||||
<input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="email" class="form-control">
|
||||
<input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="text" class="form-control">
|
||||
<div class="form-text">{{ $t("Separate multiple email addresses with commas") }}</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="sendgrid-bcc-email" class="form-label">{{ $t("smtpBCC") }}</label>
|
||||
<input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="email" class="form-control">
|
||||
<input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="text" class="form-control">
|
||||
<small class="form-text text-muted">{{ $t("Separate multiple email addresses with commas") }}</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
<option value="docker">
|
||||
{{ $t("Docker Container") }}
|
||||
</option>
|
||||
<option value="docker-service-availability">
|
||||
{{ $t("Docker Service (Simple Availability)") }}
|
||||
</option>
|
||||
|
||||
<option value="real-browser">
|
||||
HTTP(s) - Browser Engine (Chrome/Chromium) (Beta)
|
||||
|
@ -414,9 +417,16 @@
|
|||
<input id="docker_container" v-model="monitor.docker_container" type="text" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<!-- Docker Service Name / ID -->
|
||||
<!-- For Docker Service Type -->
|
||||
<div v-if="monitor.type === 'docker-service-availability'" class="my-3">
|
||||
<label for="docker_service" class="form-label">{{ $t("Service Name / ID") }}</label>
|
||||
<input id="docker_service" v-model="monitor.docker_service" type="text" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<!-- Docker Host -->
|
||||
<!-- For Docker Type -->
|
||||
<div v-if="monitor.type === 'docker'" class="my-3">
|
||||
<div v-if="['docker', 'docker-service-availability'].includes(monitor.type)" class="my-3">
|
||||
<div class="mb-3">
|
||||
<label for="docker-host" class="form-label">{{ $t("Docker Host") }}</label>
|
||||
<ActionSelect
|
||||
|
@ -1089,6 +1099,7 @@ const monitorDefaults = {
|
|||
dns_resolve_type: "A",
|
||||
dns_resolve_server: "1.1.1.1",
|
||||
docker_container: "",
|
||||
docker_service: "",
|
||||
docker_host: null,
|
||||
proxyId: null,
|
||||
mqttUsername: "",
|
||||
|
@ -1665,7 +1676,7 @@ message HealthCheckResponse {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (this.monitor.type === "docker") {
|
||||
if ([ "docker", "docker-service-availability" ].includes(this.monitor.type)) {
|
||||
if (this.monitor.docker_host == null) {
|
||||
toast.error(this.$t("DockerHostRequired"));
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue