@highstate/library 0.9.16 → 0.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/highstate.library.msgpack +0 -0
  2. package/dist/index.js +3548 -2985
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -5
  5. package/src/common/access-point.ts +105 -0
  6. package/src/common/files.ts +137 -0
  7. package/src/common/index.ts +3 -0
  8. package/src/common/server.ts +231 -0
  9. package/src/databases/index.ts +4 -0
  10. package/src/databases/mariadb.ts +37 -0
  11. package/src/databases/mongodb.ts +37 -0
  12. package/src/databases/postgresql.ts +37 -0
  13. package/src/databases/shared.ts +61 -0
  14. package/src/distributions/ubuntu.ts +13 -11
  15. package/src/dns.ts +116 -18
  16. package/src/git.ts +14 -10
  17. package/src/impl-ref.ts +26 -0
  18. package/src/index.ts +14 -15
  19. package/src/k3s.ts +14 -12
  20. package/src/k8s/apps/code-server.ts +48 -0
  21. package/src/k8s/apps/gitea.ts +25 -0
  22. package/src/k8s/apps/grocy.ts +39 -0
  23. package/src/k8s/apps/hubble.ts +30 -0
  24. package/src/{apps → k8s/apps}/index.ts +16 -13
  25. package/src/k8s/apps/kubernetes-dashboard.ts +28 -0
  26. package/src/k8s/apps/mariadb.ts +83 -0
  27. package/src/k8s/apps/maybe.ts +39 -0
  28. package/src/k8s/apps/mongodb.ts +84 -0
  29. package/src/k8s/apps/postgresql.ts +86 -0
  30. package/src/k8s/apps/shared.ts +149 -0
  31. package/src/k8s/apps/syncthing.ts +72 -0
  32. package/src/k8s/apps/traefik.ts +40 -0
  33. package/src/k8s/apps/vaultwarden.ts +31 -0
  34. package/src/k8s/apps/workload.ts +214 -0
  35. package/src/k8s/apps/zitadel.ts +26 -0
  36. package/src/k8s/cert-manager.ts +80 -0
  37. package/src/k8s/cilium.ts +64 -0
  38. package/src/k8s/gateway.ts +70 -0
  39. package/src/k8s/index.ts +9 -0
  40. package/src/{obfuscators → k8s/obfuscators}/phantun.ts +14 -10
  41. package/src/{obfuscators → k8s/obfuscators}/shared.ts +17 -11
  42. package/src/k8s/resources.ts +111 -0
  43. package/src/k8s/service.ts +65 -0
  44. package/src/k8s/shared.ts +343 -0
  45. package/src/k8s/workload.ts +77 -0
  46. package/src/network.ts +249 -63
  47. package/src/nixos.ts +38 -77
  48. package/src/proxmox.ts +203 -96
  49. package/src/restic.ts +28 -19
  50. package/src/sops.ts +19 -8
  51. package/src/ssh.ts +122 -24
  52. package/src/talos.ts +21 -19
  53. package/src/third-party/cloudflare.ts +59 -0
  54. package/src/third-party/index.ts +3 -0
  55. package/src/{mullvad.ts → third-party/mullvad.ts} +11 -9
  56. package/src/third-party/timeweb.ts +99 -0
  57. package/src/utils.ts +27 -6
  58. package/src/wireguard.ts +249 -115
  59. package/src/apps/code-server.ts +0 -34
  60. package/src/apps/deployment.ts +0 -60
  61. package/src/apps/dns.ts +0 -107
  62. package/src/apps/gitea.ts +0 -18
  63. package/src/apps/grocy.ts +0 -20
  64. package/src/apps/hubble.ts +0 -20
  65. package/src/apps/kubernetes-dashboard.ts +0 -19
  66. package/src/apps/mariadb.ts +0 -81
  67. package/src/apps/maybe.ts +0 -25
  68. package/src/apps/mongodb.ts +0 -81
  69. package/src/apps/network.ts +0 -55
  70. package/src/apps/postgresql.ts +0 -81
  71. package/src/apps/shared.ts +0 -290
  72. package/src/apps/syncthing.ts +0 -54
  73. package/src/apps/test.ts +0 -19
  74. package/src/apps/traefik.ts +0 -36
  75. package/src/apps/vaultwarden.ts +0 -23
  76. package/src/apps/zitadel.ts +0 -21
  77. package/src/cloudflare.ts +0 -26
  78. package/src/common.ts +0 -200
  79. package/src/files.ts +0 -146
  80. package/src/k8s.ts +0 -638
  81. package/src/timeweb.ts +0 -75
  82. package/src/{obfuscators → k8s/obfuscators}/index.ts +1 -1
