@highstate/k8s 0.9.18 → 0.9.20

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 (93) hide show
  1. package/dist/chunk-2EEHJZPD.js +13 -0
  2. package/dist/chunk-2EEHJZPD.js.map +1 -0
  3. package/dist/{chunk-OFFSHGC6.js → chunk-4JGXGN2L.js} +66 -48
  4. package/dist/chunk-4JGXGN2L.js.map +1 -0
  5. package/dist/chunk-A3XGSDIW.js +306 -0
  6. package/dist/chunk-A3XGSDIW.js.map +1 -0
  7. package/dist/chunk-IMTXUK2U.js +244 -0
  8. package/dist/chunk-IMTXUK2U.js.map +1 -0
  9. package/dist/chunk-JYNXQ3I3.js +287 -0
  10. package/dist/chunk-JYNXQ3I3.js.map +1 -0
  11. package/dist/{chunk-5C2BJGES.js → chunk-KDD6XUWM.js} +30 -23
  12. package/dist/chunk-KDD6XUWM.js.map +1 -0
  13. package/dist/chunk-NOFJC3EM.js +236 -0
  14. package/dist/chunk-NOFJC3EM.js.map +1 -0
  15. package/dist/chunk-NXSYCA3V.js +337 -0
  16. package/dist/chunk-NXSYCA3V.js.map +1 -0
  17. package/dist/chunk-SBC3TUIN.js +1513 -0
  18. package/dist/chunk-SBC3TUIN.js.map +1 -0
  19. package/dist/chunk-SI7X6N46.js +338 -0
  20. package/dist/chunk-SI7X6N46.js.map +1 -0
  21. package/dist/chunk-WGMJCZSK.js +360 -0
  22. package/dist/chunk-WGMJCZSK.js.map +1 -0
  23. package/dist/deployment-752P6JIT.js +8 -0
  24. package/dist/{deployment-XK3CDJOE.js.map → deployment-752P6JIT.js.map} +1 -1
  25. package/dist/highstate.manifest.json +8 -7
  26. package/dist/impl/gateway-route.js +123 -0
  27. package/dist/impl/gateway-route.js.map +1 -0
  28. package/dist/impl/tls-certificate.js +32 -0
  29. package/dist/impl/tls-certificate.js.map +1 -0
  30. package/dist/index.js +736 -208
  31. package/dist/index.js.map +1 -1
  32. package/dist/stateful-set-N64YVKR7.js +8 -0
  33. package/dist/{stateful-set-7CAQWTV2.js.map → stateful-set-N64YVKR7.js.map} +1 -1
  34. package/dist/units/cert-manager/index.js +11 -10
  35. package/dist/units/cert-manager/index.js.map +1 -1
  36. package/dist/units/dns01-issuer/index.js +27 -23
  37. package/dist/units/dns01-issuer/index.js.map +1 -1
  38. package/dist/units/existing-cluster/index.js +11 -8
  39. package/dist/units/existing-cluster/index.js.map +1 -1
  40. package/dist/units/gateway-api/index.js +2 -2
  41. package/dist/units/gateway-api/index.js.map +1 -1
  42. package/package.json +39 -13
  43. package/src/cluster.ts +30 -22
  44. package/src/config-map.ts +195 -57
  45. package/src/container.ts +5 -5
  46. package/src/cron-job.ts +403 -31
  47. package/src/deployment.ts +260 -120
  48. package/src/dns01-solver.ts +10 -0
  49. package/src/gateway/backend.ts +2 -2
  50. package/src/gateway/gateway.ts +383 -0
  51. package/src/gateway/http-route.ts +17 -24
  52. package/src/gateway/index.ts +1 -0
  53. package/src/helm.ts +83 -53
  54. package/src/impl/gateway-route.ts +155 -0
  55. package/src/impl/tls-certificate.ts +33 -0
  56. package/src/index.ts +22 -67
  57. package/src/job.ts +393 -28
  58. package/src/namespace.ts +236 -99
  59. package/src/network-policy.ts +216 -165
  60. package/src/network.ts +2 -2
  61. package/src/pvc.ts +266 -65
  62. package/src/rbac.ts +218 -0
  63. package/src/scripting/bundle.ts +9 -20
  64. package/src/scripting/container.ts +1 -1
  65. package/src/scripting/environment.ts +5 -5
  66. package/src/secret.ts +200 -62
  67. package/src/service.ts +288 -158
  68. package/src/shared.ts +94 -67
  69. package/src/stateful-set.ts +270 -117
  70. package/src/tls.ts +344 -0
  71. package/src/units/cert-manager/index.ts +2 -3
  72. package/src/units/dns01-issuer/index.ts +30 -14
  73. package/src/units/existing-cluster/index.ts +10 -7
  74. package/src/units/gateway-api/index.ts +2 -2
  75. package/src/worker.ts +26 -0
  76. package/src/workload.ts +275 -171
  77. package/dist/chunk-5C2BJGES.js.map +0 -1
  78. package/dist/chunk-5TLC5BXR.js +0 -256
  79. package/dist/chunk-5TLC5BXR.js.map +0 -1
  80. package/dist/chunk-BBIY3KUN.js +0 -1557
  81. package/dist/chunk-BBIY3KUN.js.map +0 -1
  82. package/dist/chunk-OFFSHGC6.js.map +0 -1
  83. package/dist/chunk-TZHOUJRC.js +0 -202
  84. package/dist/chunk-TZHOUJRC.js.map +0 -1
  85. package/dist/chunk-YWRJ4EZM.js +0 -192
  86. package/dist/chunk-YWRJ4EZM.js.map +0 -1
  87. package/dist/deployment-XK3CDJOE.js +0 -6
  88. package/dist/stateful-set-7CAQWTV2.js +0 -6
  89. package/dist/units/access-point/index.js +0 -21
  90. package/dist/units/access-point/index.js.map +0 -1
  91. package/src/access-point.ts +0 -191
  92. package/src/units/access-point/index.ts +0 -19
  93. package/src/units/dns01-issuer/solver.ts +0 -23
