@highstate/k8s 0.15.0 → 0.16.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.
Files changed (96) hide show
  1. package/dist/chunk-22GOWZQP.js +286 -0
  2. package/dist/chunk-22GOWZQP.js.map +1 -0
  3. package/dist/{chunk-VJL2BFKO.js → chunk-4G6LLC2X.js} +13 -24
  4. package/dist/chunk-4G6LLC2X.js.map +1 -0
  5. package/dist/{chunk-C6WHUOC3.js → chunk-BR2CLUUD.js} +15 -26
  6. package/dist/chunk-BR2CLUUD.js.map +1 -0
  7. package/dist/{chunk-EACAK6W4.js → chunk-DCUMJSO6.js} +17 -28
  8. package/dist/chunk-DCUMJSO6.js.map +1 -0
  9. package/dist/{chunk-NWXKLVBC.js → chunk-HJKJHTJM.js} +20 -30
  10. package/dist/chunk-HJKJHTJM.js.map +1 -0
  11. package/dist/{chunk-7H4L3DFC.js → chunk-KMLRI5UZ.js} +57 -70
  12. package/dist/chunk-KMLRI5UZ.js.map +1 -0
  13. package/dist/{chunk-6ACIPGW4.js → chunk-LGHFSXNT.js} +12 -13
  14. package/dist/chunk-LGHFSXNT.js.map +1 -0
  15. package/dist/{chunk-SEWB4FUB.js → chunk-OBDQONMV.js} +64 -23
  16. package/dist/chunk-OBDQONMV.js.map +1 -0
  17. package/dist/chunk-SL5CBM3A.js +301 -0
  18. package/dist/chunk-SL5CBM3A.js.map +1 -0
  19. package/dist/{chunk-3CKMDTYK.js → chunk-TWBMG6TD.js} +68 -91
  20. package/dist/chunk-TWBMG6TD.js.map +1 -0
  21. package/dist/{chunk-YTRQ6JRU.js → chunk-XRIC6EJ3.js} +159 -94
  22. package/dist/chunk-XRIC6EJ3.js.map +1 -0
  23. package/dist/{chunk-O64YZLA4.js → chunk-ZBFWQHE4.js} +21 -30
  24. package/dist/chunk-ZBFWQHE4.js.map +1 -0
  25. package/dist/{chunk-4VGISFL4.js → chunk-ZHVKK2U6.js} +12 -11
  26. package/dist/chunk-ZHVKK2U6.js.map +1 -0
  27. package/dist/cron-job-LX35I6HG.js +8 -0
  28. package/dist/cron-job-LX35I6HG.js.map +1 -0
  29. package/dist/deployment-HRJGAEJR.js +8 -0
  30. package/dist/{deployment-THUD5QUH.js.map → deployment-HRJGAEJR.js.map} +1 -1
  31. package/dist/highstate.manifest.json +2 -3
  32. package/dist/impl/gateway-route.js +10 -10
  33. package/dist/impl/gateway-route.js.map +1 -1
  34. package/dist/impl/tls-certificate.js +3 -3
  35. package/dist/index.js +39 -627
  36. package/dist/index.js.map +1 -1
  37. package/dist/job-J4BKBVQD.js +8 -0
  38. package/dist/job-J4BKBVQD.js.map +1 -0
  39. package/dist/stateful-set-LAJR5RL4.js +8 -0
  40. package/dist/{stateful-set-ABCZML4L.js.map → stateful-set-LAJR5RL4.js.map} +1 -1
  41. package/dist/units/cert-manager/index.js +7 -7
  42. package/dist/units/cluster-patch/index.js +9 -18
  43. package/dist/units/cluster-patch/index.js.map +1 -1
  44. package/dist/units/dns01-issuer/index.js +6 -6
  45. package/dist/units/dns01-issuer/index.js.map +1 -1
  46. package/dist/units/existing-cluster/index.js +19 -9
  47. package/dist/units/existing-cluster/index.js.map +1 -1
  48. package/dist/units/gateway-api/index.js +2 -2
  49. package/dist/units/gateway-api/index.js.map +1 -1
  50. package/dist/units/reduced-access-cluster/index.js +18 -25
  51. package/dist/units/reduced-access-cluster/index.js.map +1 -1
  52. package/package.json +6 -11
  53. package/src/cluster.ts +14 -14
  54. package/src/config-map.ts +16 -30
  55. package/src/container.ts +1 -1
  56. package/src/cron-job.ts +23 -41
  57. package/src/deployment.ts +23 -30
  58. package/src/gateway/gateway.ts +21 -29
  59. package/src/helm.ts +7 -8
  60. package/src/impl/gateway-route.ts +5 -13
  61. package/src/job.ts +20 -38
  62. package/src/namespace.ts +18 -22
  63. package/src/network-policy.ts +37 -36
  64. package/src/network.ts +18 -10
  65. package/src/pvc.ts +12 -28
  66. package/src/rbac.ts +75 -97
  67. package/src/scripting/bundle.ts +3 -3
  68. package/src/scripting/environment.ts +3 -3
  69. package/src/secret.ts +16 -30
  70. package/src/service.ts +86 -105
  71. package/src/shared.ts +82 -20
  72. package/src/stateful-set.ts +17 -28
  73. package/src/tls.ts +20 -31
  74. package/src/units/cluster-patch/index.ts +9 -19
  75. package/src/units/dns01-issuer/index.ts +6 -6
  76. package/src/units/existing-cluster/index.ts +28 -10
  77. package/src/units/gateway-api/index.ts +1 -1
  78. package/src/units/reduced-access-cluster/index.ts +16 -24
  79. package/src/worker.ts +7 -5
  80. package/src/workload.ts +172 -28
  81. package/dist/chunk-3CKMDTYK.js.map +0 -1
  82. package/dist/chunk-4VGISFL4.js.map +0 -1
  83. package/dist/chunk-6ACIPGW4.js.map +0 -1
  84. package/dist/chunk-7H4L3DFC.js.map +0 -1
  85. package/dist/chunk-C6WHUOC3.js.map +0 -1
  86. package/dist/chunk-EACAK6W4.js.map +0 -1
  87. package/dist/chunk-NWXKLVBC.js.map +0 -1
  88. package/dist/chunk-O64YZLA4.js.map +0 -1
  89. package/dist/chunk-SEWB4FUB.js.map +0 -1
  90. package/dist/chunk-VJL2BFKO.js.map +0 -1
  91. package/dist/chunk-YTRQ6JRU.js.map +0 -1
  92. package/dist/deployment-THUD5QUH.js +0 -8
  93. package/dist/stateful-set-ABCZML4L.js +0 -8
  94. package/dist/units/cluster-dns/index.js +0 -37
  95. package/dist/units/cluster-dns/index.js.map +0 -1
  96. package/src/units/cluster-dns/index.ts +0 -37
