Compare commits

...

163 Commits

Author SHA1 Message Date
public-glueops-renovatebot[bot]
d25922c37a chore(fallback): update postgres 2026-02-11 20:19:43 +00:00
public-glueops-renovatebot[bot]
a40da0c23d chore(patch): update @types/react to 19.2.13 #patch (#650)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-11 20:04:26 +00:00
public-glueops-renovatebot[bot]
1c740da56d chore(patch): update @types/node to 25.2.2 #patch (#652)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-11 06:00:17 +00:00
public-glueops-renovatebot[bot]
0136c8ef78 chore(patch): update shadcn to 3.8.3 #patch (#642)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-07 17:45:19 +00:00
public-glueops-renovatebot[bot]
d4fdd85671 chore(patch): update @types/react to 19.2.11 #patch (#645)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-07 15:00:28 +00:00
public-glueops-renovatebot[bot]
5d3f0bfaf6 chore: lock file maintenance (#624)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:06:43 +00:00
public-glueops-renovatebot[bot]
3926bafa5c feat: update docker/login-action to v3.7.0 #minor (#623)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:03:13 +00:00
public-glueops-renovatebot[bot]
210a056fe6 feat: update github.com/aws/aws-sdk-go-v2/service/s3 to v1.96.0 #minor (#627)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:03:00 +00:00
public-glueops-renovatebot[bot]
b864187af5 feat: update typescript-eslint to 8.54.0 #minor (#618)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:44 +00:00
public-glueops-renovatebot[bot]
10725d9263 chore(lockfile): update motion-lockfile #patch (#633)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:30 +00:00
public-glueops-renovatebot[bot]
84d5575ea8 feat: update eslint-plugin-react-refresh to 0.5.0 #minor (#629)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:23 +00:00
public-glueops-renovatebot[bot]
b7b2c3c65d chore(patch): update motion to 12.29.3 #patch (#632)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:13 +00:00
public-glueops-renovatebot[bot]
94cd1ca2df chore(patch): update github.com/golang-jwt/jwt/v5 to v5.3.1 #patch (#626)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:59 +00:00
public-glueops-renovatebot[bot]
9379e8dd05 chore(patch): update golang to 1.25.7 #patch (#639)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:48 +00:00
public-glueops-renovatebot[bot]
e0b15f6b9e chore(patch): update github.com/go-chi/chi/v5 to v5.2.5 #patch (#641)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:42 +00:00
public-glueops-renovatebot[bot]
accf590d24 chore(patch): update @vitejs/plugin-react to 5.1.3 #patch (#631)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:21 +00:00
public-glueops-renovatebot[bot]
b910ff52ab feat: update @types/node to 25.2.1 #minor (#630)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 22:48:50 +00:00
public-glueops-renovatebot[bot]
1e498b309b chore(patch): update @types/react to 19.2.10 #patch (#619)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 22:40:45 +00:00
public-glueops-renovatebot[bot]
85601bcb84 chore(patch): update shadcn to 3.8.2 #patch (#635)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 11:32:21 +00:00
public-glueops-renovatebot[bot]
ce348a65ea chore(patch): update shadcn to 3.8.1 #patch (#634)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-03 11:59:38 +00:00
public-glueops-renovatebot[bot]
37153a6eed feat: update shadcn to 3.8.0 #minor (#628)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-03 00:52:13 +00:00
public-glueops-renovatebot[bot]
936891d110 chore(patch): update typescript-eslint to 8.53.1 #patch (#608)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:49:07 +00:00
public-glueops-renovatebot[bot]
965a5ed88b chore: lock file maintenance (#620)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:23:14 +00:00
public-glueops-renovatebot[bot]
c2b76f1dea chore(patch): update prettier to 3.8.1 #patch (#611)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:37 +00:00
public-glueops-renovatebot[bot]
5c9768b0b2 chore(patch): update @tanstack/react-query to 5.90.20 #patch (#598)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:22 +00:00
public-glueops-renovatebot[bot]
a02c29f333 chore(fallback): update golang (#607)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:16 +00:00
public-glueops-renovatebot[bot]
223d89bdd1 chore(patch): update @types/node to 25.0.10 #patch (#613)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:09 +00:00
public-glueops-renovatebot[bot]
411c98174a chore(lockfile): update motion-lockfile #patch (#614)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:03 +00:00
public-glueops-renovatebot[bot]
a7657368ed chore: lock file maintenance (#605)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:21:14 +00:00
public-glueops-renovatebot[bot]
134153c197 feat: update shadcn to 3.7.0 #minor (#603)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:44 +00:00
public-glueops-renovatebot[bot]
b4905b8c59 feat: update lucide-react to 0.563.0 #minor (#616)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:23 +00:00
public-glueops-renovatebot[bot]
f9dc0d4db5 chore(lockfile): update react-router-dom-lockfile #patch (#617)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:11 +00:00
public-glueops-renovatebot[bot]
3d6e53d24d chore(lockfile): update motion-lockfile #patch (#610)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:19:38 +00:00
public-glueops-renovatebot[bot]
2f6a382733 chore(lockfile): update motion-lockfile #patch (#606)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:19:27 +00:00
public-glueops-renovatebot[bot]
8261b5d702 chore(patch): update @types/react to 19.2.9 #patch (#609)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:01:27 +00:00
public-glueops-renovatebot[bot]
23415ead6d chore(patch): update @types/node to 25.0.9 #patch (#604)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-22 01:15:32 +00:00
public-glueops-renovatebot[bot]
ba8098acac feat: update prettier to 3.8.0 #minor (#600)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-21 18:51:23 +00:00
public-glueops-renovatebot[bot]
da5801cc6b chore: lock file maintenance (#596)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:44 +00:00
public-glueops-renovatebot[bot]
809c0930ae chore(patch): update golang to 1.25.6 #patch (#601)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:10 +00:00
public-glueops-renovatebot[bot]
17af4e8da4 chore(patch): update motion to 12.26.2 #patch (#592)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:05 +00:00
public-glueops-renovatebot[bot]
039fb04c97 chore(patch): update github.com/go-chi/chi/v5 to v5.2.4 #patch (#599)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:32:52 +00:00
public-glueops-renovatebot[bot]
335fd10fab chore(patch): update @types/react to 19.2.8 #patch (#590)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:32:43 +00:00
public-glueops-renovatebot[bot]
a3ec862e12 feat: update typescript-eslint to 8.53.0 #minor (#594)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:31:14 +00:00
public-glueops-renovatebot[bot]
66595daa4b chore(patch): update @types/node to 25.0.8 #patch (#602)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:16:31 +00:00
public-glueops-renovatebot[bot]
d6d1806907 chore(patch): update @types/node to 25.0.7 #patch (#597)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 08:30:02 +00:00
public-glueops-renovatebot[bot]
3c61f66c9a chore(patch): update @types/node to 25.0.6 #patch (#595)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 18:14:04 +00:00
public-glueops-renovatebot[bot]
0fb6fa3389 feat: update golang.org/x/crypto to v0.47.0 #minor (#593)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:35:28 +00:00
public-glueops-renovatebot[bot]
4cd9f77694 chore(patch): update github.com/aws/aws-sdk-go-v2 to v1.41.1 #patch (#588)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:23:26 +00:00
public-glueops-renovatebot[bot]
f6af0d970f chore(patch): update vite to 7.3.1 #patch (#578)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:02:47 +00:00
public-glueops-renovatebot[bot]
1138b346e3 chore: lock file maintenance (#587)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:02:17 +00:00
public-glueops-renovatebot[bot]
4e612652a2 chore(patch): update @types/node to 25.0.5 #patch (#589)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 03:24:39 +00:00
public-glueops-renovatebot[bot]
4127c0dd06 chore: lock file maintenance (#586)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:45:20 +00:00
public-glueops-renovatebot[bot]
8e97df134a chore(patch): update github.com/swaggo/swag/v2 to v2.0.0-rc5 #patch (#584)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:44:46 +00:00
public-glueops-renovatebot[bot]
636b500108 chore(patch): update shadcn to 3.6.3 #patch (#572)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:43:54 +00:00
public-glueops-renovatebot[bot]
2e3fd44b34 chore: lock file maintenance (#583)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 18:28:09 +00:00
public-glueops-renovatebot[bot]
2bfd8b0a78 chore: lock file maintenance (#581)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 17:14:27 +00:00
public-glueops-renovatebot[bot]
c7fb0bcf18 feat: update typescript-eslint to 8.52.0 #minor (#570)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 17:13:05 +00:00
public-glueops-renovatebot[bot]
c4a0fbd7b8 chore: lock file maintenance (#580)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-07 09:46:32 +00:00
public-glueops-renovatebot[bot]
8616336279 chore: lock file maintenance (#579)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-07 09:45:20 +00:00
public-glueops-renovatebot[bot]
d1ea3667e6 chore: lock file maintenance (#577)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-06 17:29:30 +00:00
allanice001
0f562ac5f4 ui fixes 2026-01-06 17:05:52 +00:00
allanice001
810218124e revert, but increase httprate 2026-01-06 10:11:42 +00:00
allanice001
5aff256377 fix import issue 2026-01-06 09:59:23 +00:00
Alanis
bdd6b61859 Remove rate limiting by IP from routes
Removed rate limiting middleware from the API routes.
2026-01-06 09:50:10 +00:00
public-glueops-renovatebot[bot]
42a86b22dd chore: lock file maintenance (#567)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-05 10:45:19 +00:00
public-glueops-renovatebot[bot]
b8cb1e1a2a chore: lock file maintenance (#566)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-05 10:11:13 +00:00
public-glueops-renovatebot[bot]
5a4ae19900 chore: lock file maintenance (#564)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 10:51:50 +00:00
public-glueops-renovatebot[bot]
d9db293894 chore: lock file maintenance (#563)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 08:27:53 +00:00
public-glueops-renovatebot[bot]
19d5ee7251 chore: lock file maintenance (#562)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 04:12:39 +00:00
public-glueops-renovatebot[bot]
6b91a5760b chore: lock file maintenance (#560)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-03 13:32:05 +00:00
public-glueops-renovatebot[bot]
bbd4c86013 chore: lock file maintenance (#559)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-02 14:40:46 +00:00
public-glueops-renovatebot[bot]
99ebcb11a3 chore: lock file maintenance (#558)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-02 13:44:37 +00:00
public-glueops-renovatebot[bot]
be1b35da3c feat: update typescript-eslint to 8.51.0 #minor (#540)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-01 17:09:21 +00:00
public-glueops-renovatebot[bot]
a6a296f283 chore: lock file maintenance (#556)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 23:27:07 +00:00
public-glueops-renovatebot[bot]
341ecf8b0a chore: lock file maintenance (#555)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 19:37:14 +00:00
public-glueops-renovatebot[bot]
92998015ec chore: lock file maintenance (#554)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 16:10:12 +00:00
public-glueops-renovatebot[bot]
9345c2761c chore: lock file maintenance (#553)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 15:08:55 +00:00
public-glueops-renovatebot[bot]
6944e5d027 chore: lock file maintenance (#552)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 06:14:14 +00:00
public-glueops-renovatebot[bot]
48b3bf5d3c chore: lock file maintenance (#551)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 06:13:11 +00:00
public-glueops-renovatebot[bot]
4c595db85e chore: lock file maintenance (#550)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 05:42:43 +00:00
allanice001
79f3259bd6 fix: ensure only a single instance is fired
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-30 17:30:38 +00:00
allanice001
e0d163181a Merge branch 'main' of github.com:GlueOps/autoglue 2025-12-30 16:35:18 +00:00
allanice001
e8d568eba7 fix: ensure only a single instance is fired
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-30 16:35:00 +00:00
public-glueops-renovatebot[bot]
c21a766dab chore: lock file maintenance (#548)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-30 15:09:36 +00:00
public-glueops-renovatebot[bot]
495c1551b4 chore: lock file maintenance (#547)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-30 08:45:47 +00:00
public-glueops-renovatebot[bot]
4a5c0df481 chore: lock file maintenance (#545)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 22:09:22 +00:00
public-glueops-renovatebot[bot]
c92bba5518 chore: lock file maintenance (#544)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 22:08:16 +00:00
public-glueops-renovatebot[bot]
823088e294 chore: lock file maintenance (#543)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 19:52:02 +00:00
public-glueops-renovatebot[bot]
938689fda3 chore: lock file maintenance (#542)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 18:46:56 +00:00
public-glueops-renovatebot[bot]
77332f208f chore: lock file maintenance (#541)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 17:26:24 +00:00
public-glueops-renovatebot[bot]
711488492c breaking: the dependency actions/checkout has been updated to a new major version (v6), which may include breaking changes. #major (#536)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 17:03:09 +00:00
public-glueops-renovatebot[bot]
27b89722a4 chore: lock file maintenance (#539)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 16:27:51 +00:00
public-glueops-renovatebot[bot]
c8a537e30f chore(fallback): update postgres (#535)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 12:34:44 +00:00
public-glueops-renovatebot[bot]
98de70b96b chore: lock file maintenance (#538)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 12:34:10 +00:00
public-glueops-renovatebot[bot]
63c4574f9c chore(fallback): update axllent/mailpit (#534)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 12:33:13 +00:00
public-glueops-renovatebot[bot]
5e85cad5b7 chore(pin): update typescript to #patch (#533)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-29 12:32:35 +00:00
allanice001
53725bb834 chore: add org id to org table 2025-12-29 11:59:27 +00:00
public-glueops-renovatebot[bot]
6611dc4950 chore(patch): update typescript-eslint to 8.50.1 #patch (#511)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-28 01:26:48 +00:00
public-glueops-renovatebot[bot]
49665ffc9c feat: update github.com/aws/aws-sdk-go-v2/service/s3 to v1.95.0 #minor (#516)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-28 01:26:33 +00:00
public-glueops-renovatebot[bot]
ac14ef8fff chore: lock file maintenance (#528)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-28 01:25:13 +00:00
allanice001
f8e543b595 fix: improve dns error logging 2025-12-28 00:08:42 +00:00
allanice001
8cc81e52b7 fix: add get record for dns 2025-12-27 23:21:59 +00:00
public-glueops-renovatebot[bot]
d6e28c7fa2 chore(patch): update @types/node to 25.0.3 #patch (#507)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:30:04 +00:00
public-glueops-renovatebot[bot]
9832229194 chore(patch): update eslint-plugin-react-refresh to 0.4.26 #patch (#508)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:29:07 +00:00
public-glueops-renovatebot[bot]
da82998754 chore(fallback): update alpine (#487)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:28:34 +00:00
public-glueops-renovatebot[bot]
bca32fe784 chore(fallback): update golang (#486)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:28:18 +00:00
public-glueops-renovatebot[bot]
848e8d5179 chore(patch): update shadcn to 3.6.2 #patch (#510)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:28:03 +00:00
public-glueops-renovatebot[bot]
d3ee38881c feat: update docker/setup-buildx-action to v3.12.0 #minor (#515)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:27:20 +00:00
public-glueops-renovatebot[bot]
d39db44aa7 feat: update lucide-react to 0.562.0 #minor (#518)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:26:54 +00:00
public-glueops-renovatebot[bot]
01b29a4706 feat: update vite to 7.3.0 #minor (#519)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 15:26:38 +00:00
allanice001
bc3bd92d54 fix: improve job tracking
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-26 15:14:48 +00:00
allanice001
2057f92b82 fix: improve job tracking 2025-12-26 15:04:31 +00:00
allanice001
169283b6c7 fix: improve job tracking
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-26 15:04:15 +00:00
allanice001
865270312c fix: update jobs
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-26 04:47:08 +00:00
public-glueops-renovatebot[bot]
7cc447c0f5 chore(lockfile): update react-hook-form-lockfile #patch (#496)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 01:12:10 +00:00
public-glueops-renovatebot[bot]
8a0345f7f5 chore: lock file maintenance (#520)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 01:11:47 +00:00
public-glueops-renovatebot[bot]
bb7114efe9 feat: update github.com/go-playground/validator/v10 to v10.30.1 #minor (#517)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 00:45:14 +00:00
public-glueops-renovatebot[bot]
9dd0148764 chore(lockfile): update react-router-dom-lockfile #patch (#514)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 00:45:00 +00:00
public-glueops-renovatebot[bot]
bcc69e1c86 chore(lockfile): update react-day-picker-lockfile #patch (#513)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 00:44:27 +00:00
public-glueops-renovatebot[bot]
a7bf6b43b4 chore(patch): update zod to 4.2.1 #patch (#512)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 00:44:17 +00:00
public-glueops-renovatebot[bot]
ced0a0663f chore(patch): update github.com/aws/aws-sdk-go-v2/config to v1.32.6 #patch (#509)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-26 00:43:51 +00:00
allanice001
dac28d3ea5 feat: move jobs to action based
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-26 00:30:46 +00:00
allanice001
dd0cefc08a fix: bugfix jobs
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-16 01:15:00 +00:00
allanice001
842f7c9be6 fix: bugfix jobs
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-16 00:52:16 +00:00
public-glueops-renovatebot[bot]
c15311a5a1 chore(patch): update @eslint/js to 9.39.2 #patch (#456)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 22:26:54 +00:00
public-glueops-renovatebot[bot]
25ced343c4 feat: update shadcn to 3.6.0 #minor (#454)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 20:23:28 +00:00
public-glueops-renovatebot[bot]
b72a8d384d feat: update github.com/aws/aws-sdk-go-v2/service/s3 to v1.94.0 #minor (#470)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 20:22:48 +00:00
public-glueops-renovatebot[bot]
c786a79b60 chore: lock file maintenance (#469)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 19:39:22 +00:00
public-glueops-renovatebot[bot]
01b1434842 chore: lock file maintenance (#468)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 19:38:13 +00:00
public-glueops-renovatebot[bot]
e8c9cde474 chore: lock file maintenance (#467)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 19:09:53 +00:00
public-glueops-renovatebot[bot]
ae92d05cd4 feat: update typescript-eslint to 8.50.0 #minor (#465)
* chore: lock file maintenance (#452)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* feat: update github.com/go-playground/validator/v10 to v10.29.0 #minor (#453)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* chore: lock file maintenance (#455)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* chore: lock file maintenance (#457)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* chore: lock file maintenance (#462)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* chore: lock file maintenance (#464)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* chore: lock file maintenance (#466)

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>

* feat: update typescript-eslint to 8.50.0 #minor

---------

Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-15 18:08:04 +00:00
allanice001
67d50d2b15 fix: bugfix in responding with correct label ids 2025-12-15 18:04:22 +00:00
allanice001
e5a664b812 Merge remote-tracking branch 'origin/main' 2025-12-12 11:36:33 +00:00
allanice001
f722ba8dca chore: update dependencies
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-12 11:36:25 +00:00
public-glueops-renovatebot[bot]
20e6d8d186 chore: lock file maintenance (#449)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-12 07:40:12 +00:00
allanice001
85f37cd113 fix: ui updates for org api keys
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-12 02:05:31 +00:00
allanice001
fd1a81ecd8 fix: api keys form bugfix and org key sweeper job
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-12 01:37:42 +00:00
allanice001
793daf3ac3 Merge remote-tracking branch 'origin/main' 2025-12-12 00:20:34 +00:00
allanice001
7bef4ef6f1 feat: add org_key and org_secret to payload on bastion
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-12 00:20:27 +00:00
public-glueops-renovatebot[bot]
9fa9cd169b chore: lock file maintenance (#448)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-11 23:26:33 +00:00
public-glueops-renovatebot[bot]
8812b43346 chore: lock file maintenance (#447)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-11 20:39:59 +00:00
public-glueops-renovatebot[bot]
21a6d7d5a1 chore: lock file maintenance (#445)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-11 19:37:53 +00:00
public-glueops-renovatebot[bot]
da332c89dd chore: lock file maintenance (#443)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-11 17:12:09 +00:00
public-glueops-renovatebot[bot]
fd25825f34 chore: lock file maintenance (#441)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-11 15:54:18 +00:00
allanice001
de3740e974 Merge remote-tracking branch 'origin/main' 2025-12-11 13:08:47 +00:00
allanice001
21dd26503f feat: add kubeconfig to payload if available
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-11 13:08:39 +00:00
public-glueops-renovatebot[bot]
e1da229c30 chore: lock file maintenance (#439)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-10 14:43:04 +00:00
allanice001
5377e521e9 fix: fix build error
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-10 14:19:10 +00:00
allanice001
a929561bc8 fix: bg jobs sequencing 2025-12-10 13:25:12 +00:00
allanice001
c63f9f1cf3 Merge remote-tracking branch 'origin/main' 2025-12-10 12:35:10 +00:00
allanice001
4c02179b70 fix: fix payload shape
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-10 12:34:11 +00:00
public-glueops-renovatebot[bot]
c8289c6936 chore: lock file maintenance (#435)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-10 11:38:00 +00:00
allanice001
c17caf22a2 fix: ui typo fix 2025-12-10 09:51:38 +00:00
allanice001
986eeb9bf9 fix: ui typo fix
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-10 09:51:13 +00:00
allanice001
b0bbc13946 fix: ui typo fix
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-10 09:51:07 +00:00
public-glueops-renovatebot[bot]
f50dcae823 feat: update github.com/aws/aws-sdk-go-v2/service/route53 to v1.62.0 #minor (#433)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-09 21:20:27 +00:00
public-glueops-renovatebot[bot]
ab9a77e1f5 chore(patch): update github.com/aws/aws-sdk-go-v2/config to v1.32.5 #patch (#432)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-09 20:41:11 +00:00
allanice001
416b2ff4e2 Merge remote-tracking branch 'origin/main' 2025-12-09 18:11:01 +00:00
allanice001
20bef7545c chore: log background jobs
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-09 18:10:50 +00:00
public-glueops-renovatebot[bot]
15e101439b chore: lock file maintenance (#430)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-09 17:05:07 +00:00
public-glueops-renovatebot[bot]
fb0901a812 chore(patch): update github.com/aws/aws-sdk-go-v2/config to v1.32.4 #patch (#428)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-09 16:56:56 +00:00
allanice001
fee4c64551 fix: fix background jobs
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-09 15:49:31 +00:00
allanice001
4d37a6363f feat: add docker_image and docker_tag to cluster api
Signed-off-by: allanice001 <allanice001@gmail.com>
2025-12-08 17:04:10 +00:00
163 changed files with 9612 additions and 5862 deletions

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
@@ -47,13 +47,13 @@ jobs:
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}

View File

@@ -1,7 +1,7 @@
#################################
# Builder: Go + Node in one
#################################
FROM golang:1.25.5-alpine@sha256:26111811bc967321e7b6f852e914d14bede324cd1accb7f81811929a6a57fea9 AS builder
FROM golang:1.25.7-alpine@sha256:81d49e1de26fa223b9ae0b4d5a4065ff8176a7d80aa5ef0bd9f2eee430afe4d7 AS builder
RUN apk add --no-cache \
bash git ca-certificates tzdata \
@@ -24,7 +24,7 @@ RUN make build
#################################
# Runtime
#################################
FROM alpine:3.23@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375
FROM alpine:3.23@sha256:865b95f46d98cf867a156fe4a135ad3fe50d2056aa3f25ed31662dff6da4eb62
RUN apk add --no-cache ca-certificates tzdata postgresql17-client \
&& addgroup -S app && adduser -S app -G app

View File

@@ -204,6 +204,7 @@ swagger: $(DOCS_JSON) ## Generate Swagger docs if stale
# --- build ---
build: prepare ui swagger sdk-all ## Build everything: Go hygiene, UI, Swagger, SDKs, then Go binary
@echo ">> Building Go binary: $(BIN)"
@$(GOCMD) get github.com/swaggo/swag/v2@v2.0.0-rc4
@$(GOCMD) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) $(MAIN)
# Handy: print resolved version metadata

View File

@@ -116,6 +116,7 @@ var serveCmd = &cobra.Command{
log.Printf("failed to enqueue bootstrap_bastion: %v", err)
}
/*
_, err = jobs.Enqueue(
context.Background(),
uuid.NewString(),
@@ -156,6 +157,22 @@ var serveCmd = &cobra.Command{
if err != nil {
log.Printf("failed to enqueue cluster bootstrap: %v", err)
}
*/
_, err = jobs.Enqueue(
context.Background(),
uuid.NewString(),
"org_key_sweeper",
bg.OrgKeySweeperArgs{
IntervalS: 3600,
RetentionDays: 10,
},
archer.WithMaxRetries(1),
archer.WithScheduleTime(time.Now()),
)
if err != nil {
log.Printf("failed to enqueue org_key_sweeper: %v", err)
}
}
_ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey)

View File

@@ -15,7 +15,7 @@ services:
- postgres_data:/var/lib/postgresql/data
mailpit:
image: axllent/mailpit@sha256:e22dce5b36f93c77082e204a3942fb6b283b7896e057458400a4c88344c3df68
image: axllent/mailpit@sha256:c076638db1e15662150be4fb62b8a6e96ef6ba5bde90c838a0239225854830f7
restart: always
ports:
- "1025:1025"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,23 @@
components:
schemas:
dto.ActionResponse:
properties:
created_at:
format: date-time
type: string
description:
type: string
id:
format: uuid
type: string
label:
type: string
make_target:
type: string
updated_at:
format: date-time
type: string
type: object
dto.AnnotationResponse:
properties:
created_at:
@@ -96,10 +114,16 @@ components:
$ref: '#/components/schemas/dto.RecordSetResponse'
created_at:
type: string
docker_image:
type: string
docker_tag:
type: string
glueops_load_balancer:
$ref: '#/components/schemas/dto.LoadBalancerResponse'
id:
type: string
kubeconfig:
type: string
last_error:
type: string
name:
@@ -109,6 +133,10 @@ components:
$ref: '#/components/schemas/dto.NodePoolResponse'
type: array
uniqueItems: false
org_key:
type: string
org_secret:
type: string
random_token:
type: string
region:
@@ -118,6 +146,42 @@ components:
updated_at:
type: string
type: object
dto.ClusterRunResponse:
properties:
action:
type: string
cluster_id:
format: uuid
type: string
created_at:
format: date-time
type: string
error:
type: string
finished_at:
format: date-time
type: string
id:
format: uuid
type: string
organization_id:
format: uuid
type: string
status:
type: string
updated_at:
format: date-time
type: string
type: object
dto.CreateActionRequest:
properties:
description:
type: string
label:
type: string
make_target:
type: string
type: object
dto.CreateAnnotationRequest:
properties:
key:
@@ -129,6 +193,10 @@ components:
properties:
cluster_provider:
type: string
docker_image:
type: string
docker_tag:
type: string
name:
type: string
region:
@@ -702,6 +770,15 @@ components:
example: Bearer
type: string
type: object
dto.UpdateActionRequest:
properties:
description:
type: string
label:
type: string
make_target:
type: string
type: object
dto.UpdateAnnotationRequest:
properties:
key:
@@ -713,6 +790,10 @@ components:
properties:
cluster_provider:
type: string
docker_image:
type: string
docker_tag:
type: string
name:
type: string
region:
@@ -1025,6 +1106,8 @@ components:
type: object
models.APIKey:
properties:
cluster_id:
type: string
created_at:
format: date-time
type: string
@@ -1034,6 +1117,8 @@ components:
id:
format: uuid
type: string
is_ephemeral:
type: boolean
last_used_at:
format: date-time
type: string
@@ -1044,6 +1129,8 @@ components:
type: string
prefix:
type: string
purpose:
type: string
revoked:
type: boolean
scope:
@@ -1178,6 +1265,222 @@ paths:
summary: Get JWKS
tags:
- Auth
/admin/actions:
get:
description: Returns all admin-configured actions.
operationId: ListActions
responses:
"200":
content:
application/json:
schema:
items:
$ref: '#/components/schemas/dto.ActionResponse'
type: array
description: OK
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
summary: List available actions
tags:
- Actions
post:
description: Creates a new admin-configured action.
operationId: CreateAction
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/dto.CreateActionRequest'
description: payload
required: true
responses:
"201":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.ActionResponse'
description: Created
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
summary: Create an action
tags:
- Actions
/admin/actions/{actionID}:
delete:
description: Deletes an action.
operationId: DeleteAction
parameters:
- description: Action ID
in: path
name: actionID
required: true
schema:
type: string
responses:
"204":
content:
application/json:
schema:
type: string
description: deleted
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"404":
content:
application/json:
schema:
type: string
description: not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
summary: Delete an action
tags:
- Actions
get:
description: Returns a single action.
operationId: GetAction
parameters:
- description: Action ID
in: path
name: actionID
required: true
schema:
type: string
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.ActionResponse'
description: OK
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"404":
content:
application/json:
schema:
type: string
description: not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
summary: Get a single action by ID
tags:
- Actions
patch:
description: Updates an action. Only provided fields are modified.
operationId: UpdateAction
parameters:
- description: Action ID
in: path
name: actionID
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/dto.UpdateActionRequest'
description: payload
required: true
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.ActionResponse'
description: OK
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"404":
content:
application/json:
schema:
type: string
description: not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
summary: Update an action
tags:
- Actions
/admin/archer/jobs:
get:
description: Paginated background jobs with optional filters. Search `q` may
@@ -2100,6 +2403,73 @@ paths:
summary: Update basic cluster details (org scoped)
tags:
- Clusters
/clusters/{clusterID}/actions/{actionID}/runs:
post:
description: Creates a ClusterRun record for the cluster/action. Execution is
handled asynchronously by workers.
operationId: RunClusterAction
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
schema:
type: string
- description: Cluster ID
in: path
name: clusterID
required: true
schema:
type: string
- description: Action ID
in: path
name: actionID
required: true
schema:
type: string
responses:
"201":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.ClusterRunResponse'
description: Created
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"403":
content:
application/json:
schema:
type: string
description: organization required
"404":
content:
application/json:
schema:
type: string
description: cluster or action not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
- OrgKeyAuth: []
- OrgSecretAuth: []
summary: Run an admin-configured action on a cluster (org scoped)
tags:
- ClusterRuns
/clusters/{clusterID}/apps-load-balancer:
delete:
description: Clears apps_load_balancer_id on the cluster.
@@ -2993,6 +3363,128 @@ paths:
summary: Detach a node pool from a cluster
tags:
- Clusters
/clusters/{clusterID}/runs:
get:
description: Returns runs for a cluster within the organization in X-Org-ID.
operationId: ListClusterRuns
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
schema:
type: string
- description: Cluster ID
in: path
name: clusterID
required: true
schema:
type: string
responses:
"200":
content:
application/json:
schema:
items:
$ref: '#/components/schemas/dto.ClusterRunResponse'
type: array
description: OK
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"403":
content:
application/json:
schema:
type: string
description: organization required
"404":
content:
application/json:
schema:
type: string
description: cluster not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
- OrgKeyAuth: []
- OrgSecretAuth: []
summary: List cluster runs (org scoped)
tags:
- ClusterRuns
/clusters/{clusterID}/runs/{runID}:
get:
description: Returns a single run for a cluster within the organization in X-Org-ID.
operationId: GetClusterRun
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
schema:
type: string
- description: Cluster ID
in: path
name: clusterID
required: true
schema:
type: string
- description: Run ID
in: path
name: runID
required: true
schema:
type: string
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.ClusterRunResponse'
description: OK
"400":
content:
application/json:
schema:
type: string
description: bad request
"401":
content:
application/json:
schema:
type: string
description: Unauthorized
"403":
content:
application/json:
schema:
type: string
description: organization required
"404":
content:
application/json:
schema:
type: string
description: not found
"500":
content:
application/json:
schema:
type: string
description: db error
security:
- BearerAuth: []
- OrgKeyAuth: []
- OrgSecretAuth: []
summary: Get a cluster run (org scoped)
tags:
- ClusterRuns
/credentials:
get:
description: Returns credential metadata for the current org. Secrets are never
@@ -3672,6 +4164,42 @@ paths:
external deletion policy)
tags:
- DNS
get:
operationId: GetRecordSet
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
schema:
type: string
- description: Record Set ID (UUID)
in: path
name: id
required: true
schema:
type: string
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/dto.RecordSetResponse'
description: OK
"403":
content:
application/json:
schema:
type: string
description: organization required
"404":
content:
application/json:
schema:
type: string
description: not found
summary: Get a record set (org scoped)
tags:
- DNS
patch:
operationId: UpdateRecordSet
parameters:

60
go.mod
View File

@@ -4,28 +4,29 @@ go 1.25.4
require (
github.com/alexedwards/argon2id v1.0.0
github.com/aws/aws-sdk-go-v2 v1.40.1
github.com/aws/aws-sdk-go-v2/config v1.32.3
github.com/aws/aws-sdk-go-v2/credentials v1.19.3
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0
github.com/aws/aws-sdk-go-v2 v1.41.1
github.com/aws/aws-sdk-go-v2/config v1.32.7
github.com/aws/aws-sdk-go-v2/credentials v1.19.7
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0
github.com/aws/smithy-go v1.24.0
github.com/coreos/go-oidc/v3 v3.17.0
github.com/dyaksa/archer v1.1.5
github.com/fergusstrange/embedded-postgres v1.33.0
github.com/gin-gonic/gin v1.11.0
github.com/go-chi/chi/v5 v5.2.3
github.com/go-chi/chi/v5 v5.2.5
github.com/go-chi/cors v1.2.2
github.com/go-chi/httprate v0.15.0
github.com/go-playground/validator/v10 v10.28.0
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/go-playground/validator/v10 v10.30.1
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
github.com/rs/zerolog v1.34.0
github.com/sosedoff/pgweb v0.17.0
github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0
github.com/swaggo/swag/v2 v2.0.0-rc4
golang.org/x/crypto v0.45.0
github.com/swaggo/swag/v2 v2.0.0-rc5
golang.org/x/crypto v0.47.0
golang.org/x/oauth2 v0.34.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/datatypes v1.2.7
@@ -39,20 +40,19 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 // indirect
github.com/aws/smithy-go v1.24.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
@@ -61,7 +61,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -113,7 +113,7 @@ require (
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/sv-tools/openapi v0.2.1 // indirect
github.com/sv-tools/openapi v0.4.0 // indirect
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
@@ -122,12 +122,12 @@ require (
go.uber.org/mock v0.5.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/tools v0.38.0 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.40.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gorm.io/driver/mysql v1.5.7 // indirect

158
go.sum
View File

@@ -10,44 +10,78 @@ github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 h1:VauE2GcJNZFun2O
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w=
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
github.com/aws/aws-sdk-go-v2 v1.40.1 h1:difXb4maDZkRH0x//Qkwcfpdg1XQVXEAEs2DdXldFFc=
github.com/aws/aws-sdk-go-v2 v1.40.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
github.com/aws/aws-sdk-go-v2/config v1.32.3 h1:cpz7H2uMNTDa0h/5CYL5dLUEzPSLo2g0NkbxTRJtSSU=
github.com/aws/aws-sdk-go-v2/config v1.32.3/go.mod h1:srtPKaJJe3McW6T/+GMBZyIPc+SeqJsNPJsd4mOYZ6s=
github.com/aws/aws-sdk-go-v2/credentials v1.19.3 h1:01Ym72hK43hjwDeJUfi1l2oYLXBAOR8gNSZNmXmvuas=
github.com/aws/aws-sdk-go-v2/credentials v1.19.3/go.mod h1:55nWF/Sr9Zvls0bGnWkRxUdhzKqj9uRNlPvgV1vgxKc=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 h1:utxLraaifrSBkeyII9mIbVwXXWrZdlPO7FIKmyLCEcY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15/go.mod h1:hW6zjYUDQwfz3icf4g2O41PHi77u10oAzJ84iSzR/lo=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 h1:Y5YXgygXwDI5P4RkteB5yF7v35neH7LfJKBG+hzIons=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15/go.mod h1:K+/1EpG42dFSY7CBj+Fruzm8PsCGWTXJ3jdeJ659oGQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 h1:AvltKnW9ewxX2hFmQS0FyJH93aSvJVUEFvXfU+HWtSE=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15/go.mod h1:3I4oCdZdmgrREhU74qS1dK9yZ62yumob+58AbFR4cQA=
github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8=
github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI=
github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY=
github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE=
github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 h1:NLYTEyZmVZo0Qh183sC8nC+ydJXOOeIL/qI/sS3PdLY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15/go.mod h1:Z803iB3B0bc8oJV8zH2PERLRfQUJ2n2BXISpsA4+O1M=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 h1:JqcdRG//czea7Ppjb+g/n4o8i/R50aTBHkA7vu0lK+k=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17/go.mod h1:CO+WeGmIdj/MlPel2KwID9Gt7CNq4M65HUfBW97liM0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 h1:P1MU/SuhadGvg2jtviDXPEejU3jBNhoeeAlRadHzvHI=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6/go.mod h1:5KYaMG6wmVKMFBSfWoyG/zH8pWwzQFnKgpoSRlXHKdQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 h1:3/u/4yZOffg5jdNk1sDpOQ4Y+R6Xbh+GzpDrSZjuy3U=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15/go.mod h1:4Zkjq0FKjE78NKjabuM4tRXKFzUJWXgP0ItEZK8l7JU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 h1:wsSQ4SVz5YE1crz0Ap7VBZrV4nNqZt4CIBBT8mnwoNc=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15/go.mod h1:I7sditnFGtYMIqPRU1QoHZAUrXkGp4SczmlLwrNPlD0=
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1 h1:ik9tMw+xWZqzffOtGH3PfV0Yy/V+QsCb1XYXXXjUskk=
github.com/aws/aws-sdk-go-v2/service/route53 v1.61.1/go.mod h1:JRqmldxIPU6uck5bcFS8ExwwG2mUwfy+jiUmismOxJs=
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0 h1:IrbE3B8O9pm3lsg96AXIN5MXX4pECEuExh/A0Du3AuI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0/go.mod h1:/sJLzHtiiZvs6C1RbxS/anSAFwZD6oC6M/kotQzOiLw=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 h1:d/6xOGIllc/XW1lzG9a4AUBMmpLA9PXcQnVPTuHHcik=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3/go.mod h1:fQ7E7Qj9GiW8y0ClD7cUJk3Bz5Iw8wZkWDHsTe8vDKs=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 h1:8sTTiw+9yuNXcfWeqKF2x01GqCF49CpP4Z9nKrrk/ts=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6/go.mod h1:8WYg+Y40Sn3X2hioaaWAAIngndR8n1XFdRPPX+7QBaM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 h1:E+KqWoVsSrj1tJ6I/fjDIu5xoS2Zacuu1zT+H7KtiIk=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11/go.mod h1:qyWHz+4lvkXcr3+PoGlGHEI+3DLLiU6/GdrFfMaAhB0=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 h1:tzMkjh0yTChUqJDgGkcDdxvZDSrJ/WB6R6ymI5ehqJI=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3/go.mod h1:T270C0R5sZNLbWUe8ueiAF42XSZxxPocTaGSgs5c/60=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8/go.mod h1:FsTpJtvC4U1fyDXk7c71XoDv3HlRm8V3NiYLeYLh5YE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 h1:bGeHBsGZx0Dvu/eJC0Lh9adJa3M1xREcndxLNZlve2U=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17/go.mod h1:dcW24lbU0CzHusTE8LLHhRLI42ejmINN8Lcr22bwh/g=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0 h1:80pDB3Tpmb2RCSZORrK9/3iQxsd+w6vSzVqpT1FGiwE=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0/go.mod h1:6EZUGGNLPLh5Unt30uEoA+KQcByERfXIkax9qrc80nA=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1 h1:1jIdwWOulae7bBLIgB36OZ0DINACb1wxM6wdGlx4eHE=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1/go.mod h1:tE2zGlMIlxWv+7Otap7ctRp3qeKqtnja7DZguj3Vu/Y=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 h1:MIWra+MSq53CFaXXAywB2qg9YvVZifkk6vEGl/1Qor0=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.1 h1:C2dUPSnEpy4voWFIq3JNd8gN0Y5vYGDo44eUE58a/p8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.1/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 h1:oeu8VPlOre74lBA/PMhxa5vewaMIMmILM+RraSyB8KA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -79,14 +113,18 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/chi/v5 v5.2.4 h1:WtFKPHwlywe8Srng8j2BhOD9312j9cGUxG1SP4V2cR4=
github.com/go-chi/chi/v5 v5.2.4/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/httprate v0.15.0 h1:j54xcWV9KGmPf/X4H32/aTH+wBlrvxL7P+SdnRqxh5g=
@@ -112,8 +150,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
@@ -127,6 +165,8 @@ github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7Lk
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
@@ -263,8 +303,12 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA=
github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg=
github.com/sv-tools/openapi v0.4.0 h1:UhD9DVnGox1hfTePNclpUzUFgos57FvzT2jmcAuTOJ4=
github.com/sv-tools/openapi v0.4.0/go.mod h1:kD/dG+KP0+Fom1r6nvcj/ORtLus8d8enXT6dyRZDirE=
github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY=
github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE=
github.com/swaggo/swag/v2 v2.0.0-rc5 h1:fK7d6ET9rrEsdB8IyuwXREWMcyQN3N7gawGFbbrjgHk=
github.com/swaggo/swag/v2 v2.0.0-rc5/go.mod h1:kCL8Fu4Zl8d5tB2Bgj96b8wRowwrwk175bZHXfuGVFI=
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 h1:yL0l/u242MzDP6D0B5vGC+wxm5WRY+alQZy+dJk3bFI=
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948/go.mod h1:a06d/M1pxWi51qiSrfGMHaEydtuXT06nha8N2aNQuXk=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
@@ -290,12 +334,16 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -304,15 +352,15 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -328,29 +376,35 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=

View File

@@ -22,5 +22,16 @@ func mountAdminRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs, authUser func(ht
archer.Post("/jobs/{id}/cancel", handlers.AdminCancelArcherJob(db))
archer.Get("/queues", handlers.AdminListArcherQueues(db))
})
admin.Route("/actions", func(action chi.Router) {
action.Use(authUser)
action.Use(httpmiddleware.RequirePlatformAdmin())
action.Get("/", handlers.ListActions(db))
action.Post("/", handlers.CreateAction(db))
action.Get("/{actionID}", handlers.GetAction(db))
action.Patch("/{actionID}", handlers.UpdateAction(db))
action.Delete("/{actionID}", handlers.DeleteAction(db))
})
})
}

View File

@@ -33,7 +33,7 @@ func mountAPIRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs) {
mountNodePoolRoutes(v1, db, authOrg)
mountDNSRoutes(v1, db, authOrg)
mountLoadBalancerRoutes(v1, db, authOrg)
mountClusterRoutes(v1, db, authOrg)
mountClusterRoutes(v1, db, jobs, authOrg)
})
})
}

View File

@@ -3,12 +3,13 @@ package api
import (
"net/http"
"github.com/glueops/autoglue/internal/bg"
"github.com/glueops/autoglue/internal/handlers"
"github.com/go-chi/chi/v5"
"gorm.io/gorm"
)
func mountClusterRoutes(r chi.Router, db *gorm.DB, authOrg func(http.Handler) http.Handler) {
func mountClusterRoutes(r chi.Router, db *gorm.DB, jobs *bg.Jobs, authOrg func(http.Handler) http.Handler) {
r.Route("/clusters", func(c chi.Router) {
c.Use(authOrg)
c.Get("/", handlers.ListClusters(db))
@@ -36,6 +37,10 @@ func mountClusterRoutes(r chi.Router, db *gorm.DB, authOrg func(http.Handler) ht
c.Delete("/{clusterID}/kubeconfig", handlers.ClearClusterKubeconfig(db))
c.Post("/{clusterID}/node-pools", handlers.AttachNodePool(db))
c.Delete("/{clusterID}/node-pools/{nodePoolID}", handlers.DeleteNodePool(db))
c.Delete("/{clusterID}/node-pools/{nodePoolID}", handlers.DetachNodePool(db))
c.Get("/{clusterID}/runs", handlers.ListClusterRuns(db))
c.Get("/{clusterID}/runs/{runID}", handlers.GetClusterRun(db))
c.Post("/{clusterID}/actions/{actionID}/runs", handlers.RunClusterAction(db, jobs))
})
}

View File

@@ -20,6 +20,7 @@ func mountDNSRoutes(r chi.Router, db *gorm.DB, authOrg func(http.Handler) http.H
d.Get("/domains/{domain_id}/records", handlers.ListRecordSets(db))
d.Post("/domains/{domain_id}/records", handlers.CreateRecordSet(db))
d.Get("/records/{id}", handlers.GetRecordSet(db))
d.Patch("/records/{id}", handlers.UpdateRecordSet(db))
d.Delete("/records/{id}", handlers.DeleteRecordSet(db))
})

View File

@@ -37,7 +37,7 @@ func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
r.Use(middleware.Recoverer)
r.Use(SecurityHeaders)
r.Use(requestBodyLimit(10 << 20))
r.Use(httprate.LimitByIP(100, 1*time.Minute))
r.Use(httprate.LimitByIP(1000, 1*time.Minute))
r.Use(middleware.StripSlashes)
allowed := getAllowedOrigins()

View File

@@ -44,6 +44,9 @@ func NewRuntime() *Runtime {
&models.RecordSet{},
&models.LoadBalancer{},
&models.Cluster{},
&models.Action{},
&models.Cluster{},
&models.ClusterRun{},
)
if err != nil {

View File

@@ -107,7 +107,7 @@ func NewJobs(gdb *gorm.DB, dbUrl string) (*Jobs, error) {
archer.WithInstances(1),
archer.WithTimeout(2*time.Minute),
)
/*
c.Register(
"prepare_cluster",
ClusterPrepareWorker(gdb, jobs),
@@ -129,6 +129,20 @@ func NewJobs(gdb *gorm.DB, dbUrl string) (*Jobs, error) {
archer.WithTimeout(60*time.Minute),
)
*/
c.Register(
"org_key_sweeper",
OrgKeySweeperWorker(gdb, jobs),
archer.WithInstances(1),
archer.WithTimeout(5*time.Minute),
)
c.Register(
"cluster_action",
ClusterActionWorker(gdb),
archer.WithInstances(1),
)
return jobs, nil
}

View File

@@ -0,0 +1,195 @@
package bg
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/dyaksa/archer"
"github.com/dyaksa/archer/job"
"github.com/glueops/autoglue/internal/mapper"
"github.com/glueops/autoglue/internal/models"
"github.com/glueops/autoglue/internal/utils"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
)
type ClusterActionArgs struct {
OrgID uuid.UUID `json:"org_id"`
ClusterID uuid.UUID `json:"cluster_id"`
Action string `json:"action"`
MakeTarget string `json:"make_target"`
}
type ClusterActionResult struct {
Status string `json:"status"`
Action string `json:"action"`
ClusterID string `json:"cluster_id"`
ElapsedMs int `json:"elapsed_ms"`
}
func ClusterActionWorker(db *gorm.DB) archer.WorkerFn {
return func(ctx context.Context, j job.Job) (any, error) {
start := time.Now()
var args ClusterActionArgs
_ = j.ParseArguments(&args)
runID, _ := uuid.Parse(j.ID)
updateRun := func(status string, errMsg string) {
updates := map[string]any{
"status": status,
"error": errMsg,
}
if status == "succeeded" || status == "failed" {
updates["finished_at"] = time.Now().UTC().Format(time.RFC3339)
}
db.Model(&models.ClusterRun{}).Where("id = ?", runID).Updates(updates)
}
updateRun("running", "")
logger := log.With().
Str("job", j.ID).
Str("cluster_id", args.ClusterID.String()).
Str("action", args.Action).
Logger()
var c models.Cluster
if err := db.
Preload("BastionServer.SshKey").
Preload("CaptainDomain").
Preload("ControlPlaneRecordSet").
Preload("AppsLoadBalancer").
Preload("GlueOpsLoadBalancer").
Preload("NodePools").
Preload("NodePools.Labels").
Preload("NodePools.Annotations").
Preload("NodePools.Taints").
Preload("NodePools.Servers.SshKey").
Where("id = ? AND organization_id = ?", args.ClusterID, args.OrgID).
First(&c).Error; err != nil {
updateRun("failed", fmt.Errorf("load cluster: %w", err).Error())
return nil, fmt.Errorf("load cluster: %w", err)
}
// ---- Step 1: Prepare (mostly lifted from ClusterPrepareWorker)
if err := setClusterStatus(db, c.ID, clusterStatusBootstrapping, ""); err != nil {
updateRun("failed", err.Error())
return nil, fmt.Errorf("mark bootstrapping: %w", err)
}
c.Status = clusterStatusBootstrapping
if err := validateClusterForPrepare(&c); err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
updateRun("failed", err.Error())
return nil, fmt.Errorf("validate: %w", err)
}
allServers := flattenClusterServers(&c)
keyPayloads, sshConfig, err := buildSSHAssetsForCluster(db, &c, allServers)
if err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
updateRun("failed", err.Error())
return nil, fmt.Errorf("build ssh assets: %w", err)
}
dtoCluster := mapper.ClusterToDTO(c)
if c.EncryptedKubeconfig != "" && c.KubeIV != "" && c.KubeTag != "" {
kubeconfig, err := utils.DecryptForOrg(
c.OrganizationID,
c.EncryptedKubeconfig,
c.KubeIV,
c.KubeTag,
db,
)
if err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
return nil, fmt.Errorf("decrypt kubeconfig: %w", err)
}
dtoCluster.Kubeconfig = &kubeconfig
}
orgKey, orgSecret, err := findOrCreateClusterAutomationKey(db, c.OrganizationID, c.ID, 24*time.Hour)
if err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
updateRun("failed", err.Error())
return nil, fmt.Errorf("org key: %w", err)
}
dtoCluster.OrgKey = &orgKey
dtoCluster.OrgSecret = &orgSecret
payloadJSON, err := json.MarshalIndent(dtoCluster, "", " ")
if err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
updateRun("failed", err.Error())
return nil, fmt.Errorf("marshal payload: %w", err)
}
{
runCtx, cancel := context.WithTimeout(ctx, 8*time.Minute)
err := pushAssetsToBastion(runCtx, db, &c, sshConfig, keyPayloads, payloadJSON)
cancel()
if err != nil {
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
updateRun("failed", err.Error())
return nil, fmt.Errorf("push assets: %w", err)
}
}
if err := setClusterStatus(db, c.ID, clusterStatusPending, ""); err != nil {
updateRun("failed", err.Error())
return nil, fmt.Errorf("mark pending: %w", err)
}
c.Status = clusterStatusPending
// ---- Step 2: Setup (ping-servers)
{
runCtx, cancel := context.WithTimeout(ctx, 30*time.Minute)
out, err := runMakeOnBastion(runCtx, db, &c, "ping-servers")
cancel()
if err != nil {
logger.Error().Err(err).Str("output", out).Msg("ping-servers failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make ping-servers: %v", err))
updateRun("failed", err.Error())
return nil, fmt.Errorf("ping-servers: %w", err)
}
}
if err := setClusterStatus(db, c.ID, clusterStatusProvisioning, ""); err != nil {
updateRun("failed", err.Error())
return nil, fmt.Errorf("mark provisioning: %w", err)
}
c.Status = clusterStatusProvisioning
// ---- Step 3: Bootstrap (parameterized target)
{
runCtx, cancel := context.WithTimeout(ctx, 60*time.Minute)
out, err := runMakeOnBastion(runCtx, db, &c, args.MakeTarget)
cancel()
if err != nil {
logger.Error().Err(err).Str("output", out).Msg("bootstrap target failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make %s: %v", args.MakeTarget, err))
updateRun("failed", err.Error())
return nil, fmt.Errorf("make %s: %w", args.MakeTarget, err)
}
}
if err := setClusterStatus(db, c.ID, clusterStatusReady, ""); err != nil {
updateRun("failed", err.Error())
return nil, fmt.Errorf("mark ready: %w", err)
}
updateRun("succeeded", "")
return ClusterActionResult{
Status: "ok",
Action: args.Action,
ClusterID: c.ID.String(),
ElapsedMs: int(time.Since(start).Milliseconds()),
}, nil
}
}

View File

@@ -68,14 +68,14 @@ func ClusterBootstrapWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
logger.Info().Msg("[cluster_bootstrap] running make bootstrap")
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
out, err := runMakeOnBastion(runCtx, db, c, "bootstrap")
out, err := runMakeOnBastion(runCtx, db, c, "setup")
cancel()
if err != nil {
failCount++
failedIDs = append(failedIDs, c.ID)
logger.Error().Err(err).Str("output", out).Msg("[cluster_bootstrap] make bootstrap failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make bootstrap: %v", err))
logger.Error().Err(err).Str("output", out).Msg("[cluster_bootstrap] make setup failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make setup: %v", err))
continue
}

View File

@@ -68,14 +68,14 @@ func ClusterSetupWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
logger.Info().Msg("[cluster_setup] running make setup")
runCtx, cancel := context.WithTimeout(ctx, perClusterTimeout)
out, err := runMakeOnBastion(runCtx, db, c, "setup")
out, err := runMakeOnBastion(runCtx, db, c, "ping-servers")
cancel()
if err != nil {
failCount++
failedIDs = append(failedIDs, c.ID)
logger.Error().Err(err).Str("output", out).Msg("[cluster_setup] make setup failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make setup: %v", err))
logger.Error().Err(err).Str("output", out).Msg("[cluster_setup] make ping-servers failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, fmt.Sprintf("make ping-servers: %v", err))
continue
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/glueops/autoglue/internal/models"
"github.com/glueops/autoglue/internal/utils"
"github.com/google/uuid"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
@@ -23,6 +24,8 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials"
r53 "github.com/aws/aws-sdk-go-v2/service/route53"
r53types "github.com/aws/aws-sdk-go-v2/service/route53/types"
"github.com/aws/smithy-go"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
/************* args & small DTOs *************/
@@ -47,6 +50,9 @@ const externalDNSPoisonOwner = "autoglue-lock"
// ExternalDNS poison content fake owner so real external-dns skips it.
const externalDNSPoisonValue = "heritage=external-dns,external-dns/owner=" + externalDNSPoisonOwner + ",external-dns/resource=manual/autoglue"
// Default TTL for non-alias records (alias not supported in this reconciler)
const defaultRecordTTLSeconds int64 = 300
/************* entrypoint worker *************/
func DNSReconsileWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
@@ -225,7 +231,14 @@ func processPendingRecordsForDomain(ctx context.Context, db *gorm.DB, d *models.
applied := 0
for i := range records {
if err := applyRecord(ctx, db, r53c, d, &records[i]); err != nil {
log.Error().Err(err).Str("rr", records[i].Name).Msg("[dns] apply record failed")
log.Error().
Err(err).
Str("zone_id", d.ZoneID).
Str("domain", d.DomainName).
Str("record_id", records[i].ID.String()).
Str("name", records[i].Name).
Str("type", strings.ToUpper(records[i].Type)).
Msg("[dns] apply record failed")
_ = setRecordFailed(db, &records[i], err)
continue
}
@@ -249,12 +262,24 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
mname := markerName(fq)
expected := buildMarkerValue(d.OrganizationID.String(), r.ID.String(), r.Fingerprint)
logCtx := log.With().
Str("zone_id", zoneID).
Str("domain", d.DomainName).
Str("fqdn", fq).
Str("rr_type", rt).
Str("record_id", r.ID.String()).
Str("org_id", d.OrganizationID.String()).
Logger()
start := time.Now()
// ---- ExternalDNS preflight ----
extOwned, err := hasExternalDNSOwnership(ctx, r53c, zoneID, fq, rt)
if err != nil {
return fmt.Errorf("external_dns_lookup: %w", err)
}
if extOwned {
logCtx.Warn().Msg("[dns] ownership conflict: external-dns claims this record")
r.Owner = "external"
_ = db.Save(r).Error
return fmt.Errorf("ownership_conflict: external-dns claims %s; refusing to modify", strings.TrimSuffix(fq, "."))
@@ -265,6 +290,7 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
if err != nil {
return fmt.Errorf("marker lookup: %w", err)
}
hasForeignOwner := false
hasOurExact := false
for _, v := range markerVals {
@@ -279,25 +305,26 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
hasForeignOwner = true
}
}
logCtx.Debug().
Bool("externaldns_owned", extOwned).
Int("marker_txt_count", len(markerVals)).
Bool("marker_has_our_exact", hasOurExact).
Bool("marker_has_foreign", hasForeignOwner).
Msg("[dns] ownership preflight")
if hasForeignOwner {
logCtx.Warn().Msg("[dns] ownership conflict: foreign _autoglue marker")
r.Owner = "external"
_ = db.Save(r).Error
return fmt.Errorf("ownership_conflict: marker for %s is owned by another controller; refusing to modify", strings.TrimSuffix(fq, "."))
}
// Build RR change (UPSERT)
rrChange := r53types.Change{
Action: r53types.ChangeActionUpsert,
ResourceRecordSet: &r53types.ResourceRecordSet{
Name: aws.String(fq),
Type: r53types.RRType(rt),
},
}
// Decode user values
var userVals []string
if len(r.Values) > 0 {
if err := jsonUnmarshalStrict([]byte(r.Values), &userVals); err != nil {
rawVals := strings.TrimSpace(string(r.Values))
if rawVals != "" && rawVals != "null" {
if err := jsonUnmarshalStrict([]byte(rawVals), &userVals); err != nil {
return fmt.Errorf("values decode: %w", err)
}
}
@@ -306,15 +333,38 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
recs := make([]r53types.ResourceRecord, 0, len(userVals))
for _, v := range userVals {
v = strings.TrimSpace(v)
if v == "" {
continue
}
if rt == "TXT" && !(strings.HasPrefix(v, `"`) && strings.HasSuffix(v, `"`)) {
v = strconv.Quote(v)
}
recs = append(recs, r53types.ResourceRecord{Value: aws.String(v)})
}
rrChange.ResourceRecordSet.ResourceRecords = recs
if r.TTL != nil {
ttl := int64(*r.TTL)
rrChange.ResourceRecordSet.TTL = aws.Int64(ttl)
// Alias is NOT supported - enforce at least one value for all record types we manage
if len(recs) == 0 {
logCtx.Warn().
Str("raw_values", truncateForLog(string(r.Values), 240)).
Int("decoded_value_count", len(userVals)).
Msg("[dns] invalid record: no values (alias not supported)")
return fmt.Errorf("invalid_record: %s %s requires at least one value (alias not supported)", strings.TrimSuffix(fq, "."), rt)
}
ttl := defaultRecordTTLSeconds
if r.TTL != nil && *r.TTL > 0 {
ttl = int64(*r.TTL)
}
// Build RR change (UPSERT)
rrChange := r53types.Change{
Action: r53types.ChangeActionUpsert,
ResourceRecordSet: &r53types.ResourceRecordSet{
Name: aws.String(fq),
Type: r53types.RRType(rt),
TTL: aws.Int64(ttl),
ResourceRecords: recs,
},
}
// Build marker TXT change (UPSERT)
@@ -323,7 +373,7 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
ResourceRecordSet: &r53types.ResourceRecordSet{
Name: aws.String(mname),
Type: r53types.RRTypeTxt,
TTL: aws.Int64(300),
TTL: aws.Int64(defaultRecordTTLSeconds),
ResourceRecords: []r53types.ResourceRecord{
{Value: aws.String(strconv.Quote(expected))},
},
@@ -337,14 +387,26 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
changes := []r53types.Change{rrChange, markerChange}
changes = append(changes, poisonChanges...)
// Log what we are about to send
logCtx.Debug().
Interface("route53_change_batch", toLogChangeBatch(zoneID, changes)).
Msg("[dns] route53 request preview")
_, err = r53c.ChangeResourceRecordSets(ctx, &r53.ChangeResourceRecordSetsInput{
HostedZoneId: aws.String(zoneID),
ChangeBatch: &r53types.ChangeBatch{Changes: changes},
})
if err != nil {
logAWSError(logCtx, err)
logCtx.Info().Dur("elapsed", time.Since(start)).Msg("[dns] apply failed")
return err
}
logCtx.Info().
Dur("elapsed", time.Since(start)).
Int("change_count", len(changes)).
Msg("[dns] apply ok")
// Success → mark ready & ownership
r.Status = "ready"
r.LastError = ""
@@ -352,6 +414,7 @@ func applyRecord(ctx context.Context, db *gorm.DB, r53c *r53.Client, d *models.D
if err := db.Save(r).Error; err != nil {
return err
}
_ = hasOurExact // could be used to skip marker write in future
return nil
}
@@ -568,7 +631,7 @@ func buildExternalDNSPoisonTXTChanges(fqdn, rrType string) []r53types.Change {
ResourceRecordSet: &r53types.ResourceRecordSet{
Name: aws.String(n),
Type: r53types.RRTypeTxt,
TTL: aws.Int64(300),
TTL: aws.Int64(defaultRecordTTLSeconds),
ResourceRecords: []r53types.ResourceRecord{
{Value: aws.String(val)},
},
@@ -595,3 +658,125 @@ func jsonUnmarshalStrict(b []byte, dst any) error {
}
return json.Unmarshal(b, dst)
}
/************* logging DTOs & helpers *************/
type logRR struct {
Value string `json:"value"`
}
type logRRSet struct {
Action string `json:"action"`
Name string `json:"name"`
Type string `json:"type"`
TTL *int64 `json:"ttl,omitempty"`
Records []logRR `json:"records,omitempty"`
RecordCount int `json:"record_count"`
HasAliasTarget bool `json:"has_alias_target"`
SetIdentifier *string `json:"set_identifier,omitempty"`
}
type logChangeBatch struct {
HostedZoneID string `json:"hosted_zone_id"`
ChangeCount int `json:"change_count"`
Changes []logRRSet `json:"changes"`
}
func truncateForLog(s string, max int) string {
s = strings.TrimSpace(s)
if max <= 0 || len(s) <= max {
return s
}
return s[:max] + "…"
}
func toLogChangeBatch(zoneID string, changes []r53types.Change) logChangeBatch {
out := logChangeBatch{
HostedZoneID: zoneID,
ChangeCount: len(changes),
Changes: make([]logRRSet, 0, len(changes)),
}
for _, ch := range changes {
if ch.ResourceRecordSet == nil {
continue
}
rrs := ch.ResourceRecordSet
lc := logRRSet{
Action: string(ch.Action),
Name: aws.ToString(rrs.Name),
Type: string(rrs.Type),
TTL: rrs.TTL,
HasAliasTarget: rrs.AliasTarget != nil,
SetIdentifier: rrs.SetIdentifier,
RecordCount: len(rrs.ResourceRecords),
Records: make([]logRR, 0, min(len(rrs.ResourceRecords), 5)),
}
// Log up to first 5 values (truncate each) to avoid log bloat / secrets
for i, rr := range rrs.ResourceRecords {
if i >= 5 {
break
}
lc.Records = append(lc.Records, logRR{Value: truncateForLog(aws.ToString(rr.Value), 160)})
}
out.Changes = append(out.Changes, lc)
}
return out
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
// logAWSError extracts useful smithy/HTTP metadata (status code + request id + api code) into logs.
// logAWSError extracts useful smithy/HTTP metadata (status code + request id + api code) into logs.
func logAWSError(l zerolog.Logger, err error) {
// Add operation context if present
var opErr *smithy.OperationError
if errors.As(err, &opErr) {
l = l.With().
Str("aws_service", opErr.ServiceID).
Str("aws_operation", opErr.OperationName).
Logger()
err = opErr.Unwrap()
}
// HTTP status + request id (smithy-go transport/http)
var re *smithyhttp.ResponseError
if errors.As(err, &re) {
status := re.HTTPStatusCode()
reqID := ""
if resp := re.HTTPResponse(); resp != nil && resp.Header != nil {
reqID = resp.Header.Get("x-amzn-RequestId")
if reqID == "" {
reqID = resp.Header.Get("x-amz-request-id")
}
}
ev := l.Error().Int("http_status", status).Err(err)
if reqID != "" {
ev = ev.Str("aws_request_id", reqID)
}
ev.Msg("[dns] aws route53 call failed")
return
}
// API error code/message (best-effort)
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
l.Error().
Str("aws_error_code", apiErr.ErrorCode()).
Str("aws_error_message", apiErr.ErrorMessage()).
Err(err).
Msg("[dns] aws route53 api error")
return
}
l.Error().Err(err).Msg("[dns] aws route53 error")
}

View File

@@ -0,0 +1,95 @@
package bg
import (
"context"
"time"
"github.com/dyaksa/archer"
"github.com/dyaksa/archer/job"
"github.com/glueops/autoglue/internal/models"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
)
type OrgKeySweeperArgs struct {
IntervalS int `json:"interval_seconds,omitempty"`
RetentionDays int `json:"retention_days,omitempty"`
}
type OrgKeySweeperResult struct {
Status string `json:"status"`
MarkedRevoked int `json:"marked_revoked"`
DeletedEphemeral int `json:"deleted_ephemeral"`
ElapsedMs int `json:"elapsed_ms"`
}
func OrgKeySweeperWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
return func(ctx context.Context, j job.Job) (any, error) {
args := OrgKeySweeperArgs{
IntervalS: 3600,
RetentionDays: 10,
}
start := time.Now()
_ = j.ParseArguments(&args)
if args.IntervalS <= 0 {
args.IntervalS = 3600
}
if args.RetentionDays <= 0 {
args.RetentionDays = 10
}
now := time.Now()
// 1) Mark expired keys as revoked
res1 := db.Model(&models.APIKey{}).
Where("expires_at IS NOT NULL AND expires_at <= ? AND revoked = false", now).
Updates(map[string]any{
"revoked": true,
"updated_at": now,
})
if res1.Error != nil {
log.Error().Err(res1.Error).Msg("[org_key_sweeper] mark expired revoked failed")
return nil, res1.Error
}
markedRevoked := int(res1.RowsAffected)
// 2) Hard-delete ephemeral keys that are revoked and older than retention
cutoff := now.Add(-time.Duration(args.RetentionDays) * 24 * time.Hour)
res2 := db.
Where("is_ephemeral = ? AND revoked = ? AND updated_at <= ?", true, true, cutoff).
Delete(&models.APIKey{})
if res2.Error != nil {
log.Error().Err(res2.Error).Msg("[org_key_sweeper] delete revoked ephemeral keys failed")
return nil, res2.Error
}
deletedEphemeral := int(res2.RowsAffected)
out := OrgKeySweeperResult{
Status: "ok",
MarkedRevoked: markedRevoked,
DeletedEphemeral: deletedEphemeral,
ElapsedMs: int(time.Since(start).Milliseconds()),
}
log.Info().
Int("marked_revoked", markedRevoked).
Int("deleted_ephemeral", deletedEphemeral).
Msg("[org_key_sweeper] cleanup tick ok")
// Re-enqueue the sweeper
next := time.Now().Add(time.Duration(args.IntervalS) * time.Second)
_, _ = jobs.Enqueue(
ctx,
uuid.NewString(),
"org_key_sweeper",
args,
archer.WithScheduleTime(next),
archer.WithMaxRetries(1),
)
return out, nil
}
}

View File

@@ -3,6 +3,7 @@ package bg
import (
"bytes"
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
@@ -12,6 +13,8 @@ import (
"github.com/dyaksa/archer"
"github.com/dyaksa/archer/job"
"github.com/glueops/autoglue/internal/auth"
"github.com/glueops/autoglue/internal/mapper"
"github.com/glueops/autoglue/internal/models"
"github.com/glueops/autoglue/internal/utils"
"github.com/google/uuid"
@@ -47,6 +50,7 @@ const (
clusterStatusProvisioning = models.ClusterStatusProvisioning
clusterStatusReady = models.ClusterStatusReady
clusterStatusFailed = models.ClusterStatusFailed
clusterStatusBootstrapping = models.ClusterStatusBootstrapping
)
func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
@@ -66,6 +70,12 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
Preload("BastionServer.SshKey").
Preload("CaptainDomain").
Preload("ControlPlaneRecordSet").
Preload("AppsLoadBalancer").
Preload("GlueOpsLoadBalancer").
Preload("NodePools").
Preload("NodePools.Labels").
Preload("NodePools.Annotations").
Preload("NodePools.Taints").
Preload("NodePools.Servers.SshKey").
Where("status = ?", clusterStatusPrePending).
Find(&clusters).Error; err != nil {
@@ -88,6 +98,13 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
continue
}
if err := setClusterStatus(db, c.ID, clusterStatusBootstrapping, ""); err != nil {
log.Error().Err(err).Msg("[cluster_prepare] failed to mark cluster bootstrapping")
continue
}
c.Status = clusterStatusBootstrapping
clusterLog := log.With().
Str("job", jobID).
Str("cluster_id", c.ID.String()).
@@ -124,7 +141,55 @@ func ClusterPrepareWorker(db *gorm.DB, jobs *Jobs) archer.WorkerFn {
continue
}
payloadJSON, err := json.MarshalIndent(c, "", " ")
dtoCluster := mapper.ClusterToDTO(*c)
if c.EncryptedKubeconfig != "" && c.KubeIV != "" && c.KubeTag != "" {
kubeconfig, err := utils.DecryptForOrg(
c.OrganizationID,
c.EncryptedKubeconfig,
c.KubeIV,
c.KubeTag,
db,
)
if err != nil {
fail++
failedIDs = append(failedIDs, c.ID)
failures = append(failures, ClusterPrepareFailure{
ClusterID: c.ID,
Step: "decrypt_kubeconfig",
Reason: err.Error(),
})
clusterLog.Error().Err(err).Msg("[cluster_prepare] decrypt kubeconfig failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
continue
}
dtoCluster.Kubeconfig = &kubeconfig
}
orgKey, orgSecret, err := findOrCreateClusterAutomationKey(
db,
c.OrganizationID,
c.ID,
24*time.Hour,
)
if err != nil {
fail++
failedIDs = append(failedIDs, c.ID)
failures = append(failures, ClusterPrepareFailure{
ClusterID: c.ID,
Step: "create_org_key",
Reason: err.Error(),
})
clusterLog.Error().Err(err).Msg("[cluster_prepare] create org key for payload failed")
_ = setClusterStatus(db, c.ID, clusterStatusFailed, err.Error())
continue
}
dtoCluster.OrgKey = &orgKey
dtoCluster.OrgSecret = &orgSecret
payloadJSON, err := json.MarshalIndent(dtoCluster, "", " ")
if err != nil {
fail++
failedIDs = append(failedIDs, c.ID)
@@ -443,6 +508,11 @@ func runMakeOnBastion(
c *models.Cluster,
target string,
) (string, error) {
logger := log.With().
Str("cluster_id", c.ID.String()).
Str("cluster_name", c.Name).
Logger()
bastion := c.BastionServer
if bastion == nil {
return "", fmt.Errorf("bastion server is nil")
@@ -500,7 +570,13 @@ func runMakeOnBastion(
defer sess.Close()
clusterDir := fmt.Sprintf("$HOME/autoglue/clusters/%s", c.ID.String())
cmd := fmt.Sprintf("cd %s && make %s", clusterDir, target)
sshDir := fmt.Sprintf("$HOME/.ssh")
cmd := fmt.Sprintf("cd %s && docker run -v %s:/root/.ssh -v ./payload.json:/opt/gluekube/platform.json %s:%s make %s", clusterDir, sshDir, c.DockerImage, c.DockerTag, target)
logger.Info().
Str("cmd", cmd).
Msg("[runMakeOnBastion] executing remote command")
out, runErr := sess.CombinedOutput(cmd)
if runErr != nil {
@@ -508,3 +584,75 @@ func runMakeOnBastion(
}
return string(out), nil
}
func randomB64URL(n int) (string, error) {
b := make([]byte, n)
if _, err := rand.Read(b); err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(b), nil
}
func findOrCreateClusterAutomationKey(
db *gorm.DB,
orgID uuid.UUID,
clusterID uuid.UUID,
ttl time.Duration,
) (orgKey string, orgSecret string, err error) {
now := time.Now()
name := fmt.Sprintf("cluster-%s-bastion", clusterID.String())
// 1) Delete any existing ephemeral cluster-bastion key for this org+cluster
if err := db.Where(
"org_id = ? AND scope = ? AND purpose = ? AND cluster_id = ? AND is_ephemeral = ?",
orgID, "org", "cluster_bastion", clusterID, true,
).Delete(&models.APIKey{}).Error; err != nil {
return "", "", fmt.Errorf("delete existing cluster key: %w", err)
}
// 2) Mint a fresh keypair
keySuffix, err := randomB64URL(16)
if err != nil {
return "", "", fmt.Errorf("entropy_error: %w", err)
}
sec, err := randomB64URL(32)
if err != nil {
return "", "", fmt.Errorf("entropy_error: %w", err)
}
orgKey = "org_" + keySuffix
orgSecret = sec
keyHash := auth.SHA256Hex(orgKey)
secretHash, err := auth.HashSecretArgon2id(orgSecret)
if err != nil {
return "", "", fmt.Errorf("hash_error: %w", err)
}
exp := now.Add(ttl)
prefix := orgKey
if len(prefix) > 12 {
prefix = prefix[:12]
}
rec := models.APIKey{
OrgID: &orgID,
Scope: "org",
Purpose: "cluster_bastion",
ClusterID: &clusterID,
IsEphemeral: true,
Name: name,
KeyHash: keyHash,
SecretHash: &secretHash,
ExpiresAt: &exp,
Revoked: false,
Prefix: &prefix,
}
if err := db.Create(&rec).Error; err != nil {
return "", "", fmt.Errorf("db_error: %w", err)
}
return orgKey, orgSecret, nil
}

View File

@@ -0,0 +1,256 @@
package handlers
import (
"encoding/json"
"errors"
"net/http"
"strings"
"github.com/glueops/autoglue/internal/handlers/dto"
"github.com/glueops/autoglue/internal/models"
"github.com/glueops/autoglue/internal/utils"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"gorm.io/gorm"
)
// ListActions godoc
//
// @ID ListActions
// @Summary List available actions
// @Description Returns all admin-configured actions.
// @Tags Actions
// @Produce json
// @Success 200 {array} dto.ActionResponse
// @Failure 401 {string} string "Unauthorized"
// @Failure 500 {string} string "db error"
// @Router /admin/actions [get]
// @Security BearerAuth
func ListActions(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var rows []models.Action
if err := db.Order("label ASC").Find(&rows).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
out := make([]dto.ActionResponse, 0, len(rows))
for _, a := range rows {
out = append(out, actionToDTO(a))
}
utils.WriteJSON(w, http.StatusOK, out)
}
}
// GetAction godoc
//
// @ID GetAction
// @Summary Get a single action by ID
// @Description Returns a single action.
// @Tags Actions
// @Produce json
// @Param actionID path string true "Action ID"
// @Success 200 {object} dto.ActionResponse
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 404 {string} string "not found"
// @Failure 500 {string} string "db error"
// @Router /admin/actions/{actionID} [get]
// @Security BearerAuth
func GetAction(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
return
}
var row models.Action
if err := db.Where("id = ?", actionID).First(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
utils.WriteJSON(w, http.StatusOK, actionToDTO(row))
}
}
// CreateAction godoc
//
// @ID CreateAction
// @Summary Create an action
// @Description Creates a new admin-configured action.
// @Tags Actions
// @Accept json
// @Produce json
// @Param body body dto.CreateActionRequest true "payload"
// @Success 201 {object} dto.ActionResponse
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 500 {string} string "db error"
// @Router /admin/actions [post]
// @Security BearerAuth
func CreateAction(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var in dto.CreateActionRequest
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_json", err.Error())
return
}
label := strings.TrimSpace(in.Label)
desc := strings.TrimSpace(in.Description)
target := strings.TrimSpace(in.MakeTarget)
if label == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "label is required")
return
}
if desc == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "description is required")
return
}
if target == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "make_target is required")
return
}
row := models.Action{
Label: label,
Description: desc,
MakeTarget: target,
}
if err := db.Create(&row).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
utils.WriteJSON(w, http.StatusCreated, actionToDTO(row))
}
}
// UpdateAction godoc
//
// @ID UpdateAction
// @Summary Update an action
// @Description Updates an action. Only provided fields are modified.
// @Tags Actions
// @Accept json
// @Produce json
// @Param actionID path string true "Action ID"
// @Param body body dto.UpdateActionRequest true "payload"
// @Success 200 {object} dto.ActionResponse
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 404 {string} string "not found"
// @Failure 500 {string} string "db error"
// @Router /admin/actions/{actionID} [patch]
// @Security BearerAuth
func UpdateAction(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
return
}
var in dto.UpdateActionRequest
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_json", err.Error())
return
}
var row models.Action
if err := db.Where("id = ?", actionID).First(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
if in.Label != nil {
v := strings.TrimSpace(*in.Label)
if v == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "label cannot be empty")
return
}
row.Label = v
}
if in.Description != nil {
v := strings.TrimSpace(*in.Description)
if v == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "description cannot be empty")
return
}
row.Description = v
}
if in.MakeTarget != nil {
v := strings.TrimSpace(*in.MakeTarget)
if v == "" {
utils.WriteError(w, http.StatusBadRequest, "validation_error", "make_target cannot be empty")
return
}
row.MakeTarget = v
}
if err := db.Save(&row).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
utils.WriteJSON(w, http.StatusOK, actionToDTO(row))
}
}
// DeleteAction godoc
//
// @ID DeleteAction
// @Summary Delete an action
// @Description Deletes an action.
// @Tags Actions
// @Produce json
// @Param actionID path string true "Action ID"
// @Success 204 {string} string "deleted"
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 404 {string} string "not found"
// @Failure 500 {string} string "db error"
// @Router /admin/actions/{actionID} [delete]
// @Security BearerAuth
func DeleteAction(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
return
}
tx := db.Where("id = ?", actionID).Delete(&models.Action{})
if tx.Error != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
if tx.RowsAffected == 0 {
utils.WriteError(w, http.StatusNotFound, "not_found", "action not found")
return
}
w.WriteHeader(http.StatusNoContent)
}
}
func actionToDTO(a models.Action) dto.ActionResponse {
return dto.ActionResponse{
ID: a.ID,
Label: a.Label,
Description: a.Description,
MakeTarget: a.MakeTarget,
CreatedAt: a.CreatedAt,
UpdatedAt: a.UpdatedAt,
}
}

View File

@@ -0,0 +1,263 @@
package handlers
import (
"errors"
"net/http"
"time"
"github.com/dyaksa/archer"
"github.com/glueops/autoglue/internal/api/httpmiddleware"
"github.com/glueops/autoglue/internal/bg"
"github.com/glueops/autoglue/internal/handlers/dto"
"github.com/glueops/autoglue/internal/models"
"github.com/glueops/autoglue/internal/utils"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"gorm.io/gorm"
)
// ListClusterRuns godoc
//
// @ID ListClusterRuns
// @Summary List cluster runs (org scoped)
// @Description Returns runs for a cluster within the organization in X-Org-ID.
// @Tags ClusterRuns
// @Produce json
// @Param X-Org-ID header string false "Organization UUID"
// @Param clusterID path string true "Cluster ID"
// @Success 200 {array} dto.ClusterRunResponse
// @Failure 401 {string} string "Unauthorized"
// @Failure 403 {string} string "organization required"
// @Failure 404 {string} string "cluster not found"
// @Failure 500 {string} string "db error"
// @Router /clusters/{clusterID}/runs [get]
// @Security BearerAuth
// @Security OrgKeyAuth
// @Security OrgSecretAuth
func ListClusterRuns(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
return
}
// Ensure cluster exists + org scoped
if err := db.Select("id").
Where("id = ? AND organization_id = ?", clusterID, orgID).
First(&models.Cluster{}).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "cluster not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
var rows []models.ClusterRun
if err := db.
Where("organization_id = ? AND cluster_id = ?", orgID, clusterID).
Order("created_at DESC").
Find(&rows).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
out := make([]dto.ClusterRunResponse, 0, len(rows))
for _, cr := range rows {
out = append(out, clusterRunToDTO(cr))
}
utils.WriteJSON(w, http.StatusOK, out)
}
}
// GetClusterRun godoc
//
// @ID GetClusterRun
// @Summary Get a cluster run (org scoped)
// @Description Returns a single run for a cluster within the organization in X-Org-ID.
// @Tags ClusterRuns
// @Produce json
// @Param X-Org-ID header string false "Organization UUID"
// @Param clusterID path string true "Cluster ID"
// @Param runID path string true "Run ID"
// @Success 200 {object} dto.ClusterRunResponse
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 403 {string} string "organization required"
// @Failure 404 {string} string "not found"
// @Failure 500 {string} string "db error"
// @Router /clusters/{clusterID}/runs/{runID} [get]
// @Security BearerAuth
// @Security OrgKeyAuth
// @Security OrgSecretAuth
func GetClusterRun(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
return
}
runID, err := uuid.Parse(chi.URLParam(r, "runID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_run_id", "invalid run id")
return
}
var row models.ClusterRun
if err := db.
Where("id = ? AND organization_id = ? AND cluster_id = ?", runID, orgID, clusterID).
First(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "run not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
utils.WriteJSON(w, http.StatusOK, clusterRunToDTO(row))
}
}
// RunClusterAction godoc
//
// @ID RunClusterAction
// @Summary Run an admin-configured action on a cluster (org scoped)
// @Description Creates a ClusterRun record for the cluster/action. Execution is handled asynchronously by workers.
// @Tags ClusterRuns
// @Produce json
// @Param X-Org-ID header string false "Organization UUID"
// @Param clusterID path string true "Cluster ID"
// @Param actionID path string true "Action ID"
// @Success 201 {object} dto.ClusterRunResponse
// @Failure 400 {string} string "bad request"
// @Failure 401 {string} string "Unauthorized"
// @Failure 403 {string} string "organization required"
// @Failure 404 {string} string "cluster or action not found"
// @Failure 500 {string} string "db error"
// @Router /clusters/{clusterID}/actions/{actionID}/runs [post]
// @Security BearerAuth
// @Security OrgKeyAuth
// @Security OrgSecretAuth
func RunClusterAction(db *gorm.DB, jobs *bg.Jobs) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
clusterID, err := uuid.Parse(chi.URLParam(r, "clusterID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_cluster_id", "invalid cluster id")
return
}
actionID, err := uuid.Parse(chi.URLParam(r, "actionID"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_action_id", "invalid action id")
return
}
// cluster must exist + org scoped
var cluster models.Cluster
if err := db.Select("id", "organization_id").
Where("id = ? AND organization_id = ?", clusterID, orgID).
First(&cluster).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "cluster not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
// action is global/admin-configured (not org scoped)
var action models.Action
if err := db.Where("id = ?", actionID).First(&action).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "action_not_found", "action not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
run := models.ClusterRun{
OrganizationID: orgID,
ClusterID: clusterID,
Action: action.MakeTarget, // this is what you actually execute
Status: models.ClusterRunStatusQueued,
Error: "",
FinishedAt: time.Time{},
}
if err := db.Create(&run).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
}
args := bg.ClusterActionArgs{
OrgID: orgID,
ClusterID: clusterID,
Action: action.MakeTarget,
MakeTarget: action.MakeTarget,
}
// Enqueue with run.ID as the job ID so the worker can look it up.
_, enqueueErr := jobs.Enqueue(
r.Context(),
run.ID.String(),
"cluster_action",
args,
archer.WithMaxRetries(0),
)
if enqueueErr != nil {
_ = db.Model(&models.ClusterRun{}).
Where("id = ?", run.ID).
Updates(map[string]any{
"status": models.ClusterRunStatusFailed,
"error": "failed to enqueue job: " + enqueueErr.Error(),
"finished_at": time.Now().UTC(),
}).Error
utils.WriteError(w, http.StatusInternalServerError, "job_error", "failed to enqueue cluster action")
return
}
utils.WriteJSON(w, http.StatusCreated, clusterRunToDTO(run))
}
}
func clusterRunToDTO(cr models.ClusterRun) dto.ClusterRunResponse {
var finished *time.Time
if !cr.FinishedAt.IsZero() {
t := cr.FinishedAt
finished = &t
}
return dto.ClusterRunResponse{
ID: cr.ID,
OrganizationID: cr.OrganizationID,
ClusterID: cr.ClusterID,
Action: cr.Action,
Status: cr.Status,
Error: cr.Error,
CreatedAt: cr.CreatedAt,
UpdatedAt: cr.UpdatedAt,
FinishedAt: finished,
}
}

View File

@@ -69,7 +69,17 @@ func ListClusters(db *gorm.DB) http.HandlerFunc {
out := make([]dto.ClusterResponse, 0, len(rows))
for _, row := range rows {
out = append(out, clusterToDTO(row))
cr := clusterToDTO(row)
if row.EncryptedKubeconfig != "" && row.KubeIV != "" && row.KubeTag != "" {
kubeconfig, err := utils.DecryptForOrg(orgID, row.EncryptedKubeconfig, row.KubeIV, row.KubeTag, db)
if err != nil {
utils.WriteError(w, http.StatusInternalServerError, "kubeconfig_decrypt_failed", "failed to decrypt kubeconfig")
return
}
cr.Kubeconfig = &kubeconfig
}
out = append(out, cr)
}
utils.WriteJSON(w, http.StatusOK, out)
}
@@ -131,7 +141,18 @@ func GetCluster(db *gorm.DB) http.HandlerFunc {
return
}
utils.WriteJSON(w, http.StatusOK, clusterToDTO(cluster))
resp := clusterToDTO(cluster)
if cluster.EncryptedKubeconfig != "" && cluster.KubeIV != "" && cluster.KubeTag != "" {
kubeconfig, err := utils.DecryptForOrg(orgID, cluster.EncryptedKubeconfig, cluster.KubeIV, cluster.KubeTag, db)
if err != nil {
utils.WriteError(w, http.StatusInternalServerError, "kubeconfig_decrypt_failed", "failed to decrypt kubeconfig")
return
}
resp.Kubeconfig = &kubeconfig
}
utils.WriteJSON(w, http.StatusOK, resp)
}
}
@@ -189,6 +210,8 @@ func CreateCluster(db *gorm.DB) http.HandlerFunc {
LastError: "",
CertificateKey: certificateKey,
RandomToken: randomToken,
DockerImage: in.DockerImage,
DockerTag: in.DockerTag,
}
if err := db.Create(&c).Error; err != nil {
@@ -262,6 +285,14 @@ func UpdateCluster(db *gorm.DB) http.HandlerFunc {
cluster.Region = *in.Region
}
if in.DockerImage != nil {
cluster.DockerImage = *in.DockerImage
}
if in.DockerTag != nil {
cluster.DockerTag = *in.DockerTag
}
if err := db.Save(&cluster).Error; err != nil {
utils.WriteError(w, http.StatusInternalServerError, "db_error", "db error")
return
@@ -1547,6 +1578,8 @@ func clusterToDTO(c models.Cluster) dto.ClusterResponse {
RandomToken: c.RandomToken,
CertificateKey: c.CertificateKey,
NodePools: nps,
DockerImage: c.DockerImage,
DockerTag: c.DockerTag,
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
}

View File

@@ -503,6 +503,50 @@ func ListRecordSets(db *gorm.DB) http.HandlerFunc {
}
}
// GetRecordSet godoc
//
// @ID GetRecordSet
// @Summary Get a record set (org scoped)
// @Tags DNS
// @Produce json
// @Param X-Org-ID header string false "Organization UUID"
// @Param id path string true "Record Set ID (UUID)"
// @Success 200 {object} dto.RecordSetResponse
// @Failure 403 {string} string "organization required"
// @Failure 404 {string} string "not found"
// @Router /dns/records/{id} [get]
func GetRecordSet(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
id, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_id", "invalid UUID")
return
}
var row models.RecordSet
if err := db.
Joins("Domain").
Where(`record_sets.id = ? AND "Domain"."organization_id" = ?`, id, orgID).
First(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "record set not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", err.Error())
return
}
utils.WriteJSON(w, http.StatusOK, recordOut(&row))
}
}
// CreateRecordSet godoc
//
// @ID CreateRecordSet

View File

@@ -0,0 +1,28 @@
package dto
import (
"time"
"github.com/google/uuid"
)
type ActionResponse struct {
ID uuid.UUID `json:"id" format:"uuid"`
Label string `json:"label"`
Description string `json:"description"`
MakeTarget string `json:"make_target"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
}
type CreateActionRequest struct {
Label string `json:"label"`
Description string `json:"description"`
MakeTarget string `json:"make_target"`
}
type UpdateActionRequest struct {
Label *string `json:"label,omitempty"`
Description *string `json:"description,omitempty"`
MakeTarget *string `json:"make_target,omitempty"`
}

View File

@@ -0,0 +1,19 @@
package dto
import (
"time"
"github.com/google/uuid"
)
type ClusterRunResponse struct {
ID uuid.UUID `json:"id" format:"uuid"`
OrganizationID uuid.UUID `json:"organization_id" format:"uuid"`
ClusterID uuid.UUID `json:"cluster_id" format:"uuid"`
Action string `json:"action"`
Status string `json:"status"`
Error string `json:"error"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
FinishedAt *time.Time `json:"finished_at,omitempty" format:"date-time"`
}

View File

@@ -22,6 +22,11 @@ type ClusterResponse struct {
RandomToken string `json:"random_token"`
CertificateKey string `json:"certificate_key"`
NodePools []NodePoolResponse `json:"node_pools,omitempty"`
DockerImage string `json:"docker_image"`
DockerTag string `json:"docker_tag"`
Kubeconfig *string `json:"kubeconfig,omitempty"`
OrgKey *string `json:"org_key,omitempty"`
OrgSecret *string `json:"org_secret,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
@@ -30,12 +35,16 @@ type CreateClusterRequest struct {
Name string `json:"name"`
ClusterProvider string `json:"cluster_provider"`
Region string `json:"region"`
DockerImage string `json:"docker_image"`
DockerTag string `json:"docker_tag"`
}
type UpdateClusterRequest struct {
Name *string `json:"name,omitempty"`
ClusterProvider *string `json:"cluster_provider,omitempty"`
Region *string `json:"region,omitempty"`
DockerImage *string `json:"docker_image,omitempty"`
DockerTag *string `json:"docker_tag,omitempty"`
}
type AttachCaptainDomainRequest struct {

View File

@@ -828,16 +828,16 @@ func ListNodePoolLabels(db *gorm.DB) http.HandlerFunc {
}
out := make([]dto.LabelResponse, 0, len(np.Taints))
for _, taint := range np.Taints {
for _, label := range np.Labels {
out = append(out, dto.LabelResponse{
AuditFields: common.AuditFields{
ID: taint.ID,
OrganizationID: taint.OrganizationID,
CreatedAt: taint.CreatedAt,
UpdatedAt: taint.UpdatedAt,
ID: label.ID,
OrganizationID: label.OrganizationID,
CreatedAt: label.CreatedAt,
UpdatedAt: label.UpdatedAt,
},
Key: taint.Key,
Value: taint.Value,
Key: label.Key,
Value: label.Value,
})
}
utils.WriteJSON(w, http.StatusOK, out)

View File

@@ -585,13 +585,22 @@ func CreateOrgKey(db *gorm.DB) http.HandlerFunc {
exp = &e
}
prefix := orgKey
if len(prefix) > 12 {
prefix = prefix[:12]
}
rec := models.APIKey{
OrgID: &oid,
Scope: "org",
Purpose: "user",
IsEphemeral: false,
Name: req.Name,
KeyHash: keyHash,
SecretHash: &secretHash,
ExpiresAt: exp,
Revoked: false,
Prefix: &prefix,
}
if err := db.Create(&rec).Error; err != nil {
utils.WriteError(w, 500, "db_error", err.Error())

182
internal/mapper/cluster.go Normal file
View File

@@ -0,0 +1,182 @@
package mapper
import (
"fmt"
"time"
"github.com/glueops/autoglue/internal/common"
"github.com/glueops/autoglue/internal/handlers/dto"
"github.com/glueops/autoglue/internal/models"
"github.com/google/uuid"
)
func ClusterToDTO(c models.Cluster) dto.ClusterResponse {
var bastion *dto.ServerResponse
if c.BastionServer != nil {
b := ServerToDTO(*c.BastionServer)
bastion = &b
}
var captainDomain *dto.DomainResponse
if c.CaptainDomainID != nil && c.CaptainDomain.ID != uuid.Nil {
dr := DomainToDTO(c.CaptainDomain)
captainDomain = &dr
}
var controlPlane *dto.RecordSetResponse
if c.ControlPlaneRecordSet != nil {
rr := RecordSetToDTO(*c.ControlPlaneRecordSet)
controlPlane = &rr
}
var cfqdn *string
if captainDomain != nil && controlPlane != nil {
fq := fmt.Sprintf("%s.%s", controlPlane.Name, captainDomain.DomainName)
cfqdn = &fq
}
var appsLB *dto.LoadBalancerResponse
if c.AppsLoadBalancer != nil {
lr := LoadBalancerToDTO(*c.AppsLoadBalancer)
appsLB = &lr
}
var glueOpsLB *dto.LoadBalancerResponse
if c.GlueOpsLoadBalancer != nil {
lr := LoadBalancerToDTO(*c.GlueOpsLoadBalancer)
glueOpsLB = &lr
}
nps := make([]dto.NodePoolResponse, 0, len(c.NodePools))
for _, np := range c.NodePools {
nps = append(nps, NodePoolToDTO(np))
}
return dto.ClusterResponse{
ID: c.ID,
Name: c.Name,
CaptainDomain: captainDomain,
ControlPlaneRecordSet: controlPlane,
ControlPlaneFQDN: cfqdn,
AppsLoadBalancer: appsLB,
GlueOpsLoadBalancer: glueOpsLB,
BastionServer: bastion,
Provider: c.Provider,
Region: c.Region,
Status: c.Status,
LastError: c.LastError,
RandomToken: c.RandomToken,
CertificateKey: c.CertificateKey,
NodePools: nps,
DockerImage: c.DockerImage,
DockerTag: c.DockerTag,
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
}
}
func NodePoolToDTO(np models.NodePool) dto.NodePoolResponse {
labels := make([]dto.LabelResponse, 0, len(np.Labels))
for _, l := range np.Labels {
labels = append(labels, dto.LabelResponse{
Key: l.Key,
Value: l.Value,
})
}
annotations := make([]dto.AnnotationResponse, 0, len(np.Annotations))
for _, a := range np.Annotations {
annotations = append(annotations, dto.AnnotationResponse{
Key: a.Key,
Value: a.Value,
})
}
taints := make([]dto.TaintResponse, 0, len(np.Taints))
for _, t := range np.Taints {
taints = append(taints, dto.TaintResponse{
Key: t.Key,
Value: t.Value,
Effect: t.Effect,
})
}
servers := make([]dto.ServerResponse, 0, len(np.Servers))
for _, s := range np.Servers {
servers = append(servers, ServerToDTO(s))
}
return dto.NodePoolResponse{
AuditFields: common.AuditFields{
ID: np.ID,
OrganizationID: np.OrganizationID,
CreatedAt: np.CreatedAt,
UpdatedAt: np.UpdatedAt,
},
Name: np.Name,
Role: dto.NodeRole(np.Role),
Labels: labels,
Annotations: annotations,
Taints: taints,
Servers: servers,
}
}
func ServerToDTO(s models.Server) dto.ServerResponse {
return dto.ServerResponse{
ID: s.ID,
Hostname: s.Hostname,
PrivateIPAddress: s.PrivateIPAddress,
PublicIPAddress: s.PublicIPAddress,
Role: s.Role,
Status: s.Status,
SSHUser: s.SSHUser,
SshKeyID: s.SshKeyID,
CreatedAt: s.CreatedAt.UTC().Format(time.RFC3339),
UpdatedAt: s.UpdatedAt.UTC().Format(time.RFC3339),
}
}
func DomainToDTO(d models.Domain) dto.DomainResponse {
return dto.DomainResponse{
ID: d.ID.String(),
OrganizationID: d.OrganizationID.String(),
DomainName: d.DomainName,
ZoneID: d.ZoneID,
Status: d.Status,
LastError: d.LastError,
CredentialID: d.CredentialID.String(),
CreatedAt: d.CreatedAt.UTC().Format(time.RFC3339),
UpdatedAt: d.UpdatedAt.UTC().Format(time.RFC3339),
}
}
func RecordSetToDTO(rs models.RecordSet) dto.RecordSetResponse {
return dto.RecordSetResponse{
ID: rs.ID.String(),
DomainID: rs.DomainID.String(),
Name: rs.Name,
Type: rs.Type,
TTL: rs.TTL,
Values: []byte(rs.Values),
Fingerprint: rs.Fingerprint,
Status: rs.Status,
Owner: rs.Owner,
LastError: rs.LastError,
CreatedAt: rs.CreatedAt.UTC().Format(time.RFC3339),
UpdatedAt: rs.UpdatedAt.UTC().Format(time.RFC3339),
}
}
func LoadBalancerToDTO(lb models.LoadBalancer) dto.LoadBalancerResponse {
return dto.LoadBalancerResponse{
ID: lb.ID,
OrganizationID: lb.OrganizationID,
Name: lb.Name,
Kind: lb.Kind,
PublicIPAddress: lb.PublicIPAddress,
PrivateIPAddress: lb.PrivateIPAddress,
CreatedAt: lb.CreatedAt,
UpdatedAt: lb.UpdatedAt,
}
}

16
internal/models/action.go Normal file
View File

@@ -0,0 +1,16 @@
package models
import (
"time"
"github.com/google/uuid"
)
type Action struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
Label string `gorm:"type:varchar(255);not null;uniqueIndex" json:"label"`
Description string `gorm:"type:text;not null" json:"description"`
MakeTarget string `gorm:"type:varchar(255);not null;uniqueIndex" json:"make_target"`
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()" format:"date-time"`
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()" format:"date-time"`
}

View File

@@ -8,12 +8,15 @@ import (
type APIKey struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
OrgID *uuid.UUID `json:"org_id,omitempty" format:"uuid"`
Scope string `gorm:"not null;default:''" json:"scope"`
Purpose string `json:"purpose"`
ClusterID *uuid.UUID `json:"cluster_id,omitempty"`
IsEphemeral bool `json:"is_ephemeral"`
Name string `gorm:"not null;default:''" json:"name"`
KeyHash string `gorm:"uniqueIndex;not null" json:"-"`
Scope string `gorm:"not null;default:''" json:"scope"`
UserID *uuid.UUID `json:"user_id,omitempty" format:"uuid"`
OrgID *uuid.UUID `json:"org_id,omitempty" format:"uuid"`
SecretHash *string `json:"-"`
UserID *uuid.UUID `json:"user_id,omitempty" format:"uuid"`
ExpiresAt *time.Time `json:"expires_at,omitempty" format:"date-time"`
Revoked bool `gorm:"not null;default:false" json:"revoked"`
Prefix *string `json:"prefix,omitempty"`

View File

@@ -13,6 +13,7 @@ const (
ClusterStatusProvisioning = "provisioning"
ClusterStatusReady = "ready"
ClusterStatusFailed = "failed" // provisioning/runtime failure
ClusterStatusBootstrapping = "bootstrapping"
)
type Cluster struct {
@@ -40,6 +41,8 @@ type Cluster struct {
EncryptedKubeconfig string `gorm:"type:text" json:"-"`
KubeIV string `json:"-"`
KubeTag string `json:"-"`
DockerImage string `json:"docker_image"`
DockerTag string `json:"docker_tag"`
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()"`
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()"`
}

View File

@@ -0,0 +1,27 @@
package models
import (
"time"
"github.com/google/uuid"
)
const (
ClusterRunStatusQueued = "queued"
ClusterRunStatusRunning = "running"
ClusterRunStatusSuccess = "success"
ClusterRunStatusFailed = "failed"
ClusterRunStatusCanceled = "canceled"
)
type ClusterRun struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" format:"uuid"`
OrganizationID uuid.UUID `json:"organization_id" gorm:"type:uuid;index"`
ClusterID uuid.UUID `json:"cluster_id" gorm:"type:uuid;index"`
Action string `json:"action" gorm:"type:text;not null"`
Status string `json:"status" gorm:"type:text;not null"`
Error string `json:"error" gorm:"type:text;not null"`
CreatedAt time.Time `json:"created_at,omitempty" gorm:"type:timestamptz;column:created_at;not null;default:now()" format:"date-time"`
UpdatedAt time.Time `json:"updated_at,omitempty" gorm:"type:timestamptz;autoUpdateTime;column:updated_at;not null;default:now()" format:"date-time"`
FinishedAt time.Time `json:"finished_at,omitempty" gorm:"type:timestamptz" format:"date-time"`
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

4186
internal/web/dist/assets/index-GteqH5KT.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,9 +5,9 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AutoGlue</title>
<script type="module" crossorigin src="/assets/index-BwyDjDcq.js"></script>
<link rel="modulepreload" crossorigin href="/assets/react-Dt2M6tWj.js">
<link rel="stylesheet" crossorigin href="/assets/index-VHZG0dIU.css">
<script type="module" crossorigin src="/assets/index-GteqH5KT.js"></script>
<link rel="modulepreload" crossorigin href="/assets/react-v1TLhXpT.js">
<link rel="stylesheet" crossorigin href="/assets/index-Cdjh6IZW.css">
</head>
<body>
<div id="root"></div>

Binary file not shown.

Binary file not shown.

View File

@@ -1,2 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88"
height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,4 +1,4 @@
FROM postgres:17.7@sha256:44640f16641cf36716cabd011e2f7eb4742b6b6b19f4488ddcbb7c250e5c9753
FROM postgres:17.7@sha256:2006493727bd5277eece187319af1ef82b4cf82cf4fc1ed00da0775b646ac2a4
RUN cd /var/lib/postgresql/ && \
openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req -keyout privkey.pem && \

View File

@@ -12,6 +12,8 @@
| `control_plane_fqdn` | string |
| `control_plane_record_set` | [DtoRecordSetResponse](DtoRecordSetResponse.md) |
| `created_at` | string |
| `docker_image` | string |
| `docker_tag` | string |
| `glueops_load_balancer` | [DtoLoadBalancerResponse](DtoLoadBalancerResponse.md) |
| `id` | string |
| `last_error` | string |
@@ -37,6 +39,8 @@ const example = {
control_plane_fqdn: null,
control_plane_record_set: null,
created_at: null,
docker_image: null,
docker_tag: null,
glueops_load_balancer: null,
id: null,
last_error: null,

View File

@@ -5,6 +5,8 @@
| Name | Type |
| ------------------ | ------ |
| `cluster_provider` | string |
| `docker_image` | string |
| `docker_tag` | string |
| `name` | string |
| `region` | string |
@@ -16,6 +18,8 @@ import type { DtoCreateClusterRequest } from "@glueops/autoglue-sdk-go";
// TODO: Update the object below with actual values
const example = {
cluster_provider: null,
docker_image: null,
docker_tag: null,
name: null,
region: null,
} satisfies DtoCreateClusterRequest;

View File

@@ -5,6 +5,8 @@
| Name | Type |
| ------------------ | ------ |
| `cluster_provider` | string |
| `docker_image` | string |
| `docker_tag` | string |
| `name` | string |
| `region` | string |
@@ -16,6 +18,8 @@ import type { DtoUpdateClusterRequest } from "@glueops/autoglue-sdk-go";
// TODO: Update the object below with actual values
const example = {
cluster_provider: null,
docker_image: null,
docker_tag: null,
name: null,
region: null,
} satisfies DtoUpdateClusterRequest;

View File

@@ -13,10 +13,17 @@
*/
import * as runtime from "../runtime";
import type {DtoAnnotationResponse, DtoCreateAnnotationRequest, DtoUpdateAnnotationRequest,} from "../models/index";
import type {
DtoAnnotationResponse,
DtoCreateAnnotationRequest,
DtoUpdateAnnotationRequest,
} from "../models/index";
import {
DtoAnnotationResponseFromJSON,
DtoAnnotationResponseToJSON,
DtoCreateAnnotationRequestFromJSON,
DtoCreateAnnotationRequestToJSON,
DtoUpdateAnnotationRequestFromJSON,
DtoUpdateAnnotationRequestToJSON,
} from "../models/index";

View File

@@ -13,8 +13,22 @@
*/
import * as runtime from "../runtime";
import type {DtoEnqueueRequest, DtoJob, DtoPageJob, DtoQueueInfo,} from "../models/index";
import {DtoEnqueueRequestToJSON, DtoJobFromJSON, DtoPageJobFromJSON, DtoQueueInfoFromJSON,} from "../models/index";
import type {
DtoEnqueueRequest,
DtoJob,
DtoPageJob,
DtoQueueInfo,
} from "../models/index";
import {
DtoEnqueueRequestFromJSON,
DtoEnqueueRequestToJSON,
DtoJobFromJSON,
DtoJobToJSON,
DtoPageJobFromJSON,
DtoPageJobToJSON,
DtoQueueInfoFromJSON,
DtoQueueInfoToJSON,
} from "../models/index";
export interface AdminCancelArcherJobRequest {
id: string;

View File

@@ -13,13 +13,24 @@
*/
import * as runtime from "../runtime";
import type {DtoAuthStartResponse, DtoJWKS, DtoLogoutRequest, DtoRefreshRequest, DtoTokenPair,} from "../models/index";
import type {
DtoAuthStartResponse,
DtoJWKS,
DtoLogoutRequest,
DtoRefreshRequest,
DtoTokenPair,
} from "../models/index";
import {
DtoAuthStartResponseFromJSON,
DtoAuthStartResponseToJSON,
DtoJWKSFromJSON,
DtoJWKSToJSON,
DtoLogoutRequestFromJSON,
DtoLogoutRequestToJSON,
DtoRefreshRequestFromJSON,
DtoRefreshRequestToJSON,
DtoTokenPairFromJSON,
DtoTokenPairToJSON,
} from "../models/index";
export interface AuthCallbackRequest {

View File

@@ -25,14 +25,23 @@ import type {
DtoUpdateClusterRequest,
} from "../models/index";
import {
DtoAttachBastionRequestFromJSON,
DtoAttachBastionRequestToJSON,
DtoAttachCaptainDomainRequestFromJSON,
DtoAttachCaptainDomainRequestToJSON,
DtoAttachLoadBalancerRequestFromJSON,
DtoAttachLoadBalancerRequestToJSON,
DtoAttachNodePoolRequestFromJSON,
DtoAttachNodePoolRequestToJSON,
DtoAttachRecordSetRequestFromJSON,
DtoAttachRecordSetRequestToJSON,
DtoClusterResponseFromJSON,
DtoClusterResponseToJSON,
DtoCreateClusterRequestFromJSON,
DtoCreateClusterRequestToJSON,
DtoSetKubeconfigRequestFromJSON,
DtoSetKubeconfigRequestToJSON,
DtoUpdateClusterRequestFromJSON,
DtoUpdateClusterRequestToJSON,
} from "../models/index";

View File

@@ -13,10 +13,17 @@
*/
import * as runtime from "../runtime";
import type {DtoCreateCredentialRequest, DtoCredentialOut, DtoUpdateCredentialRequest,} from "../models/index";
import type {
DtoCreateCredentialRequest,
DtoCredentialOut,
DtoUpdateCredentialRequest,
} from "../models/index";
import {
DtoCreateCredentialRequestFromJSON,
DtoCreateCredentialRequestToJSON,
DtoCredentialOutFromJSON,
DtoCredentialOutToJSON,
DtoUpdateCredentialRequestFromJSON,
DtoUpdateCredentialRequestToJSON,
} from "../models/index";

View File

@@ -22,11 +22,17 @@ import type {
DtoUpdateRecordSetRequest,
} from "../models/index";
import {
DtoCreateDomainRequestFromJSON,
DtoCreateDomainRequestToJSON,
DtoCreateRecordSetRequestFromJSON,
DtoCreateRecordSetRequestToJSON,
DtoDomainResponseFromJSON,
DtoDomainResponseToJSON,
DtoRecordSetResponseFromJSON,
DtoRecordSetResponseToJSON,
DtoUpdateDomainRequestFromJSON,
DtoUpdateDomainRequestToJSON,
DtoUpdateRecordSetRequestFromJSON,
DtoUpdateRecordSetRequestToJSON,
} from "../models/index";

View File

@@ -13,8 +13,11 @@
*/
import * as runtime from "../runtime";
import type {HandlersHealthStatus} from "../models/index";
import {HandlersHealthStatusFromJSON,} from "../models/index";
import type { HandlersHealthStatus } from "../models/index";
import {
HandlersHealthStatusFromJSON,
HandlersHealthStatusToJSON,
} from "../models/index";
/**
*

View File

@@ -13,8 +13,19 @@
*/
import * as runtime from "../runtime";
import type {DtoCreateLabelRequest, DtoLabelResponse, DtoUpdateLabelRequest,} from "../models/index";
import {DtoCreateLabelRequestToJSON, DtoLabelResponseFromJSON, DtoUpdateLabelRequestToJSON,} from "../models/index";
import type {
DtoCreateLabelRequest,
DtoLabelResponse,
DtoUpdateLabelRequest,
} from "../models/index";
import {
DtoCreateLabelRequestFromJSON,
DtoCreateLabelRequestToJSON,
DtoLabelResponseFromJSON,
DtoLabelResponseToJSON,
DtoUpdateLabelRequestFromJSON,
DtoUpdateLabelRequestToJSON,
} from "../models/index";
export interface CreateLabelRequest {
dtoCreateLabelRequest: DtoCreateLabelRequest;

View File

@@ -19,8 +19,11 @@ import type {
DtoUpdateLoadBalancerRequest,
} from "../models/index";
import {
DtoCreateLoadBalancerRequestFromJSON,
DtoCreateLoadBalancerRequestToJSON,
DtoLoadBalancerResponseFromJSON,
DtoLoadBalancerResponseToJSON,
DtoUpdateLoadBalancerRequestFromJSON,
DtoUpdateLoadBalancerRequestToJSON,
} from "../models/index";

View File

@@ -13,8 +13,16 @@
*/
import * as runtime from "../runtime";
import type {HandlersCreateUserKeyRequest, HandlersUserAPIKeyOut,} from "../models/index";
import {HandlersCreateUserKeyRequestToJSON, HandlersUserAPIKeyOutFromJSON,} from "../models/index";
import type {
HandlersCreateUserKeyRequest,
HandlersUserAPIKeyOut,
} from "../models/index";
import {
HandlersCreateUserKeyRequestFromJSON,
HandlersCreateUserKeyRequestToJSON,
HandlersUserAPIKeyOutFromJSON,
HandlersUserAPIKeyOutToJSON,
} from "../models/index";
export interface CreateUserAPIKeyRequest {
handlersCreateUserKeyRequest: HandlersCreateUserKeyRequest;

View File

@@ -13,8 +13,19 @@
*/
import * as runtime from "../runtime";
import type {HandlersMeResponse, HandlersUpdateMeRequest, ModelsUser,} from "../models/index";
import {HandlersMeResponseFromJSON, HandlersUpdateMeRequestToJSON, ModelsUserFromJSON,} from "../models/index";
import type {
HandlersMeResponse,
HandlersUpdateMeRequest,
ModelsUser,
} from "../models/index";
import {
HandlersMeResponseFromJSON,
HandlersMeResponseToJSON,
HandlersUpdateMeRequestFromJSON,
HandlersUpdateMeRequestToJSON,
ModelsUserFromJSON,
ModelsUserToJSON,
} from "../models/index";
export interface UpdateMeRequest {
handlersUpdateMeRequest: HandlersUpdateMeRequest;

View File

@@ -13,8 +13,11 @@
*/
import * as runtime from "../runtime";
import type {HandlersVersionResponse} from "../models/index";
import {HandlersVersionResponseFromJSON,} from "../models/index";
import type { HandlersVersionResponse } from "../models/index";
import {
HandlersVersionResponseFromJSON,
HandlersVersionResponseToJSON,
} from "../models/index";
/**
*

View File

@@ -28,15 +28,26 @@ import type {
} from "../models/index";
import {
DtoAnnotationResponseFromJSON,
DtoAnnotationResponseToJSON,
DtoAttachAnnotationsRequestFromJSON,
DtoAttachAnnotationsRequestToJSON,
DtoAttachLabelsRequestFromJSON,
DtoAttachLabelsRequestToJSON,
DtoAttachServersRequestFromJSON,
DtoAttachServersRequestToJSON,
DtoAttachTaintsRequestFromJSON,
DtoAttachTaintsRequestToJSON,
DtoCreateNodePoolRequestFromJSON,
DtoCreateNodePoolRequestToJSON,
DtoLabelResponseFromJSON,
DtoLabelResponseToJSON,
DtoNodePoolResponseFromJSON,
DtoNodePoolResponseToJSON,
DtoServerResponseFromJSON,
DtoServerResponseToJSON,
DtoTaintResponseFromJSON,
DtoTaintResponseToJSON,
DtoUpdateNodePoolRequestFromJSON,
DtoUpdateNodePoolRequestToJSON,
} from "../models/index";

View File

@@ -22,16 +22,27 @@ import type {
HandlersOrgUpdateReq,
ModelsAPIKey,
ModelsOrganization,
UtilsErrorResponse,
} from "../models/index";
import {
HandlersMemberOutFromJSON,
HandlersMemberOutToJSON,
HandlersMemberUpsertReqFromJSON,
HandlersMemberUpsertReqToJSON,
HandlersOrgCreateReqFromJSON,
HandlersOrgCreateReqToJSON,
HandlersOrgKeyCreateReqFromJSON,
HandlersOrgKeyCreateReqToJSON,
HandlersOrgKeyCreateRespFromJSON,
HandlersOrgKeyCreateRespToJSON,
HandlersOrgUpdateReqFromJSON,
HandlersOrgUpdateReqToJSON,
ModelsAPIKeyFromJSON,
ModelsAPIKeyToJSON,
ModelsOrganizationFromJSON,
ModelsOrganizationToJSON,
UtilsErrorResponseFromJSON,
UtilsErrorResponseToJSON,
} from "../models/index";
export interface AddOrUpdateMemberRequest {

View File

@@ -13,8 +13,19 @@
*/
import * as runtime from "../runtime";
import type {DtoCreateServerRequest, DtoServerResponse, DtoUpdateServerRequest,} from "../models/index";
import {DtoCreateServerRequestToJSON, DtoServerResponseFromJSON, DtoUpdateServerRequestToJSON,} from "../models/index";
import type {
DtoCreateServerRequest,
DtoServerResponse,
DtoUpdateServerRequest,
} from "../models/index";
import {
DtoCreateServerRequestFromJSON,
DtoCreateServerRequestToJSON,
DtoServerResponseFromJSON,
DtoServerResponseToJSON,
DtoUpdateServerRequestFromJSON,
DtoUpdateServerRequestToJSON,
} from "../models/index";
export interface CreateServerRequest {
dtoCreateServerRequest: DtoCreateServerRequest;

View File

@@ -13,8 +13,19 @@
*/
import * as runtime from "../runtime";
import type {DtoCreateSSHRequest, DtoSshResponse, GetSSHKey200Response,} from "../models/index";
import {DtoCreateSSHRequestToJSON, DtoSshResponseFromJSON, GetSSHKey200ResponseFromJSON,} from "../models/index";
import type {
DtoCreateSSHRequest,
DtoSshResponse,
GetSSHKey200Response,
} from "../models/index";
import {
DtoCreateSSHRequestFromJSON,
DtoCreateSSHRequestToJSON,
DtoSshResponseFromJSON,
DtoSshResponseToJSON,
GetSSHKey200ResponseFromJSON,
GetSSHKey200ResponseToJSON,
} from "../models/index";
export interface CreateSSHKeyRequest {
dtoCreateSSHRequest: DtoCreateSSHRequest;

View File

@@ -13,8 +13,19 @@
*/
import * as runtime from "../runtime";
import type {DtoCreateTaintRequest, DtoTaintResponse, DtoUpdateTaintRequest,} from "../models/index";
import {DtoCreateTaintRequestToJSON, DtoTaintResponseFromJSON, DtoUpdateTaintRequestToJSON,} from "../models/index";
import type {
DtoCreateTaintRequest,
DtoTaintResponse,
DtoUpdateTaintRequest,
} from "../models/index";
import {
DtoCreateTaintRequestFromJSON,
DtoCreateTaintRequestToJSON,
DtoTaintResponseFromJSON,
DtoTaintResponseToJSON,
DtoUpdateTaintRequestFromJSON,
DtoUpdateTaintRequestToJSON,
} from "../models/index";
export interface CreateTaintRequest {
dtoCreateTaintRequest: DtoCreateTaintRequest;

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,16 +12,42 @@
* Do not edit the class manually.
*/
import type {DtoDomainResponse} from "./DtoDomainResponse";
import {DtoDomainResponseFromJSON, DtoDomainResponseToJSON,} from "./DtoDomainResponse";
import type {DtoLoadBalancerResponse} from "./DtoLoadBalancerResponse";
import {DtoLoadBalancerResponseFromJSON, DtoLoadBalancerResponseToJSON,} from "./DtoLoadBalancerResponse";
import type {DtoNodePoolResponse} from "./DtoNodePoolResponse";
import {DtoNodePoolResponseFromJSON, DtoNodePoolResponseToJSON,} from "./DtoNodePoolResponse";
import type {DtoServerResponse} from "./DtoServerResponse";
import {DtoServerResponseFromJSON, DtoServerResponseToJSON,} from "./DtoServerResponse";
import type {DtoRecordSetResponse} from "./DtoRecordSetResponse";
import {DtoRecordSetResponseFromJSON, DtoRecordSetResponseToJSON,} from "./DtoRecordSetResponse";
import { mapValues } from "../runtime";
import type { DtoDomainResponse } from "./DtoDomainResponse";
import {
DtoDomainResponseFromJSON,
DtoDomainResponseFromJSONTyped,
DtoDomainResponseToJSON,
DtoDomainResponseToJSONTyped,
} from "./DtoDomainResponse";
import type { DtoLoadBalancerResponse } from "./DtoLoadBalancerResponse";
import {
DtoLoadBalancerResponseFromJSON,
DtoLoadBalancerResponseFromJSONTyped,
DtoLoadBalancerResponseToJSON,
DtoLoadBalancerResponseToJSONTyped,
} from "./DtoLoadBalancerResponse";
import type { DtoNodePoolResponse } from "./DtoNodePoolResponse";
import {
DtoNodePoolResponseFromJSON,
DtoNodePoolResponseFromJSONTyped,
DtoNodePoolResponseToJSON,
DtoNodePoolResponseToJSONTyped,
} from "./DtoNodePoolResponse";
import type { DtoServerResponse } from "./DtoServerResponse";
import {
DtoServerResponseFromJSON,
DtoServerResponseFromJSONTyped,
DtoServerResponseToJSON,
DtoServerResponseToJSONTyped,
} from "./DtoServerResponse";
import type { DtoRecordSetResponse } from "./DtoRecordSetResponse";
import {
DtoRecordSetResponseFromJSON,
DtoRecordSetResponseFromJSONTyped,
DtoRecordSetResponseToJSON,
DtoRecordSetResponseToJSONTyped,
} from "./DtoRecordSetResponse";
/**
*
@@ -77,6 +103,18 @@ export interface DtoClusterResponse {
* @memberof DtoClusterResponse
*/
created_at?: string;
/**
*
* @type {string}
* @memberof DtoClusterResponse
*/
docker_image?: string;
/**
*
* @type {string}
* @memberof DtoClusterResponse
*/
docker_tag?: string;
/**
*
* @type {DtoLoadBalancerResponse}
@@ -179,6 +217,9 @@ export function DtoClusterResponseFromJSONTyped(
? undefined
: DtoRecordSetResponseFromJSON(json["control_plane_record_set"]),
created_at: json["created_at"] == null ? undefined : json["created_at"],
docker_image:
json["docker_image"] == null ? undefined : json["docker_image"],
docker_tag: json["docker_tag"] == null ? undefined : json["docker_tag"],
glueops_load_balancer:
json["glueops_load_balancer"] == null
? undefined
@@ -223,6 +264,8 @@ export function DtoClusterResponseToJSONTyped(
value["control_plane_record_set"],
),
created_at: value["created_at"],
docker_image: value["docker_image"],
docker_tag: value["docker_tag"],
glueops_load_balancer: DtoLoadBalancerResponseToJSON(
value["glueops_load_balancer"],
),

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export
@@ -24,6 +25,18 @@ export interface DtoCreateClusterRequest {
* @memberof DtoCreateClusterRequest
*/
cluster_provider?: string;
/**
*
* @type {string}
* @memberof DtoCreateClusterRequest
*/
docker_image?: string;
/**
*
* @type {string}
* @memberof DtoCreateClusterRequest
*/
docker_tag?: string;
/**
*
* @type {string}
@@ -63,6 +76,9 @@ export function DtoCreateClusterRequestFromJSONTyped(
return {
cluster_provider:
json["cluster_provider"] == null ? undefined : json["cluster_provider"],
docker_image:
json["docker_image"] == null ? undefined : json["docker_image"],
docker_tag: json["docker_tag"] == null ? undefined : json["docker_tag"],
name: json["name"] == null ? undefined : json["name"],
region: json["region"] == null ? undefined : json["region"],
};
@@ -84,6 +100,8 @@ export function DtoCreateClusterRequestToJSONTyped(
return {
cluster_provider: value["cluster_provider"],
docker_image: value["docker_image"],
docker_tag: value["docker_tag"],
name: value["name"],
region: value["region"],
};

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

View File

@@ -12,6 +12,7 @@
* Do not edit the class manually.
*/
import { mapValues } from "../runtime";
/**
*
* @export

Some files were not shown because too many files have changed in this diff Show More