@@ -1,9 +1,11 @@
1
- import { networking, types, type core } from "@pulumi/kubernetes"
1
+ import type { Namespace } from "./namespace"
2
+ import { networking, type types, type core } from "@pulumi/kubernetes"
2
3
  import {
3
4
  ComponentResource,
4
5
  interpolate,
5
6
  normalize,
6
7
  output,
8
+ toPromise,
7
9
  type Input,
8
10
  type InputArray,
9
11
  type Output,
@@ -11,25 +13,27 @@ import {
11
13
  type ResourceOptions,
12
14
  type Unwrap,
13
15
  } from "@highstate/pulumi"
14
- import { capitalize, flat, groupBy, merge, mergeDeep, uniqueBy } from "remeda"
15
- import { k8s, network } from "@highstate/library"
16
+ import { flat, groupBy, merge, mergeDeep, uniqueBy } from "remeda"
17
+ import type { k8s, network } from "@highstate/library"
16
18
  import {
17
19
  l34EndpointToString,
18
20
  l3EndpointToCidr,
19
21
  parseL34Endpoint,
20
22
  type InputL34Endpoint,
23
+ ImplementationMediator,
21
24
  } from "@highstate/common"
25
+ import { z } from "@highstate/contract"
22
26
  import {
23
- getProvider,
27
+ getProviderAsync,
24
28
  mapMetadata,
25
- mapNamespaceLikeToNamespaceName,
29
+ getNamespaceName,
26
30
  mapNamespaceNameToSelector,
27
31
  mapSelectorLikeToSelector,
28
- type CommonArgs,
32
+ type ScopedResourceArgs,
29
33
  type NamespaceLike,
30
34
  type SelectorLike,
31
35
  } from "./shared"
32
- import { getServiceMetadata, isFromCluster, mapServiceToLabelSelector } from "./service"
36
+ import { isEndpointFromCluster, mapServiceToLabelSelector } from "./service"
33
37
  import { requireBestEndpoint } from "./network"
34
38
 
35
39
  export type NetworkPolicyPort = {
@@ -295,7 +299,7 @@ export type EgressRuleArgs = {
295
299
  toPorts?: InputArray<NetworkPolicyPort>
296
300
  }
297
301
 
298
- export type NetworkPolicyArgs = CommonArgs & {
302
+ export type NetworkPolicyArgs = ScopedResourceArgs & {
299
303
  /**
300
304
  * The description of this network policy.
301
305
  */
@@ -350,11 +354,6 @@ export type NetworkPolicyArgs = CommonArgs & {
350
354
  * By default, `false`.
351
355
  */
352
356
  allowKubeDns?: Input<boolean>
353
-
354
- /**
355
- * The cluster to create the network policy in.
356
- */
357
- cluster: Input<k8s.Cluster>
358
357
  }
359
358
 
360
359
  export type NormalizedRuleArgs = {
@@ -379,6 +378,7 @@ export type NormalizedNetworkPolicyArgs = Omit<
379
378
  | "allowKubeApiServer"
380
379
  | "allowKubeDNS"
381
380
  > & {
381
+ cluster: k8s.Cluster
382
382
  podSelector: Unwrap<types.input.meta.v1.LabelSelector>
383
383
 
384
384
  isolateIngress: boolean
@@ -390,24 +390,31 @@ export type NormalizedNetworkPolicyArgs = Omit<
390
390
  egressRules: NormalizedRuleArgs[]
391
391
  }
392
392
 
393
+ export const networkPolicyMediator = new ImplementationMediator(
394
+ "network-policy",
395
+ z.object({ name: z.string(), args: z.custom<NormalizedNetworkPolicyArgs>() }),
396
+ z.instanceof(ComponentResource),
397
+ )
398
+
393
399
  /**
394
- * The abstract resource for creating network policies.
395
- * Will use different resources depending on the environment.
400
+ * The resource for creating network policies.
401
+ * Will use different resources depending on the cluster configuration.
396
402
  *
397
403
  * Note: In the worst case, it will create native `NetworkPolicy` resources and ignore some features like L7 rules.
398
404
  */
399
- export abstract class NetworkPolicy extends ComponentResource {
405
+ export class NetworkPolicy extends ComponentResource {
400
406
  /**
401
407
  * The underlying network policy resource.
402
408
  */
403
409
  public readonly networkPolicy: Output<Resource>
404
410
 
405
- protected constructor(name: string, args: Unwrap<NetworkPolicyArgs>, opts?: ResourceOptions) {
411
+ constructor(name: string, args: NetworkPolicyArgs, opts?: ResourceOptions) {
406
412
  super("k8s:network-policy", name, args, opts)
407
413
 
408
- const normalizedArgs = output(args).apply(args => {
414
+ const normalizedArgs = output(args).apply(async args => {
409
415
  const ingressRules = normalize(args.ingressRule, args.ingressRules)
410
416
  const egressRules = normalize(args.egressRule, args.egressRules)
417
+ const cluster = await toPromise(args.namespace.cluster)
411
418
 
412
419
  const extraEgressRules: NormalizedRuleArgs[] = []
413
420
 
@@ -427,6 +434,7 @@ export abstract class NetworkPolicy extends ComponentResource {
427
434
  ...args,
428
435
 
429
436
  podSelector: args.selector ? mapSelectorLikeToSelector(args.selector) : {},
437
+ cluster,
430
438
 
431
439
  isolateEgress: args.isolateEgress ?? false,
432
440
  isolateIngress: args.isolateIngress ?? false,
@@ -438,21 +446,21 @@ export abstract class NetworkPolicy extends ComponentResource {
438
446
  const parsedEndpoints = endpoints.map(parseL34Endpoint)
439
447
 
440
448
  const endpointsNamespaces = groupBy(parsedEndpoints, endpoint => {
441
- const namespace = isFromCluster(endpoint, args.cluster)
442
- ? endpoint.metadata.k8sService.namespace
449
+ const namespace = isEndpointFromCluster(endpoint, cluster)
450
+ ? endpoint.metadata["k8s.service"].namespace
443
451
  : ""
444
452
 
445
453
  return namespace
446
454
  })
447
455
 
448
456
  const l3OnlyRule = endpointsNamespaces[""]
449
- ? NetworkPolicy.getRuleFromEndpoint(undefined, endpointsNamespaces[""], args.cluster)
457
+ ? NetworkPolicy.getRuleFromEndpoint(undefined, endpointsNamespaces[""], cluster)
450
458
  : undefined
451
459
 
452
460
  const otherRules = Object.entries(endpointsNamespaces)
453
461
  .filter(([key]) => key !== "")
454
462
  .map(([, endpoints]) => {
455
- return NetworkPolicy.getRuleFromEndpoint(undefined, endpoints, args.cluster)
463
+ return NetworkPolicy.getRuleFromEndpoint(undefined, endpoints, cluster)
456
464
  })
457
465
 
458
466
  return [
@@ -476,12 +484,12 @@ export abstract class NetworkPolicy extends ComponentResource {
476
484
  const parsedEndpoints = endpoints.map(parseL34Endpoint)
477
485
 
478
486
  const endpointsByPortsAnsNamespaces = groupBy(parsedEndpoints, endpoint => {
479
- const namespace = isFromCluster(endpoint, args.cluster)
480
- ? endpoint.metadata.k8sService.namespace
487
+ const namespace = isEndpointFromCluster(endpoint, cluster)
488
+ ? endpoint.metadata["k8s.service"].namespace
481
489
  : ""
482
490
 
483
- const port = isFromCluster(endpoint, args.cluster)
484
- ? endpoint.metadata.k8sService.targetPort
491
+ const port = isEndpointFromCluster(endpoint, cluster)
492
+ ? endpoint.metadata["k8s.service"].targetPort
485
493
  : endpoint.port
486
494
 
487
495
  return `${port ?? "0"}:${namespace}`
@@ -491,7 +499,7 @@ export abstract class NetworkPolicy extends ComponentResource {
491
499
  ? NetworkPolicy.getRuleFromEndpoint(
492
500
  undefined,
493
501
  endpointsByPortsAnsNamespaces["0:"],
494
- args.cluster,
502
+ cluster,
495
503
  )
496
504
  : undefined
497
505
 
@@ -500,9 +508,9 @@ export abstract class NetworkPolicy extends ComponentResource {
500
508
  .map(([key, endpoints]) => {
501
509
  const [port] = key.split(":")
502
510
  const portNumber = parseInt(port, 10)
503
- const portValue = isNaN(portNumber) ? port : portNumber
511
+ const portValue = Number.isNaN(portNumber) ? port : portNumber
504
512
 
505
- return NetworkPolicy.getRuleFromEndpoint(portValue, endpoints, args.cluster)
513
+ return NetworkPolicy.getRuleFromEndpoint(portValue, endpoints, cluster)
506
514
  })
507
515
 
508
516
  return [
@@ -525,13 +533,23 @@ export abstract class NetworkPolicy extends ComponentResource {
525
533
 
526
534
  this.networkPolicy = output(
527
535
  normalizedArgs.apply(async args => {
528
- return output(
529
- this.create(name, args as NormalizedNetworkPolicyArgs, {
530
- ...opts,
531
- parent: this,
532
- provider: await getProvider(args.cluster),
533
- }),
534
- )
536
+ const cluster = args.cluster
537
+
538
+ // Check if cluster has a custom network policy implementation
539
+ if (cluster.networkPolicyImplRef) {
540
+ return networkPolicyMediator.call(cluster.networkPolicyImplRef, {
541
+ name,
542
+ args: args as NormalizedNetworkPolicyArgs,
543
+ })
544
+ }
545
+
546
+ // Fallback to native network policy
547
+ const nativePolicy = new NativeNetworkPolicy(name, args as NormalizedNetworkPolicyArgs, {
548
+ ...opts,
549
+ parent: this,
550
+ provider: await getProviderAsync(output(args.namespace).cluster),
551
+ })
552
+ return nativePolicy.networkPolicy
535
553
  }),
536
554
  )
537
555
  }
@@ -557,7 +575,7 @@ export abstract class NetworkPolicy extends ComponentResource {
557
575
  : []
558
576
 
559
577
  const cidrs = endpoints
560
- .filter(endpoint => !isFromCluster(endpoint, cluster))
578
+ .filter(endpoint => !isEndpointFromCluster(endpoint, cluster))
561
579
  .filter(endpoint => endpoint.type === "ipv4" || endpoint.type === "ipv6")
562
580
  .map(NetworkPolicy.mapCidrFromEndpoint)
563
581
 
@@ -566,12 +584,12 @@ export abstract class NetworkPolicy extends ComponentResource {
566
584
  .map(endpoint => endpoint.hostname)
567
585
 
568
586
  const selectors = endpoints
569
- .filter(endpoint => isFromCluster(endpoint, cluster))
570
- .map(endpoint => endpoint.metadata.k8sService.selector)
587
+ .filter(endpoint => isEndpointFromCluster(endpoint, cluster))
588
+ .map(endpoint => endpoint.metadata["k8s.service"].selector)
571
589
 
572
590
  const namespace = endpoints
573
- .filter(endpoint => isFromCluster(endpoint, cluster))
574
- .map(endpoint => getServiceMetadata(endpoint)?.namespace)[0]
591
+ .filter(endpoint => isEndpointFromCluster(endpoint, cluster))
592
+ .map(endpoint => endpoint.metadata["k8s.service"].namespace)[0]
575
593
 
576
594
  return {
577
595
  all: false,
@@ -596,52 +614,25 @@ export abstract class NetworkPolicy extends ComponentResource {
596
614
  )
597
615
  }
598
616
 
599
- protected abstract create(
600
- name: string,
601
- args: NormalizedNetworkPolicyArgs,
602
- opts?: ResourceOptions,
603
- ): Input<Resource>
604
-
605
- static create(
606
- name: string,
607
- args: NetworkPolicyArgs,
617
+ /**
618
+ * Creates network policy to isolate the namespace by denying all traffic to/from it.
619
+ *
620
+ * Automatically names the policy as: `isolate-namespace.{clusterName}.{namespace}.{clusterId}`.
621
+ *
622
+ * @param namespace The namespace to isolate.
623
+ * @param opts Optional resource options.
624
+ */
625
+ static async isolateNamespace(
626
+ namespace: Input<Namespace>,
608
627
  opts?: ResourceOptions,
609
- ): Output<NetworkPolicy> {
610
- return output(args).apply(async args => {
611
- const cni = args.cluster.cni
612
-
613
- if (cni === "other") {
614
- return new NativeNetworkPolicy(name, args, opts)
615
- }
616
-
617
- const implName = `${capitalize(cni)}NetworkPolicy`
618
- const implModule = (await import(`@highstate/${cni}`)) as Record<string, unknown>
619
-
620
- type NetworkPolicyFactory = new (
621
- name: string,
622
- args: Unwrap<NetworkPolicyArgs>,
623
- opts?: ResourceOptions,
624
- ) => NetworkPolicy
625
-
626
- const implClass = implModule[implName] as NetworkPolicyFactory | undefined
627
- if (!implClass) {
628
- throw new Error(`No implementation found for ${cni}`)
629
- }
628
+ ): Promise<NetworkPolicy> {
629
+ const name = await toPromise(output(namespace).metadata.name)
630
+ const cluster = await toPromise(output(namespace).cluster)
630
631
 
631
- return new implClass(name, args, opts)
632
- })
633
- }
634
-
635
- static isolate(
636
- namespace: Input<NamespaceLike>,
637
- cluster: Input<k8s.Cluster>,
638
- opts?: ResourceOptions,
639
- ) {
640
- return NetworkPolicy.create(
641
- "isolate",
632
+ return new NetworkPolicy(
633
+ `isolate-namespace.${cluster.name}.${name}.${cluster.id}`,
642
634
  {
643
635
  namespace,
644
- cluster,
645
636
 
646
637
  description: "By default, deny all traffic to/from the namespace.",
647
638
 
@@ -652,20 +643,26 @@ export abstract class NetworkPolicy extends ComponentResource {
652
643
  )
653
644
  }
654
645
 
655
- static allowInsideNamespace(
656
- namespace: Input<NamespaceLike>,
657
- cluster: Input<k8s.Cluster>,
646
+ /**
647
+ * Creates network policy to allow all traffic inside the namespace (pod to pod within same namespace).
648
+ *
649
+ * Automatically names the policy as: `allow-inside-namespace.{clusterName}.{namespace}.{clusterId}`.
650
+ *
651
+ * @param namespace The namespace to create the policy in.
652
+ * @param opts Optional resource options.
653
+ */
654
+ static async allowInsideNamespace(
655
+ namespace: Input<Namespace>,
658
656
  opts?: ResourceOptions,
659
- ): Output<NetworkPolicy> {
660
- return NetworkPolicy.create(
661
- "allow-inside-namespace",
657
+ ): Promise<NetworkPolicy> {
658
+ const nsName = await toPromise(output(namespace).metadata.name)
659
+ const cluster = await toPromise(output(namespace).cluster)
660
+
661
+ return new NetworkPolicy(
662
+ `allow-inside-namespace.${cluster.name}.${nsName}.${cluster.id}`,
662
663
  {
663
664
  namespace,
664
- cluster,
665
-
666
665
  description: "Allow all traffic inside the namespace.",
667
- selector: {},
668
-
669
666
  ingressRule: { fromNamespace: namespace },
670
667
  egressRule: { toNamespace: namespace },
671
668
  },
@@ -673,133 +670,184 @@ export abstract class NetworkPolicy extends ComponentResource {
673
670
  )
674
671
  }
675
672
 
676
- static allowKubeApiServer(
677
- namespace: Input<NamespaceLike>,
678
- cluster: Input<k8s.Cluster>,
673
+ /**
674
+ * Creates network policy to allow traffic from the namespace to the Kubernetes API server.
675
+ *
676
+ * Automatically names the policy as: `allow-kube-api-server.{clusterName}.{namespace}.{clusterId}`.
677
+ *
678
+ * @param namespace The namespace to create the policy in.
679
+ * @param opts Optional resource options.
680
+ */
681
+ static async allowKubeApiServer(
682
+ namespace: Input<Namespace>,
679
683
  opts?: ResourceOptions,
680
- ): Output<NetworkPolicy> {
681
- return NetworkPolicy.create(
682
- "allow-kube-api-server",
684
+ ): Promise<NetworkPolicy> {
685
+ const nsName = await toPromise(output(namespace).metadata.name)
686
+ const cluster = await toPromise(output(namespace).cluster)
687
+
688
+ return new NetworkPolicy(
689
+ `allow-kube-api-server.${cluster.name}.${nsName}.${cluster.id}`,
683
690
  {
684
691
  namespace,
685
- cluster,
686
-
687
692
  description: "Allow all traffic to the Kubernetes API server from the namespace.",
688
-
689
693
  allowKubeApiServer: true,
690
694
  },
691
695
  opts,
692
696
  )
693
697
  }
694
698
 
695
- static allowKubeDns(
696
- namespace: Input<NamespaceLike>,
697
- cluster: Input<k8s.Cluster>,
699
+ /**
700
+ * Creates network policy to allow egress DNS traffic (UDP 53) required for name resolution.
701
+ *
702
+ * Automatically names the policy as: `allow-kube-dns.{clusterName}.{namespace}.{clusterId}`.
703
+ *
704
+ * @param namespace The namespace to create the policy in.
705
+ * @param opts Optional resource options.
706
+ */
707
+ static async allowKubeDns(
708
+ namespace: Input<Namespace>,
698
709
  opts?: ResourceOptions,
699
- ): Output<NetworkPolicy> {
700
- return NetworkPolicy.create(
701
- "allow-kube-dns",
710
+ ): Promise<NetworkPolicy> {
711
+ const nsName = await toPromise(output(namespace).metadata.name)
712
+ const cluster = await toPromise(output(namespace).cluster)
713
+
714
+ return new NetworkPolicy(
715
+ `allow-kube-dns.${cluster.name}.${nsName}.${cluster.id}`,
702
716
  {
703
717
  namespace,
704
- cluster,
705
-
706
718
  description: "Allow all traffic to the Kubernetes DNS server from the namespace.",
707
-
708
719
  allowKubeDns: true,
709
720
  },
710
721
  opts,
711
722
  )
712
723
  }
713
724
 
714
- static allowAllEgress(
715
- namespace: Input<NamespaceLike>,
716
- cluster: Input<k8s.Cluster>,
725
+ /**
726
+ * Creates network policy to allow all egress traffic from the namespace.
727
+ *
728
+ * Automatically names the policy as: `allow-all-egress.{clusterName}.{namespace}.{clusterId}`.
729
+ *
730
+ * @param namespace The namespace to create the policy in.
731
+ * @param opts Optional resource options.
732
+ */
733
+ static async allowAllEgress(
734
+ namespace: Input<Namespace>,
717
735
  opts?: ResourceOptions,
718
- ): Output<NetworkPolicy> {
719
- return NetworkPolicy.create(
720
- "allow-all-egress",
736
+ ): Promise<NetworkPolicy> {
737
+ const nsName = await toPromise(output(namespace).metadata.name)
738
+ const cluster = await toPromise(output(namespace).cluster)
739
+
740
+ return new NetworkPolicy(
741
+ `allow-all-egress.${cluster.name}.${nsName}.${cluster.id}`,
721
742
  {
722
743
  namespace,
723
- cluster,
724
-
725
744
  description: "Allow all egress traffic from the namespace.",
726
-
727
745
  egressRule: { toAll: true },
728
746
  },
729
747
  opts,
730
748
  )
731
749
  }
732
750
 
733
- static allowAllIngress(
734
- namespace: Input<NamespaceLike>,
735
- cluster: Input<k8s.Cluster>,
751
+ /**
752
+ * Creates network policy to allow all ingress traffic to the namespace.
753
+ *
754
+ * Automatically names the policy as: `allow-all-ingress.{clusterName}.{namespace}.{clusterId}`.
755
+ *
756
+ * @param namespace The namespace to create the policy in.
757
+ * @param opts Optional resource options.
758
+ */
759
+ static async allowAllIngress(
760
+ namespace: Input<Namespace>,
736
761
  opts?: ResourceOptions,
737
- ): Output<NetworkPolicy> {
738
- return NetworkPolicy.create(
739
- "allow-all-ingress",
762
+ ): Promise<NetworkPolicy> {
763
+ const nsName = await toPromise(output(namespace).metadata.name)
764
+ const cluster = await toPromise(output(namespace).cluster)
765
+ return new NetworkPolicy(
766
+ `allow-all-ingress.${cluster.name}.${nsName}.${cluster.id}`,
740
767
  {
741
768
  namespace,
742
- cluster,
743
-
744
769
  description: "Allow all ingress traffic to the namespace.",
745
-
746
770
  ingressRule: { fromAll: true },
747
771
  },
748
772
  opts,
749
773
  )
750
774
  }
751
775
 
752
- static allowEgressToEndpoint(
776
+ /**
777
+ * Creates network policy to allow egress traffic to a specific L3/L4 endpoint.
778
+ *
779
+ * Automatically names the policy as: `allow-egress-to-<endpoint>.{clusterName}.{namespace}.{clusterId}`.
780
+ *
781
+ * @param namespace The namespace to create the policy in.
782
+ * @param endpoint The endpoint to allow egress to.
783
+ * @param opts Optional resource options.
784
+ */
785
+ static async allowEgressToEndpoint(
786
+ namespace: Input<Namespace>,
753
787
  endpoint: InputL34Endpoint,
754
- namespace: Input<NamespaceLike>,
755
- cluster: Input<k8s.Cluster>,
756
788
  opts?: ResourceOptions,
757
- ): Output<NetworkPolicy> {
789
+ ): Promise<NetworkPolicy> {
758
790
  const parsedEndpoint = parseL34Endpoint(endpoint)
791
+ const endpointStr = l34EndpointToString(parsedEndpoint).replace(/:/g, "-")
792
+ const nsName = await toPromise(output(namespace).metadata.name)
793
+ const cluster = await toPromise(output(namespace).cluster)
759
794
 
760
- return NetworkPolicy.create(
761
- `allow-egress-to-${l34EndpointToString(parsedEndpoint).replace(":", "-")}`,
795
+ return new NetworkPolicy(
796
+ `allow-egress-to-${endpointStr}.${cluster.name}.${nsName}.${cluster.id}`,
762
797
  {
763
798
  namespace,
764
- cluster,
765
-
766
- description: interpolate`Allow egress traffic to "${l34EndpointToString(parsedEndpoint)}" from the namespace.`,
767
-
799
+ description: `Allow egress traffic to "${l34EndpointToString(parsedEndpoint)}" from the namespace.`,
768
800
  egressRule: { toEndpoint: endpoint },
769
801
  },
770
802
  opts,
771
803
  )
772
804
  }
773
805
 
774
- static allowEgressToBestEndpoint(
806
+ /**
807
+ * Creates network policy to allow egress traffic to the best endpoint among provided candidates.
808
+ *
809
+ * Automatically names the policy as: `allow-egress-to-<bestEndpoint>.{clusterName}.{namespace}.{clusterId}`.
810
+ *
811
+ * @param namespace The namespace to create the policy in.
812
+ * @param endpoints The candidate endpoints to select from.
813
+ * @param opts Optional resource options.
814
+ */
815
+ static async allowEgressToBestEndpoint(
816
+ namespace: Input<Namespace>,
775
817
  endpoints: InputArray<InputL34Endpoint>,
776
- namespace: Input<NamespaceLike>,
777
- cluster: Input<k8s.Cluster>,
778
818
  opts?: ResourceOptions,
779
- ): Output<NetworkPolicy> {
780
- return output({ endpoints, cluster }).apply(({ endpoints, cluster }) => {
781
- const bestEndpoint = requireBestEndpoint(endpoints.map(parseL34Endpoint), cluster)
819
+ ): Promise<NetworkPolicy> {
820
+ const cluster = await toPromise(output(namespace).cluster)
821
+ const resolvedEndpoints = await toPromise(output(endpoints))
822
+ const bestEndpoint = requireBestEndpoint(resolvedEndpoints.map(parseL34Endpoint), cluster)
782
823
 
783
- return NetworkPolicy.allowEgressToEndpoint(bestEndpoint, namespace, cluster, opts)
784
- })
824
+ return await NetworkPolicy.allowEgressToEndpoint(namespace, bestEndpoint, opts)
785
825
  }
786
826
 
787
- static allowIngressFromEndpoint(
827
+ /**
828
+ * Creates network policy to allow ingress traffic from a specific L3/L4 endpoint.
829
+ *
830
+ * Automatically names the policy as: `allow-ingress-from-<endpoint>.{clusterName}.{namespace}.{clusterId}`.
831
+ *
832
+ * @param namespace The namespace to create the policy in.
833
+ * @param endpoint The endpoint to allow ingress from.
834
+ * @param opts Optional resource options.
835
+ */
836
+ static async allowIngressFromEndpoint(
837
+ namespace: Input<Namespace>,
788
838
  endpoint: InputL34Endpoint,
789
- namespace: Input<NamespaceLike>,
790
- cluster: Input<k8s.Cluster>,
791
839
  opts?: ResourceOptions,
792
- ): Output<NetworkPolicy> {
840
+ ): Promise<NetworkPolicy> {
793
841
  const parsedEndpoint = parseL34Endpoint(endpoint)
842
+ const endpointStr = l34EndpointToString(parsedEndpoint).replace(/:/g, "-")
843
+ const nsName = await toPromise(output(namespace).metadata.name)
844
+ const cluster = await toPromise(output(namespace).cluster)
794
845
 
795
- return NetworkPolicy.create(
796
- `allow-ingress-from-${l34EndpointToString(parsedEndpoint)}`,
846
+ return new NetworkPolicy(
847
+ `allow-ingress-from-${endpointStr}.${cluster.name}.${nsName}.${cluster.id}`,
797
848
  {
798
849
  namespace,
799
- cluster,
800
-
801
850
  description: interpolate`Allow ingress traffic from "${l34EndpointToString(parsedEndpoint)}" to the namespace.`,
802
-
803
851
  ingressRule: { fromEndpoint: endpoint },
804
852
  },
805
853
  opts,
@@ -807,12 +855,15 @@ export abstract class NetworkPolicy extends ComponentResource {
807
855
  }
808
856
  }
809
857
 
810
- export class NativeNetworkPolicy extends NetworkPolicy {
811
- protected create(
812
- name: string,
813
- args: NormalizedNetworkPolicyArgs,
814
- opts?: ResourceOptions,
815
- ): Resource {
858
+ export class NativeNetworkPolicy extends ComponentResource {
859
+ /**
860
+ * The underlying native network policy resource.
861
+ */
862
+ public readonly networkPolicy: Resource
863
+
864
+ constructor(name: string, args: NormalizedNetworkPolicyArgs, opts?: ResourceOptions) {
865
+ super("k8s:native-network-policy", name, args, opts)
866
+
816
867
  const ingress = NativeNetworkPolicy.createIngressRules(args)
817
868
  const egress = NativeNetworkPolicy.createEgressRules(args)
818
869
 
@@ -826,7 +877,7 @@ export class NativeNetworkPolicy extends NetworkPolicy {
826
877
  policyTypes.push("Egress")
827
878
  }
828
879
 
829
- return new networking.v1.NetworkPolicy(
880
+ this.networkPolicy = new networking.v1.NetworkPolicy(
830
881
  name,
831
882
  {
832
883
  metadata: mergeDeep(mapMetadata(args, name), {
@@ -841,7 +892,7 @@ export class NativeNetworkPolicy extends NetworkPolicy {
841
892
  policyTypes,
842
893
  },
843
894
  },
844
- opts,
895
+ { ...opts, parent: this },
845
896
  )
846
897
  }
847
898
 
@@ -992,7 +1043,7 @@ export class NativeNetworkPolicy extends NetworkPolicy {
992
1043
  this: void,
993
1044
  namespace: NamespaceLike,
994
1045
  ): types.input.networking.v1.NetworkPolicyPeer {
995
- const namespaceName = mapNamespaceLikeToNamespaceName(namespace)
1046
+ const namespaceName = getNamespaceName(namespace)
996
1047
  const namespaceSelector = mapNamespaceNameToSelector(namespaceName)
997
1048
 
998
1049
  return { namespaceSelector }
package/src/network.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { k8s, network } from "@highstate/library"
2
2
  import { filterEndpoints } from "@highstate/common"
3
- import { isFromCluster } from "./service"
3
+ import { isEndpointFromCluster } from "./service"
4
4
 
5
5
  export function getBestEndpoint<TEndpoint extends network.L34Endpoint>(
6
6
  endpoints: TEndpoint[],
@@ -18,7 +18,7 @@ export function getBestEndpoint<TEndpoint extends network.L34Endpoint>(
18
18
  return filterEndpoints(endpoints)[0]
19
19
  }
20
20
 
21
- const clusterEndpoint = endpoints.find(endpoint => isFromCluster(endpoint, cluster))
21
+ const clusterEndpoint = endpoints.find(endpoint => isEndpointFromCluster(endpoint, cluster))
22
22
 
23
23
  if (clusterEndpoint) {
24
24
  return clusterEndpoint