@highstate/library 0.7.1 → 0.7.3

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.
package/src/k8s.ts ADDED
@@ -0,0 +1,353 @@
1
+ import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
2
+ import { providerEntity } from "./dns"
3
+
4
+ export const clusterInfoSchema = Type.Object({
5
+ id: Type.String(),
6
+ name: Type.String(),
7
+ cni: Type.Optional(Type.String()),
8
+ externalIps: Type.Array(Type.String()),
9
+ })
10
+
11
+ export const serviceTypeSchema = Type.StringEnum(["NodePort", "LoadBalancer", "ClusterIP"])
12
+
13
+ export const metadataSchema = Type.Object({
14
+ namespace: Type.Optional(Type.String()),
15
+ name: Type.String(),
16
+ labels: Type.Optional(Type.Record(Type.String(), Type.String())),
17
+ annotations: Type.Optional(Type.Record(Type.String(), Type.String())),
18
+ })
19
+
20
+ export const servicePortSchema = Type.Object({
21
+ name: Type.Optional(Type.String()),
22
+ port: Type.Optional(Type.Number()),
23
+ targetPort: Type.Optional(Type.Union([Type.Number(), Type.String()])),
24
+ protocol: Type.Optional(Type.String()),
25
+ })
26
+
27
+ export const serviceSpecSchema = Type.Object({
28
+ type: Type.Optional(Type.String()),
29
+ selector: Type.Record(Type.String(), Type.String()),
30
+ ports: Type.Array(servicePortSchema),
31
+ clusterIP: Type.Optional(Type.String()),
32
+ clusterIPs: Type.Optional(Type.Array(Type.String())),
33
+ externalIPs: Type.Optional(Type.Array(Type.String())),
34
+ })
35
+
36
+ export const serviceEntity = defineEntity({
37
+ type: "k8s.service",
38
+
39
+ schema: Type.Object({
40
+ type: Type.Literal("k8s.service"),
41
+ clusterInfo: clusterInfoSchema,
42
+ metadata: metadataSchema,
43
+ spec: serviceSpecSchema,
44
+ }),
45
+
46
+ meta: {
47
+ color: "#2196F3",
48
+ },
49
+ })
50
+
51
+ export const clusterEntity = defineEntity({
52
+ type: "k8s.cluster",
53
+
54
+ schema: Type.Object({
55
+ info: clusterInfoSchema,
56
+ kubeconfig: Type.String(),
57
+ }),
58
+
59
+ meta: {
60
+ color: "#2196F3",
61
+ },
62
+ })
63
+
64
+ export const internalIpsPolicySchema = Type.StringEnum(["always", "public", "never"])
65
+
66
+ export const existingCluster = defineUnit({
67
+ type: "k8s.existing-cluster",
68
+
69
+ args: {
70
+ /**
71
+ * The list of external IPs of the cluster nodes allowed to be used for external access.
72
+ *
73
+ * If not provided, will be automatically detected by querying the cluster nodes.
74
+ *
75
+ * @schema
76
+ */
77
+ externalIps: Type.Optional(Type.Array(Type.String())),
78
+
79
+ /**
80
+ * The policy for using internal IPs of the nodes as external IPs.
81
+ *
82
+ * - `always`: always use internal IPs as external IPs;
83
+ * - `public`: use internal IPs as external IPs only if they are (theoretically) routable from the public internet **(default)**;
84
+ * - `never`: never use internal IPs as external IPs.
85
+ *
86
+ * @schema
87
+ */
88
+ internalIpsPolicy: { ...internalIpsPolicySchema, default: "public" },
89
+
90
+ /**
91
+ * The FQDN to register the cluster nodes with.
92
+ *
93
+ * If provided and `registerFqdn` is set to `true`, the corresponding DNS provider must be provided to set up the DNS records.
94
+ *
95
+ * @schema
96
+ */
97
+ fqdn: Type.Optional(Type.String()),
98
+
99
+ /**
100
+ * Whether to register the cluster nodes with the provided FQDN.
101
+ *
102
+ * By default, `true`.
103
+ *
104
+ * @schema
105
+ */
106
+ registerFqdn: Type.Boolean({ default: true }),
107
+ },
108
+
109
+ secrets: {
110
+ /**
111
+ * The kubeconfig of the cluster to use for connecting to the cluster.
112
+ *
113
+ * Will be available for all components using `cluster` output of this unit.
114
+ *
115
+ * @schema
116
+ */
117
+ kubeconfig: Type.Record(Type.String(), Type.Any()),
118
+ },
119
+
120
+ outputs: {
121
+ cluster: clusterEntity,
122
+ },
123
+
124
+ meta: {
125
+ displayName: "Existing Cluster",
126
+ description: "An existing Kubernetes cluster.",
127
+ primaryIcon: "mdi:kubernetes",
128
+ },
129
+
130
+ source: {
131
+ package: "@highstate/k8s",
132
+ path: "existing-cluster",
133
+ },
134
+ })
135
+
136
+ export const gatewayEntity = defineEntity({
137
+ type: "k8s.gateway",
138
+
139
+ schema: Type.Object({
140
+ clusterInfo: clusterInfoSchema,
141
+ gatewayClassName: Type.String(),
142
+ httpListenerPort: Type.Number(),
143
+ httpsListenerPort: Type.Number(),
144
+ ip: Type.String(),
145
+ service: Type.Optional(serviceEntity.schema),
146
+ }),
147
+
148
+ meta: {
149
+ color: "#4CAF50",
150
+ },
151
+ })
152
+
153
+ export const tlsIssuerEntity = defineEntity({
154
+ type: "k8s.tls-issuer",
155
+
156
+ schema: Type.Object({
157
+ clusterInfo: clusterInfoSchema,
158
+ clusterIssuerName: Type.String(),
159
+ }),
160
+
161
+ meta: {
162
+ color: "#f06292",
163
+ },
164
+ })
165
+
166
+ export const accessPointEntity = defineEntity({
167
+ type: "common.access-point",
168
+ schema: Type.Object({
169
+ gateway: gatewayEntity.schema,
170
+ tlsIssuer: tlsIssuerEntity.schema,
171
+ dnsProvider: providerEntity.schema,
172
+ }),
173
+
174
+ meta: {
175
+ color: "#FFC107",
176
+ },
177
+ })
178
+
179
+ export const accessPoint = defineUnit({
180
+ type: "k8s.access-point",
181
+
182
+ inputs: {
183
+ gateway: gatewayEntity,
184
+ tlsIssuer: tlsIssuerEntity,
185
+ dnsProvider: providerEntity,
186
+ },
187
+
188
+ outputs: {
189
+ accessPoint: accessPointEntity,
190
+ },
191
+
192
+ meta: {
193
+ displayName: "Access Point",
194
+ description: "An access point which can be used to connect to services.",
195
+ primaryIcon: "mdi:access-point",
196
+ },
197
+
198
+ source: {
199
+ package: "@highstate/k8s",
200
+ path: "access-point",
201
+ },
202
+ })
203
+
204
+ export const certManager = defineUnit({
205
+ type: "k8s.cert-manager",
206
+
207
+ inputs: {
208
+ k8sCluster: clusterEntity,
209
+ },
210
+
211
+ outputs: {
212
+ k8sCluster: clusterEntity,
213
+ },
214
+
215
+ meta: {
216
+ displayName: "Cert Manager",
217
+ description: "A certificate manager for managing TLS certificates.",
218
+ primaryIcon: "simple-icons:letsencrypt",
219
+ },
220
+
221
+ source: {
222
+ package: "@highstate/k8s",
223
+ path: "cert-manager",
224
+ },
225
+ })
226
+
227
+ export const dns01TlsIssuer = defineUnit({
228
+ type: "k8s.dns01-issuer",
229
+
230
+ inputs: {
231
+ k8sCluster: clusterEntity,
232
+ dnsProvider: providerEntity,
233
+ },
234
+
235
+ outputs: {
236
+ tlsIssuer: tlsIssuerEntity,
237
+ },
238
+
239
+ meta: {
240
+ displayName: "DNS01 Issuer",
241
+ description: "A TLS issuer for issuing certificate using DNS01 challenge.",
242
+ primaryIcon: "mdi:certificate",
243
+ },
244
+
245
+ source: {
246
+ package: "@highstate/k8s",
247
+ path: "dns01-issuer",
248
+ },
249
+ })
250
+
251
+ export const containerSchema = Type.Object({
252
+ name: Type.String(),
253
+ image: Type.String(),
254
+ })
255
+
256
+ export const labelSelectorSchema = Type.Object({
257
+ matchLabels: Type.Record(Type.String(), Type.String()),
258
+ })
259
+
260
+ export const deploymentSpecSchema = Type.Object({
261
+ replicas: Type.Number(),
262
+ selector: labelSelectorSchema,
263
+ template: Type.Object({
264
+ metadata: metadataSchema,
265
+ spec: Type.Object({
266
+ containers: Type.Array(containerSchema),
267
+ }),
268
+ }),
269
+ })
270
+
271
+ export const deploymentEntity = defineEntity({
272
+ type: "k8s.deployment",
273
+
274
+ schema: Type.Object({
275
+ type: Type.Literal("k8s.deployment"),
276
+ clusterInfo: clusterInfoSchema,
277
+ metadata: metadataSchema,
278
+
279
+ service: Type.Optional(serviceEntity.schema),
280
+ }),
281
+
282
+ meta: {
283
+ color: "#4CAF50",
284
+ },
285
+ })
286
+
287
+ export const statefulSetEntity = defineEntity({
288
+ type: "k8s.stateful-set",
289
+
290
+ schema: Type.Object({
291
+ type: Type.Literal("k8s.stateful-set"),
292
+ clusterInfo: clusterInfoSchema,
293
+ metadata: metadataSchema,
294
+
295
+ service: Type.Optional(serviceEntity.schema),
296
+ }),
297
+
298
+ meta: {
299
+ color: "#FFC107",
300
+ },
301
+ })
302
+
303
+ export const persistentVolumeClaimEntity = defineEntity({
304
+ type: "k8s.persistent-volume-claim",
305
+
306
+ schema: Type.Object({
307
+ type: Type.Literal("k8s.persistent-volume-claim"),
308
+ clusterInfo: clusterInfoSchema,
309
+ metadata: metadataSchema,
310
+ }),
311
+
312
+ meta: {
313
+ color: "#FFC107",
314
+ },
315
+ })
316
+
317
+ export const interfaceEntity = defineEntity({
318
+ type: "k8s.interface",
319
+
320
+ schema: Type.Object({
321
+ name: Type.String(),
322
+ deployment: deploymentEntity.schema,
323
+ }),
324
+
325
+ meta: {
326
+ color: "#2196F3",
327
+ description:
328
+ "The interface in a network space of pod kernel which can accept or transmit packets.",
329
+ },
330
+ })
331
+
332
+ export type ClusterInfo = Static<typeof clusterInfoSchema>
333
+ export type Cluster = Static<typeof clusterEntity.schema>
334
+
335
+ export type Gateway = Static<typeof gatewayEntity.schema>
336
+ export type TlsIssuer = Static<typeof tlsIssuerEntity.schema>
337
+ export type AccessPoint = Static<typeof accessPointEntity.schema>
338
+
339
+ export type Metadata = Static<typeof metadataSchema>
340
+
341
+ export type ServiceType = Static<typeof serviceTypeSchema>
342
+ export type ServicePort = Static<typeof servicePortSchema>
343
+ export type ServiceSpec = Static<typeof serviceSpecSchema>
344
+ export type Service = Static<typeof serviceEntity.schema>
345
+
346
+ export type Container = Static<typeof containerSchema>
347
+ export type DeploymentSpec = Static<typeof deploymentSpecSchema>
348
+ export type Deployment = Static<typeof deploymentEntity.schema>
349
+
350
+ export type PersistentVolumeClaim = Static<typeof persistentVolumeClaimEntity.schema>
351
+ export type StatefulSet = Static<typeof statefulSetEntity.schema>
352
+
353
+ export type Interface = Static<typeof interfaceEntity.schema>
package/src/mullvad.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { defineUnit, Type } from "@highstate/contract"
2
+ import { networkEntity, peerEntity } from "./wireguard"
3
+
4
+ export const endpointType = Type.Union([
5
+ Type.Literal("fqdn"),
6
+ Type.Literal("ipv4"),
7
+ Type.Literal("ipv6"),
8
+ ])
9
+
10
+ export const peer = defineUnit({
11
+ type: "mullvad.peer",
12
+
13
+ args: {
14
+ hostname: Type.Optional(Type.String()),
15
+ endpointType: Type.Optional({ ...endpointType, default: "fqdn" }),
16
+ },
17
+
18
+ inputs: {
19
+ /**
20
+ * The network to use for the WireGuard peer.
21
+ *
22
+ * If not provided, the peer will use default network configuration.
23
+ */
24
+ network: {
25
+ entity: networkEntity,
26
+ required: false,
27
+ },
28
+ },
29
+
30
+ outputs: {
31
+ peer: peerEntity,
32
+ },
33
+
34
+ meta: {
35
+ displayName: "Mullvad Peer",
36
+ description: "The Mullvad WireGuard peer fetched from the Mullvad API.",
37
+ primaryIcon: "simple-icons:mullvad",
38
+ secondaryIcon: "cib:wireguard",
39
+ secondaryIconColor: "#88171a",
40
+ },
41
+
42
+ source: {
43
+ package: "@highstate/mullvad",
44
+ path: "peer",
45
+ },
46
+ })
package/src/proxmox.ts ADDED
@@ -0,0 +1,188 @@
1
+ import { defineEntity, defineUnit, Type } from "@highstate/contract"
2
+ import { serverEntity } from "./common"
3
+ import { keyPairEntity } from "./ssh"
4
+
5
+ export const clusterEntity = defineEntity({
6
+ type: "proxmox.cluster",
7
+
8
+ schema: Type.Object({
9
+ endpoint: Type.String(),
10
+ insecure: Type.Optional(Type.Boolean()),
11
+ username: Type.Optional(Type.String()),
12
+
13
+ defaultNodeName: Type.String(),
14
+ defaultDatastoreId: Type.String(),
15
+
16
+ password: Type.Optional(Type.String()),
17
+ apiToken: Type.Optional(Type.String()),
18
+ }),
19
+
20
+ meta: {
21
+ color: "#e56901",
22
+ },
23
+ })
24
+
25
+ export const imageEntity = defineEntity({
26
+ type: "proxmox.image",
27
+
28
+ schema: Type.Object({
29
+ id: Type.String(),
30
+ }),
31
+
32
+ meta: {
33
+ color: "#e56901",
34
+ },
35
+ })
36
+
37
+ export const connection = defineUnit({
38
+ type: "proxmox.connection",
39
+
40
+ args: {
41
+ endpoint: Type.String(),
42
+ insecure: Type.Optional(Type.Boolean()),
43
+ username: Type.Optional(Type.String()),
44
+
45
+ defaultNodeName: Type.Optional(Type.String()),
46
+ defaultDatastoreId: Type.Optional(Type.String()),
47
+ },
48
+
49
+ secrets: {
50
+ password: Type.Optional(Type.String()),
51
+ apiToken: Type.Optional(Type.String()),
52
+ },
53
+
54
+ outputs: {
55
+ proxmoxCluster: clusterEntity,
56
+ },
57
+
58
+ meta: {
59
+ displayName: "Proxmox Connection",
60
+ description: "The connection to an existing Proxmox cluster.",
61
+ category: "Proxmox",
62
+ primaryIcon: "simple-icons:proxmox",
63
+ primaryIconColor: "#e56901",
64
+ secondaryIcon: "codicon:vm",
65
+ },
66
+
67
+ source: {
68
+ package: "@highstate/proxmox",
69
+ path: "connection",
70
+ },
71
+ })
72
+
73
+ export const image = defineUnit({
74
+ type: "proxmox.image",
75
+
76
+ args: {
77
+ url: Type.String(),
78
+ nodeName: Type.Optional(Type.String()),
79
+ sha256: Type.Optional(Type.String()),
80
+ datastoreId: Type.Optional(Type.String()),
81
+ },
82
+
83
+ inputs: {
84
+ proxmoxCluster: clusterEntity,
85
+ },
86
+
87
+ outputs: {
88
+ image: imageEntity,
89
+ },
90
+
91
+ meta: {
92
+ displayName: "Proxmox Image",
93
+ description: "The image to upload to a Proxmox cluster.",
94
+ category: "Proxmox",
95
+ primaryIcon: "simple-icons:proxmox",
96
+ primaryIconColor: "#e56901",
97
+ secondaryIcon: "mage:compact-disk-fill",
98
+ },
99
+
100
+ source: {
101
+ package: "@highstate/proxmox",
102
+ path: "image",
103
+ },
104
+ })
105
+
106
+ export const existingImage = defineUnit({
107
+ type: "proxmox.existing-image",
108
+
109
+ args: {
110
+ id: Type.String(),
111
+ },
112
+
113
+ outputs: {
114
+ image: imageEntity,
115
+ },
116
+
117
+ meta: {
118
+ displayName: "Proxmox Existing Image",
119
+ description: "The existing image on a Proxmox cluster.",
120
+ category: "Proxmox",
121
+ primaryIcon: "simple-icons:proxmox",
122
+ primaryIconColor: "#e56901",
123
+ secondaryIcon: "mage:compact-disk-fill",
124
+ },
125
+
126
+ source: {
127
+ package: "@highstate/proxmox",
128
+ path: "existing-image",
129
+ },
130
+ })
131
+
132
+ export const virtualMachine = defineUnit({
133
+ type: "proxmox.virtual-machine",
134
+
135
+ args: {
136
+ nodeName: Type.Optional(Type.String()),
137
+
138
+ cpuType: Type.Optional(Type.String({ default: "host" })),
139
+ cores: Type.Optional(Type.Number({ default: 1 })),
140
+ sockets: Type.Optional(Type.Number({ default: 1 })),
141
+ memory: Type.Optional(Type.Number({ default: 512 })),
142
+
143
+ ipv4: Type.Optional(Type.String()),
144
+ ipv4Gateway: Type.Optional(Type.String()),
145
+ dns: Type.Optional(Type.Array(Type.String())),
146
+
147
+ datastoreId: Type.Optional(Type.String()),
148
+ diskSize: Type.Optional(Type.Number({ default: 8 })),
149
+ bridge: Type.Optional(Type.String({ default: "vmbr0" })),
150
+
151
+ sshPort: Type.Optional(Type.Number({ default: 22 })),
152
+ sshUser: Type.Optional(Type.String({ default: "root" })),
153
+
154
+ waitForAgent: Type.Optional(Type.Boolean({ default: true })),
155
+ },
156
+
157
+ inputs: {
158
+ proxmoxCluster: clusterEntity,
159
+ image: imageEntity,
160
+
161
+ sshKeyPair: {
162
+ entity: keyPairEntity,
163
+ required: false,
164
+ },
165
+ },
166
+
167
+ secrets: {
168
+ sshPassword: Type.Optional(Type.String()),
169
+ },
170
+
171
+ outputs: {
172
+ server: serverEntity,
173
+ },
174
+
175
+ meta: {
176
+ displayName: "Proxmox Virtual Machine",
177
+ description: "The virtual machine on a Proxmox cluster.",
178
+ category: "Proxmox",
179
+ primaryIcon: "simple-icons:proxmox",
180
+ primaryIconColor: "#e56901",
181
+ secondaryIcon: "codicon:vm",
182
+ },
183
+
184
+ source: {
185
+ package: "@highstate/proxmox",
186
+ path: "virtual-machine",
187
+ },
188
+ })
package/src/restic.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
2
+
3
+ export const repoEntity = defineEntity({
4
+ type: "restic.repo",
5
+
6
+ schema: Type.Object({
7
+ password: Type.String(),
8
+ remoteDomains: Type.Array(Type.String()),
9
+
10
+ type: Type.Literal("rclone"),
11
+ rcloneConfig: Type.String(),
12
+ remoteName: Type.String(),
13
+ basePath: Type.String(),
14
+ }),
15
+
16
+ meta: {
17
+ color: "#e56901",
18
+ },
19
+ })
20
+
21
+ export const repo = defineUnit({
22
+ type: "restic.repo",
23
+
24
+ args: {
25
+ remoteDomains: Type.Optional(Type.Array(Type.String())),
26
+ basePath: Type.Optional(Type.String()),
27
+ },
28
+
29
+ secrets: {
30
+ password: Type.Optional(Type.String()),
31
+ rcloneConfig: Type.String({ multiline: true }),
32
+ },
33
+
34
+ outputs: {
35
+ repo: repoEntity,
36
+ },
37
+
38
+ meta: {
39
+ displayName: "Restic Repo",
40
+ description: "Holds the configuration for a Restic repository and its remote storage.",
41
+ primaryIconColor: "#e56901",
42
+ primaryIcon: "material-symbols:backup",
43
+ },
44
+
45
+ source: {
46
+ package: "@highstate/restic",
47
+ path: "repo",
48
+ },
49
+ })
50
+
51
+ export type Repo = Static<typeof repoEntity.schema>
package/src/ssh.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { defineEntity, defineUnit, Type, type Static } from "@highstate/contract"
2
+
3
+ export const keyTypeSchema = Type.Union([
4
+ //
5
+ Type.Literal("rsa"),
6
+ Type.Literal("ed25519"),
7
+ ])
8
+
9
+ export const keyPairEntity = defineEntity({
10
+ type: "ssh.key-pair",
11
+
12
+ schema: Type.Object({
13
+ type: keyTypeSchema,
14
+ privateKey: Type.String(),
15
+ publicKey: Type.String(),
16
+ }),
17
+
18
+ meta: {
19
+ color: "#2b5797",
20
+ },
21
+ })
22
+
23
+ export const credentialsSchema = Type.Object({
24
+ endpoint: Type.Optional(Type.String()),
25
+ user: Type.Optional(Type.String()),
26
+ port: Type.Optional(Type.Number()),
27
+ password: Type.Optional(Type.String()),
28
+ privateKey: Type.Optional(Type.String()),
29
+ })
30
+
31
+ export const keyPair = defineUnit({
32
+ type: "ssh.key-pair",
33
+
34
+ secrets: {
35
+ privateKey: Type.Optional(Type.String()),
36
+ },
37
+
38
+ outputs: {
39
+ keyPair: keyPairEntity,
40
+ },
41
+
42
+ meta: {
43
+ displayName: "SSH Key Pair",
44
+ description: "Holds the ED25519 SSH key pair and generates the private key if not provided.",
45
+ category: "ssh",
46
+ primaryIcon: "charm:key",
47
+ primaryIconColor: "#ffffff",
48
+ secondaryIcon: "mdi:lock",
49
+ secondaryIconColor: "#ffffff",
50
+ },
51
+
52
+ source: {
53
+ package: "@highstate/common",
54
+ path: "ssh/key-pair",
55
+ },
56
+ })
57
+
58
+ export type KeyType = Static<typeof keyTypeSchema>
59
+ export type Credentials = Static<typeof credentialsSchema>
60
+ export type KeyPair = Static<typeof keyPairEntity.schema>