Mercurial > code > home > repos > racc
changeset 6:b1043d39e493
start web console
author | drewp@bigasterisk.com |
---|---|
date | Mon, 13 Mar 2023 18:53:45 -0700 |
parents | 5a99bde7a506 |
children | 0f6c6c70610c |
files | console/Dockerfile console/index.html console/ingress.yaml console/package.json console/pnpm-lock.yaml console/skaffold.yaml console/src/main.css console/src/main.ts console/tsconfig.json console/vite.config.ts |
diffstat | 10 files changed, 689 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/console/Dockerfile Mon Mar 13 18:52:00 2023 -0700 +++ b/console/Dockerfile Mon Mar 13 18:53:45 2023 -0700 @@ -1,7 +1,28 @@ FROM bang5:5000/base_basic +ENV KEYRING=/usr/share/keyrings/nodesource.gpg +ENV VERSION=node_18.x +ENV DISTRO=jammy +RUN apt-get install -y gpg + +RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee "$KEYRING" >/dev/null && \ + echo "deb [signed-by=$KEYRING] https://deb.nodesource.com/$VERSION $DISTRO main" | tee /etc/apt/sources.list.d/nodesource.list && \ + echo "deb-src [signed-by=$KEYRING] https://deb.nodesource.com/$VERSION $DISTRO main" | tee -a /etc/apt/sources.list.d/nodesource.list && \ + apt-get update && \ + apt-get remove -y nodejs libnode-dev libnode72 && \ + apt-get install -y nodejs && \ + apt autoremove -y && \ + pnpm add -g pnpm + WORKDIR /opt COPY .pdm.toml pdm.lock pyproject.toml ./ RUN pdm sync +RUN pnpm config set @bigasterisk:registry https://bigasterisk.com/js/ +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install + +COPY console.py index.html tsconfig.json vite.config.ts ./ +COPY src ./src/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/index.html Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>racc admin</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" type="text/css" media="screen" href="src/main.css" /> + + <script type="module" src="src/main.ts"></script> + </head> + <body> + racc admin + <div id="chart1" style="width:100%; height: 800px"></div> + + <p><a href="https://bigasterisk.com/m/targets?endpoint_search=5150">targets list</a></p> + <div id="debug1"></div> + + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/ingress.yaml Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: racc-console + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + ingress.pomerium.io/allow_public_unauthenticated_access: "false" + ingress.pomerium.io/pass_identity_headers: "true" + ingress.pomerium.io/preserve_host_header: "true" + ingress.pomerium.io/policy: | + allow: + or: + - { email: { is: "drewpca@gmail.com" }} + - { email: { is: "kelsimp@gmail.com" }} + ingress.pomerium.io/allow_websockets: "true" +spec: + ingressClassName: pomerium + rules: + - host: "bigasterisk.com" + http: + paths: + - {pathType: Prefix, path: /racc/console/api/, backend: { service: { name: racc-console, port: { name: py } } }} + - {pathType: Prefix, path: /racc/console/metrics, backend: { service: { name: racc-console, port: { name: py } } }} + - {pathType: Prefix, path: /racc/console/, backend: { service: { name: racc-console, port: { name: vite } } }} + tls: + - hosts: [bigasterisk.com] + secretName: bigasterisk.com-tls
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/package.json Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,21 @@ +{ + "name": "racc", + "version": "1.0.0", + "description": "apt install libxss-dev", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@types/tabulator-tables": "^5.4.5", + "typescript": "^4.9.5" + }, + "dependencies": { + "date-fns": "^2.29.3", + "echarts": "^5.4.1", + "tabulator-tables": "^5.4.4", + "vite": "^4.1.4" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/pnpm-lock.yaml Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,393 @@ +lockfileVersion: 5.3 + +specifiers: + '@types/tabulator-tables': ^5.4.5 + date-fns: ^2.29.3 + echarts: ^5.4.1 + tabulator-tables: ^5.4.4 + typescript: ^4.9.5 + vite: ^4.1.4 + +dependencies: + date-fns: 2.29.3 + echarts: 5.4.1 + tabulator-tables: 5.4.4 + vite: 4.1.4 + +devDependencies: + '@types/tabulator-tables': 5.4.5 + typescript: 4.9.5 + +packages: + + /@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@types/tabulator-tables/5.4.5: + resolution: {integrity: sha512-JCmigqOupYh/21JG0GqlrICyDyakzj1XJId6WoqUP5XSz1Khi1C7/skqdlN3B3AkUBIqYZ07QVIpUnyxknxODQ==} + dev: true + + /date-fns/2.29.3: + resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} + engines: {node: '>=0.11'} + dev: false + + /echarts/5.4.1: + resolution: {integrity: sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==} + dependencies: + tslib: 2.3.0 + zrender: 5.4.1 + dev: false + + /esbuild/0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + dev: false + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: false + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: false + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: false + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: false + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: false + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: false + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: false + + /rollup/3.19.1: + resolution: {integrity: sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: false + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /tabulator-tables/5.4.4: + resolution: {integrity: sha512-WqPWLRwrD8UMISUjQqZyj6y9k3ajQBs7eJtRosbt9q8RRkZlYCJYGxLt3L44jEXaQCE5q5EJFbGeDUEDJa1a3w==} + dev: false + + /tslib/2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + dev: false + + /typescript/4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /vite/4.1.4: + resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.19.1 + optionalDependencies: + fsevents: 2.3.2 + dev: false + + /zrender/5.4.1: + resolution: {integrity: sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==} + dependencies: + tslib: 2.3.0 + dev: false
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/skaffold.yaml Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,21 @@ +apiVersion: skaffold/v3 +kind: Config +metadata: + name: racc +build: + artifacts: + - image: bang5:5000/racc_console_image + sync: + infer: + - src/* + - index.html + tagPolicy: + dateTime: + format: 2006-01-02_15-04-05 + timezone: Local +manifests: + rawYaml: + - deploy.yaml + - ingress.yaml +deploy: + kubectl: {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/src/main.css Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,1 @@ +@import "tabulator-tables/dist/css/tabulator.min.css"; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/src/main.ts Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,143 @@ +import { startOfDay, subDays, differenceInMinutes, getUnixTime, addDays, format, min, formatISO } from "date-fns"; +import * as echarts from "echarts"; +import { TabulatorFull as Tabulator } from "tabulator-tables"; + +const QUERY_RANGE = "https://bigasterisk.com/m/prometheus/api/v1/query_range"; +const MAC = new Map([ +]); + +function progQueryUrl(prog: string, s: Date, e: Date): URL { + const rangeMins = differenceInMinutes(e, s); + const out = new URL(QUERY_RANGE); + + const host = "Kelsis-iMac"; + const isRunningQl = `racc_running{prog="${prog}",host="${host}"}`; + const isNonIdleQl = `max(racc_idle{host="${host}"}) < 100`; + const countedTimeQl = `(${isRunningQl}) if (${isNonIdleQl})`; + const integralQl = `integrate((${countedTimeQl})[${rangeMins}m])`; + const hoursQl = `${integralQl}/1h`; + + out.searchParams.append("query", hoursQl); + out.searchParams.append("start", "" + getUnixTime(s)); + out.searchParams.append("end", "" + getUnixTime(e)); + out.searchParams.append("step", "1m"); + return out; +} + +async function queryLastRow(queryUrl: URL): Promise<string> { + const response = await fetch(queryUrl); + const body = await response.json(); + if (!body?.data?.result) { + return "0"; + } + const m = body.data.result[0]; + if (m?.values?.length) { + const lastRow = m.values[m.values.length - 1]; + return parseFloat(lastRow[1]).toFixed(2); + } + return "0"; +} + +async function makeSeries(now: Date, meas: string, prog: string, numDays: number): Promise<echarts.BarSeriesOption> { + const rows = []; + const sod = startOfDay(now); + + for (let i = numDays-1 ; i >= 0; i--) { + const s = subDays(sod, i); + const e = min([now, addDays(s, 1)]); + console.log(i, formatISO(s), formatISO(e)); + rows.push(queryLastRow(progQueryUrl(prog, s, e))); + } + const mc = await Promise.all(rows); + + return { + name: meas, + type: "bar", + animation: false, + data: mc, + emphasis: { focus: "series" }, + label: { show: true }, + stack: "total", + + }; +} + +function dateRowLabels(now: Date, days: number) { + const rowNames = []; + for (let d = subDays(now, days - 1); d < now; d = addDays(d, 1)) { + rowNames.push(format(d, "MM/dd EEE")); + } + rowNames.push(format(now, "MM/dd EEE") + " (today)"); + return rowNames; +} + +function fillDebugTable(el: HTMLElement) { + var rows = []; + + const vmui = (expr: string, range: string): string => + "https://bigasterisk.com/m/vmui/?" + + "g0.expr=" + + encodeURIComponent(expr) + // + "&g0.range_input=" + + encodeURIComponent(range); + const view = (url: string): string => `<a href="${url}">view</a>`; + for (let host of ["Kelsis-iMac", "dash", "dot", "plus"]) { + rows.push({ + id: rows.length, + host: host, + metrics: view(`http://${host}:5150/metrics`), + uptime: view(vmui(`python_info{job="racc",instance="${host}:5150"}`, "14d")), + traffic: view(vmui(`rate(lan_bytes_sent_from_total{mac="${MAC.get(host)}"})`, "6h")), + }); + } + var table = new Tabulator(el, { + data: rows, + columns: [ + { title: "Host", field: "host" }, + { title: "current /metrics", field: "metrics", formatter: "html" }, + { title: "racc uptime history", field: "uptime", formatter: "html" }, + { title: "outgoing net traffic", field: "traffic", formatter: "html" }, + ], + }); +} + +async function main() { + fillDebugTable(document.getElementById("debug1")!); + + const now = new Date(); + + const chartDom = document.getElementById("chart1")!; + const chart = echarts.init(chartDom); + + const nDays = 8; + const rowNames = dateRowLabels(now, nDays); + + const option: echarts.EChartsOption = { + tooltip: { + trigger: "axis", + axisPointer: { + type: "shadow", + }, + }, + legend: {}, + grid: { + left: "0%", + containLabel: true, + }, + xAxis: { + type: "value", + max: 10, + }, + yAxis: { + type: "category", + data: rowNames, + }, + series: await Promise.all([ + makeSeries(now, "Minecraft hours", "minecraft", nDays), // + makeSeries(now, "Roblox hours", "roblox", nDays), + ]), + }; +console.log(option); + chart.setOption(option); +} +main();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/tsconfig.json Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "es2020", + "strict": true, + "moduleResolution": "node", + "esModuleInterop": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": false + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/vite.config.ts Mon Mar 13 18:53:45 2023 -0700 @@ -0,0 +1,30 @@ +import { defineConfig } from "vite"; + +export default defineConfig({ + base: "https://bigasterisk.com/racc/console/", + server: { + host: "0.0.0.0", + strictPort: true, + port: 8002, + hmr: { path: "vite-ws" }, + fs: { allow: ["src", "node_modules", "."] }, + }, + build: { + assetsDir: "src", + target: "esnext", + lib: { + entry: "src/index.ts", + formats: ["es"], + }, + rollupOptions: { + // input: { app: "src/index.html" }, + external: /^lit/, + }, + }, + resolve: { + alias: [{ find: "rdf-canonize-native", replacement: "" }], + }, + define: { + global: {}, + }, +});