@highstate/library 0.12.0 → 0.13.0
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/dist/highstate.library.msgpack +0 -0
- package/dist/index.js +319 -5
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/databases/index.ts +2 -0
- package/src/databases/redis.ts +48 -0
- package/src/databases/s3.ts +123 -0
- package/src/k8s/apps/index.ts +3 -0
- package/src/k8s/apps/maybe.ts +1 -1
- package/src/k8s/apps/minio.ts +81 -0
- package/src/k8s/apps/remnawave.ts +66 -0
- package/src/k8s/apps/shared.ts +4 -1
- package/src/k8s/apps/traefik.ts +7 -1
- package/src/k8s/apps/valkey.ts +52 -0
- package/src/proxmox.ts +7 -0
- package/src/third-party/timeweb.ts +9 -0
- package/src/third-party/yandex.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/library",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"highstate": {
|
|
6
6
|
"type": "library"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
22
|
+
"remeda": "^2.21.0",
|
|
23
|
+
"@highstate/contract": "0.13.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@biomejs/biome": "2.2.0",
|
|
27
|
-
"@highstate/cli": "^0.10.0",
|
|
28
27
|
"@typescript/native-preview": "^7.0.0-dev.20250920.1",
|
|
29
|
-
"type-fest": "^4.41.0"
|
|
28
|
+
"type-fest": "^4.41.0",
|
|
29
|
+
"@highstate/cli": "0.13.0"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"url": "https://github.com/highstate-io/highstate"
|
package/src/databases/index.ts
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { defineEntity, defineUnit, z } from "@highstate/contract"
|
|
2
|
+
import { sharedArgs, sharedInputs, sharedSchema } from "./shared"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents the Redis database or virtual database behind it.
|
|
6
|
+
*/
|
|
7
|
+
export const redisEntity = defineEntity({
|
|
8
|
+
type: "databases.redis.v1",
|
|
9
|
+
|
|
10
|
+
schema: sharedSchema.pick({ endpoints: true }).extend({
|
|
11
|
+
/**
|
|
12
|
+
* The number of the database to use.
|
|
13
|
+
*/
|
|
14
|
+
database: z.number().default(0),
|
|
15
|
+
}),
|
|
16
|
+
|
|
17
|
+
meta: {
|
|
18
|
+
color: "#dc382d",
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The existing Redis database or virtual database behind it.
|
|
24
|
+
*/
|
|
25
|
+
export const existingRedis = defineUnit({
|
|
26
|
+
type: "databases.redis.existing.v1",
|
|
27
|
+
|
|
28
|
+
args: sharedArgs,
|
|
29
|
+
inputs: sharedInputs,
|
|
30
|
+
|
|
31
|
+
outputs: {
|
|
32
|
+
redis: redisEntity,
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
source: {
|
|
36
|
+
package: "@highstate/common",
|
|
37
|
+
path: "units/databases/existing-redis",
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
meta: {
|
|
41
|
+
title: "Existing Redis Database",
|
|
42
|
+
icon: "simple-icons:redis",
|
|
43
|
+
secondaryIcon: "mdi:database",
|
|
44
|
+
category: "Databases",
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export type Redis = z.infer<typeof redisEntity.schema>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { $args, $inputs, $secrets, defineEntity, defineUnit, z } from "@highstate/contract"
|
|
2
|
+
import { l4EndpointEntity } from "../network"
|
|
3
|
+
|
|
4
|
+
export const s3BucketPolicySchema = z.enum(["none", "download", "upload", "public"])
|
|
5
|
+
|
|
6
|
+
export const s3BucketSchema = z.object({
|
|
7
|
+
/**
|
|
8
|
+
* The name of the bucket.
|
|
9
|
+
*/
|
|
10
|
+
name: z.string(),
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The optional policy applied to the bucket.
|
|
14
|
+
*/
|
|
15
|
+
policy: s3BucketPolicySchema.optional(),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const s3Args = $args({
|
|
19
|
+
/**
|
|
20
|
+
* The endpoints to connect to the S3-compatible API in form of `host:port`.
|
|
21
|
+
*/
|
|
22
|
+
endpoints: z.string().array().min(1),
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The access key used to authenticate against the S3-compatible API.
|
|
26
|
+
*/
|
|
27
|
+
accessKey: z.string(),
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The region associated with the S3-compatible deployment.
|
|
31
|
+
*/
|
|
32
|
+
region: z.string().optional(),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The buckets that must exist on the instance.
|
|
36
|
+
*/
|
|
37
|
+
buckets: s3BucketSchema.array().default([]),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const s3Secrets = $secrets({
|
|
41
|
+
/**
|
|
42
|
+
* The secret key used to authenticate against the S3-compatible API.
|
|
43
|
+
*/
|
|
44
|
+
secretKey: z.string(),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const s3Inputs = $inputs({
|
|
48
|
+
/**
|
|
49
|
+
* The endpoints to connect to the S3-compatible API.
|
|
50
|
+
*/
|
|
51
|
+
endpoints: {
|
|
52
|
+
entity: l4EndpointEntity,
|
|
53
|
+
multiple: true,
|
|
54
|
+
required: false,
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Represents an S3-compatible object storage endpoint.
|
|
60
|
+
*/
|
|
61
|
+
export const s3Entity = defineEntity({
|
|
62
|
+
type: "databases.s3.v1",
|
|
63
|
+
|
|
64
|
+
schema: z.object({
|
|
65
|
+
/**
|
|
66
|
+
* The endpoints that expose the S3-compatible API.
|
|
67
|
+
*/
|
|
68
|
+
endpoints: l4EndpointEntity.schema.array(),
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The region associated with the object storage instance.
|
|
72
|
+
*/
|
|
73
|
+
region: z.string().optional(),
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The access key used to authenticate against the API.
|
|
77
|
+
*/
|
|
78
|
+
accessKey: z.string(),
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The secret key used to authenticate against the API.
|
|
82
|
+
*/
|
|
83
|
+
secretKey: z.string(),
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The buckets that must exist on the instance.
|
|
87
|
+
*/
|
|
88
|
+
buckets: s3BucketSchema.array(),
|
|
89
|
+
}),
|
|
90
|
+
|
|
91
|
+
meta: {
|
|
92
|
+
color: "#ff9900",
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The existing S3-compatible object storage instance.
|
|
98
|
+
*/
|
|
99
|
+
export const existingS3 = defineUnit({
|
|
100
|
+
type: "databases.s3.existing.v1",
|
|
101
|
+
|
|
102
|
+
args: s3Args,
|
|
103
|
+
secrets: s3Secrets,
|
|
104
|
+
inputs: s3Inputs,
|
|
105
|
+
|
|
106
|
+
outputs: {
|
|
107
|
+
s3: s3Entity,
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
source: {
|
|
111
|
+
package: "@highstate/common",
|
|
112
|
+
path: "units/databases/existing-s3",
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
meta: {
|
|
116
|
+
title: "Existing S3-Compatible Storage",
|
|
117
|
+
icon: "simple-icons:amazons3",
|
|
118
|
+
secondaryIcon: "mdi:bucket",
|
|
119
|
+
category: "Databases",
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
export type S3 = z.infer<typeof s3Entity.schema>
|
package/src/k8s/apps/index.ts
CHANGED
|
@@ -4,8 +4,10 @@ export * from "./hubble"
|
|
|
4
4
|
export * from "./kubernetes-dashboard"
|
|
5
5
|
export * from "./mariadb"
|
|
6
6
|
export * from "./maybe"
|
|
7
|
+
export * from "./minio"
|
|
7
8
|
export * from "./mongodb"
|
|
8
9
|
export * from "./postgresql"
|
|
10
|
+
export * from "./remnawave"
|
|
9
11
|
export {
|
|
10
12
|
appName,
|
|
11
13
|
optionalSharedArgs,
|
|
@@ -18,5 +20,6 @@ export * from "./syncthing"
|
|
|
18
20
|
// export * from "./zitadel"
|
|
19
21
|
// export * from "./gitea"
|
|
20
22
|
export * from "./traefik"
|
|
23
|
+
export * from "./valkey"
|
|
21
24
|
export * from "./vaultwarden"
|
|
22
25
|
export * from "./workload"
|
package/src/k8s/apps/maybe.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const maybe = defineUnit({
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
inputs: {
|
|
27
|
-
...pick(sharedInputs, ["k8sCluster", "accessPoint", "postgresql"]),
|
|
27
|
+
...pick(sharedInputs, ["k8sCluster", "accessPoint", "postgresql", "redis"]),
|
|
28
28
|
...pick(optionalSharedInputs, ["resticRepo"]),
|
|
29
29
|
},
|
|
30
30
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { $secrets, defineUnit, text, z } 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 { appName, optionalSharedInputs, sharedArgs, sharedInputs, source } from "./shared"
|
|
7
|
+
|
|
8
|
+
const minioSecrets = $secrets({
|
|
9
|
+
/**
|
|
10
|
+
* The secret key used to authenticate with MinIO.
|
|
11
|
+
*/
|
|
12
|
+
secretKey: z.string().optional(),
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The key that protects Restic backups.
|
|
16
|
+
*/
|
|
17
|
+
backupKey: z.string().optional(),
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The MinIO object storage deployed on Kubernetes.
|
|
22
|
+
*/
|
|
23
|
+
export const minio = defineUnit({
|
|
24
|
+
type: "k8s.apps.minio.v1",
|
|
25
|
+
args: {
|
|
26
|
+
...appName("minio"),
|
|
27
|
+
...pick(sharedArgs, ["external"]),
|
|
28
|
+
|
|
29
|
+
accessKey: {
|
|
30
|
+
schema: z.string().default("admin"),
|
|
31
|
+
meta: {
|
|
32
|
+
description: text`
|
|
33
|
+
The access key used to authenticate with MinIO.
|
|
34
|
+
If not provided, defaults to "admin".
|
|
35
|
+
`,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
region: {
|
|
40
|
+
schema: z.string().optional(),
|
|
41
|
+
meta: {
|
|
42
|
+
description: text`The region associated with the MinIO deployment.`,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
buckets: {
|
|
47
|
+
schema: databases.s3BucketSchema.array().default([]),
|
|
48
|
+
meta: {
|
|
49
|
+
description: text`
|
|
50
|
+
The buckets that must exist on the MinIO instance.
|
|
51
|
+
Each entry can optionally include a bucket policy: none, download, upload, or public.
|
|
52
|
+
`,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
secrets: minioSecrets,
|
|
58
|
+
|
|
59
|
+
inputs: {
|
|
60
|
+
...pick(sharedInputs, ["k8sCluster"]),
|
|
61
|
+
...pick(optionalSharedInputs, ["resticRepo"]),
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
outputs: {
|
|
65
|
+
s3: databases.s3Entity,
|
|
66
|
+
service: serviceEntity,
|
|
67
|
+
endpoints: {
|
|
68
|
+
entity: l4EndpointEntity,
|
|
69
|
+
multiple: true,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
meta: {
|
|
74
|
+
title: "MinIO",
|
|
75
|
+
icon: "simple-icons:minio",
|
|
76
|
+
secondaryIcon: "mdi:bucket",
|
|
77
|
+
category: "Databases",
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
source: source("minio/app"),
|
|
81
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defineEntity, defineUnit, z } from "@highstate/contract"
|
|
2
|
+
import { pick } from "remeda"
|
|
3
|
+
import { optionalSharedInputs, sharedInputs, source } from "./shared"
|
|
4
|
+
|
|
5
|
+
export const remnawaveEntity = defineEntity({
|
|
6
|
+
type: "k8s.apps.remnawave.v1",
|
|
7
|
+
|
|
8
|
+
schema: z.object({
|
|
9
|
+
/**
|
|
10
|
+
* The ID of the Remnawave instance.
|
|
11
|
+
*/
|
|
12
|
+
instanceId: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The Remnawave backend deployed on Kubernetes.
|
|
18
|
+
*/
|
|
19
|
+
export const remnawave = defineUnit({
|
|
20
|
+
type: "k8s.apps.remnawave.backend.v1",
|
|
21
|
+
|
|
22
|
+
secrets: {
|
|
23
|
+
jwtAuthSecret: z.string(),
|
|
24
|
+
jwtApiTokensSecret: z.string(),
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
inputs: {
|
|
28
|
+
...pick(sharedInputs, ["k8sCluster", "accessPoint", "postgresql", "redis"]),
|
|
29
|
+
...pick(optionalSharedInputs, ["resticRepo"]),
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
outputs: {
|
|
33
|
+
remnawave: remnawaveEntity,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
meta: {
|
|
37
|
+
title: "Remnawave Backend",
|
|
38
|
+
icon: "mdi:waveform",
|
|
39
|
+
iconColor: "#0066cc",
|
|
40
|
+
category: "VPN",
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
source: source("remnawave/backend"),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The Remnawave node deployed on Kubernetes.
|
|
48
|
+
*/
|
|
49
|
+
export const node = defineUnit({
|
|
50
|
+
type: "k8s.apps.remnawave.node.v1",
|
|
51
|
+
|
|
52
|
+
inputs: {
|
|
53
|
+
remnawave: remnawaveEntity,
|
|
54
|
+
...pick(sharedInputs, ["k8sCluster"]),
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
meta: {
|
|
58
|
+
title: "Remnawave Node",
|
|
59
|
+
icon: "mdi:waveform",
|
|
60
|
+
iconColor: "#0066cc",
|
|
61
|
+
secondaryIcon: "mdi:server-network",
|
|
62
|
+
category: "VPN",
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
source: source("remnawave/node"),
|
|
66
|
+
})
|
package/src/k8s/apps/shared.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "@highstate/contract"
|
|
13
13
|
import { mapValues } from "remeda"
|
|
14
14
|
import { accessPointEntity } from "../../common"
|
|
15
|
-
import { mariadbEntity, mongodbEntity, postgresqlEntity } from "../../databases"
|
|
15
|
+
import { mariadbEntity, mongodbEntity, postgresqlEntity, redisEntity } from "../../databases"
|
|
16
16
|
import { providerEntity } from "../../dns"
|
|
17
17
|
import { repositoryEntity } from "../../restic"
|
|
18
18
|
import { namespaceEntity, persistentVolumeClaimEntity } from "../resources"
|
|
@@ -138,6 +138,9 @@ export const sharedInputs = $inputs({
|
|
|
138
138
|
mongodb: {
|
|
139
139
|
entity: mongodbEntity,
|
|
140
140
|
},
|
|
141
|
+
redis: {
|
|
142
|
+
entity: redisEntity,
|
|
143
|
+
},
|
|
141
144
|
})
|
|
142
145
|
|
|
143
146
|
type ToOptionalInputs<T extends Record<string, FullComponentInputOptions>> = Simplify<{
|
package/src/k8s/apps/traefik.ts
CHANGED
|
@@ -14,7 +14,13 @@ export const traefik = defineUnit({
|
|
|
14
14
|
args: {
|
|
15
15
|
...appName("traefik"),
|
|
16
16
|
...pick(sharedArgs, ["external", "replicas", "endpoints"]),
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The name of the class to configure for ingress and gateway resources.
|
|
20
|
+
*
|
|
21
|
+
* Defaults to "traefik".
|
|
22
|
+
*/
|
|
23
|
+
className: z.string().default("traefik"),
|
|
18
24
|
},
|
|
19
25
|
|
|
20
26
|
inputs: {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineUnit } from "@highstate/contract"
|
|
2
|
+
import { pick } from "remeda"
|
|
3
|
+
import { databases } from "../.."
|
|
4
|
+
import { l4EndpointEntity } from "../../network"
|
|
5
|
+
import { serviceEntity } from "../service"
|
|
6
|
+
import {
|
|
7
|
+
appName,
|
|
8
|
+
optionalSharedInputs,
|
|
9
|
+
sharedArgs,
|
|
10
|
+
sharedInputs,
|
|
11
|
+
sharedSecrets,
|
|
12
|
+
source,
|
|
13
|
+
} from "./shared"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The Valkey instance deployed on Kubernetes.
|
|
17
|
+
*/
|
|
18
|
+
export const valkey = defineUnit({
|
|
19
|
+
type: "k8s.apps.valkey.v1",
|
|
20
|
+
|
|
21
|
+
args: {
|
|
22
|
+
...appName("valkey"),
|
|
23
|
+
...pick(sharedArgs, ["external"]),
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
secrets: {
|
|
27
|
+
...pick(sharedSecrets, ["backupKey"]),
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
inputs: {
|
|
31
|
+
...pick(sharedInputs, ["k8sCluster"]),
|
|
32
|
+
...pick(optionalSharedInputs, ["resticRepo"]),
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
outputs: {
|
|
36
|
+
redis: databases.redisEntity,
|
|
37
|
+
service: serviceEntity,
|
|
38
|
+
endpoints: {
|
|
39
|
+
entity: l4EndpointEntity,
|
|
40
|
+
multiple: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
meta: {
|
|
45
|
+
title: "Valkey (Redis)",
|
|
46
|
+
icon: "simple-icons:redis",
|
|
47
|
+
secondaryIcon: "mdi:database",
|
|
48
|
+
category: "Databases",
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
source: source("valkey/app"),
|
|
52
|
+
})
|
package/src/proxmox.ts
CHANGED
|
@@ -260,6 +260,13 @@ export const virtualMachine = defineUnit({
|
|
|
260
260
|
type: "proxmox.virtual-machine.v1",
|
|
261
261
|
|
|
262
262
|
args: {
|
|
263
|
+
/**
|
|
264
|
+
* The name of the virtual machine.
|
|
265
|
+
*
|
|
266
|
+
* If not specified, the unit name will be used.
|
|
267
|
+
*/
|
|
268
|
+
vmName: z.string().optional(),
|
|
269
|
+
|
|
263
270
|
/**
|
|
264
271
|
* The name of the node to create the virtual machine on.
|
|
265
272
|
*
|
|
@@ -46,6 +46,13 @@ export const virtualMachine = defineUnit({
|
|
|
46
46
|
type: "timeweb.virtual-machine.v1",
|
|
47
47
|
|
|
48
48
|
args: {
|
|
49
|
+
/**
|
|
50
|
+
* The name of the virtual machine.
|
|
51
|
+
*
|
|
52
|
+
* If not provided, the name of the unit will be used.
|
|
53
|
+
*/
|
|
54
|
+
vmName: z.string().optional(),
|
|
55
|
+
|
|
49
56
|
/**
|
|
50
57
|
* The ID of the preset to use for the virtual machine.
|
|
51
58
|
*
|
|
@@ -97,3 +104,5 @@ export const virtualMachine = defineUnit({
|
|
|
97
104
|
path: "virtual-machine",
|
|
98
105
|
},
|
|
99
106
|
})
|
|
107
|
+
|
|
108
|
+
export type Connection = z.infer<typeof connectionEntity.schema>
|
|
@@ -342,6 +342,15 @@ export const virtualMachine = defineUnit({
|
|
|
342
342
|
* Whether to assign a public IP.
|
|
343
343
|
*/
|
|
344
344
|
assignPublicIp: z.boolean().default(true),
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Whether to reserve the public IP permanently.
|
|
348
|
+
*
|
|
349
|
+
* If not set, the public IP can be changed when the VM is stopped and started again.
|
|
350
|
+
*
|
|
351
|
+
* Makes no sense if `assignPublicIp` is false.
|
|
352
|
+
*/
|
|
353
|
+
reservePublicIp: z.boolean().default(true),
|
|
345
354
|
})
|
|
346
355
|
.prefault({}),
|
|
347
356
|
|