-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
chore: migrate steam to an monitoring type and add a test #6652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
CommanderStorm
wants to merge
13
commits into
louislam:master
Choose a base branch
from
CommanderStorm:steam-monitoring-type
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+190
−50
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
8e8d05f
Fix shield image links in README.md
CommanderStorm 63017e3
Merge branch 'louislam:master' into master
CommanderStorm 072a661
fix: webhook method is undefined on older notification providers (#6650)
CommanderStorm 71670f3
chore: improve misc i18n things (#6645)
CommanderStorm a052ae1
feat: add Halo PSA webhook notification provider (#6560)
Yasindu20 19e6e95
chore: make the monitors consistently log using this.name where appro…
CommanderStorm a44cfd1
move steam
CommanderStorm 31b5c84
tmp
CommanderStorm 5c67062
remove one if
CommanderStorm 6647bed
simplify test
CommanderStorm 738900a
Merge branch 'master' into steam-monitoring-type
CommanderStorm a2d67b7
[autofix.ci] apply automated fixes
autofix-ci[bot] c52a57d
Merge branch 'master' into steam-monitoring-type
CommanderStorm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| const { MonitorType } = require("./monitor-type"); | ||
| const { | ||
| UP, | ||
| PING_COUNT_DEFAULT, | ||
| PING_GLOBAL_TIMEOUT_DEFAULT, | ||
| PING_PER_REQUEST_TIMEOUT_DEFAULT, | ||
| } = require("../../src/util"); | ||
| const { ping, checkStatusCode, setting } = require("../util-server"); | ||
| const axios = require("axios"); | ||
| const https = require("https"); | ||
| const http = require("http"); | ||
| const crypto = require("crypto"); | ||
|
|
||
| class SteamMonitorType extends MonitorType { | ||
| name = "steam"; | ||
| steamApiUrl = "https://api.steampowered.com/IGameServersService/GetServerList/v1/"; | ||
|
|
||
| /** | ||
| * @inheritdoc | ||
| */ | ||
| async check(monitor, heartbeat, _server) { | ||
| const res = await this.getServerList(monitor); | ||
| if (res.data.response && res.data.response.servers && res.data.response.servers.length > 0) { | ||
| heartbeat.status = UP; | ||
| heartbeat.msg = res.data.response.servers[0].name; | ||
|
|
||
| try { | ||
| heartbeat.ping = await ping( | ||
| monitor.hostname, | ||
| PING_COUNT_DEFAULT, | ||
| "", | ||
| true, | ||
| monitor.packetSize, | ||
| PING_GLOBAL_TIMEOUT_DEFAULT, | ||
| PING_PER_REQUEST_TIMEOUT_DEFAULT | ||
| ); | ||
| } catch (_) {} | ||
| } else { | ||
| throw new Error("Server not found on Steam"); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Get server list from Steam API | ||
| * @param {Monitor} monitor Monitor object | ||
| * @returns {Promise<axios.AxiosResponse>} Axios response object containing server list data | ||
| * @throws {Error} If Steam API Key is not configured | ||
| */ | ||
| async getServerList(monitor) { | ||
| const steamAPIKey = await setting("steamAPIKey"); | ||
| const filter = `addr\\${monitor.hostname}:${monitor.port}`; | ||
|
|
||
| if (!steamAPIKey) { | ||
| throw new Error("Steam API Key not found"); | ||
| } | ||
| const options = { | ||
| timeout: monitor.timeout * 1000, | ||
| headers: { | ||
| Accept: "*/*", | ||
| }, | ||
| httpsAgent: new https.Agent({ | ||
| maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) | ||
| rejectUnauthorized: !monitor.ignoreTls, | ||
| secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT, | ||
| }), | ||
| httpAgent: new http.Agent({ | ||
| maxCachedSessions: 0, | ||
| }), | ||
| maxRedirects: monitor.maxredirects, | ||
| validateStatus: (status) => { | ||
| return checkStatusCode(status, monitor.getAcceptedStatuscodes()); | ||
| }, | ||
| params: { | ||
| filter: filter, | ||
| key: steamAPIKey, | ||
| }, | ||
| }; | ||
| return await axios.get(this.steamApiUrl, options); | ||
| } | ||
| } | ||
|
|
||
| module.exports = { | ||
| SteamMonitorType, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| process.env.UPTIME_KUMA_HIDE_LOG = ["info_db", "info_server"].join(","); | ||
|
|
||
| const { describe, test, before, after } = require("node:test"); | ||
| const assert = require("node:assert"); | ||
| const express = require("express"); | ||
| const { UP, PENDING } = require("../../../src/util"); | ||
| const { SteamMonitorType } = require("../../../server/monitor-types/steam"); | ||
| const { setSetting } = require("../../../server/util-server"); | ||
| const TestDB = require("../../mock-testdb"); | ||
|
|
||
| const testDb = new TestDB(); | ||
| const TEST_PORT = 30158; | ||
| let mockServer; | ||
|
|
||
| describe("Steam Monitor", () => { | ||
| before(async () => { | ||
| await testDb.create(); | ||
| await setSetting("steamAPIKey", "test-steam-api-key"); | ||
|
|
||
| // Create shared mock Steam API server with different endpoints | ||
| const app = express(); | ||
| app.use(express.json()); | ||
| app.get("/GetServerList/", (req, res) => { | ||
| res.json({ | ||
| response: { | ||
| servers: [ | ||
| { | ||
| name: "Test Game Server", | ||
| addr: "127.0.0.1:27015", | ||
| }, | ||
| ], | ||
| }, | ||
| }); | ||
| }); | ||
| app.get("/EmptyGetServerList/", (req, res) => { | ||
| res.json({ | ||
| response: { | ||
| servers: [], | ||
| }, | ||
| }); | ||
| }); | ||
|
|
||
| mockServer = await new Promise((resolve) => { | ||
| const server = app.listen(TEST_PORT, () => resolve(server)); | ||
| }); | ||
| }); | ||
|
|
||
| after(async () => { | ||
| if (mockServer) { | ||
| await new Promise((resolve) => mockServer.close(resolve)); | ||
| } | ||
| await testDb.destroy(); | ||
| }); | ||
|
|
||
| test("check() sets status to UP when Steam API returns valid server response", async () => { | ||
| const steamMonitor = new SteamMonitorType(); | ||
| steamMonitor.steamApiUrl = `http://127.0.0.1:${TEST_PORT}/GetServerList/`; | ||
|
|
||
| const monitor = { | ||
| hostname: "127.0.0.1", | ||
| port: 27015, | ||
| timeout: 2, | ||
| packetSize: 56, | ||
CommanderStorm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ignoreTls: false, | ||
| maxredirects: 10, | ||
| getAcceptedStatuscodes: () => ["200-299"], | ||
| }; | ||
|
|
||
| const heartbeat = { | ||
| msg: "", | ||
| status: PENDING, | ||
| ping: null, | ||
| }; | ||
|
|
||
| await steamMonitor.check(monitor, heartbeat, {}); | ||
|
|
||
| assert.strictEqual(heartbeat.status, UP); | ||
| assert.strictEqual(heartbeat.msg, "Test Game Server"); | ||
| // Note: ping may be null or a value depending on if ICMP ping succeeds | ||
| }); | ||
|
|
||
| test("check() throws error when Steam API returns empty server list", async () => { | ||
| const steamMonitor = new SteamMonitorType(); | ||
| steamMonitor.steamApiUrl = `http://127.0.0.1:${TEST_PORT}/EmptyGetServerList/`; | ||
|
|
||
| const monitor = { | ||
| hostname: "127.0.0.1", | ||
| port: 27015, | ||
| timeout: 2, | ||
| ignoreTls: false, | ||
| maxredirects: 10, | ||
| getAcceptedStatuscodes: () => ["200-299"], | ||
| }; | ||
|
|
||
| const heartbeat = { | ||
| msg: "", | ||
| status: PENDING, | ||
| }; | ||
|
|
||
| await assert.rejects(steamMonitor.check(monitor, heartbeat, {}), { | ||
| message: "Server not found on Steam", | ||
| }); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.