Skip to content

Commit

Permalink
server-checks chatops
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssa committed Oct 16, 2024
1 parent d4970dc commit 2f48731
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
"dependencies": {
"@beenotung/level-ts": "^1.15.0",
"@types/ioredis": "^4.28.10",
"@types/node": "^22.7.5",
"axios": "^0.24.0",
"detritus-client-rest": "^0.10.5",
"detritus-client-socket": "^0.8.3",
"ioredis": "^5.0.2",
"ts-node": "^10.7.0",
"typescript": "^4.4.3"
"typescript": "^5.6.3"
}
}
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default {
chat_role_id: "823595534567866428",
restrict_role_id: "895972446992228382",
admin_role_id: "686489711719612502",
infra_role_id: "1291763746657669211",
// 2 weeks
newAccountDuration:
60 // seconds
Expand Down
150 changes: 150 additions & 0 deletions src/evt/messageCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export default async (evt: any, ctx: Context) => {

const content: string = evt.content.toLowerCase();

if (evt.author.id != "883545422860283964") return;

if (content == "?ping")
return await ctx.rest.createMessage(evt.channel_id, "meow!");

Expand Down Expand Up @@ -116,4 +118,152 @@ export default async (evt: any, ctx: Context) => {

await ctx.rest.createMessage(evt.channel_id, res);
}

if (content?.startsWith("+s") && evt.member.roles.includes(config.infra_role_id)) {
if (content == "+s h" || content == "+s help") {
await ctx.rest.createMessage(evt.channel_id, "server-checks chatops\n\n`+s`: list silences\n`+s +<silence>`: create silence\n`+s -<silence>`: delete silence"
+ "\n`+s override`: override @infra pings to your account (for testing and such)\n`+s clearoverride`: clear ping override");
} else if (content.length == 2) {
let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{ headers: { authorization: `Bearer ${process.env.cf_token}` } })
.then((x: any) => x.json());
console.log(res);
let silences = res.map((x: any) => `- \`${x.check ?? (x.checkPrefix+"*")}@${x.node}\``).join("\n");
if (silences == "") silences = "no silences set";
await ctx.rest.createMessage(evt.channel_id, silences);
} else if (content[3] == "+") {
// add silence
let newsilence: any = content.slice(4).split("@");
if (newsilence.length != 2) {
await ctx.rest.createMessage(evt.channel_id, "format: `check@host`, optionally accepting a wildcard for hostname (`somecheck@*`) and/or at end of check name (someprefix*@somehost)")
return
}
// parse text
newsilence = [newsilence].map(x => ({ check: x[0], checkPrefix: null, node: x[1] }))
.map(x => {
if (x.check.endsWith("*")) {
x.checkPrefix = x.check.slice(0, -1);
x.check = null;
}
return x;
})[0];
console.log(newsilence);

let curSilences = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{ headers: { authorization: `Bearer ${process.env.cf_token}` } })
.then((x: any) => x.json());

if (!!curSilences.find((x: any) => x.check == newsilence.check && x.checkPrefix == newsilence.checkPrefix && x.node == newsilence.node)) {
await ctx.rest.createMessage(evt.channel_id, "check already exists");
return;
}

curSilences.push(newsilence);

let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{
method: "PUT",
headers: { authorization: `Bearer ${process.env.cf_token}` },
body: JSON.stringify(curSilences),
})
.then((x: any) => x.json());
if (res.success) {
await ctx.rest.createMessage(evt.channel_id, "ok");
} else {
await ctx.rest.createMessage(evt.channel_id, `not ok: ${JSON.stringify(res)}`);
}
} else if (content[3] == "-") {
// remove silence
let newsilence: any = content.slice(4).split("@");
if (newsilence.length != 2) {
await ctx.rest.createMessage(evt.channel_id, "format: `check@host`, optionally accepting a wildcard for hostname (`somecheck@*`) and/or at end of check name (someprefix*@somehost)")
return
}
// parse text
newsilence = [newsilence].map(x => ({ check: x[0], checkPrefix: null, node: x[1] }))
.map(x => {
if (x.check.endsWith("*")) {
x.checkPrefix = x.check.slice(0, -1);
x.check = null;
}
return x;
})[0];
console.log(newsilence);

let curSilences = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{ headers: { authorization: `Bearer ${process.env.cf_token}` } })
.then((x: any) => x.json());
console.log("del: get", curSilences);

let idx = curSilences.find((x: any) => x.check == newsilence.check && x.checkPrefix == newsilence.checkPrefix && x.node == newsilence.node);

if (idx == null) {
await ctx.rest.createMessage(evt.channel_id, "check doesn't exist");
return;
}

curSilences.splice(idx, 1);
console.log("del: send", curSilences);

let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{
method: "PUT",
headers: { authorization: `Bearer ${process.env.cf_token}` },
body: JSON.stringify(curSilences),
})
.then((x: any) => x.json());
if (res.success) {
await ctx.rest.createMessage(evt.channel_id, "ok");
} else {
await ctx.rest.createMessage(evt.channel_id, `not ok: ${JSON.stringify(res)}`);
}
} else if (content == "+s clear") {
let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/silences`,
{
method: "PUT",
headers: { authorization: `Bearer ${process.env.cf_token}` },
body: JSON.stringify([]),
})
.then((x: any) => x.json());
if (res.success) {
await ctx.rest.createMessage(evt.channel_id, "ok");
} else {
await ctx.rest.createMessage(evt.channel_id, `not ok: ${JSON.stringify(res)}`);
}
} else if (content == "+s override") {
let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/notif`,
{
method: "PUT",
headers: { authorization: `Bearer ${process.env.cf_token}` },
body: `<@${evt.author.id}>`,
})
.then((x: any) => x.json());
if (res.success) {
await ctx.rest.createMessage(evt.channel_id, "ok");
} else {
await ctx.rest.createMessage(evt.channel_id, `not ok: ${JSON.stringify(res)}`);
}
} else if (content == "+s clearoverride") {
let res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.cf_account}/storage/kv/namespaces/4fd4893d94354dac96da55a68c5df4fc/values/notif`,
{
method: "PUT",
headers: { authorization: `Bearer ${process.env.cf_token}` },
body: "",
})
.then((x: any) => x.json());
if (res.success) {
await ctx.rest.createMessage(evt.channel_id, "ok");
} else {
await ctx.rest.createMessage(evt.channel_id, `not ok: ${JSON.stringify(res)}`);
}
}
}
}
20 changes: 16 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.21.tgz#6359d8cf73481e312a43886fa50afc70ce5592c6"
integrity sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==

"@types/node@^22.7.5":
version "22.7.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==
dependencies:
undici-types "~6.19.2"

abstract-leveldown@^6.2.1:
version "6.3.0"
resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a"
Expand Down Expand Up @@ -642,10 +649,15 @@ typedarray-to-buffer@~3.1.5:
dependencies:
is-typedarray "^1.0.0"

typescript@^4.4.3:
version "4.4.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==
typescript@^5.6.3:
version "5.6.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b"
integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==

undici-types@~6.19.2:
version "6.19.8"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==

util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
Expand Down

0 comments on commit 2f48731

Please sign in to comment.