@highstate/k8s 0.7.2 → 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.
Files changed (44) hide show
  1. package/dist/{helm-wPTgVV1N.js → chunk-K4WKJ4L5.js} +89 -47
  2. package/dist/chunk-K4WKJ4L5.js.map +1 -0
  3. package/dist/{shared-Clzbl5K-.js → chunk-T5Z2M4JE.js} +21 -7
  4. package/dist/chunk-T5Z2M4JE.js.map +1 -0
  5. package/dist/highstate.manifest.json +9 -0
  6. package/dist/index.js +304 -154
  7. package/dist/index.js.map +1 -0
  8. package/dist/units/access-point/index.js +9 -7
  9. package/dist/units/access-point/index.js.map +1 -0
  10. package/dist/units/cert-manager/index.js +29 -29
  11. package/dist/units/cert-manager/index.js.map +1 -0
  12. package/dist/units/dns01-issuer/index.js +22 -14
  13. package/dist/units/dns01-issuer/index.js.map +1 -0
  14. package/dist/units/existing-cluster/index.js +49 -21
  15. package/dist/units/existing-cluster/index.js.map +1 -0
  16. package/package.json +15 -16
  17. package/src/access-point.ts +185 -0
  18. package/src/container.ts +271 -0
  19. package/src/cron-job.ts +77 -0
  20. package/src/deployment.ts +210 -0
  21. package/src/gateway/backend.ts +61 -0
  22. package/src/gateway/http-route.ts +139 -0
  23. package/src/gateway/index.ts +2 -0
  24. package/src/helm.ts +298 -0
  25. package/src/index.ts +61 -0
  26. package/src/job.ts +66 -0
  27. package/src/network-policy.ts +732 -0
  28. package/src/pod.ts +5 -0
  29. package/src/pvc.ts +178 -0
  30. package/src/scripting/bundle.ts +244 -0
  31. package/src/scripting/container.ts +44 -0
  32. package/src/scripting/environment.ts +79 -0
  33. package/src/scripting/index.ts +3 -0
  34. package/src/service.ts +279 -0
  35. package/src/shared.ts +150 -0
  36. package/src/stateful-set.ts +159 -0
  37. package/src/units/access-point/index.ts +12 -0
  38. package/src/units/cert-manager/index.ts +37 -0
  39. package/src/units/dns01-issuer/index.ts +41 -0
  40. package/src/units/dns01-issuer/solver.ts +23 -0
  41. package/src/units/existing-cluster/index.ts +107 -0
  42. package/src/workload.ts +150 -0
  43. package/assets/charts.json +0 -8
  44. package/dist/index.d.ts +0 -1036
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/deployment.ts","../src/container.ts","../src/pvc.ts","../src/workload.ts","../src/stateful-set.ts","../src/network-policy.ts","../src/access-point.ts","../src/scripting/bundle.ts","../src/scripting/environment.ts","../src/scripting/container.ts","../src/job.ts","../src/cron-job.ts"],"sourcesContent":["import type { k8s } from \"@highstate/library\"\nimport type { HttpRoute } from \"./gateway\"\nimport type { Service } from \"./service\"\nimport {\n output,\n type ComponentResourceOptions,\n Output,\n type Inputs,\n ComponentResource,\n type InputArray,\n Resource,\n type Input,\n type InstanceTerminal,\n interpolate,\n} from \"@highstate/pulumi\"\nimport { apps, types } from \"@pulumi/kubernetes\"\nimport { omit } from \"remeda\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { trimIndentation } from \"@highstate/contract\"\nimport { mapMetadata, verifyProvider } from \"./shared\"\nimport { mapContainerToRaw } from \"./container\"\nimport {\n getPublicWorkloadComponents,\n publicWorkloadExtraArgs,\n type PublicWorkloadArgs,\n} from \"./workload\"\n\nexport type DeploymentArgs = Omit<PublicWorkloadArgs, \"patch\"> & {\n patch?: Input<k8s.Deployment>\n\n /**\n * The shell to use in the terminal.\n *\n * By default, `bash` is used.\n */\n terminalShell?: string\n} & Omit<Partial<types.input.apps.v1.DeploymentSpec>, \"template\"> & {\n template?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Partial<types.input.core.v1.PodSpec>\n }\n }\n\nexport abstract class Deployment extends ComponentResource {\n protected constructor(\n type: string,\n name: string,\n private readonly args: Inputs,\n opts: ComponentResourceOptions,\n\n /**\n * The cluster where the deployment is created.\n */\n readonly cluster: Output<k8s.Cluster>,\n\n /**\n * The metadata of the underlying Kubernetes deployment.\n */\n readonly metadata: Output<types.output.meta.v1.ObjectMeta>,\n\n /**\n * The spec of the underlying Kubernetes deployment.\n */\n readonly spec: Output<types.output.apps.v1.DeploymentSpec>,\n\n /**\n * The status of the underlying Kubernetes deployment.\n */\n readonly status: Output<types.output.apps.v1.DeploymentStatus>,\n\n private readonly _service: Output<Service | undefined>,\n private readonly _httpRoute: Output<HttpRoute | undefined>,\n\n /**\n * The resources associated with the deployment.\n */\n readonly resources: InputArray<Resource>,\n ) {\n super(type, name, args, opts)\n }\n\n /**\n * The Highstate deployment entity.\n */\n get entity(): Output<k8s.Deployment> {\n return output({\n type: \"k8s.deployment\",\n clusterInfo: this.cluster.info,\n metadata: this.metadata,\n spec: this.spec,\n service: this._service.apply(service => service?.entity),\n })\n }\n\n get optionalService(): Output<Service | undefined> {\n return this._service\n }\n\n /**\n * The service associated with the deployment.\n */\n get service(): Output<Service> {\n return this._service.apply(service => {\n if (!service) {\n throw new Error(\"The service is not available.\")\n }\n\n return service\n })\n }\n\n /**\n * The HTTP route associated with the deployment.\n */\n get httpRoute(): Output<HttpRoute> {\n return this._httpRoute.apply(httpRoute => {\n if (!httpRoute) {\n throw new Error(\"The HTTP route is not available.\")\n }\n\n return httpRoute\n })\n }\n\n /**\n * The instance terminal to interact with the deployment.\n */\n get terminal(): Output<InstanceTerminal> {\n return output({\n name: this.metadata.name,\n title: this.metadata.name,\n image: \"ghcr.io/exeteres/highstate/terminal-kubectl\",\n command: [\"script\", \"-q\", \"-c\", \"/enter-container.sh\", \"/dev/null\"],\n files: {\n \"/kubeconfig\": this.cluster.kubeconfig,\n\n \"/enter-container.sh\": {\n mode: 0o755,\n content: interpolate`\n #!/bin/bash\n\n exec kubectl exec -it -n ${this.metadata.namespace} deployment/${this.metadata.name} -- ${this.args.terminalShell ?? \"bash\"}\n `.apply(trimIndentation),\n },\n },\n env: {\n KUBECONFIG: \"/kubeconfig\",\n },\n })\n }\n\n static create(name: string, args: DeploymentArgs, opts: ComponentResourceOptions): Deployment {\n return new CreatedDeployment(name, args, opts)\n }\n}\n\nclass CreatedDeployment extends Deployment {\n constructor(name: string, args: DeploymentArgs, opts: ComponentResourceOptions) {\n const { labels, containers, volumes, service, httpRoute } = getPublicWorkloadComponents(\n name,\n args,\n () => this,\n opts,\n )\n\n const deployment = output({ args, containers, volumes }).apply(\n async ({ args, containers, volumes }) => {\n await verifyProvider(opts.provider, args.cluster.info)\n\n return new (args.patch ? apps.v1.DeploymentPatch : apps.v1.Deployment)(\n name,\n {\n metadata: mapMetadata(args.patch?.metadata ?? args, name),\n spec: deepmerge(\n {\n template: {\n metadata: !args.patch ? { labels } : undefined,\n spec: {\n containers: containers.map(container => mapContainerToRaw(container, name)),\n volumes,\n },\n },\n selector: !args.patch ? { matchLabels: labels } : undefined,\n },\n omit(args, publicWorkloadExtraArgs),\n ),\n },\n { parent: this, ...opts },\n )\n },\n )\n\n super(\n \"highstate:k8s:Deployment\",\n name,\n args,\n opts,\n\n output(args.cluster),\n deployment.metadata,\n deployment.spec,\n deployment.status,\n\n service,\n httpRoute,\n\n [deployment],\n )\n }\n}\n","import type { PartialKeys } from \"@highstate/contract\"\nimport { core, type types } from \"@pulumi/kubernetes\"\nimport { normalize, output, type Input, type InputArray, type Unwrap } from \"@highstate/pulumi\"\nimport { concat, map, omit } from \"remeda\"\nimport { PersistentVolumeClaim } from \"./pvc\"\n\nexport type Container = Omit<PartialKeys<types.input.core.v1.Container, \"name\">, \"volumeMounts\"> & {\n /**\n * The single port to add to the container.\n */\n port?: Input<types.input.core.v1.ContainerPort>\n\n /**\n * The volume mount to attach to the container.\n */\n volumeMount?: Input<ContainerVolumeMount>\n\n /**\n * The volume mounts to attach to the container.\n */\n volumeMounts?: InputArray<ContainerVolumeMount>\n\n /**\n * The volume to include in the parent workload.\n * It is like the `volumes` property, but defined at the container level.\n * It will be defined as a volume mount in the parent workload automatically.\n */\n volume?: Input<WorkloadVolume>\n\n /**\n * The volumes to include in the parent workload.\n * It is like the `volumes` property, but defined at the container level.\n * It will be defined as a volume mount in the parent workload automatically.\n */\n volumes?: InputArray<WorkloadVolume>\n\n /**\n * The map of environment variables to set in the container.\n * It is like the `env` property, but more convenient to use.\n */\n environment?: Input<ContainerEnvironment>\n\n /**\n * The source of environment variables to set in the container.\n * It is like the `envFrom` property, but more convenient to use.\n */\n environmentSource?: Input<ContainerEnvironmentSource>\n\n /**\n * The sources of environment variables to set in the container.\n * It is like the `envFrom` property, but more convenient to use.\n */\n environmentSources?: InputArray<ContainerEnvironmentSource>\n}\n\nconst containerExtraArgs = [\n \"port\",\n \"volumeMount\",\n \"volume\",\n \"environment\",\n \"environmentSource\",\n \"environmentSources\",\n] as const\n\nexport type ContainerEnvironment = Record<\n string,\n Input<string | undefined | null | ContainerEnvironmentVariable>\n>\n\nexport type ContainerEnvironmentVariable =\n | types.input.core.v1.EnvVarSource\n | {\n /**\n * The secret to select from.\n */\n secret: Input<core.v1.Secret>\n\n /**\n * The key of the secret to select from.\n */\n key: string\n }\n | {\n /**\n * The config map to select from.\n */\n configMap: Input<core.v1.ConfigMap>\n\n /**\n * The key of the config map to select from.\n */\n key: string\n }\n\nexport type ContainerEnvironmentSource =\n | types.input.core.v1.EnvFromSource\n | core.v1.ConfigMap\n | core.v1.Secret\n\nexport type ContainerVolumeMount =\n | types.input.core.v1.VolumeMount\n | (Omit<types.input.core.v1.VolumeMount, \"name\"> & {\n /**\n * The volume to mount.\n */\n volume: Input<WorkloadVolume>\n })\n\nexport type WorkloadVolume =\n | types.input.core.v1.Volume\n | core.v1.PersistentVolumeClaim\n | PersistentVolumeClaim\n | core.v1.ConfigMap\n | core.v1.Secret\n\nexport function mapContainerToRaw(\n container: Unwrap<Container>,\n fallbackName: string,\n): types.input.core.v1.Container {\n const containerName = container.name ?? fallbackName\n\n return {\n ...omit(container, containerExtraArgs),\n\n name: containerName,\n ports: normalize(container.port, container.ports),\n\n volumeMounts: map(normalize(container.volumeMount, container.volumeMounts), mapVolumeMount),\n\n env: concat(\n container.environment ? mapContainerEnvironment(container.environment) : [],\n container.env ?? [],\n ),\n\n envFrom: concat(\n map(\n normalize(container.environmentSource, container.environmentSources),\n mapEnvironmentSource,\n ),\n container.envFrom ?? [],\n ),\n }\n}\n\nexport function mapContainerEnvironment(\n environment: Unwrap<ContainerEnvironment>,\n): types.input.core.v1.EnvVar[] {\n const envVars: types.input.core.v1.EnvVar[] = []\n\n for (const [name, value] of Object.entries(environment)) {\n if (!value) {\n continue\n }\n\n if (typeof value === \"string\") {\n envVars.push({ name, value })\n continue\n }\n\n if (\"secret\" in value) {\n envVars.push({\n name,\n valueFrom: {\n secretKeyRef: {\n name: value.secret.metadata.name,\n key: value.key,\n },\n },\n })\n continue\n }\n\n if (\"configMap\" in value) {\n envVars.push({\n name,\n valueFrom: {\n configMapKeyRef: {\n name: value.configMap.metadata.name,\n key: value.key,\n },\n },\n })\n continue\n }\n\n envVars.push({ name, valueFrom: value })\n }\n\n return envVars\n}\n\nexport function mapVolumeMount(volumeMount: ContainerVolumeMount): types.input.core.v1.VolumeMount {\n if (\"volume\" in volumeMount) {\n return omit(\n {\n ...volumeMount,\n name: output(volumeMount.volume)\n .apply(mapWorkloadVolume)\n .apply(volume => output(volume.name)),\n },\n [\"volume\"],\n )\n }\n\n return {\n ...volumeMount,\n name: volumeMount.name,\n }\n}\n\nexport function mapEnvironmentSource(\n envFrom: ContainerEnvironmentSource,\n): types.input.core.v1.EnvFromSource {\n if (envFrom instanceof core.v1.ConfigMap) {\n return {\n configMapRef: {\n name: envFrom.metadata.name,\n },\n }\n }\n\n if (envFrom instanceof core.v1.Secret) {\n return {\n secretRef: {\n name: envFrom.metadata.name,\n },\n }\n }\n\n return envFrom\n}\n\nexport function mapWorkloadVolume(volume: WorkloadVolume) {\n if (volume instanceof PersistentVolumeClaim) {\n return {\n name: volume.metadata.name,\n persistentVolumeClaim: {\n claimName: volume.metadata.name,\n },\n }\n }\n\n if (volume instanceof core.v1.PersistentVolumeClaim) {\n return {\n name: volume.metadata.name,\n persistentVolumeClaim: {\n claimName: volume.metadata.name,\n },\n }\n }\n\n if (volume instanceof core.v1.ConfigMap) {\n return {\n name: volume.metadata.name,\n configMap: {\n name: volume.metadata.name,\n },\n }\n }\n\n if (volume instanceof core.v1.Secret) {\n return {\n name: volume.metadata.name,\n secret: {\n secretName: volume.metadata.name,\n },\n }\n }\n\n return volume\n}\n","import type { k8s } from \"@highstate/library\"\nimport { core, type types } from \"@pulumi/kubernetes\"\nimport {\n ComponentResource,\n Output,\n output,\n type ComponentResourceOptions,\n type CustomResourceOptions,\n type Input,\n type Inputs,\n} from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { omit } from \"remeda\"\nimport {\n commonExtraArgs,\n mapMetadata,\n resourceIdToString,\n verifyProvider,\n type CommonArgs,\n type ResourceId,\n} from \"./shared\"\n\nexport type PersistentVolumeClaimArgs = CommonArgs &\n types.input.core.v1.PersistentVolumeClaimSpec & {\n /**\n * The size of the volume to request.\n *\n * By default, the size is set to \"100Mi\".\n */\n size?: string\n\n /**\n * The cluster to create the resource in.\n */\n cluster: Input<k8s.Cluster>\n }\n\nconst extraPersistentVolumeClaimArgs = [...commonExtraArgs, \"size\", \"cluster\"] as const\n\nexport abstract class PersistentVolumeClaim extends ComponentResource {\n protected constructor(\n type: string,\n name: string,\n args: Inputs,\n opts: ComponentResourceOptions,\n\n /**\n * The cluster info associated with the pvc.\n */\n readonly clusterInfo: Output<k8s.ClusterInfo>,\n\n /**\n * The metadata of the underlying Kubernetes pvc.\n */\n readonly metadata: Output<types.output.meta.v1.ObjectMeta>,\n\n /**\n * The spec of the underlying Kubernetes pvc.\n */\n readonly spec: Output<types.output.core.v1.PersistentVolumeClaimSpec>,\n\n /**\n * The status of the underlying Kubernetes pvc.\n */\n readonly status: Output<types.output.core.v1.PersistentVolumeClaimStatus>,\n ) {\n super(type, name, args, opts)\n }\n\n /**\n * The Highstate service entity.\n */\n get entity(): Output<k8s.PersistentVolumeClaim> {\n return output({\n type: \"k8s.persistent-volume-claim\",\n clusterInfo: this.clusterInfo,\n metadata: this.metadata,\n })\n }\n\n static create(\n name: string,\n args: PersistentVolumeClaimArgs,\n opts: ComponentResourceOptions,\n ): PersistentVolumeClaim {\n return new CreatedPersistentVolumeClaim(name, args, opts)\n }\n\n static of(\n name: string,\n entity: Input<k8s.PersistentVolumeClaim>,\n opts: ComponentResourceOptions,\n ): PersistentVolumeClaim {\n return new ExternalPersistentVolumeClaim(\n name,\n output(entity).metadata,\n output(entity).clusterInfo,\n opts,\n )\n }\n}\n\nexport class CreatedPersistentVolumeClaim extends PersistentVolumeClaim {\n constructor(name: string, args: PersistentVolumeClaimArgs, opts: CustomResourceOptions) {\n const pvc = output(args).apply(args => {\n return new core.v1.PersistentVolumeClaim(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: deepmerge(\n {\n accessModes: [\"ReadWriteOnce\"],\n resources: {\n requests: {\n storage: args.size ?? \"100Mi\",\n },\n },\n } satisfies types.input.core.v1.PersistentVolumeClaimSpec,\n omit(args, extraPersistentVolumeClaimArgs),\n ),\n },\n opts,\n )\n })\n\n super(\n \"k8s:PersistentVolumeClaim\",\n name,\n args,\n opts,\n\n output(args.cluster).info,\n pvc.metadata,\n pvc.spec,\n pvc.status,\n )\n }\n}\n\nexport class ExternalPersistentVolumeClaim extends PersistentVolumeClaim {\n constructor(\n name: string,\n id: Input<ResourceId>,\n clusterInfo: Input<k8s.ClusterInfo>,\n opts: ComponentResourceOptions,\n ) {\n const pvc = output(id).apply(async id => {\n await verifyProvider(opts.provider, this.clusterInfo)\n\n return core.v1.PersistentVolumeClaim.get(\n //\n name,\n resourceIdToString(id),\n { parent: this, provider: opts.provider },\n )\n })\n\n super(\n \"highstate:k8s:ExternalPersistentVolumeClaim\",\n name,\n { id, clusterInfo },\n opts,\n\n output(clusterInfo),\n pvc.metadata,\n pvc.spec,\n pvc.status,\n )\n }\n}\n\nexport function getAutoVolumeName(workloadName: string, index: number): string {\n if (index === 0) {\n return `${workloadName}-data`\n }\n\n return `${workloadName}-data-${index}`\n}\n","import type { types } from \"@pulumi/kubernetes\"\nimport type { k8s } from \"@highstate/library\"\nimport { normalize, type ComponentResourceOptions, type InputArray } from \"@highstate/pulumi\"\nimport { ComponentResource, output, type Input, type Output } from \"@pulumi/pulumi\"\nimport { uniqueBy } from \"remeda\"\nimport { commonExtraArgs, type CommonArgs } from \"./shared\"\nimport { mapContainerPortToServicePort, Service, type ServiceArgs } from \"./service\"\nimport { HttpRoute, type HttpRouteArgs } from \"./gateway\"\nimport {\n mapContainerToRaw,\n mapWorkloadVolume,\n type Container,\n type WorkloadVolume,\n} from \"./container\"\n\nexport type WorkloadArgs = CommonArgs & {\n container?: Input<Container>\n containers?: InputArray<Container>\n\n /**\n * The cluster to create the resource in.\n */\n cluster: Input<k8s.Cluster>\n}\n\nexport const workloadExtraArgs = [...commonExtraArgs, \"container\", \"containers\"] as const\n\nexport class WorkloadBase<TArgs extends WorkloadArgs> extends ComponentResource {\n protected readonly containers: Output<types.input.core.v1.Container[]>\n protected readonly volumes: Output<types.input.core.v1.Volume[]>\n\n constructor(type: string, name: string, args: TArgs, opts: ComponentResourceOptions | undefined) {\n super(type, name, args, opts)\n\n const containers = output(args).apply(args => normalize(args.container, args.containers))\n\n this.containers = containers.apply(containers =>\n containers.map(container => mapContainerToRaw(container, name)),\n )\n\n this.volumes = containers.apply(containers =>\n containers\n .flatMap(container => normalize(container.volume, container.volumes))\n .map(mapWorkloadVolume),\n )\n }\n}\n\nexport type PublicWorkloadArgs = WorkloadArgs & {\n service?: Input<Omit<ServiceArgs, \"cluster\" | \"namespace\">>\n httpRoute?: Input<Omit<HttpRouteArgs, \"cluster\" | \"namespace\">>\n patch?: Input<k8s.Deployment | k8s.StatefulSet>\n} & Partial<types.input.apps.v1.StatefulSetSpec>\n\nexport const publicWorkloadExtraArgs = [...workloadExtraArgs, \"service\", \"httpRoute\"] as const\n\nexport function getWorkloadComponents(name: string, args: WorkloadArgs) {\n const labels = {\n \"app.kubernetes.io/name\": name,\n }\n\n const containers = output(args).apply(args => normalize(args.container, args.containers))\n const volumes = containers.apply(containers => {\n const containerVolumes = containers\n .flatMap(container => normalize(container.volume, container.volumes))\n .map(mapWorkloadVolume)\n\n const containerVolumeMounts = containers\n .flatMap(container => {\n return normalize(container.volumeMount, container.volumeMounts)\n .map(volumeMount => {\n return \"volume\" in volumeMount ? volumeMount.volume : undefined\n })\n .filter(Boolean) as WorkloadVolume[]\n })\n .map(mapWorkloadVolume)\n\n return uniqueBy([...containerVolumes, ...containerVolumeMounts], volume => volume.name)\n })\n\n return { labels, containers, volumes }\n}\n\nexport function getPublicWorkloadComponents(\n name: string,\n args: PublicWorkloadArgs,\n parent: () => ComponentResource,\n opts: ComponentResourceOptions,\n) {\n const { labels, containers, volumes } = getWorkloadComponents(name, args)\n\n const service = output({ args, containers }).apply(({ args, containers }) => {\n if (!args.service && !args.httpRoute) {\n return undefined\n }\n\n if (args.patch?.service) {\n return Service.of(name, args.patch.service, { parent: parent(), ...opts })\n }\n\n if (args.patch) {\n return undefined\n }\n\n const ports = containers.flatMap(container => normalize(container.port, container.ports))\n\n return Service.create(\n name,\n {\n ...args.service,\n selector: labels,\n cluster: args.cluster,\n namespace: args.namespace,\n\n ports:\n // allow to completely override the ports\n !args.service?.port && !args.service?.ports\n ? ports.map(mapContainerPortToServicePort)\n : args.service?.ports,\n },\n { parent: parent(), ...opts },\n )\n })\n\n const httpRoute = output({\n args,\n service,\n }).apply(({ args, service }) => {\n if (!args.httpRoute || !service) {\n return undefined\n }\n\n if (args.patch) {\n return undefined\n }\n\n return new HttpRoute(\n name,\n {\n ...args.httpRoute,\n rule: {\n backend: service,\n },\n },\n { parent: parent(), ...opts },\n )\n })\n\n return { labels, containers, volumes, service, httpRoute }\n}\n","import type { k8s } from \"@highstate/library\"\nimport type { HttpRoute } from \"./gateway\"\nimport type { Service } from \"./service\"\nimport {\n output,\n type ComponentResourceOptions,\n ComponentResource,\n Output,\n type Inputs,\n type Input,\n} from \"@highstate/pulumi\"\nimport { apps, type types } from \"@pulumi/kubernetes\"\nimport { omit } from \"remeda\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport {\n getPublicWorkloadComponents,\n publicWorkloadExtraArgs,\n type PublicWorkloadArgs,\n} from \"./workload\"\nimport { mapMetadata, verifyProvider } from \"./shared\"\nimport { mapContainerToRaw } from \"./container\"\n\nexport type StatefulSetArgs = Omit<PublicWorkloadArgs, \"patch\"> & {\n patch?: Input<k8s.StatefulSet>\n} & Partial<types.input.apps.v1.StatefulSetSpec>\n\nexport abstract class StatefulSet extends ComponentResource {\n protected constructor(\n type: string,\n name: string,\n args: Inputs,\n opts: ComponentResourceOptions,\n\n /**\n * The cluster info associated with the stateful set.\n */\n readonly clusterInfo: Output<k8s.ClusterInfo>,\n\n /**\n * The metadata of the underlying Kubernetes stateful set.\n */\n readonly metadata: Output<types.output.meta.v1.ObjectMeta>,\n\n /**\n * The spec of the underlying Kubernetes stateful set.\n */\n readonly spec: Output<types.output.apps.v1.StatefulSetSpec>,\n\n /**\n * The status of the underlying Kubernetes stateful set.\n */\n readonly status: Output<types.output.apps.v1.StatefulSetStatus>,\n\n private readonly _service: Output<Service | undefined>,\n private readonly _httpRoute: Output<HttpRoute | undefined>,\n ) {\n super(type, name, args, opts)\n }\n\n /**\n * The Highstate stateful set entity.\n */\n get entity(): Output<k8s.StatefulSet> {\n return output({\n type: \"k8s.stateful-set\",\n clusterInfo: this.clusterInfo,\n metadata: this.metadata,\n service: this.service.entity,\n })\n }\n\n get optionalService(): Output<Service | undefined> {\n return this._service\n }\n\n /**\n * The service associated with the stateful set.\n */\n get service(): Output<Service> {\n return this._service.apply(service => {\n if (!service) {\n throw new Error(\"The service is not available.\")\n }\n\n return service\n })\n }\n\n /**\n * The HTTP route associated with the stateful set.\n */\n get httpRoute(): Output<HttpRoute> {\n return this._httpRoute.apply(httpRoute => {\n if (!httpRoute) {\n throw new Error(\"The HTTP route is not available.\")\n }\n\n return httpRoute\n })\n }\n\n static create(name: string, args: StatefulSetArgs, opts: ComponentResourceOptions): StatefulSet {\n return new CreatedStatefulSet(name, args, opts)\n }\n}\n\nclass CreatedStatefulSet extends StatefulSet {\n constructor(name: string, args: StatefulSetArgs, opts: ComponentResourceOptions) {\n const { containers, volumes, labels, service, httpRoute } = getPublicWorkloadComponents(\n name,\n args,\n () => this,\n opts,\n )\n\n const statefulSet = output({ args, containers, volumes, service }).apply(\n async ({ args, containers, volumes, service }) => {\n await verifyProvider(opts.provider, args.cluster?.info)\n\n return new (args.patch ? apps.v1.StatefulSetPatch : apps.v1.StatefulSet)(\n name,\n {\n metadata: mapMetadata(args.patch?.metadata ?? args, name),\n spec: deepmerge(\n {\n serviceName: service?.metadata.name || name,\n template: {\n metadata: !args.patch ? { labels } : undefined,\n spec: {\n containers: containers.map(container => mapContainerToRaw(container, name)),\n volumes,\n },\n },\n selector: !args.patch ? { matchLabels: labels } : undefined,\n },\n omit(args, publicWorkloadExtraArgs),\n ),\n },\n { parent: this, ...opts },\n )\n },\n )\n\n super(\n \"highstate:k8s:StatefulSet\",\n name,\n args,\n opts,\n\n output(args.cluster).info,\n statefulSet.metadata,\n statefulSet.spec,\n statefulSet.status,\n\n service,\n httpRoute,\n )\n }\n}\n","import { networking, types, type core } from \"@pulumi/kubernetes\"\nimport {\n ComponentResource,\n normalize,\n output,\n type Input,\n type InputArray,\n type Output,\n type Resource,\n type ResourceOptions,\n type Unwrap,\n} from \"@highstate/pulumi\"\nimport { capitalize, flat, merge, mergeDeep } from \"remeda\"\nimport { parseDomain, ParseResultType, type ParseResultIp } from \"parse-domain\"\nimport { k8s } from \"@highstate/library\"\nimport {\n mapMetadata,\n mapNamespaceLikeToNamespaceName,\n mapNamespaceNameToSelector,\n mapSelectorLikeToSelector,\n type CommonArgs,\n type NamespaceLike,\n type SelectorLike,\n} from \"./shared\"\nimport { mapServiceToLabelSelector } from \"./service\"\n\nexport type NetworkPolicyPort = {\n /**\n * The protocol to match.\n *\n * If not provided, \"TCP\" will be used.\n */\n protocol?: string\n} & (\n | {\n /**\n * The single port to match.\n */\n port: number\n }\n | {\n /**\n * The range of ports to match.\n */\n range: [start: number, end: number]\n }\n)\n\nexport type IngressRuleArgs = {\n /**\n * Whether to allow all incoming traffic.\n *\n * If set to `true`, all other rules will be ignored for matched traffic.\n */\n fromAll?: Input<boolean>\n\n /**\n * The allowed cidr for incoming traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n fromCidr?: Input<string>\n\n /**\n * The list of allowed cidrs for incoming traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n fromCidrs?: InputArray<string>\n\n /**\n * The service to allow traffic from.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n fromService?: Input<core.v1.Service>\n\n /**\n * The list of allowed services for incoming traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n fromServices?: InputArray<core.v1.Service>\n\n /**\n * The namespace to allow traffic from.\n *\n * If provided with `fromSelector(s)`, it will be ANDed with them.\n * Otherwise, it will match all pods in the namespace.\n *\n * Will be ORed with other conditions inside the same rule (except ports and selectors).\n */\n fromNamespace?: Input<NamespaceLike>\n\n /**\n * The list of allowed namespaces for incoming traffic.\n *\n * If provided with `fromSelector(s)`, it will be ANDed with them.\n * Otherwise, it will match all pods in the namespaces.\n *\n * Will be ORed with other conditions inside the same rule (except ports and selectors).\n */\n fromNamespaces?: InputArray<NamespaceLike>\n\n /**\n * The selector for incoming traffic.\n *\n * If provided with `fromNamespace(s)`, it will be ANDed with them.\n * Otherwise, it will match pods in all namespaces.\n *\n * Will be ORed with other conditions inside the same rule (except ports and namespaces).\n */\n fromSelector?: Input<SelectorLike>\n\n /**\n * The list of selectors for incoming traffic.\n *\n * If provided with `fromNamespace(s)`, it will be ANDed with them.\n * Otherwise, it will match pods in all namespaces.\n *\n * Will be ORed with other conditions inside the same rule (except ports and namespaces).\n */\n fromSelectors?: InputArray<SelectorLike>\n\n /**\n * The port to allow incoming traffic on.\n *\n * Will be ANDed with all conditions inside the same rule.\n */\n toPort?: Input<NetworkPolicyPort>\n\n /**\n * The list of allowed ports for incoming traffic.\n *\n * Will be ANDed with all conditions inside the same rule.\n */\n toPorts?: InputArray<NetworkPolicyPort>\n}\n\nexport type EgressRuleArgs = {\n /**\n * Whether to allow all outgoing traffic.\n *\n * If set to `true`, all other rules will be ignored for matched traffic.\n */\n toAll?: Input<boolean>\n\n /**\n * The allowed cidr for outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toCidr?: Input<string>\n\n /**\n * The list of allowed cidrs for outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toCidrs?: InputArray<string>\n\n /**\n * The FQDN to allow outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toFqdn?: Input<string>\n\n /**\n * The list of allowed FQDNs for outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toFqdns?: InputArray<string>\n\n /**\n * Either the FQDN or the IP address of the endpoint to allow outgoing traffic.\n *\n * Just a syntactic sugar for `toFqdn` and `toCidr` for cases when the endpoint can be both.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toEndpoint?: Input<string>\n\n /**\n * The list of allowed endpoints for outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toEndpoints?: InputArray<string>\n\n /**\n * The service to allow traffic to.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toService?: Input<core.v1.Service>\n\n /**\n * The list of allowed services for outgoing traffic.\n *\n * Will be ORed with other conditions inside the same rule (except ports).\n */\n toServices?: InputArray<core.v1.Service>\n\n /**\n * The namespace to allow traffic to.\n *\n * If provided with `toSelector(s)`, it will be ANDed with them.\n * Otherwise, it will match all pods in the namespace.\n *\n * Will be ORed with other conditions inside the same rule (except ports and selectors).\n */\n toNamespace?: Input<NamespaceLike>\n\n /**\n * The list of allowed namespaces for outgoing traffic.\n *\n * If provided with `toSelector(s)`, it will be ANDed with them.\n * Otherwise, it will match all pods in the namespaces.\n *\n * Will be ORed with other conditions inside the same rule (except ports and selectors).\n */\n toNamespaces?: InputArray<NamespaceLike>\n\n /**\n * The selector for outgoing traffic.\n *\n * If provided with `toNamespace(s)`, it will be ANDe with them.\n *\n * Otherwise, it will match pods only in all namespaces.\n */\n toSelector?: Input<SelectorLike>\n\n /**\n * The list of selectors for outgoing traffic.\n *\n * If provided with `toNamespace(s)`, it will be ANDed with them.\n * Otherwise, it will match pods only in all namespaces.\n */\n toSelectors?: InputArray<SelectorLike>\n\n /**\n * The port to allow outgoing traffic on.\n *\n * Will be ANDed with all conditions inside the same rule.\n */\n toPort?: Input<NetworkPolicyPort>\n\n /**\n * The list of allowed ports for outgoing traffic.\n *\n * Will be ANDed with all conditions inside the same rule.\n */\n toPorts?: InputArray<NetworkPolicyPort>\n}\n\nexport type NetworkPolicyArgs = CommonArgs & {\n /**\n * The description of this network policy.\n */\n description?: Input<string>\n\n /**\n * The pod selector for this network policy.\n * If not provided, it will select all pods in the namespace.\n */\n selector?: SelectorLike\n\n /**\n * The rule for incoming traffic.\n */\n ingressRule?: Input<IngressRuleArgs>\n\n /**\n * The rules for incoming traffic.\n */\n ingressRules?: InputArray<IngressRuleArgs>\n\n /**\n * The rule for outgoing traffic.\n */\n egressRule?: Input<EgressRuleArgs>\n\n /**\n * The rules for outgoing traffic.\n */\n egressRules?: InputArray<EgressRuleArgs>\n\n /**\n * Enable the isolation of ingress traffic, so that only matched traffic can ingress.\n */\n isolateIngress?: Input<boolean>\n\n /**\n * Enable the isolation of egress traffic, so that only matched traffic can egress.\n */\n isolateEgress?: Input<boolean>\n\n /**\n * Allow the eggress traffic to the API server of the cluster.\n *\n * By default, `false`.\n */\n allowKubeApiServer?: Input<boolean>\n\n /**\n * Allow the eggress traffic to the DNS server of the cluster.\n *\n * By default, `false`.\n */\n allowKubeDns?: Input<boolean>\n}\n\nexport type FullNetworkPolicyArgs = NetworkPolicyArgs & {\n /**\n * The name of the CNI plugin to use for creating network policies.\n * If not provided or set to `unknown`, it will use the native `NetworkPolicy` resource.\n */\n cni?: Input<string | undefined>\n}\n\nexport type NormalizedRuleArgs = {\n all: boolean\n cidrs: string[]\n fqdns: string[]\n services: core.v1.Service[]\n namespaces: NamespaceLike[]\n selectors: SelectorLike[]\n ports: NetworkPolicyPort[]\n}\n\nexport type NormalizedNetworkPolicyArgs = Omit<\n Unwrap<NetworkPolicyArgs>,\n | \"podSelector\"\n | \"ingressRule\"\n | \"ingressRules\"\n | \"egressRule\"\n | \"egressRules\"\n | \"isolateIngress\"\n | \"isolateEgress\"\n | \"allowKubeApiServer\"\n | \"allowKubeDNS\"\n> & {\n podSelector: Unwrap<types.input.meta.v1.LabelSelector>\n\n isolateIngress: boolean\n isolateEgress: boolean\n\n allowKubeApiServer: boolean\n\n ingressRules: NormalizedRuleArgs[]\n egressRules: NormalizedRuleArgs[]\n}\n\n/**\n * The abstract resource for creating network policies.\n * Will use different resources depending on the environment.\n *\n * Note: In the worst case, it will create native `NetworkPolicy` resources and ignore some features like L7 rules.\n */\nexport abstract class NetworkPolicy extends ComponentResource {\n /**\n * The underlying network policy resource.\n */\n public readonly networkPolicy: Output<Resource>\n\n protected constructor(name: string, args: Unwrap<NetworkPolicyArgs>, opts?: ResourceOptions) {\n super(\"k8s:network-policy\", name, args, opts)\n\n const normalizedArgs = output(args).apply(args => {\n const ingressRules = normalize(args.ingressRule, args.ingressRules)\n const egressRules = normalize(args.egressRule, args.egressRules)\n\n const endpoints = normalize(args.egressRule?.toEndpoint, args.egressRule?.toEndpoints)\n const parsedEndpoints = endpoints.map(endpoint => parseDomain(endpoint))\n\n const cidrsFromEndpoints = parsedEndpoints\n .filter(result => result.type === ParseResultType.Ip)\n .map(result => NetworkPolicy.mapCidrFromEndpoint(result))\n\n const fqdnsFromEndpoints = parsedEndpoints\n .filter(result => result.type !== ParseResultType.Invalid)\n .map(result => result.hostname)\n\n const extraEgressRules: NormalizedRuleArgs[] = []\n\n if (args.allowKubeDns) {\n extraEgressRules.push({\n namespaces: [\"kube-system\"],\n selectors: [{ matchLabels: { \"k8s-app\": \"kube-dns\" } }],\n ports: [{ port: 53, protocol: \"UDP\" }],\n all: false,\n cidrs: [],\n fqdns: [],\n services: [],\n })\n }\n\n return {\n ...args,\n\n podSelector: args.selector ? mapSelectorLikeToSelector(args.selector) : {},\n\n isolateEgress: args.isolateEgress ?? false,\n isolateIngress: args.isolateIngress ?? false,\n\n allowKubeApiServer: args.allowKubeApiServer ?? false,\n\n ingressRules: ingressRules.map(rule => ({\n all: rule.fromAll ?? false,\n cidrs: normalize(rule.fromCidr, rule.fromCidrs),\n fqdns: [],\n services: normalize(rule.fromService, rule.fromServices),\n namespaces: normalize(rule.fromNamespace, rule.fromNamespaces),\n selectors: normalize(rule.fromSelector, rule.fromSelectors),\n ports: normalize(rule.toPort, rule.toPorts),\n })),\n\n egressRules: egressRules\n .map(rule => {\n return {\n all: rule.toAll ?? false,\n cidrs: normalize(rule.toCidr, rule.toCidrs).concat(cidrsFromEndpoints),\n fqdns: normalize(rule.toFqdn, rule.toFqdns).concat(fqdnsFromEndpoints),\n services: normalize(rule.toService, rule.toServices),\n namespaces: normalize(rule.toNamespace, rule.toNamespaces),\n selectors: normalize(rule.toSelector, rule.toSelectors),\n ports: normalize(rule.toPort, rule.toPorts),\n } as NormalizedRuleArgs\n })\n .concat(extraEgressRules),\n }\n })\n\n this.networkPolicy = normalizedArgs.apply(args => {\n return output(\n this.create(name, args as NormalizedNetworkPolicyArgs, { ...opts, parent: this }),\n )\n })\n\n this.registerOutputs({ networkPolicy: this.networkPolicy })\n }\n\n private static mapCidrFromEndpoint(result: ParseResultIp): string {\n if (result.ipVersion === 4) {\n return `${result.hostname}/32`\n }\n\n return `${result.hostname}/128`\n }\n\n protected abstract create(\n name: string,\n args: NormalizedNetworkPolicyArgs,\n opts?: ResourceOptions,\n ): Input<Resource>\n\n private static readonly supportedCNIs = [\"cilium\"]\n\n static create(\n name: string,\n args: FullNetworkPolicyArgs,\n opts: ResourceOptions,\n ): Output<NetworkPolicy> {\n return output(args).apply(async args => {\n if (!args.cni || !NetworkPolicy.supportedCNIs.includes(args.cni)) {\n return new NativeNetworkPolicy(name, args, opts)\n }\n\n const implName = `${capitalize(args.cni)}NetworkPolicy`\n const implModule = (await import(`@highstate/${args.cni}`)) as Record<string, unknown>\n\n type NetworkPolicyFactory = new (\n name: string,\n args: Unwrap<NetworkPolicyArgs>,\n opts?: ResourceOptions,\n ) => NetworkPolicy\n\n const implClass = implModule[implName] as NetworkPolicyFactory | undefined\n if (!implClass) {\n throw new Error(`No implementation found for ${args.cni}`)\n }\n\n return new implClass(name, args, opts)\n })\n }\n\n static allowInsideNamespace(\n namespace: Input<NamespaceLike>,\n k8sCluster: Input<k8s.Cluster>,\n opts: ResourceOptions,\n ): Output<NetworkPolicy> {\n return NetworkPolicy.create(\n \"allow-inside-namespace\",\n {\n namespace,\n cni: output(k8sCluster).info.cni,\n\n description: \"Allow all traffic inside the namespace.\",\n selector: {},\n\n ingressRule: { fromNamespace: namespace },\n egressRule: { toNamespace: namespace },\n },\n opts,\n )\n }\n\n static allowKubeApiServer(\n namespace: Input<NamespaceLike>,\n k8sCluster: Input<k8s.Cluster>,\n opts: ResourceOptions,\n ): Output<NetworkPolicy> {\n return NetworkPolicy.create(\n \"allow-kube-api-server\",\n {\n namespace,\n cni: output(k8sCluster).info.cni,\n\n description: \"Allow all traffic to the Kubernetes API server from the namespace.\",\n\n allowKubeApiServer: true,\n },\n opts,\n )\n }\n\n static allowKubeDns(\n namespace: Input<NamespaceLike>,\n k8sCluster: Input<k8s.Cluster>,\n opts: ResourceOptions,\n ): Output<NetworkPolicy> {\n return NetworkPolicy.create(\n \"allow-kube-dns\",\n {\n namespace,\n cni: output(k8sCluster).info.cni,\n\n description: \"Allow all traffic to the Kubernetes DNS server from the namespace.\",\n\n allowKubeDns: true,\n },\n opts,\n )\n }\n\n static allowAllEgress(\n namespace: Input<NamespaceLike>,\n k8sCluster: Input<k8s.Cluster>,\n opts: ResourceOptions,\n ): Output<NetworkPolicy> {\n return NetworkPolicy.create(\n \"allow-all-egress\",\n {\n namespace,\n cni: output(k8sCluster).info.cni,\n\n description: \"Allow all egress traffic from the namespace.\",\n\n egressRule: { toAll: true },\n },\n opts,\n )\n }\n}\n\nexport class NativeNetworkPolicy extends NetworkPolicy {\n protected create(\n name: string,\n args: NormalizedNetworkPolicyArgs,\n opts?: ResourceOptions,\n ): Resource {\n const ingress = NativeNetworkPolicy.createIngressRules(args)\n const egress = NativeNetworkPolicy.createEgressRules(args)\n\n const policyTypes: string[] = []\n\n if (ingress.length > 0 || args.isolateIngress) {\n policyTypes.push(\"Ingress\")\n }\n\n if (egress.length > 0 || args.isolateEgress) {\n policyTypes.push(\"Egress\")\n }\n\n return new networking.v1.NetworkPolicy(\n name,\n {\n metadata: mergeDeep(mapMetadata(args, name), {\n annotations: args.description\n ? { \"kubernetes.io/description\": args.description }\n : undefined,\n }),\n spec: {\n podSelector: args.podSelector,\n ingress,\n egress,\n policyTypes,\n },\n },\n opts,\n )\n }\n\n private static fallbackIpBlock: types.input.networking.v1.IPBlock = {\n cidr: \"0.0.0.0/0\",\n except: [\"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"],\n }\n\n private static createIngressRules(\n args: NormalizedNetworkPolicyArgs,\n ): types.input.networking.v1.NetworkPolicyIngressRule[] {\n return args.ingressRules.map(rule => ({\n from: rule.all ? undefined : NativeNetworkPolicy.createRulePeers(rule),\n ports: NativeNetworkPolicy.mapPorts(rule.ports),\n }))\n }\n\n private static createEgressRules(\n args: NormalizedNetworkPolicyArgs,\n ): types.input.networking.v1.NetworkPolicyEgressRule[] {\n // the native resource does not support FQDNs\n // to provide compatibility, we need to fallback to all except private CIDRs\n const needFallback = args.egressRules.some(rule => rule.fqdns.length > 0)\n if (needFallback) {\n return [{ to: [{ ipBlock: NativeNetworkPolicy.fallbackIpBlock }] }]\n }\n\n const extraRules: types.input.networking.v1.NetworkPolicyEgressRule[] = []\n\n if (args.allowKubeApiServer) {\n // TODO: the \"10.96.0.1\" is not guaranteed to be the API server\n extraRules.push({ to: [{ ipBlock: { cidr: \"10.96.0.1\" } }] })\n }\n\n return args.egressRules\n .map(rule => {\n return {\n to: rule.all ? undefined : NativeNetworkPolicy.createRulePeers(rule),\n ports: NativeNetworkPolicy.mapPorts(rule.ports),\n } as types.input.networking.v1.NetworkPolicyEgressRule\n })\n .concat(extraRules)\n }\n\n private static createRulePeers(\n this: void,\n args: NormalizedRuleArgs,\n ): types.input.networking.v1.NetworkPolicyPeer[] {\n return [\n ...NativeNetworkPolicy.createCidrPeers(args),\n ...NativeNetworkPolicy.createServicePeers(args),\n ...NativeNetworkPolicy.createSelectorPeers(args),\n ]\n }\n\n private static createCidrPeers(\n args: NormalizedRuleArgs,\n ): types.input.networking.v1.NetworkPolicyPeer[] {\n return args.cidrs.map(cidr => ({ ipBlock: { cidr } }))\n }\n\n private static createServicePeers(\n args: NormalizedRuleArgs,\n ): types.input.networking.v1.NetworkPolicyPeer[] {\n return args.services.map(service => {\n const selector = mapServiceToLabelSelector(service)\n\n return {\n namespaceSelector: mapNamespaceNameToSelector(service.metadata.namespace),\n podSelector: selector,\n }\n })\n }\n\n private static createSelectorPeers(\n args: NormalizedRuleArgs,\n ): types.input.networking.v1.NetworkPolicyPeer[] {\n const selectorPeers = args.selectors.map(selector => ({\n podSelector: mapSelectorLikeToSelector(selector),\n }))\n\n const namespacePeers = args.namespaces.map(NativeNetworkPolicy.createNamespacePeer)\n\n if (namespacePeers.length === 0) {\n // if there are no namespaces, we can just return selector peers\n return selectorPeers\n }\n\n if (selectorPeers.length === 0) {\n // if there are no selectors, we can just return namespace peers\n return namespacePeers\n }\n\n // if there are both, we need to create a cartesian product\n return flat(\n selectorPeers.map(selectorPeer => {\n return namespacePeers.map(namespacePeer => merge(selectorPeer, namespacePeer))\n }),\n )\n }\n\n private static createNamespacePeer(\n this: void,\n namespace: NamespaceLike,\n ): types.input.networking.v1.NetworkPolicyPeer {\n const namespaceName = mapNamespaceLikeToNamespaceName(namespace)\n const namespaceSelector = mapNamespaceNameToSelector(namespaceName)\n\n return { namespaceSelector }\n }\n\n private static mapPorts(\n ports: NetworkPolicyPort[],\n ): types.input.networking.v1.NetworkPolicyPort[] {\n return ports.map(port => {\n if (\"port\" in port) {\n return {\n port: port.port,\n protocol: port.protocol ?? \"TCP\",\n }\n }\n\n return {\n port: port.range[0],\n endPort: port.range[1],\n protocol: port.protocol ?? \"TCP\",\n }\n })\n }\n}\n","import type { k8s } from \"@highstate/library\"\nimport type { core, Provider } from \"@pulumi/kubernetes\"\nimport { DnsRecord } from \"@highstate/common\"\nimport { gateway } from \"@highstate/gateway-api\"\nimport {\n normalize,\n Output,\n output,\n toPromise,\n type Input,\n type InputArray,\n} from \"@highstate/pulumi\"\nimport { NetworkPolicy } from \"./network-policy\"\nimport { getAppDisplayName, getAppName, mapNamespaceLikeToNamespaceName } from \"./shared\"\n\nexport type UseAccessPointResult = {\n /**\n * The gateway instance created according to the access point.\n */\n gateway: gateway.v1.Gateway\n\n /**\n * The DNS record associated created according to the access point and gateway.\n */\n dnsRecords: DnsRecord[]\n\n /**\n * The network policies associated with the access point.\n */\n networkPolicies: NetworkPolicy[]\n}\n\nexport type UseAccessPointArgs = Omit<CreateGatewayArgs, \"gateway\"> & {\n accessPoint: Input<k8s.AccessPoint>\n}\n\nexport function useAccessPoint(args: UseAccessPointArgs): Promise<UseAccessPointResult> {\n const result = output({ args, namespaceName: output(args.namespace).metadata.name }).apply(\n ({ args, namespaceName }) => {\n const gateway = createGateway({\n ...args,\n annotations: {\n \"cert-manager.io/cluster-issuer\": args.accessPoint.tlsIssuer.clusterIssuerName,\n },\n gateway: args.accessPoint.gateway,\n })\n\n const dnsRecords = normalize(args.fqdn, args.fqdns).map(fqdn => {\n return DnsRecord.create(fqdn, {\n provider: args.accessPoint.dnsProvider,\n type: \"A\",\n value: args.accessPoint.gateway.ip,\n })\n })\n\n const networkPolicies: Output<NetworkPolicy>[] = []\n\n if (args.accessPoint.gateway.service) {\n const displayName = getAppDisplayName(args.accessPoint.gateway.service.metadata)\n\n networkPolicies.push(\n NetworkPolicy.create(\n `allow-ingress-from-${getAppName(args.accessPoint.gateway.service.metadata)}`,\n {\n cni: args.accessPoint.gateway.service.clusterInfo.cni,\n namespace: args.namespace,\n\n description: `Allow ingress traffic from the gateway \"${displayName}\".`,\n\n ingressRule: {\n fromNamespace: args.accessPoint.gateway.service.metadata.namespace,\n fromSelector: args.accessPoint.gateway.service.spec.selector,\n },\n },\n { provider: args.provider },\n ),\n\n NetworkPolicy.create(\n `allow-egress-to-${namespaceName}`,\n {\n cni: args.accessPoint.gateway.service.clusterInfo.cni,\n namespace: args.accessPoint.gateway.service.metadata.namespace,\n selector: args.accessPoint.gateway.service.spec.selector,\n\n description: `Allow egress traffic to the namespace \"${namespaceName}\".`,\n\n egressRule: {\n toNamespace: args.namespace,\n },\n },\n { provider: args.provider },\n ),\n )\n }\n\n return output({\n gateway,\n dnsRecords,\n networkPolicies,\n })\n },\n )\n\n return toPromise(result)\n}\n\nexport type StandardAccessPointArgs = {\n fqdn: string\n}\n\nexport type StandardAccessPointInputs = {\n accessPoint: Output<k8s.AccessPoint>\n k8sCluster: Output<k8s.Cluster>\n}\n\nexport function useStandardAcessPoint(\n appName: string,\n namespace: core.v1.Namespace,\n args: StandardAccessPointArgs,\n inputs: StandardAccessPointInputs,\n provider: Provider,\n): Promise<UseAccessPointResult> {\n return useAccessPoint({\n name: appName,\n namespace,\n\n fqdn: args.fqdn,\n\n accessPoint: inputs.accessPoint,\n clusterInfo: inputs.k8sCluster.info,\n provider,\n })\n}\n\nexport type CreateGatewayArgs = {\n name: string\n namespace: Input<core.v1.Namespace>\n annotations?: Input<Record<string, string>>\n\n fqdn?: Input<string>\n fqdns?: InputArray<string>\n\n gateway: Input<k8s.Gateway>\n clusterInfo: Input<k8s.ClusterInfo>\n provider: Provider\n}\n\nexport function createGateway(args: CreateGatewayArgs): Output<gateway.v1.Gateway> {\n return output(args).apply(args => {\n if (args.clusterInfo.id !== args.gateway.clusterInfo.id) {\n throw new Error(\n \"The provided Kubernetes cluster is different from the one where the gateway controller is deployed.\",\n )\n }\n\n return new gateway.v1.Gateway(\n args.name,\n {\n metadata: {\n name: args.name,\n namespace: mapNamespaceLikeToNamespaceName(args.namespace),\n annotations: args.annotations,\n },\n spec: {\n gatewayClassName: output(args.gateway).gatewayClassName,\n listeners: normalize(args.fqdn, args.fqdns).map(fqdn => {\n const normalizedName = fqdn.replace(/\\*/g, \"wildcard\")\n\n return {\n name: `https-${normalizedName}`,\n port: output(args.gateway).httpsListenerPort,\n protocol: \"HTTPS\",\n hostname: fqdn,\n tls: {\n mode: \"Terminate\",\n certificateRefs: [{ name: normalizedName }],\n },\n }\n }),\n },\n },\n { provider: args.provider, deletedWith: args.namespace },\n )\n })\n}\n","import type { ContainerEnvironment, ContainerVolumeMount, WorkloadVolume } from \"../container\"\nimport { core } from \"@pulumi/kubernetes\"\nimport { apply, normalize, type InputArray } from \"@highstate/pulumi\"\nimport {\n ComponentResource,\n output,\n type ComponentResourceOptions,\n type Input,\n type Output,\n type Unwrap,\n} from \"@pulumi/pulumi\"\nimport { pipe } from \"remeda\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { text, trimIndentation } from \"@highstate/contract\"\nimport { mapMetadata, type CommonArgs } from \"../shared\"\nimport {\n emptyScriptEnvironment,\n type ResolvedScriptEnvironment,\n type ScriptDistribution,\n type ScriptEnvironment,\n} from \"./environment\"\n\nexport type ScriptBundleArgs = CommonArgs & {\n /**\n * The environment to bundle the scripts from.\n */\n environment?: Input<ScriptEnvironment>\n\n /**\n * The environments to bundle the scripts from.\n */\n environments?: InputArray<ScriptEnvironment>\n\n /**\n * The distribution to use for the scripts.\n */\n distribution: ScriptDistribution\n}\n\nexport class ScriptBundle extends ComponentResource {\n /**\n * The config map containing the scripts.\n */\n readonly configMap: Output<core.v1.ConfigMap>\n\n /**\n * The volumes that should be included in the workload.\n */\n readonly volumes: Output<WorkloadVolume[]>\n\n /**\n * The volume mounts that should be defined in the container.\n */\n readonly volumeMounts: Output<ContainerVolumeMount[]>\n\n /**\n * The environment variables that should be defined in the container.\n */\n readonly environment: Output<ContainerEnvironment>\n\n /**\n * The distribution to use for the scripts.\n */\n readonly distribution: ScriptDistribution\n\n constructor(name: string, args: ScriptBundleArgs, opts?: ComponentResourceOptions) {\n super(\"highstate:k8s:ScriptBundle\", name, args, opts)\n\n const scriptEnvironment = pipe(\n output(args),\n apply(args => normalize(args.environment, args.environments)),\n apply(args => deepmerge(emptyScriptEnvironment, ...args)),\n ) as Output<Unwrap<ResolvedScriptEnvironment>>\n\n this.distribution = args.distribution\n this.environment = scriptEnvironment.environment\n\n this.configMap = output({ scriptEnvironment, args }).apply(({ scriptEnvironment, args }) => {\n return new core.v1.ConfigMap(\n name,\n {\n metadata: mapMetadata(args, name),\n data: createScriptData(this.distribution, scriptEnvironment),\n },\n { ...opts, parent: this },\n )\n })\n\n this.volumes = scriptEnvironment.volumes.apply(volumes => {\n return [\n ...volumes,\n {\n name: this.configMap.metadata.name,\n\n configMap: {\n name: this.configMap.metadata.name,\n defaultMode: 0o550, // read and execute permissions\n },\n },\n ]\n })\n\n this.volumeMounts = scriptEnvironment.volumeMounts.apply(volumeMounts => {\n return [\n ...volumeMounts,\n {\n volume: this.configMap,\n mountPath: \"/scripts\",\n },\n ]\n })\n\n this.registerOutputs({\n configMap: this.configMap,\n volumes: this.volumes,\n volumeMounts: this.volumeMounts,\n environment: this.environment,\n })\n }\n}\n\nfunction createScriptData(\n distribution: ScriptDistribution,\n environment: Unwrap<ResolvedScriptEnvironment>,\n): Record<string, string> {\n const scriptData: Record<string, string> = {}\n const actions: string[] = []\n\n const distributionEnvironment = environment[distribution]\n\n if (distributionEnvironment.preInstallPackages.length > 0) {\n scriptData[\"pre-install-packages.sh\"] = getInstallPackagesScript(\n distribution,\n distributionEnvironment.preInstallPackages,\n )\n\n actions.push(`\n echo \"+ Installing pre-install packages...\"\n /scripts/pre-install-packages.sh\n echo \"+ Pre-install packages installed successfully\"\n `)\n }\n\n if (Object.keys(distributionEnvironment.preInstallScripts).length > 0) {\n for (const key in distributionEnvironment.preInstallScripts) {\n scriptData[`pre-install-${key}`] = distributionEnvironment.preInstallScripts[key]\n\n actions.push(`\n echo \"+ Running pre-install script '${key}'...\"\n /scripts/pre-install-${key}\n echo \"+ Pre-install script '${key}'... Done\"\n `)\n }\n }\n\n if (distributionEnvironment.packages.length > 0) {\n scriptData[\"install-packages.sh\"] = getInstallPackagesScript(\n distribution,\n distributionEnvironment.packages,\n )\n\n actions.push(`\n echo \"+ Installing packages...\"\n /scripts/install-packages.sh\n echo \"+ Packages installed successfully\"\n `)\n }\n\n if (Object.keys(environment.setupScripts).length > 0) {\n for (const key in environment.setupScripts) {\n scriptData[`setup-${key}`] = environment.setupScripts[key]\n\n actions.push(`\n echo \"+ Running setup script '${key}'...\"\n /scripts/setup-${key}\n echo \"+ Setup script '${key}'... Done\"\n `)\n }\n }\n\n if (Object.keys(environment.cleanupScripts).length > 0) {\n const cleanupActions: string[] = []\n\n for (const key in environment.cleanupScripts) {\n scriptData[`cleanup-${key}`] = environment.cleanupScripts[key]\n\n cleanupActions.push(`\n echo \"+ Running cleanup script '${key}'...\"\n /scripts/cleanup-${key}\n echo \"+ Cleanup script '${key}'... Done\"\n `)\n }\n\n actions.push(`\n function cleanup() {\n ${cleanupActions.map(s => s.trim()).join(\"\\n\\n\")}\n }\n\n trap cleanup EXIT\n trap cleanup SIGTERM\n `)\n }\n\n for (const key in environment.scripts) {\n scriptData[key] = environment.scripts[key]\n }\n\n scriptData[\"entrypoint.sh\"] = trimIndentation(`\n #!/bin/sh\n set -e\n\n if [ -z \"$1\" ]; then\n echo \"Usage: entrypoint.sh <main script> [args...]\"\n exit 1\n fi\n\n ${actions.map(s => s.trim()).join(\"\\n\\n\")}\n\n echo \"+ Running main script...\"\n $@\n echo \"+ Main script completed\"\n `)\n\n return scriptData\n}\n\nfunction getInstallPackagesScript(distribution: ScriptDistribution, packages: string[]): string {\n if (distribution === \"alpine\") {\n return text`\n #!/bin/sh\n set -e\n\n apk add --no-cache ${packages.join(\" \")}\n `\n } else {\n return text`\n #!/bin/sh\n set -e\n\n apt-get update\n apt-get install -y ${packages.join(\" \")}\n `\n }\n}\n","import type { Input, InputArray, InputMap } from \"@highstate/pulumi\"\nimport type { ContainerEnvironment, ContainerVolumeMount, WorkloadVolume } from \"../container\"\n\nexport type ScriptDistribution = \"alpine\" | \"ubuntu\"\n\nexport type DistributionEnvironment = {\n /**\n * The utility packages that should be installed before running \"preInstallScripts\".\n *\n * Useful for installing tools like `curl` to install additional repositories.\n */\n preInstallPackages?: InputArray<string>\n\n /**\n * The pre-install scripts that should be run before installing packages.\n * Typically, these scripts are used to install additional repositories.\n */\n preInstallScripts?: InputMap<string>\n\n /**\n * The packages that are available in the environment.\n */\n packages?: InputArray<string>\n}\n\nexport type ScriptEnvironment = {\n [distribution in ScriptDistribution]?: DistributionEnvironment\n} & {\n /**\n * The setup scripts that should be run before the script.\n */\n setupScripts?: InputMap<string>\n\n /**\n * The cleanup scripts that should be run after the script.\n */\n cleanupScripts?: InputMap<string>\n\n /**\n * The arbitrary scripts available in the environment.\n */\n scripts?: InputMap<string>\n\n /**\n * The volumes that should be defined in the environment.\n */\n volumes?: InputArray<WorkloadVolume>\n\n /**\n * The volume mounts that should be defined in the environment.\n */\n volumeMounts?: InputArray<ContainerVolumeMount>\n\n /**\n * The environment variables that should be defined in the environment.\n */\n environment?: Input<ContainerEnvironment>\n}\n\nexport type ResolvedScriptEnvironment = Omit<Required<ScriptEnvironment>, ScriptDistribution> & {\n [distribution in ScriptDistribution]: Required<DistributionEnvironment>\n}\n\nconst emptyDistributionEnvironment: Required<DistributionEnvironment> = {\n preInstallPackages: [],\n preInstallScripts: {},\n packages: [],\n}\n\nexport const emptyScriptEnvironment: ResolvedScriptEnvironment = {\n alpine: emptyDistributionEnvironment,\n ubuntu: emptyDistributionEnvironment,\n setupScripts: {},\n cleanupScripts: {},\n scripts: {},\n volumes: [],\n volumeMounts: [],\n environment: {},\n}\n","import type { Container } from \"../container\"\nimport type { ScriptBundle } from \"./bundle\"\nimport { Output, output, type Input } from \"@pulumi/pulumi\"\nimport { merge } from \"remeda\"\n\nexport interface ScriptContainer extends Container {\n /**\n * The script bundle to use.\n */\n bundle: Input<ScriptBundle>\n\n /**\n * The name of the main script to run.\n * The script must be available in the bundle.\n */\n main: Input<string>\n}\n\n/**\n * Creates a spec for a container that runs a script.\n * This spec can be used to create a complete workload or an init container.\n *\n * @param options The options to create the container spec.\n * @returns The container spec.\n */\nexport function createScriptContainer(options: ScriptContainer): Output<Container> {\n return output(options).apply(options => {\n const image =\n options.bundle.distribution === \"alpine\"\n ? \"alpine@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c\"\n : \"ubuntu@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782\"\n\n return {\n image,\n command: [\"/scripts/entrypoint.sh\", `/scripts/${options.main}`],\n\n ...options,\n\n volumeMounts: merge(options.bundle.volumeMounts, options.volumeMounts),\n volumes: merge(options.bundle.volumes, options.volumes),\n environment: merge(options.bundle.environment, options.environment),\n }\n })\n}\n","import { batch, type types } from \"@pulumi/kubernetes\"\nimport {\n ComponentResource,\n normalize,\n Output,\n output,\n type ComponentResourceOptions,\n type Input,\n type InputArray,\n} from \"@highstate/pulumi\"\nimport { mergeDeep, omit } from \"remeda\"\nimport { mapContainerToRaw, mapWorkloadVolume, type Container } from \"./container\"\nimport { commonExtraArgs, mapMetadata, type CommonArgs } from \"./shared\"\n\nexport type JobArgs = CommonArgs & {\n container?: Input<Container>\n containers?: InputArray<Container>\n} & Omit<Partial<types.input.batch.v1.JobSpec>, \"template\"> & {\n template?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Partial<types.input.core.v1.PodSpec>\n }\n }\n\nconst jobExtraArgs = [...commonExtraArgs, \"container\", \"containers\"] as const\n\nexport class Job extends ComponentResource {\n /**\n * The underlying Kubernetes job.\n */\n public readonly job: Output<batch.v1.Job>\n\n constructor(name: string, args: JobArgs, opts?: ComponentResourceOptions) {\n super(\"highstate:k8s:Job\", name, args, opts)\n\n this.job = output(args).apply(args => {\n const containers = normalize(args.container, args.containers)\n\n return new batch.v1.Job(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: mergeDeep(\n {\n template: {\n spec: {\n containers: containers.map(container => mapContainerToRaw(container, name)),\n\n volumes: containers\n .flatMap(container => normalize(container.volume, container.volumes))\n .map(mapWorkloadVolume),\n\n restartPolicy: \"Never\",\n },\n },\n } satisfies types.input.batch.v1.JobSpec,\n omit(args, jobExtraArgs) as types.input.batch.v1.JobSpec,\n ),\n },\n { parent: this, ...opts },\n )\n })\n\n this.registerOutputs({ job: this.job })\n }\n}\n","import type { RequiredKeys } from \"@highstate/contract\"\nimport { batch, type types } from \"@pulumi/kubernetes\"\nimport {\n ComponentResource,\n normalize,\n Output,\n output,\n type ComponentResourceOptions,\n type Input,\n type InputArray,\n} from \"@highstate/pulumi\"\nimport { mergeDeep, omit } from \"remeda\"\nimport { mapContainerToRaw, mapWorkloadVolume, type Container } from \"./container\"\nimport { commonExtraArgs, mapMetadata, type CommonArgs } from \"./shared\"\n\nexport type CronJobArgs = CommonArgs & {\n container?: Input<Container>\n containers?: InputArray<Container>\n} & Omit<RequiredKeys<Partial<types.input.batch.v1.CronJobSpec>, \"schedule\">, \"jobTemplate\"> & {\n jobTemplate?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Omit<types.input.batch.v1.JobSpec, \"template\"> & {\n template?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Partial<types.input.core.v1.PodSpec>\n }\n }\n }\n }\n\nconst cronJobExtraArgs = [...commonExtraArgs, \"container\", \"containers\"] as const\n\nexport class CronJob extends ComponentResource {\n /**\n * The underlying Kubernetes job.\n */\n public readonly cronJob: Output<batch.v1.CronJob>\n\n constructor(name: string, args: CronJobArgs, opts?: ComponentResourceOptions) {\n super(\"highstate:k8s:CronJob\", name, args, opts)\n\n this.cronJob = output(args).apply(args => {\n const containers = normalize(args.container, args.containers)\n\n return new batch.v1.CronJob(\n name,\n {\n metadata: mapMetadata(args, name),\n\n spec: mergeDeep(\n {\n jobTemplate: {\n spec: {\n template: {\n spec: {\n containers: containers.map(container => mapContainerToRaw(container, name)),\n\n volumes: containers\n .flatMap(container => normalize(container.volume, container.volumes))\n .map(mapWorkloadVolume),\n },\n },\n },\n },\n\n schedule: args.schedule,\n } satisfies types.input.batch.v1.CronJobSpec,\n omit(args, cronJobExtraArgs) as types.input.batch.v1.CronJobSpec,\n ),\n },\n { parent: this, ...opts },\n )\n })\n\n this.registerOutputs({ cronJob: this.cronJob })\n }\n}\n"],"mappings":"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","names":["output","ComponentResource","omit","deepmerge","core","output","omit","args","id","omit","output","core","normalize","ComponentResource","output","output","args","normalize","containers","service","ComponentResource","output","args","containers","volumes","deepmerge","omit","output","ComponentResource","apps","omit","deepmerge","ComponentResource","output","args","containers","volumes","service","apps","deepmerge","omit","ComponentResource","normalize","output","ComponentResource","output","args","normalize","normalize","output","output","args","gateway","normalize","core","normalize","ComponentResource","output","deepmerge","trimIndentation","ComponentResource","output","args","normalize","deepmerge","scriptEnvironment","core","trimIndentation","output","merge","options","ComponentResource","normalize","output","mergeDeep","omit","ComponentResource","output","args","normalize","mergeDeep","omit","batch","ComponentResource","normalize","output","mergeDeep","omit","ComponentResource","output","args","normalize","batch","mergeDeep","omit"]}
@@ -1,13 +1,15 @@
1
- import { k8s } from '@highstate/library';
2
- import { forUnit } from '@highstate/pulumi';
3
-
4
- const { inputs, outputs } = forUnit(k8s.accessPoint);
5
- var index = outputs({
1
+ // src/units/access-point/index.ts
2
+ import { k8s } from "@highstate/library";
3
+ import { forUnit } from "@highstate/pulumi";
4
+ var { inputs, outputs } = forUnit(k8s.accessPoint);
5
+ var access_point_default = outputs({
6
6
  accessPoint: {
7
7
  dnsProvider: inputs.dnsProvider,
8
8
  gateway: inputs.gateway,
9
9
  tlsIssuer: inputs.tlsIssuer
10
10
  }
11
11
  });
12
-
13
- export { index as default };
12
+ export {
13
+ access_point_default as default
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/units/access-point/index.ts"],"sourcesContent":["import { k8s } from \"@highstate/library\"\nimport { forUnit } from \"@highstate/pulumi\"\n\nconst { inputs, outputs } = forUnit(k8s.accessPoint)\n\nexport default outputs({\n accessPoint: {\n dnsProvider: inputs.dnsProvider,\n gateway: inputs.gateway,\n tlsIssuer: inputs.tlsIssuer,\n },\n})\n"],"mappings":";AAAA,SAAS,WAAW;AACpB,SAAS,eAAe;AAExB,IAAM,EAAE,QAAQ,QAAQ,IAAI,QAAQ,IAAI,WAAW;AAEnD,IAAO,uBAAQ,QAAQ;AAAA,EACrB,aAAa;AAAA,IACX,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO;AAAA,EACpB;AACF,CAAC;","names":[]}
@@ -1,37 +1,35 @@
1
- import { k8s } from '@highstate/library';
2
- import { forUnit } from '@highstate/pulumi';
3
- import { f as getProvider, h as createNamespace } from '../../shared-Clzbl5K-.js';
4
- import { C as Chart } from '../../helm-wPTgVV1N.js';
5
- import '@pulumi/kubernetes';
6
- import 'remeda';
7
- import 'path';
8
- import 'node:fs/promises';
9
- import '@pulumi/pulumi';
10
- import 'nano-spawn';
11
- import 'crypto-hash';
12
- import '@pulumi/command';
13
- import 'glob';
14
- import 'deepmerge-ts';
15
- import '@highstate/gateway-api';
1
+ import {
2
+ Chart
3
+ } from "../../chunk-K4WKJ4L5.js";
4
+ import {
5
+ createNamespace,
6
+ getProvider
7
+ } from "../../chunk-T5Z2M4JE.js";
16
8
 
17
- var charts = {
18
- "cert-manager": {
19
- repo: "https://charts.jetstack.io",
20
- name: "cert-manager",
21
- version: "v1.17.1",
22
- sha256: "48707f6e8937290da96065dc7de8b4f5a95d9707798d4b5a0d560f78c12996f7"
23
- }
9
+ // src/units/cert-manager/index.ts
10
+ import { k8s } from "@highstate/library";
11
+ import { forUnit } from "@highstate/pulumi";
12
+
13
+ // assets/charts.json
14
+ var charts_default = {
15
+ "cert-manager": {
16
+ repo: "https://charts.jetstack.io",
17
+ name: "cert-manager",
18
+ version: "v1.17.1",
19
+ sha256: "48707f6e8937290da96065dc7de8b4f5a95d9707798d4b5a0d560f78c12996f7"
20
+ }
24
21
  };
25
22
 
26
- const { inputs, outputs } = forUnit(k8s.certManager);
27
- const provider = await getProvider(inputs.k8sCluster);
28
- const namespace = createNamespace("cert-manager", provider);
23
+ // src/units/cert-manager/index.ts
24
+ var { inputs, outputs } = forUnit(k8s.certManager);
25
+ var provider = await getProvider(inputs.k8sCluster);
26
+ var namespace = createNamespace("cert-manager", provider);
29
27
  new Chart(
30
28
  "cert-manager",
31
29
  {
32
30
  namespace: namespace.metadata.name,
33
31
  cluster: inputs.k8sCluster,
34
- chart: charts["cert-manager"],
32
+ chart: charts_default["cert-manager"],
35
33
  values: {
36
34
  crds: {
37
35
  enabled: true
@@ -45,8 +43,10 @@ new Chart(
45
43
  },
46
44
  { provider }
47
45
  );
48
- var index = outputs({
46
+ var cert_manager_default = outputs({
49
47
  k8sCluster: inputs.k8sCluster
50
48
  });
51
-
52
- export { index as default };
49
+ export {
50
+ cert_manager_default as default
51
+ };
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/units/cert-manager/index.ts","../../../assets/charts.json"],"sourcesContent":["import { k8s } from \"@highstate/library\"\nimport { forUnit } from \"@highstate/pulumi\"\nimport { createNamespace, getProvider } from \"../../shared\"\nimport { Chart } from \"../../helm\"\nimport charts from \"../../../assets/charts.json\"\n\nconst { inputs, outputs } = forUnit(k8s.certManager)\nconst provider = await getProvider(inputs.k8sCluster)\n\nconst namespace = createNamespace(\"cert-manager\", provider)\n\nnew Chart(\n \"cert-manager\",\n {\n namespace: namespace.metadata.name,\n cluster: inputs.k8sCluster,\n\n chart: charts[\"cert-manager\"],\n\n values: {\n crds: {\n enabled: true,\n },\n\n config: {\n apiVersion: \"controller.config.cert-manager.io/v1alpha1\",\n kind: \"ControllerConfiguration\",\n enableGatewayAPI: true,\n },\n },\n },\n { provider },\n)\n\nexport default outputs({\n k8sCluster: inputs.k8sCluster,\n})\n","{\n \"cert-manager\": {\n \"repo\": \"https://charts.jetstack.io\",\n \"name\": \"cert-manager\",\n \"version\": \"v1.17.1\",\n \"sha256\": \"48707f6e8937290da96065dc7de8b4f5a95d9707798d4b5a0d560f78c12996f7\"\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,WAAW;AACpB,SAAS,eAAe;;;ACDxB;AAAA,EACE,gBAAgB;AAAA,IACd,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,SAAW;AAAA,IACX,QAAU;AAAA,EACZ;AACF;;;ADDA,IAAM,EAAE,QAAQ,QAAQ,IAAI,QAAQ,IAAI,WAAW;AACnD,IAAM,WAAW,MAAM,YAAY,OAAO,UAAU;AAEpD,IAAM,YAAY,gBAAgB,gBAAgB,QAAQ;AAE1D,IAAI;AAAA,EACF;AAAA,EACA;AAAA,IACE,WAAW,UAAU,SAAS;AAAA,IAC9B,SAAS,OAAO;AAAA,IAEhB,OAAO,eAAO,cAAc;AAAA,IAE5B,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,MAEA,QAAQ;AAAA,QACN,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EACA,EAAE,SAAS;AACb;AAEA,IAAO,uBAAQ,QAAQ;AAAA,EACrB,YAAY,OAAO;AACrB,CAAC;","names":[]}
@@ -1,21 +1,27 @@
1
- import { k8s } from '@highstate/library';
2
- import { toPromise, forUnit, unsecret } from '@highstate/pulumi';
3
- import { cert_manager } from '@highstate/cert-manager';
4
- import { f as getProvider } from '../../shared-Clzbl5K-.js';
5
- import { capitalize } from 'remeda';
6
- import '@pulumi/kubernetes';
1
+ import {
2
+ getProvider
3
+ } from "../../chunk-T5Z2M4JE.js";
7
4
 
8
- async function createDns01Solver(dnsProviderInput, provider) {
5
+ // src/units/dns01-issuer/index.ts
6
+ import { k8s } from "@highstate/library";
7
+ import { forUnit, unsecret } from "@highstate/pulumi";
8
+ import { cert_manager } from "@highstate/cert-manager";
9
+
10
+ // src/units/dns01-issuer/solver.ts
11
+ import { capitalize } from "remeda";
12
+ import { toPromise } from "@highstate/pulumi";
13
+ async function createDns01Solver(dnsProviderInput, provider2) {
9
14
  const dnsProvider = await toPromise(dnsProviderInput);
10
15
  const implName = `create${capitalize(dnsProvider.type)}Dns01Solver`;
11
16
  const implModule = await import(`@highstate/${dnsProvider.type}`);
12
17
  const implFunction = implModule[implName];
13
- return implFunction(dnsProvider, provider);
18
+ return implFunction(dnsProvider, provider2);
14
19
  }
15
20
 
16
- const { name, inputs, outputs } = forUnit(k8s.dns01TlsIssuer);
17
- const provider = await getProvider(inputs.k8sCluster);
18
- const dns01Solver = await createDns01Solver(inputs.dnsProvider, provider);
21
+ // src/units/dns01-issuer/index.ts
22
+ var { name, inputs, outputs } = forUnit(k8s.dns01TlsIssuer);
23
+ var provider = await getProvider(inputs.k8sCluster);
24
+ var dns01Solver = await createDns01Solver(inputs.dnsProvider, provider);
19
25
  new cert_manager.v1.ClusterIssuer(
20
26
  name,
21
27
  {
@@ -39,11 +45,13 @@ new cert_manager.v1.ClusterIssuer(
39
45
  },
40
46
  { provider }
41
47
  );
42
- var index = outputs({
48
+ var dns01_issuer_default = outputs({
43
49
  tlsIssuer: {
44
50
  clusterInfo: unsecret(inputs.k8sCluster.info),
45
51
  clusterIssuerName: name
46
52
  }
47
53
  });
48
-
49
- export { index as default };
54
+ export {
55
+ dns01_issuer_default as default
56
+ };
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/units/dns01-issuer/index.ts","../../../src/units/dns01-issuer/solver.ts"],"sourcesContent":["import { k8s } from \"@highstate/library\"\nimport { forUnit, unsecret } from \"@highstate/pulumi\"\nimport { cert_manager } from \"@highstate/cert-manager\"\nimport { getProvider } from \"../../shared\"\nimport { createDns01Solver } from \"./solver\"\n\nconst { name, inputs, outputs } = forUnit(k8s.dns01TlsIssuer)\n\nconst provider = await getProvider(inputs.k8sCluster)\nconst dns01Solver = await createDns01Solver(inputs.dnsProvider, provider)\n\nnew cert_manager.v1.ClusterIssuer(\n name,\n {\n metadata: {\n name,\n },\n spec: {\n acme: {\n server: \"https://acme-v02.api.letsencrypt.org/directory\",\n solvers: [\n {\n dns01: dns01Solver,\n selector: { dnsZones: [inputs.dnsProvider.domain] },\n },\n ],\n privateKeySecretRef: {\n name,\n },\n },\n },\n },\n { provider },\n)\n\nexport default outputs({\n tlsIssuer: {\n clusterInfo: unsecret(inputs.k8sCluster.info),\n clusterIssuerName: name,\n },\n})\n","import type { dns } from \"@highstate/library\"\nimport type { types } from \"@highstate/cert-manager\"\nimport type { Input } from \"@pulumi/pulumi\"\nimport type { Provider } from \"@pulumi/kubernetes\"\nimport { capitalize } from \"remeda\"\nimport { toPromise } from \"@highstate/pulumi\"\n\nexport async function createDns01Solver(\n dnsProviderInput: Input<dns.Provider>,\n provider: Provider,\n): Promise<types.input.cert_manager.v1.ClusterIssuerSpecAcmeSolversDns01> {\n const dnsProvider = await toPromise(dnsProviderInput)\n\n const implName = `create${capitalize(dnsProvider.type)}Dns01Solver`\n const implModule = (await import(`@highstate/${dnsProvider.type}`)) as Record<string, unknown>\n\n const implFunction = implModule[implName] as (\n dnsProvider: dns.Provider,\n provider: Provider,\n ) => types.input.cert_manager.v1.ClusterIssuerSpecAcmeSolversDns01\n\n return implFunction(dnsProvider, provider)\n}\n"],"mappings":";;;;;AAAA,SAAS,WAAW;AACpB,SAAS,SAAS,gBAAgB;AAClC,SAAS,oBAAoB;;;ACE7B,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAE1B,eAAsB,kBACpB,kBACAA,WACwE;AACxE,QAAM,cAAc,MAAM,UAAU,gBAAgB;AAEpD,QAAM,WAAW,SAAS,WAAW,YAAY,IAAI,CAAC;AACtD,QAAM,aAAc,MAAM,OAAO,cAAc,YAAY,IAAI;AAE/D,QAAM,eAAe,WAAW,QAAQ;AAKxC,SAAO,aAAa,aAAaA,SAAQ;AAC3C;;;ADhBA,IAAM,EAAE,MAAM,QAAQ,QAAQ,IAAI,QAAQ,IAAI,cAAc;AAE5D,IAAM,WAAW,MAAM,YAAY,OAAO,UAAU;AACpD,IAAM,cAAc,MAAM,kBAAkB,OAAO,aAAa,QAAQ;AAExE,IAAI,aAAa,GAAG;AAAA,EAClB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,SAAS;AAAA,UACP;AAAA,YACE,OAAO;AAAA,YACP,UAAU,EAAE,UAAU,CAAC,OAAO,YAAY,MAAM,EAAE;AAAA,UACpD;AAAA,QACF;AAAA,QACA,qBAAqB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,EAAE,SAAS;AACb;AAEA,IAAO,uBAAQ,QAAQ;AAAA,EACrB,WAAW;AAAA,IACT,aAAa,SAAS,OAAO,WAAW,IAAI;AAAA,IAC5C,mBAAmB;AAAA,EACrB;AACF,CAAC;","names":["provider"]}
@@ -1,35 +1,61 @@
1
- import { text } from '@highstate/contract';
2
- import { k8s } from '@highstate/library';
3
- import { forUnit, toPromise } from '@highstate/pulumi';
4
- import { Provider, apps, core } from '@pulumi/kubernetes';
5
-
6
- const { name, secrets, outputs } = forUnit(k8s.existingCluster);
7
- const kubeconfig = secrets.kubeconfig.apply(JSON.stringify);
8
- const provider = new Provider(name, { kubeconfig });
9
- let cni;
10
- try {
11
- await toPromise(apps.v1.DaemonSet.get("cilium", "kube-system/cilium", { provider }).id);
1
+ // src/units/existing-cluster/index.ts
2
+ import { text } from "@highstate/contract";
3
+ import { k8s } from "@highstate/library";
4
+ import { forUnit, getUnitInstanceName, secret, toPromise } from "@highstate/pulumi";
5
+ import { core, Provider } from "@pulumi/kubernetes";
6
+ import { KubeConfig, AppsV1Api, CoreV1Api } from "@kubernetes/client-node";
7
+ var { name, args, secrets, outputs } = forUnit(k8s.existingCluster);
8
+ var kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify));
9
+ var provider = new Provider(name, { kubeconfig: kubeconfigContent });
10
+ var cni;
11
+ var kubeConfig = new KubeConfig();
12
+ kubeConfig.loadFromString(kubeconfigContent);
13
+ var appsApi = kubeConfig.makeApiClient(AppsV1Api);
14
+ var nodeApi = kubeConfig.makeApiClient(CoreV1Api);
15
+ var isCilium = await appsApi.readNamespacedDaemonSet({ name: "cilium", namespace: "kube-system" }).then(() => true).catch(() => false);
16
+ if (isCilium) {
12
17
  cni = "cilium";
13
- } catch {
14
- console.log("there is no cilium CNI");
15
18
  }
16
- const kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider });
17
- var index = outputs({
19
+ var isPrivateIp = (ip) => {
20
+ const privateIpRegex = /^(10|172\.16|192\.168)\./;
21
+ return privateIpRegex.test(ip);
22
+ };
23
+ var nodes = await nodeApi.listNode();
24
+ var externalIps = nodes.items.flatMap((node) => {
25
+ const addresses = node.status?.addresses ?? [];
26
+ const externalIp = addresses.find((address) => address.type === "ExternalIP");
27
+ const internalIp = addresses.find((address) => address.type === "InternalIP");
28
+ const result = [];
29
+ if (externalIp?.address) {
30
+ result.push(externalIp.address);
31
+ }
32
+ if (internalIp?.address && args.internalIpsPolicy === "always") {
33
+ result.push(internalIp.address);
34
+ }
35
+ if (internalIp?.address && args.internalIpsPolicy === "public" && !isPrivateIp(internalIp.address)) {
36
+ result.push(internalIp.address);
37
+ }
38
+ return result;
39
+ });
40
+ var kubeSystem = core.v1.Namespace.get("kube-system", "kube-system", { provider });
41
+ var existing_cluster_default = outputs({
18
42
  cluster: {
19
43
  info: {
20
44
  id: kubeSystem.metadata.uid,
21
45
  name,
22
- cni
46
+ cni,
47
+ externalIps
23
48
  },
24
- kubeconfig
49
+ kubeconfig: secret(kubeconfigContent)
25
50
  },
26
51
  $terminals: {
27
52
  management: {
28
- title: "Cluster Management",
53
+ title: `K8S: ${getUnitInstanceName()}`,
54
+ description: "Manage the cluster using kubectl and helm",
29
55
  image: "ghcr.io/exeteres/highstate/terminal-kubectl",
30
56
  command: ["bash", "/welcome.sh"],
31
57
  files: {
32
- "/kubeconfig": kubeconfig,
58
+ "/kubeconfig": secret(kubeconfigContent),
33
59
  "/welcome.sh": text`
34
60
  if [ "$HIGHSTATE_TERMINAL_FIRST_LAUNCH" = "1" ]; then
35
61
  echo "Connecting to the cluster..."
@@ -52,5 +78,7 @@ var index = outputs({
52
78
  cni: cni ?? "unknown"
53
79
  }
54
80
  });
55
-
56
- export { index as default };
81
+ export {
82
+ existing_cluster_default as default
83
+ };
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/units/existing-cluster/index.ts"],"sourcesContent":["import { text } from \"@highstate/contract\"\nimport { k8s } from \"@highstate/library\"\nimport { forUnit, getUnitInstanceName, secret, toPromise } from \"@highstate/pulumi\"\nimport { core, Provider } from \"@pulumi/kubernetes\"\nimport { KubeConfig, AppsV1Api, CoreV1Api } from \"@kubernetes/client-node\"\n\nconst { name, args, secrets, outputs } = forUnit(k8s.existingCluster)\n\nconst kubeconfigContent = await toPromise(secrets.kubeconfig.apply(JSON.stringify))\n\nconst provider = new Provider(name, { kubeconfig: kubeconfigContent })\n\nlet cni: string | undefined\n\nconst kubeConfig = new KubeConfig()\nkubeConfig.loadFromString(kubeconfigContent)\n\nconst appsApi = kubeConfig.makeApiClient(AppsV1Api)\nconst nodeApi = kubeConfig.makeApiClient(CoreV1Api)\n\nconst isCilium = await appsApi\n .readNamespacedDaemonSet({ name: \"cilium\", namespace: \"kube-system\" })\n .then(() => true)\n .catch(() => false)\n\nif (isCilium) {\n cni = \"cilium\"\n}\n\nconst isPrivateIp = (ip: string) => {\n const privateIpRegex = /^(10|172\\.16|192\\.168)\\./\n return privateIpRegex.test(ip)\n}\n\nconst nodes = await nodeApi.listNode()\n\nconst externalIps = nodes.items.flatMap(node => {\n const addresses = node.status?.addresses ?? []\n const externalIp = addresses.find(address => address.type === \"ExternalIP\")\n const internalIp = addresses.find(address => address.type === \"InternalIP\")\n\n const result: string[] = []\n\n if (externalIp?.address) {\n result.push(externalIp.address)\n }\n\n if (internalIp?.address && args.internalIpsPolicy === \"always\") {\n result.push(internalIp.address)\n }\n\n if (\n internalIp?.address &&\n args.internalIpsPolicy === \"public\" &&\n !isPrivateIp(internalIp.address)\n ) {\n result.push(internalIp.address)\n }\n\n return result\n})\n\nconst kubeSystem = core.v1.Namespace.get(\"kube-system\", \"kube-system\", { provider })\n\nexport default outputs({\n cluster: {\n info: {\n id: kubeSystem.metadata.uid,\n name,\n cni,\n externalIps,\n },\n kubeconfig: secret(kubeconfigContent),\n },\n\n $terminals: {\n management: {\n title: `K8S: ${getUnitInstanceName()}`,\n description: \"Manage the cluster using kubectl and helm\",\n image: \"ghcr.io/exeteres/highstate/terminal-kubectl\",\n command: [\"bash\", \"/welcome.sh\"],\n files: {\n \"/kubeconfig\": secret(kubeconfigContent),\n\n \"/welcome.sh\": text`\n if [ \"$HIGHSTATE_TERMINAL_FIRST_LAUNCH\" = \"1\" ]; then\n echo \"Connecting to the cluster...\"\n kubectl cluster-info\n\n echo \"Use 'kubectl' and 'helm' to manage the cluster.\"\n echo\n fi\n\n exec script -q -c bash /dev/null\n `,\n },\n env: {\n KUBECONFIG: \"/kubeconfig\",\n },\n },\n },\n\n $status: {\n clusterId: kubeSystem.metadata.uid,\n cni: cni ?? \"unknown\",\n },\n})\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,WAAW;AACpB,SAAS,SAAS,qBAAqB,QAAQ,iBAAiB;AAChE,SAAS,MAAM,gBAAgB;AAC/B,SAAS,YAAY,WAAW,iBAAiB;AAEjD,IAAM,EAAE,MAAM,MAAM,SAAS,QAAQ,IAAI,QAAQ,IAAI,eAAe;AAEpE,IAAM,oBAAoB,MAAM,UAAU,QAAQ,WAAW,MAAM,KAAK,SAAS,CAAC;AAElF,IAAM,WAAW,IAAI,SAAS,MAAM,EAAE,YAAY,kBAAkB,CAAC;AAErE,IAAI;AAEJ,IAAM,aAAa,IAAI,WAAW;AAClC,WAAW,eAAe,iBAAiB;AAE3C,IAAM,UAAU,WAAW,cAAc,SAAS;AAClD,IAAM,UAAU,WAAW,cAAc,SAAS;AAElD,IAAM,WAAW,MAAM,QACpB,wBAAwB,EAAE,MAAM,UAAU,WAAW,cAAc,CAAC,EACpE,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AAEpB,IAAI,UAAU;AACZ,QAAM;AACR;AAEA,IAAM,cAAc,CAAC,OAAe;AAClC,QAAM,iBAAiB;AACvB,SAAO,eAAe,KAAK,EAAE;AAC/B;AAEA,IAAM,QAAQ,MAAM,QAAQ,SAAS;AAErC,IAAM,cAAc,MAAM,MAAM,QAAQ,UAAQ;AAC9C,QAAM,YAAY,KAAK,QAAQ,aAAa,CAAC;AAC7C,QAAM,aAAa,UAAU,KAAK,aAAW,QAAQ,SAAS,YAAY;AAC1E,QAAM,aAAa,UAAU,KAAK,aAAW,QAAQ,SAAS,YAAY;AAE1E,QAAM,SAAmB,CAAC;AAE1B,MAAI,YAAY,SAAS;AACvB,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AAEA,MAAI,YAAY,WAAW,KAAK,sBAAsB,UAAU;AAC9D,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AAEA,MACE,YAAY,WACZ,KAAK,sBAAsB,YAC3B,CAAC,YAAY,WAAW,OAAO,GAC/B;AACA,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AAEA,SAAO;AACT,CAAC;AAED,IAAM,aAAa,KAAK,GAAG,UAAU,IAAI,eAAe,eAAe,EAAE,SAAS,CAAC;AAEnF,IAAO,2BAAQ,QAAQ;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,IAAI,WAAW,SAAS;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,OAAO,iBAAiB;AAAA,EACtC;AAAA,EAEA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,OAAO,QAAQ,oBAAoB,CAAC;AAAA,MACpC,aAAa;AAAA,MACb,OAAO;AAAA,MACP,SAAS,CAAC,QAAQ,aAAa;AAAA,MAC/B,OAAO;AAAA,QACL,eAAe,OAAO,iBAAiB;AAAA,QAEvC,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWjB;AAAA,MACA,KAAK;AAAA,QACH,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS;AAAA,IACP,WAAW,WAAW,SAAS;AAAA,IAC/B,KAAK,OAAO;AAAA,EACd;AACF,CAAC;","names":[]}
package/package.json CHANGED
@@ -1,17 +1,15 @@
1
1
  {
2
2
  "name": "@highstate/k8s",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "type": "module",
5
- "module": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
5
  "files": [
8
- "assets",
9
- "dist"
6
+ "dist",
7
+ "src"
10
8
  ],
11
9
  "exports": {
12
10
  ".": {
13
- "default": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
11
+ "types": "./src/index.ts",
12
+ "default": "./dist/index.js"
15
13
  },
16
14
  "./access-point": "./dist/units/access-point/index.js",
17
15
  "./cert-manager": "./dist/units/cert-manager/index.js",
@@ -22,19 +20,20 @@
22
20
  "access": "public"
23
21
  },
24
22
  "scripts": {
25
- "build": "pkgroll --tsconfig=tsconfig.build.json",
23
+ "build": "highstate build",
26
24
  "update-charts": "../../scripts/update-charts.sh ./assets/charts.json",
27
25
  "generate-crds": "./scripts/generate-crds.sh"
28
26
  },
29
27
  "dependencies": {
30
- "@highstate/cert-manager": "^0.7.2",
31
- "@highstate/common": "^0.7.2",
32
- "@highstate/contract": "^0.7.2",
33
- "@highstate/gateway-api": "^0.7.2",
34
- "@highstate/pulumi": "^0.7.2",
28
+ "@highstate/cert-manager": "^0.7.3",
29
+ "@highstate/common": "^0.7.3",
30
+ "@highstate/contract": "^0.7.3",
31
+ "@highstate/gateway-api": "^0.7.3",
32
+ "@highstate/pulumi": "^0.7.3",
33
+ "@kubernetes/client-node": "^1.1.0",
35
34
  "@pulumi/command": "^1.0.2",
36
35
  "@pulumi/kubernetes": "^4.18.0",
37
- "@pulumi/pulumi": "^3.152.0",
36
+ "@pulumi/pulumi": "patch:@pulumi/pulumi@npm%3A3.159.0#~/.yarn/patches/@pulumi-pulumi-npm-3.159.0-d07eefce5c.patch",
38
37
  "crypto-hash": "^3.1.0",
39
38
  "deepmerge-ts": "^7.1.5",
40
39
  "glob": "^11.0.1",
@@ -46,7 +45,7 @@
46
45
  "@highstate/library": "workspace:^0.4.4"
47
46
  },
48
47
  "devDependencies": {
49
- "pkgroll": "^2.5.1"
48
+ "@highstate/cli": "^0.7.3"
50
49
  },
51
- "gitHead": "e177535015e0fa3c74ae8ddc0bc6d31b191d2c54"
50
+ "gitHead": "5cf7cec27262c8fa1d96f6478833b94841459d64"
52
51
  }