@@ -1,10 +1,5 @@
1
1
  import type { Secret } from "../secret"
2
- import {
3
- filterEndpoints,
4
- type GatewayRouteSpec,
5
- gatewayRouteMediator,
6
- type TlsCertificate,
7
- } from "@highstate/common"
2
+ import { type GatewayRouteSpec, gatewayRouteMediator, type TlsCertificate } from "@highstate/common"
8
3
  import { k8s, type network } from "@highstate/library"
9
4
  import { type ComponentResourceOptions, type Input, toPromise } from "@highstate/pulumi"
10
5
  import { core } from "@pulumi/kubernetes"
@@ -279,13 +274,10 @@ async function createServiceFromEndpoints(
279
274
  throw new Error(`Gateway route "${name}" has no endpoints to expose.`)
280
275
  }
281
276
 
282
- const hostnameEndpoints = filterEndpoints(endpoints, undefined, ["hostname"])
283
- const ipEndpoints = filterEndpoints(endpoints, undefined, ["ipv4", "ipv6"])
277
+ const hostnameEndpoints = endpoints.filter(endpoint => endpoint.type === "hostname")
278
+ const ipEndpoints = endpoints.filter(endpoint => endpoint.type !== "hostname")
284
279
 
285
- if (
286
- hostnameEndpoints.length > 0 &&
287
- hostnameEndpoints[0].visibility > ipEndpoints[0]?.visibility
288
- ) {
280
+ if (hostnameEndpoints.length > 0) {
289
281
  const hostnamePortInfos: ServicePortInfo[] = []
290
282
  for (const endpoint of hostnameEndpoints) {
291
283
  hostnamePortInfos.push(toServicePortInfoFromEndpoint(endpoint))
@@ -326,7 +318,7 @@ async function createServiceFromEndpoints(
326
318
  {
327
319
  metadata: mapMetadata({ namespace }, endpointsName),
328
320
  subsets: ipEndpoints.map(endpoint => ({
329
- addresses: [{ ip: endpoint.address }],
321
+ addresses: [{ ip: endpoint.address.value }],
330
322
  ports: [l4EndpointToServicePort(endpoint)],
331
323
  })),
332
324
  },
package/src/job.ts CHANGED
@@ -36,25 +36,26 @@ export type CreateOrGetJobArgs = JobArgs & {
36
36
  /**
37
37
  * The job entity to patch/retrieve.
38
38
  */
39
- existing: Input<k8s.ScopedResource> | undefined
39
+ existing: Input<k8s.NamespacedResource> | undefined
40
40
  }
41
41
 
42
42
  /**
43
43
  * Represents a Kubernetes Job resource with metadata and spec.
44
44
  */
45
45
  export abstract class Job extends Workload {
46
+ static apiVersion = "batch/v1"
47
+ static kind = "Job"
48
+
46
49
  protected constructor(
47
50
  type: string,
48
51
  name: string,
49
52
  args: Inputs,
50
53
  opts: ComponentResourceOptions | undefined,
51
54
 
52
- apiVersion: Output<string>,
53
- kind: Output<string>,
55
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
56
+ namespace: Output<Namespace>,
54
57
  terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,
55
58
  containers: Output<Container[]>,
56
- namespace: Output<Namespace>,
57
- metadata: Output<types.output.meta.v1.ObjectMeta>,
58
59
  networkPolicy: Output<NetworkPolicy | undefined>,
59
60
 
60
61
  /**
@@ -72,12 +73,10 @@ export abstract class Job extends Workload {
72
73
  name,
73
74
  args,
74
75
  opts,
75
- apiVersion,
76
- kind,
76
+ metadata,
77
+ namespace,
77
78
  terminalArgs,
78
79
  containers,
79
- namespace,
80
- metadata,
81
80
  spec.template,
82
81
  networkPolicy,
83
82
  )
@@ -90,13 +89,8 @@ export abstract class Job extends Workload {
90
89
  /**
91
90
  * The Highstate job entity.
92
91
  */
93
- get entity(): Output<k8s.ScopedResource> {
94
- return output({
95
- type: "job",
96
- clusterId: this.cluster.id,
97
- clusterName: this.cluster.name,
98
- metadata: this.metadata,
99
- })
92
+ get entity(): Output<k8s.Job> {
93
+ return output(this.entityBase)
100
94
  }
101
95
 
102
96
  protected getTerminalMeta(): Output<UnitTerminal["meta"]> {
@@ -203,7 +197,7 @@ export abstract class Job extends Workload {
203
197
  * @param entity The entity to get the job for.
204
198
  * @param cluster The cluster where the job is located.
205
199
  */
206
- static for(entity: k8s.ScopedResource, cluster: Input<k8s.Cluster>): Job {
200
+ static for(entity: k8s.NamespacedResource, cluster: Input<k8s.Cluster>): Job {
207
201
  return getOrCreate(
208
202
  Job.jobCache,
209
203
  `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,
@@ -228,7 +222,7 @@ export abstract class Job extends Workload {
228
222
  * @param cluster The cluster where the job is located.
229
223
  */
230
224
  static async forAsync(
231
- entity: Input<k8s.ScopedResource>,
225
+ entity: Input<k8s.NamespacedResource>,
232
226
  cluster: Input<k8s.Cluster>,
233
227
  ): Promise<Job> {
234
228
  const resolvedEntity = await toPromise(entity)
@@ -277,15 +271,11 @@ class CreatedJob extends Job {
277
271
  name,
278
272
  args,
279
273
  opts,
280
-
281
- job.apiVersion,
282
- job.kind,
274
+ job.metadata,
275
+ output(args.namespace),
283
276
  output(args.terminal ?? {}),
284
277
  containers,
285
- output(args.namespace),
286
- job.metadata,
287
278
  networkPolicy,
288
-
289
279
  job.spec,
290
280
  job.status,
291
281
  )
@@ -323,15 +313,11 @@ class JobPatch extends Job {
323
313
  name,
324
314
  args,
325
315
  opts,
326
-
327
- job.apiVersion,
328
- job.kind,
316
+ job.metadata,
317
+ output(args.namespace),
329
318
  output(args.terminal ?? {}),
330
319
  containers,
331
- output(args.namespace),
332
- job.metadata,
333
320
  networkPolicy,
334
-
335
321
  job.spec,
336
322
  job.status,
337
323
  )
@@ -369,12 +355,10 @@ class WrappedJob extends Job {
369
355
  args,
370
356
  opts,
371
357
 
372
- output(args.job).apiVersion,
373
- output(args.job).kind,
358
+ output(args.job).metadata,
359
+ output(args.namespace),
374
360
  output(args.terminal ?? {}),
375
361
  output([]),
376
- output(args.namespace),
377
- output(args.job).metadata,
378
362
  output(undefined),
379
363
 
380
364
  output(args.job).spec,
@@ -411,12 +395,10 @@ class ExternalJob extends Job {
411
395
  args,
412
396
  opts,
413
397
 
414
- job.apiVersion,
415
- job.kind,
398
+ job.metadata,
399
+ output(args.namespace),
416
400
  output({}),
417
401
  output([]),
418
- output(args.namespace),
419
- job.metadata,
420
402
  output(undefined),
421
403
 
422
404
  job.spec,
package/src/namespace.ts CHANGED
@@ -3,7 +3,6 @@ import { getOrCreate } from "@highstate/contract"
3
3
  import { toPromise } from "@highstate/pulumi"
4
4
  import { core, type types } from "@pulumi/kubernetes"
5
5
  import {
6
- ComponentResource,
7
6
  type ComponentResourceOptions,
8
7
  type Input,
9
8
  type Inputs,
@@ -11,7 +10,13 @@ import {
11
10
  output,
12
11
  type Unwrap,
13
12
  } from "@pulumi/pulumi"
14
- import { getProvider, mapMetadata, type ScopedResourceArgs, validateCluster } from "./shared"
13
+ import {
14
+ getProvider,
15
+ mapMetadata,
16
+ Resource,
17
+ type ScopedResourceArgs,
18
+ validateCluster,
19
+ } from "./shared"
15
20
 
16
21
  export type NamespaceArgs = Omit<ScopedResourceArgs, "namespace"> & {
17
22
  /**
@@ -31,7 +36,7 @@ export type CreateOrGetNamespaceArgs = NamespaceArgs & {
31
36
  *
32
37
  * If not provided, the namespace will be created, otherwise it will be retrieved/patched.
33
38
  */
34
- resource?: Input<k8s.ScopedResource>
39
+ resource?: Input<k8s.NamespacedResource>
35
40
 
36
41
  /**
37
42
  * The namespace entity to patch/retrieve.
@@ -39,22 +44,18 @@ export type CreateOrGetNamespaceArgs = NamespaceArgs & {
39
44
  existing?: Input<k8s.Namespace> | undefined
40
45
  }
41
46
 
42
- export abstract class Namespace extends ComponentResource {
47
+ export abstract class Namespace extends Resource {
48
+ static readonly apiVersion = "v1"
49
+ static readonly kind = "Namespace"
50
+
43
51
  constructor(
44
52
  type: string,
45
53
  name: string,
46
54
  args: Inputs,
47
55
  opts: ComponentResourceOptions | undefined,
48
56
 
49
- /**
50
- * The cluster where the namespace is created.
51
- */
52
- readonly cluster: Output<k8s.Cluster>,
53
-
54
- /*
55
- * The metadata of the underlying Kubernetes namespace.
56
- */
57
- readonly metadata: Output<types.output.meta.v1.ObjectMeta>,
57
+ cluster: Output<k8s.Cluster>,
58
+ metadata: Output<types.output.meta.v1.ObjectMeta>,
58
59
 
59
60
  /**
60
61
  * The spec of the underlying Kubernetes namespace.
@@ -66,19 +67,14 @@ export abstract class Namespace extends ComponentResource {
66
67
  */
67
68
  readonly status: Output<types.output.core.v1.NamespaceStatus>,
68
69
  ) {
69
- super(type, name, args, opts)
70
+ super(type, name, args, opts, cluster, metadata)
70
71
  }
71
72
 
72
73
  /**
73
74
  * The Highstate namespace entity.
74
75
  */
75
76
  get entity(): Output<k8s.Namespace> {
76
- return output({
77
- type: "namespace",
78
- clusterId: this.cluster.id,
79
- clusterName: this.cluster.name,
80
- metadata: this.metadata,
81
- })
77
+ return output(this.entityBase) as Output<k8s.Namespace>
82
78
  }
83
79
 
84
80
  /**
@@ -236,7 +232,7 @@ export abstract class Namespace extends ComponentResource {
236
232
  * @param resource The resource to get the namespace for.
237
233
  * @param cluster The cluster where the namespace is located.
238
234
  */
239
- static forResource(resource: k8s.ScopedResource, cluster: Input<k8s.Cluster>): Namespace {
235
+ static forResource(resource: k8s.NamespacedResource, cluster: Input<k8s.Cluster>): Namespace {
240
236
  return getOrCreate(
241
237
  Namespace.namespaceCache,
242
238
  `${resource.clusterName}.${resource.metadata.namespace}.${resource.clusterId}`,
@@ -257,7 +253,7 @@ export abstract class Namespace extends ComponentResource {
257
253
  * @param cluster The cluster where the namespace is located.
258
254
  */
259
255
  static async forResourceAsync(
260
- resource: Input<k8s.ScopedResource>,
256
+ resource: Input<k8s.NamespacedResource>,
261
257
  cluster: Input<k8s.Cluster>,
262
258
  ): Promise<Namespace> {
263
259
  const resolvedResource = await toPromise(resource)
@@ -1,11 +1,12 @@
1
1
  import type { k8s, network } from "@highstate/library"
2
2
  import type { Namespace } from "./namespace"
3
3
  import {
4
+ addressToCidr,
5
+ endpointToString,
4
6
  ImplementationMediator,
5
- type InputL34Endpoint,
7
+ type InputEndpoint,
6
8
  l3EndpointToCidr,
7
- l34EndpointToString,
8
- parseL34Endpoint,
9
+ parseEndpoint,
9
10
  } from "@highstate/common"
10
11
  import { z } from "@highstate/contract"
11
12
  import {
@@ -22,7 +23,7 @@ import {
22
23
  type Unwrap,
23
24
  } from "@highstate/pulumi"
24
25
  import { type core, networking, type types } from "@pulumi/kubernetes"
25
- import { flat, groupBy, merge, mergeDeep, uniqueBy } from "remeda"
26
+ import { flat, groupBy, isNonNullish, merge, mergeDeep, uniqueBy } from "remeda"
26
27
  import { requireBestEndpoint } from "./network"
27
28
  import { isEndpointFromCluster, mapServiceToLabelSelector } from "./service"
28
29
  import {
@@ -90,7 +91,7 @@ export type IngressRuleArgs = {
90
91
  * If a single endpoint also has a port/protocol/service metadata,
91
92
  * it will produce separate rule for it with them and ORed with the rest of the rules.
92
93
  */
93
- fromEndpoint?: Input<InputL34Endpoint>
94
+ fromEndpoint?: Input<InputEndpoint>
94
95
 
95
96
  /**
96
97
  * The list of allowed L3 or L4 endpoints for incoming traffic.
@@ -102,7 +103,7 @@ export type IngressRuleArgs = {
102
103
  * If a single endpoint also has a port/protocol/service metadata,
103
104
  * it will produce separate rule for it with them and ORed with the rest of the rules.
104
105
  */
105
- fromEndpoints?: InputArray<InputL34Endpoint>
106
+ fromEndpoints?: InputArray<InputEndpoint>
106
107
 
107
108
  /**
108
109
  * The service to allow traffic from.
@@ -219,7 +220,7 @@ export type EgressRuleArgs = {
219
220
  * If a single endpoint also has a port/protocol/service metadata,
220
221
  * it will produce separate rule for it with them and ORed with the rest of the rules.
221
222
  */
222
- toEndpoint?: Input<InputL34Endpoint>
223
+ toEndpoint?: Input<InputEndpoint>
223
224
 
224
225
  /**
225
226
  * The list of allowed L3 or L4 endpoints for outgoing traffic.
@@ -231,7 +232,7 @@ export type EgressRuleArgs = {
231
232
  * If a single endpoint also has a port/protocol/service metadata,
232
233
  * it will produce separate rule for it with them and ORed with the rest of the rules.
233
234
  */
234
- toEndpoints?: InputArray<InputL34Endpoint>
235
+ toEndpoints?: InputArray<InputEndpoint>
235
236
 
236
237
  /**
237
238
  * The service to allow traffic to.
@@ -443,7 +444,7 @@ export class NetworkPolicy extends ComponentResource {
443
444
 
444
445
  ingressRules: ingressRules.flatMap(rule => {
445
446
  const endpoints = normalize(rule?.fromEndpoint, rule?.fromEndpoints)
446
- const parsedEndpoints = endpoints.map(parseL34Endpoint)
447
+ const parsedEndpoints = endpoints.map(endpoint => parseEndpoint(endpoint))
447
448
 
448
449
  const endpointsNamespaces = groupBy(parsedEndpoints, endpoint => {
449
450
  const namespace = isEndpointFromCluster(endpoint, cluster)
@@ -481,7 +482,7 @@ export class NetworkPolicy extends ComponentResource {
481
482
  egressRules: egressRules
482
483
  .flatMap(rule => {
483
484
  const endpoints = normalize(rule?.toEndpoint, rule?.toEndpoints)
484
- const parsedEndpoints = endpoints.map(parseL34Endpoint)
485
+ const parsedEndpoints = endpoints.map(endpoint => parseEndpoint(endpoint))
485
486
 
486
487
  const endpointsByPortsAnsNamespaces = groupBy(parsedEndpoints, endpoint => {
487
488
  const namespace = isEndpointFromCluster(endpoint, cluster)
@@ -490,7 +491,9 @@ export class NetworkPolicy extends ComponentResource {
490
491
 
491
492
  const port = isEndpointFromCluster(endpoint, cluster)
492
493
  ? endpoint.metadata["k8s.service"].targetPort
493
- : endpoint.port
494
+ : endpoint.level !== 3
495
+ ? endpoint.port
496
+ : undefined
494
497
 
495
498
  return `${port ?? "0"}:${namespace}`
496
499
  })
@@ -554,30 +557,24 @@ export class NetworkPolicy extends ComponentResource {
554
557
  )
555
558
  }
556
559
 
557
- private static mapCidrFromEndpoint(
558
- this: void,
559
- result: network.L3Endpoint & { type: "ipv4" | "ipv6" },
560
- ): string {
561
- if (result.type === "ipv4") {
562
- return `${result.address}/32`
563
- }
564
-
565
- return `${result.address}/128`
566
- }
567
-
568
560
  private static getRuleFromEndpoint(
569
561
  port: number | string | undefined,
570
- endpoints: network.L34Endpoint[],
562
+ endpoints: network.L3Endpoint[],
571
563
  cluster: k8s.Cluster,
572
564
  ): NormalizedRuleArgs {
573
565
  const ports: NetworkPolicyPort[] = port
574
- ? [{ port, protocol: endpoints[0].protocol?.toUpperCase() }]
566
+ ? [
567
+ {
568
+ port,
569
+ protocol: endpoints[0].level !== 3 ? endpoints[0].protocol?.toUpperCase() : undefined,
570
+ },
571
+ ]
575
572
  : []
576
573
 
577
574
  const cidrs = endpoints
578
575
  .filter(endpoint => !isEndpointFromCluster(endpoint, cluster))
579
- .filter(endpoint => endpoint.type === "ipv4" || endpoint.type === "ipv6")
580
- .map(NetworkPolicy.mapCidrFromEndpoint)
576
+ .map(endpoint => (endpoint.address ? addressToCidr(endpoint.address) : null))
577
+ .filter(isNonNullish)
581
578
 
582
579
  const fqdns = endpoints
583
580
  .filter(endpoint => endpoint.type === "hostname")
@@ -784,11 +781,11 @@ export class NetworkPolicy extends ComponentResource {
784
781
  */
785
782
  static async allowEgressToEndpoint(
786
783
  namespace: Input<Namespace>,
787
- endpoint: InputL34Endpoint,
784
+ endpoint: InputEndpoint,
788
785
  opts?: ResourceOptions,
789
786
  ): Promise<NetworkPolicy> {
790
- const parsedEndpoint = parseL34Endpoint(endpoint)
791
- const endpointStr = l34EndpointToString(parsedEndpoint).replace(/:/g, "-")
787
+ const parsedEndpoint = parseEndpoint(endpoint)
788
+ const endpointStr = endpointToString(parsedEndpoint).replace(/:/g, "-")
792
789
  const nsName = await toPromise(output(namespace).metadata.name)
793
790
  const cluster = await toPromise(output(namespace).cluster)
794
791
 
@@ -796,7 +793,7 @@ export class NetworkPolicy extends ComponentResource {
796
793
  `allow-egress-to-${endpointStr}.${cluster.name}.${nsName}.${cluster.id}`,
797
794
  {
798
795
  namespace,
799
- description: `Allow egress traffic to "${l34EndpointToString(parsedEndpoint)}" from the namespace.`,
796
+ description: `Allow egress traffic to "${endpointToString(parsedEndpoint)}" from the namespace.`,
800
797
  egressRule: { toEndpoint: endpoint },
801
798
  },
802
799
  opts,
@@ -814,12 +811,16 @@ export class NetworkPolicy extends ComponentResource {
814
811
  */
815
812
  static async allowEgressToBestEndpoint(
816
813
  namespace: Input<Namespace>,
817
- endpoints: InputArray<InputL34Endpoint>,
814
+ endpoints: InputArray<InputEndpoint>,
818
815
  opts?: ResourceOptions,
819
816
  ): Promise<NetworkPolicy> {
820
817
  const cluster = await toPromise(output(namespace).cluster)
821
818
  const resolvedEndpoints = await toPromise(output(endpoints))
822
- const bestEndpoint = requireBestEndpoint(resolvedEndpoints.map(parseL34Endpoint), cluster)
819
+
820
+ const bestEndpoint = requireBestEndpoint(
821
+ resolvedEndpoints.map(endpoint => parseEndpoint(endpoint)),
822
+ cluster,
823
+ )
823
824
 
824
825
  return await NetworkPolicy.allowEgressToEndpoint(namespace, bestEndpoint, opts)
825
826
  }
@@ -835,11 +836,11 @@ export class NetworkPolicy extends ComponentResource {
835
836
  */
836
837
  static async allowIngressFromEndpoint(
837
838
  namespace: Input<Namespace>,
838
- endpoint: InputL34Endpoint,
839
+ endpoint: InputEndpoint,
839
840
  opts?: ResourceOptions,
840
841
  ): Promise<NetworkPolicy> {
841
- const parsedEndpoint = parseL34Endpoint(endpoint)
842
- const endpointStr = l34EndpointToString(parsedEndpoint).replace(/:/g, "-")
842
+ const parsedEndpoint = parseEndpoint(endpoint)
843
+ const endpointStr = endpointToString(parsedEndpoint).replace(/:/g, "-")
843
844
  const nsName = await toPromise(output(namespace).metadata.name)
844
845
  const cluster = await toPromise(output(namespace).cluster)
845
846
 
@@ -847,7 +848,7 @@ export class NetworkPolicy extends ComponentResource {
847
848
  `allow-ingress-from-${endpointStr}.${cluster.name}.${nsName}.${cluster.id}`,
848
849
  {
849
850
  namespace,
850
- description: interpolate`Allow ingress traffic from "${l34EndpointToString(parsedEndpoint)}" to the namespace.`,
851
+ description: interpolate`Allow ingress traffic from "${endpointToString(parsedEndpoint)}" to the namespace.`,
851
852
  ingressRule: { fromEndpoint: endpoint },
852
853
  },
853
854
  opts,
package/src/network.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import type { k8s, network } from "@highstate/library"
2
- import { filterEndpoints } from "@highstate/common"
3
2
  import { isEndpointFromCluster } from "./service"
4
3
 
5
- export function getBestEndpoint<TEndpoint extends network.L34Endpoint>(
4
+ export function getBestEndpoint<TEndpoint extends network.L3Endpoint>(
6
5
  endpoints: TEndpoint[],
7
6
  cluster?: k8s.Cluster,
8
7
  ): TEndpoint | undefined {
@@ -14,20 +13,29 @@ export function getBestEndpoint<TEndpoint extends network.L34Endpoint>(
14
13
  return endpoints[0]
15
14
  }
16
15
 
17
- if (!cluster) {
18
- return filterEndpoints(endpoints)[0]
19
- }
16
+ // try to find an endpoint from the same cluster and access it via internal endpoint
17
+ if (cluster) {
18
+ const clusterEndpoint = endpoints.find(
19
+ endpoint =>
20
+ isEndpointFromCluster(endpoint, cluster) && endpoint.metadata["k8s.service"].isInternal,
21
+ )
20
22
 
21
- const clusterEndpoint = endpoints.find(endpoint => isEndpointFromCluster(endpoint, cluster))
23
+ if (clusterEndpoint) {
24
+ return clusterEndpoint
25
+ }
26
+ }
22
27
 
23
- if (clusterEndpoint) {
24
- return clusterEndpoint
28
+ // if there is no internal endpoint, try to find any public endpoint
29
+ const publicEndpoint = endpoints.find(endpoint => endpoint.metadata["iana.scope"] === "global")
30
+ if (publicEndpoint) {
31
+ return publicEndpoint
25
32
  }
26
33
 
27
- return filterEndpoints(endpoints)[0]
34
+ // otherwise, return the first one
35
+ return endpoints[0]
28
36
  }
29
37
 
30
- export function requireBestEndpoint<TEndpoint extends network.L34Endpoint>(
38
+ export function requireBestEndpoint<TEndpoint extends network.L3Endpoint>(
31
39
  endpoints: TEndpoint[],
32
40
  cluster: k8s.Cluster,
33
41
  ): TEndpoint {
package/src/pvc.ts CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  commonExtraArgs,
18
18
  getProvider,
19
19
  mapMetadata,
20
- ScopedResource,
20
+ NamespacedResource,
21
21
  type ScopedResourceArgs,
22
22
  } from "./shared"
23
23
 
@@ -43,17 +43,18 @@ const extraPersistentVolumeClaimArgs = [...commonExtraArgs, "size"] as const
43
43
  /**
44
44
  * Represents a Kubernetes PersistentVolumeClaim resource with metadata and spec.
45
45
  */
46
- export abstract class PersistentVolumeClaim extends ScopedResource {
46
+ export abstract class PersistentVolumeClaim extends NamespacedResource {
47
+ static apiVersion = "v1"
48
+ static kind = "PersistentVolumeClaim"
49
+
47
50
  protected constructor(
48
51
  type: string,
49
52
  name: string,
50
53
  args: Inputs,
51
54
  opts: ComponentResourceOptions | undefined,
52
55
 
53
- apiVersion: Output<string>,
54
- kind: Output<string>,
55
- namespace: Output<Namespace>,
56
56
  metadata: Output<types.output.meta.v1.ObjectMeta>,
57
+ namespace: Output<Namespace>,
57
58
 
58
59
  /**
59
60
  * The spec of the underlying Kubernetes PVC.
@@ -65,19 +66,14 @@ export abstract class PersistentVolumeClaim extends ScopedResource {
65
66
  */
66
67
  readonly status: Output<types.output.core.v1.PersistentVolumeClaimStatus>,
67
68
  ) {
68
- super(type, name, args, opts, apiVersion, kind, namespace, metadata)
69
+ super(type, name, args, opts, metadata, namespace)
69
70
  }
70
71
 
71
72
  /**
72
73
  * The Highstate PVC entity.
73
74
  */
74
75
  get entity(): Output<k8s.PersistentVolumeClaim> {
75
- return output({
76
- type: "persistent-volume-claim",
77
- clusterId: this.cluster.id,
78
- clusterName: this.cluster.name,
79
- metadata: this.metadata,
80
- })
76
+ return output(this.entityBase)
81
77
  }
82
78
 
83
79
  /**
@@ -256,11 +252,8 @@ class CreatedPersistentVolumeClaim extends PersistentVolumeClaim {
256
252
  name,
257
253
  args,
258
254
  opts,
259
-
260
- pvc.apiVersion,
261
- pvc.kind,
262
- output(args.namespace),
263
255
  pvc.metadata,
256
+ output(args.namespace),
264
257
  pvc.spec,
265
258
  pvc.status,
266
259
  )
@@ -301,11 +294,8 @@ class PersistentVolumeClaimPatch extends PersistentVolumeClaim {
301
294
  name,
302
295
  args,
303
296
  opts,
304
-
305
- pvc.apiVersion,
306
- pvc.kind,
307
- output(args.namespace),
308
297
  pvc.metadata,
298
+ output(args.namespace),
309
299
  pvc.spec,
310
300
  pvc.status,
311
301
  )
@@ -335,11 +325,8 @@ class WrappedPersistentVolumeClaim extends PersistentVolumeClaim {
335
325
  name,
336
326
  args,
337
327
  opts,
338
-
339
- output(args.pvc).apiVersion,
340
- output(args.pvc).kind,
341
- output(args.namespace),
342
328
  output(args.pvc).metadata,
329
+ output(args.namespace),
343
330
  output(args.pvc).spec,
344
331
  output(args.pvc).status,
345
332
  )
@@ -377,11 +364,8 @@ class ExternalPersistentVolumeClaim extends PersistentVolumeClaim {
377
364
  name,
378
365
  args,
379
366
  opts,
380
-
381
- pvc.apiVersion,
382
- pvc.kind,
383
- output(args.namespace),
384
367
  pvc.metadata,
368
+ output(args.namespace),
385
369
  pvc.spec,
386
370
  pvc.status,
387
371
  )