@@ -0,0 +1,83 @@
1
+ import { defineUnit } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import * as databases from "../../databases"
4
+ import { l4EndpointEntity } from "../../network"
5
+ import { serviceEntity } from "../service"
6
+ import {
7
+ appName,
8
+ optionalSharedInputs,
9
+ sharedArgs,
10
+ sharedDatabaseArgs,
11
+ sharedDatabaseSecrets,
12
+ sharedInputs,
13
+ sharedSecrets,
14
+ source,
15
+ } from "./shared"
16
+
17
+ /**
18
+ * The MariaDB database deployed on Kubernetes.
19
+ */
20
+ export const mariadb = defineUnit({
21
+ type: "k8s.apps.mariadb.v1",
22
+ args: {
23
+ ...appName("mariadb"),
24
+ ...pick(sharedArgs, ["external"]),
25
+ },
26
+
27
+ secrets: {
28
+ ...pick(sharedSecrets, ["rootPassword", "backupPassword"]),
29
+ },
30
+
31
+ inputs: {
32
+ ...pick(sharedInputs, ["k8sCluster"]),
33
+ ...pick(optionalSharedInputs, ["resticRepo"]),
34
+ },
35
+
36
+ outputs: {
37
+ mariadb: databases.mariadbEntity,
38
+ service: serviceEntity,
39
+ endpoints: {
40
+ entity: l4EndpointEntity,
41
+ multiple: true,
42
+ },
43
+ },
44
+
45
+ meta: {
46
+ title: "MariaDB",
47
+ icon: "simple-icons:mariadb",
48
+ secondaryIcon: "mdi:database",
49
+ category: "Databases",
50
+ },
51
+
52
+ source: source("mariadb/app"),
53
+ })
54
+
55
+ /**
56
+ * The virtual MariaDB database created on the MariaDB instance.
57
+ *
58
+ * Requires a Kubernetes cluster to place init jobs and secrets.
59
+ */
60
+ export const mariadbDatabase = defineUnit({
61
+ type: "k8s.apps.mariadb.database.v1",
62
+
63
+ args: sharedDatabaseArgs,
64
+ secrets: sharedDatabaseSecrets,
65
+
66
+ inputs: {
67
+ ...pick(sharedInputs, ["k8sCluster", "mariadb"]),
68
+ ...pick(optionalSharedInputs, ["namespace"]),
69
+ },
70
+
71
+ outputs: {
72
+ mariadb: databases.mariadbEntity,
73
+ },
74
+
75
+ meta: {
76
+ title: "MariaDB Database",
77
+ icon: "simple-icons:mariadb",
78
+ secondaryIcon: "mdi:database-plus",
79
+ category: "Databases",
80
+ },
81
+
82
+ source: source("mariadb/database"),
83
+ })
@@ -0,0 +1,39 @@
1
+ import { defineUnit, z } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import {
4
+ appName,
5
+ optionalSharedInputs,
6
+ sharedArgs,
7
+ sharedInputs,
8
+ sharedSecrets,
9
+ source,
10
+ } from "./shared"
11
+
12
+ export const maybe = defineUnit({
13
+ type: "k8s.apps.maybe.v1",
14
+
15
+ args: {
16
+ ...appName("maybe"),
17
+ ...pick(sharedArgs, ["fqdn"]),
18
+ },
19
+
20
+ secrets: {
21
+ ...pick(sharedSecrets, ["backupPassword"]),
22
+ postgresqlPassword: z.string().optional(),
23
+ secretKey: z.string().optional(),
24
+ },
25
+
26
+ inputs: {
27
+ ...pick(sharedInputs, ["k8sCluster", "accessPoint", "postgresql"]),
28
+ ...pick(optionalSharedInputs, ["resticRepo"]),
29
+ },
30
+
31
+ meta: {
32
+ title: "Maybe",
33
+ description: "The OS for your personal finances.",
34
+ icon: "arcticons:finance-manager",
35
+ category: "Finance",
36
+ },
37
+
38
+ source: source("maybe"),
39
+ })
@@ -0,0 +1,84 @@
1
+ import { defineUnit } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import * as databases from "../../databases"
4
+ import { l4EndpointEntity } from "../../network"
5
+ import { serviceEntity } from "../service"
6
+ import {
7
+ appName,
8
+ optionalSharedInputs,
9
+ sharedArgs,
10
+ sharedDatabaseArgs,
11
+ sharedDatabaseSecrets,
12
+ sharedInputs,
13
+ sharedSecrets,
14
+ source,
15
+ } from "./shared"
16
+
17
+ /**
18
+ * The MongoDB instance deployed on Kubernetes.
19
+ */
20
+ export const mongodb = defineUnit({
21
+ type: "k8s.apps.mongodb.v1",
22
+
23
+ args: {
24
+ ...appName("mongodb"),
25
+ ...pick(sharedArgs, ["external"]),
26
+ },
27
+
28
+ secrets: {
29
+ ...pick(sharedSecrets, ["rootPassword", "backupPassword"]),
30
+ },
31
+
32
+ inputs: {
33
+ ...pick(sharedInputs, ["k8sCluster"]),
34
+ ...pick(optionalSharedInputs, ["resticRepo"]),
35
+ },
36
+
37
+ outputs: {
38
+ mongodb: databases.mongodbEntity,
39
+ service: serviceEntity,
40
+ endpoints: {
41
+ entity: l4EndpointEntity,
42
+ multiple: true,
43
+ },
44
+ },
45
+
46
+ meta: {
47
+ title: "MongoDB",
48
+ icon: "simple-icons:mongodb",
49
+ secondaryIcon: "mdi:database",
50
+ category: "Databases",
51
+ },
52
+
53
+ source: source("mongodb/app"),
54
+ })
55
+
56
+ /**
57
+ * The virtual MongoDB database created on the MongoDB instance.
58
+ *
59
+ * Requires a Kubernetes cluster to place init jobs and secrets.
60
+ */
61
+ export const mongodbDatabase = defineUnit({
62
+ type: "k8s.apps.mongodb.database.v1",
63
+
64
+ args: sharedDatabaseArgs,
65
+ secrets: sharedDatabaseSecrets,
66
+
67
+ inputs: {
68
+ ...pick(sharedInputs, ["k8sCluster", "mongodb"]),
69
+ ...pick(optionalSharedInputs, ["namespace"]),
70
+ },
71
+
72
+ outputs: {
73
+ mongodb: databases.mongodbEntity,
74
+ },
75
+
76
+ meta: {
77
+ title: "MongoDB Database",
78
+ icon: "simple-icons:mongodb",
79
+ secondaryIcon: "mdi:database-plus",
80
+ category: "Databases",
81
+ },
82
+
83
+ source: source("mongodb/database"),
84
+ })
@@ -0,0 +1,86 @@
1
+ import { defineUnit } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import * as databases from "../../databases"
4
+ import { l4EndpointEntity } from "../../network"
5
+ import { serviceEntity } from "../service"
6
+ import {
7
+ appName,
8
+ optionalSharedInputs,
9
+ sharedArgs,
10
+ sharedDatabaseArgs,
11
+ sharedDatabaseSecrets,
12
+ sharedInputs,
13
+ sharedSecrets,
14
+ source,
15
+ } from "./shared"
16
+
17
+ /**
18
+ * The PostgreSQL instance deployed on Kubernetes.
19
+ */
20
+ export const postgresql = defineUnit({
21
+ type: "k8s.apps.postgresql.v1",
22
+
23
+ args: {
24
+ ...appName("postgresql"),
25
+ ...pick(sharedArgs, ["external"]),
26
+ },
27
+
28
+ secrets: {
29
+ ...pick(sharedSecrets, ["rootPassword", "backupPassword"]),
30
+ },
31
+
32
+ inputs: {
33
+ ...pick(sharedInputs, ["k8sCluster"]),
34
+ ...pick(optionalSharedInputs, ["resticRepo"]),
35
+ },
36
+
37
+ outputs: {
38
+ postgresql: databases.postgresqlEntity,
39
+ service: serviceEntity,
40
+ endpoints: {
41
+ entity: l4EndpointEntity,
42
+ multiple: true,
43
+ },
44
+ },
45
+
46
+ meta: {
47
+ title: "PostgreSQL",
48
+ icon: "simple-icons:postgresql",
49
+ secondaryIcon: "mdi:database",
50
+ category: "Databases",
51
+ },
52
+
53
+ source: source("postgresql/app"),
54
+ })
55
+
56
+ /**
57
+ * The virtual PostgreSQL database created on the PostgreSQL instance.
58
+ *
59
+ * The provided database must be authorized to create databases and users.
60
+ *
61
+ * Requires a Kubernetes cluster to place init jobs and secrets.
62
+ */
63
+ export const postgresqlDatabase = defineUnit({
64
+ type: "k8s.apps.postgresql.database.v1",
65
+
66
+ args: sharedDatabaseArgs,
67
+ secrets: sharedDatabaseSecrets,
68
+
69
+ inputs: {
70
+ ...pick(sharedInputs, ["k8sCluster", "postgresql"]),
71
+ ...pick(optionalSharedInputs, ["namespace"]),
72
+ },
73
+
74
+ outputs: {
75
+ postgresql: databases.postgresqlEntity,
76
+ },
77
+
78
+ meta: {
79
+ title: "PostgreSQL Database",
80
+ icon: "simple-icons:postgresql",
81
+ secondaryIcon: "mdi:database-plus",
82
+ category: "Databases",
83
+ },
84
+
85
+ source: source("postgresql/database"),
86
+ })
@@ -0,0 +1,149 @@
1
+ /** biome-ignore-all lint/style/noNonNullAssertion: to define shared inputs */
2
+
3
+ import type { Simplify } from "type-fest"
4
+ import {
5
+ $args,
6
+ $inputs,
7
+ $secrets,
8
+ type FullComponentArgumentOptions,
9
+ type FullComponentInputOptions,
10
+ z,
11
+ } from "@highstate/contract"
12
+ import { mapValues } from "remeda"
13
+ import { accessPointEntity } from "../../common"
14
+ import { mariadbEntity, mongodbEntity, postgresqlEntity } from "../../databases"
15
+ import { providerEntity } from "../../dns"
16
+ import { repositoryEntity } from "../../restic"
17
+ import { namespaceEntity, persistentVolumeClaimEntity } from "../resources"
18
+ import { clusterEntity } from "../shared"
19
+
20
+ export const sharedArgs = $args({
21
+ /**
22
+ * The FQDN where the application will be accessible.
23
+ */
24
+ fqdn: z.string(),
25
+
26
+ /**
27
+ * The endpoints where the application will or should be accessible.
28
+ */
29
+ endpoints: z.string().array(),
30
+
31
+ /**
32
+ * Whether the application should be exposed externally by NodePort or LoadBalancer service.
33
+ */
34
+ external: z.boolean().default(false),
35
+
36
+ /**
37
+ * The number of replicas for the application.
38
+ */
39
+ replicas: z.number().default(1),
40
+ })
41
+
42
+ type ToOptionalArgs<T extends Record<string, FullComponentArgumentOptions>> = Simplify<{
43
+ [K in keyof T]: Simplify<Omit<T[K], "schema"> & { schema: z.ZodOptional<T[K]["schema"]> }>
44
+ }>
45
+
46
+ export const optionalSharedArgs = mapValues(sharedArgs, arg => ({
47
+ ...arg,
48
+ schema: arg.schema.optional(),
49
+ })) as ToOptionalArgs<typeof sharedArgs>
50
+
51
+ /**
52
+ * Return the arguments definition for the application name.
53
+ *
54
+ * @param defaultAppName The default name of the application.
55
+ */
56
+ export function appName(defaultAppName: string) {
57
+ return {
58
+ appName: {
59
+ schema: z.string().default(defaultAppName),
60
+ meta: {
61
+ description: "The name of the application to deploy.",
62
+ },
63
+ },
64
+ }
65
+ }
66
+
67
+ export const sharedSecrets = $secrets({
68
+ /**
69
+ * The root password for the database instance. If not provided, a random password will be generated.
70
+ */
71
+ rootPassword: z.string().optional(),
72
+
73
+ /**
74
+ * The password to use for backup encryption. If not provided, a random password will be generated.
75
+ */
76
+ backupPassword: z.string().optional(),
77
+ })
78
+
79
+ export const sharedDatabaseArgs = $args({
80
+ /**
81
+ * The username for the database user.
82
+ *
83
+ * If not provided, defaults to the name of the instance.
84
+ */
85
+ username: z.string().optional(),
86
+
87
+ /**
88
+ * The name of the database to create.
89
+ *
90
+ * If not provided, defaults to the username.
91
+ */
92
+ database: z.string().optional(),
93
+ })
94
+
95
+ export const sharedDatabaseSecrets = $secrets({
96
+ /**
97
+ * The password for the database user.
98
+ *
99
+ * If not provided, a random password will be generated.
100
+ */
101
+ password: z.string().optional(),
102
+ })
103
+
104
+ export const sharedInputs = $inputs({
105
+ k8sCluster: {
106
+ entity: clusterEntity,
107
+ },
108
+ namespace: {
109
+ entity: namespaceEntity,
110
+ },
111
+ accessPoint: {
112
+ entity: accessPointEntity,
113
+ },
114
+ resticRepo: {
115
+ entity: repositoryEntity,
116
+ },
117
+ dnsProviders: {
118
+ entity: providerEntity,
119
+ multiple: true,
120
+ },
121
+ volume: {
122
+ entity: persistentVolumeClaimEntity,
123
+ },
124
+ mariadb: {
125
+ entity: mariadbEntity,
126
+ },
127
+ postgresql: {
128
+ entity: postgresqlEntity,
129
+ },
130
+ mongodb: {
131
+ entity: mongodbEntity,
132
+ },
133
+ })
134
+
135
+ type ToOptionalInputs<T extends Record<string, FullComponentInputOptions>> = Simplify<{
136
+ [K in keyof T]: T[K] & { required: false }
137
+ }>
138
+
139
+ export const optionalSharedInputs = mapValues(sharedInputs, input => ({
140
+ ...input,
141
+ required: false,
142
+ })) as ToOptionalInputs<typeof sharedInputs>
143
+
144
+ export function source(path: string) {
145
+ return {
146
+ package: "@highstate/k8s.apps",
147
+ path,
148
+ }
149
+ }
@@ -0,0 +1,72 @@
1
+ import { defineUnit, z } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import { l4EndpointEntity } from "../../network"
4
+ import { persistentVolumeClaimEntity } from "../resources"
5
+ import { serviceEntity } from "../service"
6
+ import {
7
+ appName,
8
+ optionalSharedInputs,
9
+ sharedArgs,
10
+ sharedInputs,
11
+ sharedSecrets,
12
+ source,
13
+ } from "./shared"
14
+
15
+ export const backupModeSchema = z.enum(["state", "full"])
16
+
17
+ /**
18
+ * The Syncthing instance deployed on Kubernetes.
19
+ */
20
+ export const syncthing = defineUnit({
21
+ type: "k8s.apps.syncthing.v1",
22
+
23
+ args: {
24
+ ...appName("syncthing"),
25
+ ...pick(sharedArgs, ["fqdn", "external"]),
26
+
27
+ /**
28
+ * The FQDN of the Syncthing instance used to sync with other devices.
29
+ *
30
+ * The `fqdn` argument unlike this one points to the gateway and used to
31
+ * access the Syncthing Web UI.
32
+ */
33
+ deviceFqdn: z.string().optional(),
34
+
35
+ /**
36
+ * The backup mode to use for the Syncthing instance.
37
+ *
38
+ * - `state`: Only the state is backed up. When the instance is restored, it will
39
+ * sync files from the other devices automatically.
40
+ * - `full`: A full backup is created including all files.
41
+ *
42
+ * The default is `state`.
43
+ */
44
+ backupMode: backupModeSchema.default("state"),
45
+ },
46
+
47
+ secrets: {
48
+ ...pick(sharedSecrets, ["backupPassword"]),
49
+ },
50
+
51
+ inputs: {
52
+ ...pick(sharedInputs, ["k8sCluster", "accessPoint"]),
53
+ ...pick(optionalSharedInputs, ["resticRepo", "volume"]),
54
+ },
55
+
56
+ outputs: {
57
+ volume: persistentVolumeClaimEntity,
58
+ service: serviceEntity,
59
+ endpoints: {
60
+ entity: l4EndpointEntity,
61
+ multiple: true,
62
+ },
63
+ },
64
+
65
+ meta: {
66
+ title: "Syncthing",
67
+ icon: "simple-icons:syncthing",
68
+ category: "File Sync",
69
+ },
70
+
71
+ source: source("syncthing"),
72
+ })
@@ -0,0 +1,40 @@
1
+ import { defineUnit, z } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import { gatewayEntity } from "../../common"
4
+ import { l4EndpointEntity } from "../../network"
5
+ import { serviceEntity } from "../service"
6
+ import { appName, sharedArgs, sharedInputs, source } from "./shared"
7
+
8
+ /**
9
+ * The Traefik instance + gateway implementation.
10
+ */
11
+ export const traefik = defineUnit({
12
+ type: "k8s.apps.traefik.v1",
13
+
14
+ args: {
15
+ ...appName("traefik"),
16
+ ...pick(sharedArgs, ["external", "replicas"]),
17
+ className: z.string().optional(),
18
+ },
19
+
20
+ inputs: {
21
+ ...pick(sharedInputs, ["k8sCluster"]),
22
+ },
23
+
24
+ outputs: {
25
+ gateway: gatewayEntity,
26
+ service: serviceEntity,
27
+ endpoints: {
28
+ entity: l4EndpointEntity,
29
+ multiple: true,
30
+ },
31
+ },
32
+
33
+ meta: {
34
+ title: "Traefik Gateway",
35
+ icon: "simple-icons:traefikproxy",
36
+ category: "Network",
37
+ },
38
+
39
+ source: source("traefik"),
40
+ })
@@ -0,0 +1,31 @@
1
+ import { defineUnit, z } from "@highstate/contract"
2
+ import { pick } from "remeda"
3
+ import { appName, sharedArgs, sharedInputs, source } from "./shared"
4
+
5
+ /**
6
+ * The Vaultwarden password manager deployed on Kubernetes.
7
+ */
8
+ export const vaultwarden = defineUnit({
9
+ type: "k8s.apps.vaultwarden.v1",
10
+
11
+ args: {
12
+ ...appName("vaultwarden"),
13
+ ...pick(sharedArgs, ["fqdn"]),
14
+ },
15
+
16
+ secrets: {
17
+ mariadbPassword: z.string().optional(),
18
+ },
19
+
20
+ inputs: {
21
+ ...pick(sharedInputs, ["k8sCluster", "accessPoint", "mariadb"]),
22
+ },
23
+
24
+ meta: {
25
+ title: "Vaultwarden",
26
+ icon: "simple-icons:vaultwarden",
27
+ category: "Security",
28
+ },
29
+
30
+ source: source("vaultwarden"),
31
+ })