@highstate/k8s 0.9.31 → 0.9.32

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 (45) hide show
  1. package/dist/{chunk-4YC2SLCU.js → chunk-2F2IID7N.js} +8 -3
  2. package/dist/chunk-2F2IID7N.js.map +1 -0
  3. package/dist/{chunk-64LNVTHJ.js → chunk-6FUARTRJ.js} +5 -5
  4. package/dist/{chunk-64LNVTHJ.js.map → chunk-6FUARTRJ.js.map} +1 -1
  5. package/dist/{chunk-2FKGGWPJ.js → chunk-6IVLEA6D.js} +3 -3
  6. package/dist/{chunk-2FKGGWPJ.js.map → chunk-6IVLEA6D.js.map} +1 -1
  7. package/dist/{chunk-HOARC4LU.js → chunk-GEXFRUDO.js} +40 -23
  8. package/dist/chunk-GEXFRUDO.js.map +1 -0
  9. package/dist/{chunk-XYJNM2EN.js → chunk-OEOMZP2C.js} +114 -12
  10. package/dist/chunk-OEOMZP2C.js.map +1 -0
  11. package/dist/{chunk-ARG3I734.js → chunk-WJQSKV2K.js} +3 -3
  12. package/dist/{chunk-ARG3I734.js.map → chunk-WJQSKV2K.js.map} +1 -1
  13. package/dist/deployment-BT6MUIT5.js +8 -0
  14. package/dist/{deployment-PKZ4IQMG.js.map → deployment-BT6MUIT5.js.map} +1 -1
  15. package/dist/highstate.manifest.json +2 -2
  16. package/dist/impl/gateway-route.js +295 -73
  17. package/dist/impl/gateway-route.js.map +1 -1
  18. package/dist/impl/tls-certificate.js +2 -2
  19. package/dist/impl/tls-certificate.js.map +1 -1
  20. package/dist/index.js +7 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/stateful-set-O44CY62K.js +8 -0
  23. package/dist/{stateful-set-OMPM2F7W.js.map → stateful-set-O44CY62K.js.map} +1 -1
  24. package/dist/units/cert-manager/index.js +4 -4
  25. package/dist/units/gateway-api/index.js +1 -1
  26. package/dist/units/gateway-api/index.js.map +1 -1
  27. package/dist/units/reduced-access-cluster/index.js +3 -3
  28. package/package.json +10 -10
  29. package/src/container.ts +8 -0
  30. package/src/gateway/gateway.ts +22 -5
  31. package/src/gateway/http-route.ts +6 -1
  32. package/src/gateway/index.ts +2 -0
  33. package/src/gateway/tcp-route.ts +87 -0
  34. package/src/gateway/udp-route.ts +87 -0
  35. package/src/impl/gateway-route.ts +418 -85
  36. package/src/impl/tls-certificate.ts +1 -1
  37. package/src/index.ts +1 -0
  38. package/src/tls.ts +9 -1
  39. package/src/units/gateway-api/index.ts +1 -1
  40. package/src/workload.ts +56 -21
  41. package/dist/chunk-4YC2SLCU.js.map +0 -1
  42. package/dist/chunk-HOARC4LU.js.map +0 -1
  43. package/dist/chunk-XYJNM2EN.js.map +0 -1
  44. package/dist/deployment-PKZ4IQMG.js +0 -8
  45. package/dist/stateful-set-OMPM2F7W.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stateful-set.ts"],"names":["service","args","podTemplate","labels"],"mappings":"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","file":"chunk-ARG3I734.js","sourcesContent":["import type { AccessPointRoute } from \"@highstate/common\"\nimport type { k8s } from \"@highstate/library\"\nimport type { Container } from \"./container\"\nimport type { NetworkPolicy } from \"./network-policy\"\nimport type { Service } from \"./service\"\nimport { getOrCreate, type UnitTerminal } from \"@highstate/contract\"\nimport {\n type ComponentResourceOptions,\n type Input,\n type Inputs,\n interpolate,\n type Output,\n output,\n toPromise,\n type Unwrap,\n} from \"@highstate/pulumi\"\nimport { apps, type types } from \"@pulumi/kubernetes\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { omit } from \"remeda\"\nimport { Namespace } from \"./namespace\"\nimport { getProvider, mapMetadata } from \"./shared\"\nimport {\n ExposableWorkload,\n type ExposableWorkloadArgs,\n exposableWorkloadExtraArgs,\n getExposableWorkloadComponents,\n type WorkloadTerminalArgs,\n} from \"./workload\"\n\nexport type StatefulSetArgs = Omit<ExposableWorkloadArgs, \"existing\"> &\n Omit<Partial<types.input.apps.v1.StatefulSetSpec>, \"template\"> & {\n template?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Partial<types.input.core.v1.PodSpec>\n }\n }\n\nexport type CreateOrGetStatefulSetArgs = StatefulSetArgs & {\n /**\n * The entity to use to determine the stateful set to patch.\n */\n existing: Input<k8s.StatefulSet> | undefined\n}\n\nexport abstract class StatefulSet extends ExposableWorkload {\n protected constructor(\n type: string,\n name: string,\n args: Inputs,\n opts: ComponentResourceOptions | undefined,\n\n apiVersion: Output<string>,\n kind: Output<string>,\n terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,\n containers: Output<Container[]>,\n namespace: Output<Namespace>,\n metadata: Output<types.output.meta.v1.ObjectMeta>,\n networkPolicy: Output<NetworkPolicy | undefined>,\n\n service: Output<Service | undefined>,\n routes: Output<AccessPointRoute[]>,\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 super(\n type,\n name,\n args,\n opts,\n apiVersion,\n kind,\n terminalArgs,\n containers,\n namespace,\n metadata,\n networkPolicy,\n service,\n routes,\n )\n }\n\n /**\n * The Highstate stateful set entity.\n */\n get entity(): Output<k8s.StatefulSet> {\n return output({\n type: \"stateful-set\",\n clusterId: this.cluster.id,\n clusterName: this.cluster.name,\n metadata: this.metadata,\n service: this.service.entity,\n })\n }\n\n /**\n * Creates a new stateful set.\n */\n static create(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions): StatefulSet {\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Creates a new stateful set or patches an existing one.\n *\n * @param name The name of the resource. May not be the same as the stateful set name.\n * @param args The arguments to create or patch the stateful set with.\n * @param opts Optional resource options.\n */\n static createOrPatch(\n name: string,\n args: CreateOrGetStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n if (args.existing) {\n return new StatefulSetPatch(name, {\n ...args,\n name: output(args.existing).metadata.name,\n namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),\n })\n }\n\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Creates a new stateful set or gets an existing one.\n *\n * @param name The name of the resource. May not be the same as the stateful set name. Will not be used when existing stateful set is retrieved.\n * @param args The arguments to create or get the stateful set with.\n * @param opts Optional resource options.\n */\n static async createOrGet(\n name: string,\n args: CreateOrGetStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): Promise<StatefulSet> {\n if (args.existing) {\n return await StatefulSet.forAsync(args.existing, output(args.namespace).cluster)\n }\n\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Patches an existing stateful set.\n *\n * Will throw an error if the stateful set does not exist.\n *\n * @param name The name of the resource. May not be the same as the stateful set name.\n * @param args The arguments to patch the stateful set with.\n * @param opts Optional resource options.\n */\n static patch(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions): StatefulSet {\n return new StatefulSetPatch(name, args, opts)\n }\n\n /**\n * Wraps an existing Kubernetes stateful set.\n */\n static wrap(\n name: string,\n args: WrappedStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n return new WrappedStatefulSet(name, args, opts)\n }\n\n /**\n * Gets an existing stateful set.\n *\n * Will throw an error if the stateful set does not exist.\n */\n static get(\n name: string,\n args: ExternalStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n return new ExternalStatefulSet(name, args, opts)\n }\n\n private static readonly statefulSetCache = new Map<string, StatefulSet>()\n\n /**\n * Gets an existing stateful set for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the stateful set for.\n * @param cluster The cluster where the stateful set is located.\n */\n static for(entity: k8s.StatefulSet, cluster: Input<k8s.Cluster>): StatefulSet {\n return getOrCreate(\n StatefulSet.statefulSetCache,\n `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,\n name => {\n return StatefulSet.get(name, {\n name: entity.metadata.name,\n namespace: Namespace.forResource(entity, cluster),\n })\n },\n )\n }\n\n /**\n * Gets an existing stateful set for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the stateful set for.\n * @param cluster The cluster where the stateful set is located.\n */\n static async forAsync(\n entity: Input<k8s.StatefulSet>,\n cluster: Input<k8s.Cluster>,\n ): Promise<StatefulSet> {\n const resolvedEntity = await toPromise(entity)\n return StatefulSet.for(resolvedEntity, cluster)\n }\n\n protected getTerminalMeta(): Output<UnitTerminal[\"meta\"]> {\n return output({\n title: \"StatefulSet\",\n globalTitle: interpolate`StatefulSet | ${this.metadata.name}`,\n description: \"The shell inside the stateful set.\",\n icon: \"devicon:kubernetes\",\n })\n }\n\n protected get resourceType(): string {\n return \"statefulset\"\n }\n}\n\nclass CreatedStatefulSet extends StatefulSet {\n constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {\n const { labels, podTemplate, networkPolicy, containers, service, routes } =\n getExposableWorkloadComponents(\n name,\n {\n ...args,\n\n // force create a service since it is required for stateful sets\n service: output(args.service).apply(service => ({ ...service })),\n },\n () => this,\n opts,\n )\n\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return new apps.v1.StatefulSet(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: output({ args, podTemplate, labels, service }).apply(\n ({ args, podTemplate, labels, service }) => {\n return deepmerge(\n {\n serviceName: service?.metadata.name,\n template: podTemplate,\n selector: { matchLabels: labels },\n },\n omit(args, exposableWorkloadExtraArgs),\n ) as types.input.apps.v1.StatefulSetSpec\n },\n ),\n },\n {\n ...opts,\n parent: this,\n provider: getProvider(cluster),\n },\n )\n })\n\n super(\n \"highstate:k8s:StatefulSet\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output(args.terminal ?? {}),\n containers,\n output(args.namespace),\n statefulSet.metadata,\n networkPolicy,\n\n service,\n routes,\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n\nclass StatefulSetPatch extends StatefulSet {\n constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {\n const { labels, podTemplate, networkPolicy, containers, service, routes } =\n getExposableWorkloadComponents(name, args, () => this, opts)\n\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return new apps.v1.StatefulSetPatch(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: output({ args, podTemplate, labels }).apply(({ args, podTemplate, labels }) => {\n return deepmerge(\n {\n template: podTemplate,\n selector: { matchLabels: labels },\n },\n omit(args, exposableWorkloadExtraArgs),\n ) as types.input.apps.v1.StatefulSetSpec\n }),\n },\n {\n ...opts,\n parent: this,\n provider: getProvider(cluster),\n },\n )\n })\n\n super(\n \"highstate:k8s:StatefulSetPatch\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output(args.terminal ?? {}),\n containers,\n output(args.namespace),\n statefulSet.metadata,\n networkPolicy,\n\n service,\n routes,\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n\nexport type WrappedStatefulSetArgs = {\n /**\n * The underlying Kubernetes stateful set to wrap.\n */\n statefulSet: Input<apps.v1.StatefulSet>\n\n // TODO: remove\n service?: Input<Service>\n\n /**\n * The namespace where the stateful set is located.\n */\n namespace: Input<Namespace>\n\n /**\n * The args for the terminal to use.\n */\n terminal?: Input<WorkloadTerminalArgs>\n}\n\nclass WrappedStatefulSet extends StatefulSet {\n constructor(name: string, args: WrappedStatefulSetArgs, opts?: ComponentResourceOptions) {\n super(\n \"highstate:k8s:WrappedStatefulSet\",\n name,\n args,\n opts,\n\n output(args.statefulSet).apiVersion,\n output(args.statefulSet).kind,\n output(args.terminal ?? {}),\n output([]),\n output(args.namespace),\n output(args.statefulSet).metadata,\n\n output(undefined),\n output(args.service),\n output([]),\n\n output(args.statefulSet).spec,\n output(args.statefulSet).status,\n )\n }\n}\n\nexport type ExternalStatefulSetArgs = {\n /**\n * The name of the stateful set to get.\n */\n name: Input<string>\n\n /**\n * The namespace where the stateful set is located.\n */\n namespace: Input<Namespace>\n}\n\nclass ExternalStatefulSet extends StatefulSet {\n constructor(name: string, args: ExternalStatefulSetArgs, opts?: ComponentResourceOptions) {\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return apps.v1.StatefulSet.get(\n name,\n interpolate`${output(args.namespace).metadata.name}/${args.name}`,\n { ...opts, parent: this, provider: getProvider(cluster) },\n )\n })\n\n super(\n \"highstate:k8s:ExternalStatefulSet\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output({}),\n output([]),\n output(args.namespace),\n statefulSet.metadata,\n\n output(undefined),\n output(undefined),\n output([]),\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/stateful-set.ts"],"names":["service","args","podTemplate","labels"],"mappings":"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","file":"chunk-WJQSKV2K.js","sourcesContent":["import type { AccessPointRoute } from \"@highstate/common\"\nimport type { k8s } from \"@highstate/library\"\nimport type { Container } from \"./container\"\nimport type { NetworkPolicy } from \"./network-policy\"\nimport type { Service } from \"./service\"\nimport { getOrCreate, type UnitTerminal } from \"@highstate/contract\"\nimport {\n type ComponentResourceOptions,\n type Input,\n type Inputs,\n interpolate,\n type Output,\n output,\n toPromise,\n type Unwrap,\n} from \"@highstate/pulumi\"\nimport { apps, type types } from \"@pulumi/kubernetes\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { omit } from \"remeda\"\nimport { Namespace } from \"./namespace\"\nimport { getProvider, mapMetadata } from \"./shared\"\nimport {\n ExposableWorkload,\n type ExposableWorkloadArgs,\n exposableWorkloadExtraArgs,\n getExposableWorkloadComponents,\n type WorkloadTerminalArgs,\n} from \"./workload\"\n\nexport type StatefulSetArgs = Omit<ExposableWorkloadArgs, \"existing\"> &\n Omit<Partial<types.input.apps.v1.StatefulSetSpec>, \"template\"> & {\n template?: {\n metadata?: types.input.meta.v1.ObjectMeta\n spec?: Partial<types.input.core.v1.PodSpec>\n }\n }\n\nexport type CreateOrGetStatefulSetArgs = StatefulSetArgs & {\n /**\n * The entity to use to determine the stateful set to patch.\n */\n existing: Input<k8s.StatefulSet> | undefined\n}\n\nexport abstract class StatefulSet extends ExposableWorkload {\n protected constructor(\n type: string,\n name: string,\n args: Inputs,\n opts: ComponentResourceOptions | undefined,\n\n apiVersion: Output<string>,\n kind: Output<string>,\n terminalArgs: Output<Unwrap<WorkloadTerminalArgs>>,\n containers: Output<Container[]>,\n namespace: Output<Namespace>,\n metadata: Output<types.output.meta.v1.ObjectMeta>,\n networkPolicy: Output<NetworkPolicy | undefined>,\n\n service: Output<Service | undefined>,\n routes: Output<AccessPointRoute[]>,\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 super(\n type,\n name,\n args,\n opts,\n apiVersion,\n kind,\n terminalArgs,\n containers,\n namespace,\n metadata,\n networkPolicy,\n service,\n routes,\n )\n }\n\n /**\n * The Highstate stateful set entity.\n */\n get entity(): Output<k8s.StatefulSet> {\n return output({\n type: \"stateful-set\",\n clusterId: this.cluster.id,\n clusterName: this.cluster.name,\n metadata: this.metadata,\n service: this.service.entity,\n })\n }\n\n /**\n * Creates a new stateful set.\n */\n static create(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions): StatefulSet {\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Creates a new stateful set or patches an existing one.\n *\n * @param name The name of the resource. May not be the same as the stateful set name.\n * @param args The arguments to create or patch the stateful set with.\n * @param opts Optional resource options.\n */\n static createOrPatch(\n name: string,\n args: CreateOrGetStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n if (args.existing) {\n return new StatefulSetPatch(name, {\n ...args,\n name: output(args.existing).metadata.name,\n namespace: Namespace.forResourceAsync(args.existing, output(args.namespace).cluster),\n })\n }\n\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Creates a new stateful set or gets an existing one.\n *\n * @param name The name of the resource. May not be the same as the stateful set name. Will not be used when existing stateful set is retrieved.\n * @param args The arguments to create or get the stateful set with.\n * @param opts Optional resource options.\n */\n static async createOrGet(\n name: string,\n args: CreateOrGetStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): Promise<StatefulSet> {\n if (args.existing) {\n return await StatefulSet.forAsync(args.existing, output(args.namespace).cluster)\n }\n\n return new CreatedStatefulSet(name, args, opts)\n }\n\n /**\n * Patches an existing stateful set.\n *\n * Will throw an error if the stateful set does not exist.\n *\n * @param name The name of the resource. May not be the same as the stateful set name.\n * @param args The arguments to patch the stateful set with.\n * @param opts Optional resource options.\n */\n static patch(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions): StatefulSet {\n return new StatefulSetPatch(name, args, opts)\n }\n\n /**\n * Wraps an existing Kubernetes stateful set.\n */\n static wrap(\n name: string,\n args: WrappedStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n return new WrappedStatefulSet(name, args, opts)\n }\n\n /**\n * Gets an existing stateful set.\n *\n * Will throw an error if the stateful set does not exist.\n */\n static get(\n name: string,\n args: ExternalStatefulSetArgs,\n opts?: ComponentResourceOptions,\n ): StatefulSet {\n return new ExternalStatefulSet(name, args, opts)\n }\n\n private static readonly statefulSetCache = new Map<string, StatefulSet>()\n\n /**\n * Gets an existing stateful set for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the stateful set for.\n * @param cluster The cluster where the stateful set is located.\n */\n static for(entity: k8s.StatefulSet, cluster: Input<k8s.Cluster>): StatefulSet {\n return getOrCreate(\n StatefulSet.statefulSetCache,\n `${entity.clusterName}.${entity.metadata.namespace}.${entity.metadata.name}.${entity.clusterId}`,\n name => {\n return StatefulSet.get(name, {\n name: entity.metadata.name,\n namespace: Namespace.forResource(entity, cluster),\n })\n },\n )\n }\n\n /**\n * Gets an existing stateful set for a given entity.\n * Prefer this method over `get` when possible.\n *\n * It automatically names the resource with the following format: `{clusterName}.{namespace}.{name}.{clusterId}`.\n *\n * This method is idempotent and will return the same instance for the same entity.\n *\n * @param entity The entity to get the stateful set for.\n * @param cluster The cluster where the stateful set is located.\n */\n static async forAsync(\n entity: Input<k8s.StatefulSet>,\n cluster: Input<k8s.Cluster>,\n ): Promise<StatefulSet> {\n const resolvedEntity = await toPromise(entity)\n return StatefulSet.for(resolvedEntity, cluster)\n }\n\n protected getTerminalMeta(): Output<UnitTerminal[\"meta\"]> {\n return output({\n title: \"StatefulSet\",\n globalTitle: interpolate`StatefulSet | ${this.metadata.name}`,\n description: \"The shell inside the stateful set.\",\n icon: \"devicon:kubernetes\",\n })\n }\n\n protected get resourceType(): string {\n return \"statefulset\"\n }\n}\n\nclass CreatedStatefulSet extends StatefulSet {\n constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {\n const { labels, podTemplate, networkPolicy, containers, service, routes } =\n getExposableWorkloadComponents(\n name,\n {\n ...args,\n\n // force create a service since it is required for stateful sets\n service: output(args.service).apply(service => ({ ...service })),\n },\n () => this,\n opts,\n )\n\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return new apps.v1.StatefulSet(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: output({ args, podTemplate, labels, service }).apply(\n ({ args, podTemplate, labels, service }) => {\n return deepmerge(\n {\n serviceName: service?.metadata.name,\n template: podTemplate,\n selector: { matchLabels: labels },\n },\n omit(args, exposableWorkloadExtraArgs),\n ) as types.input.apps.v1.StatefulSetSpec\n },\n ),\n },\n {\n ...opts,\n parent: this,\n provider: getProvider(cluster),\n },\n )\n })\n\n super(\n \"highstate:k8s:StatefulSet\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output(args.terminal ?? {}),\n containers,\n output(args.namespace),\n statefulSet.metadata,\n networkPolicy,\n\n service,\n routes,\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n\nclass StatefulSetPatch extends StatefulSet {\n constructor(name: string, args: StatefulSetArgs, opts?: ComponentResourceOptions) {\n const { labels, podTemplate, networkPolicy, containers, service, routes } =\n getExposableWorkloadComponents(name, args, () => this, opts)\n\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return new apps.v1.StatefulSetPatch(\n name,\n {\n metadata: mapMetadata(args, name),\n spec: output({ args, podTemplate, labels }).apply(({ args, podTemplate, labels }) => {\n return deepmerge(\n {\n template: podTemplate,\n selector: { matchLabels: labels },\n },\n omit(args, exposableWorkloadExtraArgs),\n ) as types.input.apps.v1.StatefulSetSpec\n }),\n },\n {\n ...opts,\n parent: this,\n provider: getProvider(cluster),\n },\n )\n })\n\n super(\n \"highstate:k8s:StatefulSetPatch\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output(args.terminal ?? {}),\n containers,\n output(args.namespace),\n statefulSet.metadata,\n networkPolicy,\n\n service,\n routes,\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n\nexport type WrappedStatefulSetArgs = {\n /**\n * The underlying Kubernetes stateful set to wrap.\n */\n statefulSet: Input<apps.v1.StatefulSet>\n\n // TODO: remove\n service?: Input<Service>\n\n /**\n * The namespace where the stateful set is located.\n */\n namespace: Input<Namespace>\n\n /**\n * The args for the terminal to use.\n */\n terminal?: Input<WorkloadTerminalArgs>\n}\n\nclass WrappedStatefulSet extends StatefulSet {\n constructor(name: string, args: WrappedStatefulSetArgs, opts?: ComponentResourceOptions) {\n super(\n \"highstate:k8s:WrappedStatefulSet\",\n name,\n args,\n opts,\n\n output(args.statefulSet).apiVersion,\n output(args.statefulSet).kind,\n output(args.terminal ?? {}),\n output([]),\n output(args.namespace),\n output(args.statefulSet).metadata,\n\n output(undefined),\n output(args.service),\n output([]),\n\n output(args.statefulSet).spec,\n output(args.statefulSet).status,\n )\n }\n}\n\nexport type ExternalStatefulSetArgs = {\n /**\n * The name of the stateful set to get.\n */\n name: Input<string>\n\n /**\n * The namespace where the stateful set is located.\n */\n namespace: Input<Namespace>\n}\n\nclass ExternalStatefulSet extends StatefulSet {\n constructor(name: string, args: ExternalStatefulSetArgs, opts?: ComponentResourceOptions) {\n const statefulSet = output(args.namespace).cluster.apply(cluster => {\n return apps.v1.StatefulSet.get(\n name,\n interpolate`${output(args.namespace).metadata.name}/${args.name}`,\n { ...opts, parent: this, provider: getProvider(cluster) },\n )\n })\n\n super(\n \"highstate:k8s:ExternalStatefulSet\",\n name,\n args,\n opts,\n\n statefulSet.apiVersion,\n statefulSet.kind,\n output({}),\n output([]),\n output(args.namespace),\n statefulSet.metadata,\n\n output(undefined),\n output(undefined),\n output([]),\n\n statefulSet.spec,\n statefulSet.status,\n )\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export { Deployment } from './chunk-6IVLEA6D.js';
2
+ import './chunk-GEXFRUDO.js';
3
+ import './chunk-SI7X6N46.js';
4
+ import './chunk-VMEJWYK2.js';
5
+ import './chunk-WGMJCZSK.js';
6
+ import './chunk-PZ5AY32C.js';
7
+ //# sourceMappingURL=deployment-BT6MUIT5.js.map
8
+ //# sourceMappingURL=deployment-BT6MUIT5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"deployment-PKZ4IQMG.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"deployment-BT6MUIT5.js"}
@@ -8,7 +8,7 @@
8
8
  "./dist/units/existing-cluster/index.js": 2212294583,
9
9
  "./dist/units/gateway-api/index.js": 2212294583,
10
10
  "./dist/units/reduced-access-cluster/index.js": 2212294583,
11
- "./dist/impl/gateway-route.js": 2217135042,
12
- "./dist/impl/tls-certificate.js": 3252383697
11
+ "./dist/impl/gateway-route.js": 2460370816,
12
+ "./dist/impl/tls-certificate.js": 171221128
13
13
  }
14
14
  }
@@ -1,5 +1,5 @@
1
- import { Certificate } from '../chunk-4YC2SLCU.js';
2
- import { Gateway, HttpRoute } from '../chunk-XYJNM2EN.js';
1
+ import { Gateway, HttpRoute, TcpRoute, UdpRoute } from '../chunk-OEOMZP2C.js';
2
+ import { Certificate } from '../chunk-2F2IID7N.js';
3
3
  import { Service, l4EndpointToServicePort } from '../chunk-SI7X6N46.js';
4
4
  import '../chunk-VMEJWYK2.js';
5
5
  import { Namespace, mapMetadata, getProvider } from '../chunk-WGMJCZSK.js';
@@ -19,85 +19,148 @@ var createGatewayRoute = gatewayRouteMediator.implement(
19
19
  group: "",
20
20
  name: certSecret.metadata.name
21
21
  } : void 0;
22
- const gateway = await Gateway.createOnce(
23
- {
22
+ if (spec.type === "http") {
23
+ return await createHttpGatewayRoute({
24
24
  name,
25
+ spec,
26
+ opts,
27
+ data,
25
28
  namespace,
26
- gatewayClassName: data.className,
27
- listeners: [
28
- {
29
- name: "https",
30
- port: data.httpsPort,
31
- protocol: "HTTPS",
32
- tls: {
33
- mode: "Terminate",
34
- certificateRefs: certificateRef ? [certificateRef] : void 0
35
- }
36
- }
37
- ]
38
- },
39
- opts
40
- );
41
- if (spec.nativeData instanceof Service) {
42
- const httpRoute2 = new HttpRoute(
43
- name,
44
- {
45
- gateway,
46
- rule: { backend: spec.nativeData }
47
- },
48
- opts
49
- );
50
- return {
51
- resource: httpRoute2,
52
- endpoints: await toPromise(gateway.endpoints)
53
- };
54
- }
55
- const endpoints = await toPromise(spec.endpoints);
56
- const hostnameEndpoints = filterEndpoints(endpoints, void 0, ["hostname"]);
57
- const ipEndpoints = filterEndpoints(endpoints, void 0, ["ipv4", "ipv6"]);
58
- let service;
59
- if (hostnameEndpoints.length > 0 && hostnameEndpoints[0].visibility > ipEndpoints[0]?.visibility) {
60
- service = Service.create(`hs-backend-${name}`, {
61
- namespace,
62
- type: "ExternalName",
63
- externalName: hostnameEndpoints[0].hostname,
64
- ports: hostnameEndpoints.map(l4EndpointToServicePort)
65
- });
66
- } else {
67
- service = Service.create(`hs-backend-${name}`, {
68
- namespace,
69
- type: "ClusterIP",
70
- ports: ipEndpoints.map(l4EndpointToServicePort)
29
+ certificateRef
71
30
  });
72
- const endpointsName = `hs-backend-${name}`;
73
- new core.v1.Endpoints(
74
- endpointsName,
75
- {
76
- metadata: mapMetadata({ namespace }, endpointsName),
77
- subsets: ipEndpoints.map((endpoint) => ({
78
- addresses: [{ ip: endpoint.address }],
79
- ports: [l4EndpointToServicePort(endpoint)]
80
- }))
81
- },
82
- { ...opts, provider: getProvider(data.cluster), parent: service }
83
- );
84
31
  }
85
- const httpRoute = new HttpRoute(
32
+ const protocol = spec.type === "tcp" ? "TCP" : "UDP";
33
+ return await createL4GatewayRoute({
86
34
  name,
87
- {
88
- gateway,
89
- rule: {
90
- backend: service
35
+ spec,
36
+ opts,
37
+ data,
38
+ namespace,
39
+ protocol
40
+ });
41
+ }
42
+ );
43
+ async function createHttpGatewayRoute({
44
+ name,
45
+ spec,
46
+ opts,
47
+ data,
48
+ namespace,
49
+ certificateRef
50
+ }) {
51
+ const backendService = spec.nativeData instanceof Service ? spec.nativeData : (await createServiceFromEndpoints(name, namespace, spec.endpoints, data.cluster, opts)).service;
52
+ const listeners = [
53
+ {
54
+ name: "https",
55
+ port: data.httpsPort,
56
+ protocol: "HTTPS",
57
+ tls: {
58
+ mode: "Terminate",
59
+ certificateRefs: certificateRef ? [certificateRef] : void 0
60
+ }
61
+ }
62
+ ];
63
+ const gateway = await Gateway.createOnce(
64
+ {
65
+ name: data.className,
66
+ namespace,
67
+ gatewayClassName: data.className,
68
+ listeners
69
+ },
70
+ opts
71
+ );
72
+ const httpRoute = new HttpRoute(
73
+ name,
74
+ {
75
+ gateway,
76
+ rule: {
77
+ backend: backendService
78
+ }
79
+ },
80
+ opts
81
+ );
82
+ return {
83
+ resource: httpRoute,
84
+ endpoints: await toPromise(gateway.endpoints)
85
+ };
86
+ }
87
+ async function createL4GatewayRoute({
88
+ name,
89
+ spec,
90
+ opts,
91
+ data,
92
+ namespace,
93
+ protocol
94
+ }) {
95
+ const serviceData = spec.nativeData instanceof Service ? {
96
+ service: spec.nativeData,
97
+ ports: await getServicePorts(spec.nativeData)
98
+ } : await createServiceFromEndpoints(name, namespace, spec.endpoints, data.cluster, opts);
99
+ const serviceName = await toPromise(serviceData.service.metadata.name);
100
+ const backendPort = await selectBackendPort({
101
+ ports: serviceData.ports,
102
+ protocol,
103
+ targetPort: spec.targetPort,
104
+ serviceName,
105
+ routeName: name
106
+ });
107
+ const listenerPort = await resolveListenerPort({
108
+ requestedPort: spec.port,
109
+ backendPort,
110
+ protocol,
111
+ routeName: name
112
+ });
113
+ const listenerName = `${protocol.toLowerCase()}-${listenerPort}`;
114
+ const gateway = await Gateway.createOnce(
115
+ {
116
+ name: data.className,
117
+ namespace,
118
+ gatewayClassName: data.className,
119
+ listeners: [
120
+ {
121
+ name: listenerName,
122
+ port: listenerPort,
123
+ protocol
91
124
  }
92
- },
93
- opts
94
- );
125
+ ]
126
+ },
127
+ opts
128
+ );
129
+ const backendRef = serviceData.service.metadata.apply((metadata) => {
130
+ if (!metadata?.name) {
131
+ throw new Error(
132
+ `Service "${serviceName}" referenced by gateway route "${name}" does not have a name.`
133
+ );
134
+ }
95
135
  return {
96
- resource: httpRoute,
97
- endpoints: await toPromise(gateway.endpoints)
136
+ name: metadata.name,
137
+ namespace: metadata.namespace,
138
+ port: backendPort.port
98
139
  };
99
- }
100
- );
140
+ });
141
+ const routeOpts = { ...opts, parent: gateway };
142
+ const route = protocol === "TCP" ? new TcpRoute(
143
+ name,
144
+ {
145
+ gateway,
146
+ listenerName,
147
+ backend: backendRef
148
+ },
149
+ routeOpts
150
+ ) : new UdpRoute(
151
+ name,
152
+ {
153
+ gateway,
154
+ listenerName,
155
+ backend: backendRef
156
+ },
157
+ routeOpts
158
+ );
159
+ return {
160
+ resource: route,
161
+ endpoints: await toPromise(gateway.endpoints)
162
+ };
163
+ }
101
164
  async function getCertificateSecret(_name, namespace, tlsCertificate) {
102
165
  const resolvedCertificate = await toPromise(tlsCertificate);
103
166
  if (!resolvedCertificate) {
@@ -117,6 +180,165 @@ async function getCertificateSecret(_name, namespace, tlsCertificate) {
117
180
  "Not implemented: copying certificate secret across namespaces/clusters/different systems"
118
181
  );
119
182
  }
183
+ async function createServiceFromEndpoints(name, namespace, endpointsInput, cluster, opts) {
184
+ const endpoints = await toPromise(endpointsInput);
185
+ if (!endpoints.length) {
186
+ throw new Error(`Gateway route "${name}" has no endpoints to expose.`);
187
+ }
188
+ const hostnameEndpoints = filterEndpoints(endpoints, void 0, ["hostname"]);
189
+ const ipEndpoints = filterEndpoints(endpoints, void 0, ["ipv4", "ipv6"]);
190
+ if (hostnameEndpoints.length > 0 && hostnameEndpoints[0].visibility > ipEndpoints[0]?.visibility) {
191
+ const hostnamePortInfos = [];
192
+ for (const endpoint of hostnameEndpoints) {
193
+ hostnamePortInfos.push(toServicePortInfoFromEndpoint(endpoint));
194
+ }
195
+ const service2 = Service.create(`hs-backend-${name}`, {
196
+ namespace,
197
+ type: "ExternalName",
198
+ externalName: hostnameEndpoints[0].hostname,
199
+ ports: hostnameEndpoints.map(l4EndpointToServicePort)
200
+ });
201
+ return {
202
+ service: service2,
203
+ ports: hostnamePortInfos
204
+ };
205
+ }
206
+ if (ipEndpoints.length === 0) {
207
+ throw new Error(`Gateway route "${name}" requires at least one IP endpoint.`);
208
+ }
209
+ const ipPortInfos = [];
210
+ for (const endpoint of ipEndpoints) {
211
+ ipPortInfos.push(toServicePortInfoFromEndpoint(endpoint));
212
+ }
213
+ const service = Service.create(`hs-backend-${name}`, {
214
+ namespace,
215
+ type: "ClusterIP",
216
+ ports: ipEndpoints.map(l4EndpointToServicePort)
217
+ });
218
+ const endpointsName = `hs-backend-${name}`;
219
+ new core.v1.Endpoints(
220
+ endpointsName,
221
+ {
222
+ metadata: mapMetadata({ namespace }, endpointsName),
223
+ subsets: ipEndpoints.map((endpoint) => ({
224
+ addresses: [{ ip: endpoint.address }],
225
+ ports: [l4EndpointToServicePort(endpoint)]
226
+ }))
227
+ },
228
+ { ...opts, provider: getProvider(cluster), parent: service }
229
+ );
230
+ return {
231
+ service,
232
+ ports: ipPortInfos
233
+ };
234
+ }
235
+ async function getServicePorts(service) {
236
+ const spec = await toPromise(service.spec);
237
+ const ports = spec.ports ?? [];
238
+ const result = [];
239
+ for (const port of ports) {
240
+ const value = port.port;
241
+ const protocol = (port.protocol ?? "TCP").toUpperCase();
242
+ if (value === void 0 || protocol !== "TCP" && protocol !== "UDP") {
243
+ continue;
244
+ }
245
+ result.push({
246
+ name: port.name ?? void 0,
247
+ port: value,
248
+ protocol,
249
+ targetPort: port.targetPort
250
+ });
251
+ }
252
+ return result;
253
+ }
254
+ function toServicePortInfoFromEndpoint(endpoint) {
255
+ return {
256
+ name: void 0,
257
+ port: endpoint.port,
258
+ protocol: endpoint.protocol.toUpperCase(),
259
+ targetPort: endpoint.port
260
+ };
261
+ }
262
+ async function selectBackendPort({
263
+ ports,
264
+ protocol,
265
+ targetPort,
266
+ serviceName,
267
+ routeName
268
+ }) {
269
+ const candidates = ports.filter((port) => port.protocol === protocol);
270
+ if (candidates.length === 0) {
271
+ throw new Error(
272
+ `Service "${serviceName}" does not expose any ${protocol} ports required by gateway route "${routeName}".`
273
+ );
274
+ }
275
+ if (!targetPort) {
276
+ return candidates[0];
277
+ }
278
+ const resolvedTarget = await toPromise(targetPort);
279
+ if (resolvedTarget === void 0 || resolvedTarget === null) {
280
+ return candidates[0];
281
+ }
282
+ if (typeof resolvedTarget === "number") {
283
+ const match2 = candidates.find((candidate) => {
284
+ if (candidate.port === resolvedTarget) {
285
+ return true;
286
+ }
287
+ if (typeof candidate.targetPort === "number") {
288
+ return candidate.targetPort === resolvedTarget;
289
+ }
290
+ return false;
291
+ });
292
+ if (match2) {
293
+ return match2;
294
+ }
295
+ throw new Error(
296
+ `Gateway route "${routeName}" requested target port ${resolvedTarget}, but service "${serviceName}" does not expose it for ${protocol} backends.`
297
+ );
298
+ }
299
+ const targetString = String(resolvedTarget);
300
+ const match = candidates.find((candidate) => {
301
+ if (candidate.name === targetString) {
302
+ return true;
303
+ }
304
+ if (typeof candidate.targetPort === "string") {
305
+ return candidate.targetPort === targetString;
306
+ }
307
+ return false;
308
+ });
309
+ if (match) {
310
+ return match;
311
+ }
312
+ throw new Error(
313
+ `Gateway route "${routeName}" requested target port "${targetString}", but service "${serviceName}" does not expose it for ${protocol} backends.`
314
+ );
315
+ }
316
+ async function resolveListenerPort({
317
+ requestedPort,
318
+ backendPort,
319
+ protocol,
320
+ routeName
321
+ }) {
322
+ if (!requestedPort) {
323
+ return backendPort.port;
324
+ }
325
+ const resolved = await toPromise(requestedPort);
326
+ if (resolved === void 0 || resolved === null) {
327
+ return backendPort.port;
328
+ }
329
+ if (!Number.isInteger(resolved)) {
330
+ throw new Error(
331
+ `Gateway route "${routeName}" must use integer listener ports for ${protocol.toLowerCase()} traffic.`
332
+ );
333
+ }
334
+ const port = Number(resolved);
335
+ if (port < 1 || port > 65535) {
336
+ throw new Error(
337
+ `Gateway route "${routeName}" specified listener port ${port}, which is outside the valid range 1-65535.`
338
+ );
339
+ }
340
+ return port;
341
+ }
120
342
 
121
343
  export { createGatewayRoute };
122
344
  //# sourceMappingURL=gateway-route.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/impl/gateway-route.ts"],"names":["httpRoute"],"mappings":"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","file":"gateway-route.js","sourcesContent":["import type { Secret } from \"../secret\"\nimport { filterEndpoints, gatewayRouteMediator, type TlsCertificate } from \"@highstate/common\"\nimport { k8s } from \"@highstate/library\"\nimport { type Input, toPromise } from \"@highstate/pulumi\"\nimport { core } from \"@pulumi/kubernetes\"\nimport { Gateway, HttpRoute } from \"../gateway\"\nimport { Namespace } from \"../namespace\"\nimport { l4EndpointToServicePort, Service } from \"../service\"\nimport { getProvider, mapMetadata } from \"../shared\"\nimport { Certificate } from \"../tls\"\n\nexport const createGatewayRoute = gatewayRouteMediator.implement(\n k8s.gatewayDataSchema,\n async ({ name, spec, opts }, data) => {\n const namespace =\n spec.nativeData instanceof Service\n ? await toPromise(spec.nativeData.namespace)\n : Namespace.for(data.namespace, data.cluster)\n\n const certSecret = await getCertificateSecret(name, namespace, spec.tlsCertificate)\n\n const certificateRef = certSecret\n ? {\n kind: \"Secret\",\n group: \"\",\n name: certSecret.metadata.name,\n }\n : undefined\n\n const gateway = await Gateway.createOnce(\n {\n name,\n namespace,\n gatewayClassName: data.className,\n listeners: [\n {\n name: \"https\",\n port: data.httpsPort,\n protocol: \"HTTPS\",\n tls: {\n mode: \"Terminate\",\n certificateRefs: certificateRef ? [certificateRef] : undefined,\n },\n },\n ],\n },\n opts,\n )\n\n // 1. short path - just create an HTTP route backed by a service\n if (spec.nativeData instanceof Service) {\n const httpRoute = new HttpRoute(\n name,\n {\n gateway,\n rule: { backend: spec.nativeData },\n },\n opts,\n )\n\n return {\n resource: httpRoute,\n endpoints: await toPromise(gateway.endpoints),\n }\n }\n\n // 2. long path - create a virtual service with provided endpoints\n const endpoints = await toPromise(spec.endpoints)\n const hostnameEndpoints = filterEndpoints(endpoints, undefined, [\"hostname\"])\n const ipEndpoints = filterEndpoints(endpoints, undefined, [\"ipv4\", \"ipv6\"])\n\n let service: Service\n\n if (\n hostnameEndpoints.length > 0 &&\n hostnameEndpoints[0].visibility > ipEndpoints[0]?.visibility\n ) {\n // if the hostname endpoints are more visible, create a service for the first hostname with ExternalName\n service = Service.create(`hs-backend-${name}`, {\n namespace,\n type: \"ExternalName\",\n externalName: hostnameEndpoints[0].hostname,\n ports: hostnameEndpoints.map(l4EndpointToServicePort),\n })\n } else {\n // otherwise, create a headless service and populate it with IPs\n service = Service.create(`hs-backend-${name}`, {\n namespace,\n type: \"ClusterIP\",\n ports: ipEndpoints.map(l4EndpointToServicePort),\n })\n\n const endpointsName = `hs-backend-${name}`\n\n new core.v1.Endpoints(\n endpointsName,\n {\n metadata: mapMetadata({ namespace }, endpointsName),\n subsets: ipEndpoints.map(endpoint => ({\n addresses: [{ ip: endpoint.address }],\n ports: [l4EndpointToServicePort(endpoint)],\n })),\n },\n { ...opts, provider: getProvider(data.cluster), parent: service },\n )\n }\n\n const httpRoute = new HttpRoute(\n name,\n {\n gateway,\n rule: {\n backend: service,\n },\n },\n opts,\n )\n\n return {\n resource: httpRoute,\n endpoints: await toPromise(gateway.endpoints),\n }\n },\n)\n\nasync function getCertificateSecret(\n _name: string,\n namespace: Namespace,\n tlsCertificate: Input<TlsCertificate | undefined> | undefined,\n): Promise<Secret | undefined> {\n const resolvedCertificate = await toPromise(tlsCertificate)\n if (!resolvedCertificate) {\n return undefined\n }\n\n const resource = await toPromise(resolvedCertificate.resource)\n\n if (resource instanceof Certificate) {\n const certNamespace = await toPromise(resource.namespace.metadata.name)\n const certClusterId = await toPromise(resource.namespace.cluster.id)\n\n const targetNamespace = await toPromise(namespace.metadata.name)\n const targetClusterId = await toPromise(namespace.cluster.id)\n\n if (certNamespace === targetNamespace && certClusterId === targetClusterId) {\n // 1. short path - same namespace and cluster, just return the secret\n return await toPromise(resource.secret)\n }\n }\n\n // 2. long path - create a new secret in the target namespace with the certificate data\n throw new Error(\n \"Not implemented: copying certificate secret across namespaces/clusters/different systems\",\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/impl/gateway-route.ts"],"names":["service","match"],"mappings":"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","file":"gateway-route.js","sourcesContent":["import type { Secret } from \"../secret\"\nimport {\n filterEndpoints,\n type GatewayRouteSpec,\n gatewayRouteMediator,\n type TlsCertificate,\n} from \"@highstate/common\"\nimport { k8s, type network } from \"@highstate/library\"\nimport { type ComponentResourceOptions, type Input, toPromise } from \"@highstate/pulumi\"\nimport { core } from \"@pulumi/kubernetes\"\nimport { Gateway, HttpRoute, TcpRoute, UdpRoute } from \"../gateway\"\nimport { Namespace } from \"../namespace\"\nimport { l4EndpointToServicePort, Service } from \"../service\"\nimport { getProvider, mapMetadata } from \"../shared\"\nimport { Certificate } from \"../tls\"\n\nexport const createGatewayRoute = gatewayRouteMediator.implement(\n k8s.gatewayDataSchema,\n async ({ name, spec, opts }, data) => {\n const namespace =\n spec.nativeData instanceof Service\n ? await toPromise(spec.nativeData.namespace)\n : Namespace.for(data.namespace, data.cluster)\n\n const certSecret = await getCertificateSecret(name, namespace, spec.tlsCertificate)\n\n const certificateRef = certSecret\n ? {\n kind: \"Secret\" as const,\n group: \"\" as const,\n name: certSecret.metadata.name,\n }\n : undefined\n\n if (spec.type === \"http\") {\n return await createHttpGatewayRoute({\n name,\n spec,\n opts,\n data,\n namespace,\n certificateRef,\n })\n }\n\n const protocol = spec.type === \"tcp\" ? \"TCP\" : \"UDP\"\n\n return await createL4GatewayRoute({\n name,\n spec,\n opts,\n data,\n namespace,\n protocol,\n })\n },\n)\n\ntype HttpGatewayRouteSpec = Extract<GatewayRouteSpec, { type: \"http\" }>\ntype L4GatewayRouteSpec = Extract<GatewayRouteSpec, { type: \"tcp\" | \"udp\" }>\n\ntype CreateHttpGatewayRouteArgs = {\n name: string\n spec: HttpGatewayRouteSpec\n opts: ComponentResourceOptions | undefined\n data: k8s.GatewayData\n namespace: Namespace\n certificateRef:\n | {\n kind: \"Secret\"\n group: \"\"\n name: Input<string>\n }\n | undefined\n}\n\nasync function createHttpGatewayRoute({\n name,\n spec,\n opts,\n data,\n namespace,\n certificateRef,\n}: CreateHttpGatewayRouteArgs) {\n const backendService =\n spec.nativeData instanceof Service\n ? spec.nativeData\n : (await createServiceFromEndpoints(name, namespace, spec.endpoints, data.cluster, opts))\n .service\n\n const listeners = [\n {\n name: \"https\",\n port: data.httpsPort,\n protocol: \"HTTPS\",\n tls: {\n mode: \"Terminate\",\n certificateRefs: certificateRef ? [certificateRef] : undefined,\n },\n },\n ]\n\n const gateway = await Gateway.createOnce(\n {\n name: data.className,\n namespace,\n gatewayClassName: data.className,\n listeners,\n },\n opts,\n )\n\n const httpRoute = new HttpRoute(\n name,\n {\n gateway,\n rule: {\n backend: backendService,\n },\n },\n opts,\n )\n\n return {\n resource: httpRoute,\n endpoints: await toPromise(gateway.endpoints),\n }\n}\n\ntype CreateL4GatewayRouteArgs = {\n name: string\n spec: L4GatewayRouteSpec\n opts: ComponentResourceOptions | undefined\n data: k8s.GatewayData\n namespace: Namespace\n protocol: \"TCP\" | \"UDP\"\n}\n\nasync function createL4GatewayRoute({\n name,\n spec,\n opts,\n data,\n namespace,\n protocol,\n}: CreateL4GatewayRouteArgs) {\n const serviceData =\n spec.nativeData instanceof Service\n ? {\n service: spec.nativeData,\n ports: await getServicePorts(spec.nativeData),\n }\n : await createServiceFromEndpoints(name, namespace, spec.endpoints, data.cluster, opts)\n\n const serviceName = await toPromise(serviceData.service.metadata.name)\n\n const backendPort = await selectBackendPort({\n ports: serviceData.ports,\n protocol,\n targetPort: spec.targetPort,\n serviceName,\n routeName: name,\n })\n\n const listenerPort = await resolveListenerPort({\n requestedPort: spec.port,\n backendPort,\n protocol,\n routeName: name,\n })\n\n const listenerName = `${protocol.toLowerCase()}-${listenerPort}`\n\n const gateway = await Gateway.createOnce(\n {\n name: data.className,\n namespace,\n gatewayClassName: data.className,\n listeners: [\n {\n name: listenerName,\n port: listenerPort,\n protocol,\n },\n ],\n },\n opts,\n )\n\n const backendRef = serviceData.service.metadata.apply(metadata => {\n if (!metadata?.name) {\n throw new Error(\n `Service \"${serviceName}\" referenced by gateway route \"${name}\" does not have a name.`,\n )\n }\n\n return {\n name: metadata.name,\n namespace: metadata.namespace,\n port: backendPort.port,\n }\n })\n\n const routeOpts = { ...opts, parent: gateway }\n\n const route =\n protocol === \"TCP\"\n ? new TcpRoute(\n name,\n {\n gateway,\n listenerName,\n backend: backendRef,\n },\n routeOpts,\n )\n : new UdpRoute(\n name,\n {\n gateway,\n listenerName,\n backend: backendRef,\n },\n routeOpts,\n )\n\n return {\n resource: route,\n endpoints: await toPromise(gateway.endpoints),\n }\n}\n\nasync function getCertificateSecret(\n _name: string,\n namespace: Namespace,\n tlsCertificate: Input<TlsCertificate | undefined> | undefined,\n): Promise<Secret | undefined> {\n const resolvedCertificate = await toPromise(tlsCertificate)\n if (!resolvedCertificate) {\n return undefined\n }\n\n const resource = await toPromise(resolvedCertificate.resource)\n\n if (resource instanceof Certificate) {\n const certNamespace = await toPromise(resource.namespace.metadata.name)\n const certClusterId = await toPromise(resource.namespace.cluster.id)\n\n const targetNamespace = await toPromise(namespace.metadata.name)\n const targetClusterId = await toPromise(namespace.cluster.id)\n\n if (certNamespace === targetNamespace && certClusterId === targetClusterId) {\n return await toPromise(resource.secret)\n }\n }\n\n throw new Error(\n \"Not implemented: copying certificate secret across namespaces/clusters/different systems\",\n )\n}\n\ntype ServicePortInfo = {\n name: string | undefined\n port: number\n protocol: \"TCP\" | \"UDP\"\n targetPort?: number | string\n}\n\nasync function createServiceFromEndpoints(\n name: string,\n namespace: Namespace,\n endpointsInput: Input<network.L4Endpoint[]>,\n cluster: k8s.Cluster,\n opts: ComponentResourceOptions | undefined,\n): Promise<{ service: Service; ports: ServicePortInfo[] }> {\n const endpoints = await toPromise(endpointsInput)\n\n if (!endpoints.length) {\n throw new Error(`Gateway route \"${name}\" has no endpoints to expose.`)\n }\n\n const hostnameEndpoints = filterEndpoints(endpoints, undefined, [\"hostname\"])\n const ipEndpoints = filterEndpoints(endpoints, undefined, [\"ipv4\", \"ipv6\"])\n\n if (\n hostnameEndpoints.length > 0 &&\n hostnameEndpoints[0].visibility > ipEndpoints[0]?.visibility\n ) {\n const hostnamePortInfos: ServicePortInfo[] = []\n for (const endpoint of hostnameEndpoints) {\n hostnamePortInfos.push(toServicePortInfoFromEndpoint(endpoint))\n }\n\n const service = Service.create(`hs-backend-${name}`, {\n namespace,\n type: \"ExternalName\",\n externalName: hostnameEndpoints[0].hostname,\n ports: hostnameEndpoints.map(l4EndpointToServicePort),\n })\n\n return {\n service,\n ports: hostnamePortInfos,\n }\n }\n\n if (ipEndpoints.length === 0) {\n throw new Error(`Gateway route \"${name}\" requires at least one IP endpoint.`)\n }\n\n const ipPortInfos: ServicePortInfo[] = []\n for (const endpoint of ipEndpoints) {\n ipPortInfos.push(toServicePortInfoFromEndpoint(endpoint))\n }\n\n const service = Service.create(`hs-backend-${name}`, {\n namespace,\n type: \"ClusterIP\",\n ports: ipEndpoints.map(l4EndpointToServicePort),\n })\n\n const endpointsName = `hs-backend-${name}`\n\n new core.v1.Endpoints(\n endpointsName,\n {\n metadata: mapMetadata({ namespace }, endpointsName),\n subsets: ipEndpoints.map(endpoint => ({\n addresses: [{ ip: endpoint.address }],\n ports: [l4EndpointToServicePort(endpoint)],\n })),\n },\n { ...opts, provider: getProvider(cluster), parent: service },\n )\n\n return {\n service,\n ports: ipPortInfos,\n }\n}\n\nasync function getServicePorts(service: Service): Promise<ServicePortInfo[]> {\n const spec = await toPromise(service.spec)\n const ports = spec.ports ?? []\n\n const result: ServicePortInfo[] = []\n\n for (const port of ports) {\n const value = port.port\n const protocol = (port.protocol ?? \"TCP\").toUpperCase()\n\n if (value === undefined || (protocol !== \"TCP\" && protocol !== \"UDP\")) {\n continue\n }\n\n result.push({\n name: port.name ?? undefined,\n port: value,\n protocol: protocol as \"TCP\" | \"UDP\",\n targetPort: port.targetPort as number | string | undefined,\n })\n }\n\n return result\n}\n\nfunction toServicePortInfoFromEndpoint(endpoint: network.L4Endpoint): ServicePortInfo {\n return {\n name: undefined,\n port: endpoint.port,\n protocol: endpoint.protocol.toUpperCase() as \"TCP\" | \"UDP\",\n targetPort: endpoint.port,\n }\n}\n\nasync function selectBackendPort({\n ports,\n protocol,\n targetPort,\n serviceName,\n routeName,\n}: {\n ports: ServicePortInfo[]\n protocol: \"TCP\" | \"UDP\"\n targetPort: Input<string | number | undefined> | undefined\n serviceName: string\n routeName: string\n}): Promise<ServicePortInfo> {\n const candidates = ports.filter(port => port.protocol === protocol)\n\n if (candidates.length === 0) {\n throw new Error(\n `Service \"${serviceName}\" does not expose any ${protocol} ports required by gateway route \"${routeName}\".`,\n )\n }\n\n if (!targetPort) {\n return candidates[0]\n }\n\n const resolvedTarget = await toPromise(targetPort)\n\n if (resolvedTarget === undefined || resolvedTarget === null) {\n return candidates[0]\n }\n\n if (typeof resolvedTarget === \"number\") {\n const match = candidates.find(candidate => {\n if (candidate.port === resolvedTarget) {\n return true\n }\n\n if (typeof candidate.targetPort === \"number\") {\n return candidate.targetPort === resolvedTarget\n }\n\n return false\n })\n\n if (match) {\n return match\n }\n\n throw new Error(\n `Gateway route \"${routeName}\" requested target port ${resolvedTarget}, but service \"${serviceName}\" does not expose it for ${protocol} backends.`,\n )\n }\n\n const targetString = String(resolvedTarget)\n\n const match = candidates.find(candidate => {\n if (candidate.name === targetString) {\n return true\n }\n\n if (typeof candidate.targetPort === \"string\") {\n return candidate.targetPort === targetString\n }\n\n return false\n })\n\n if (match) {\n return match\n }\n\n throw new Error(\n `Gateway route \"${routeName}\" requested target port \"${targetString}\", but service \"${serviceName}\" does not expose it for ${protocol} backends.`,\n )\n}\n\nasync function resolveListenerPort({\n requestedPort,\n backendPort,\n protocol,\n routeName,\n}: {\n requestedPort: Input<number | undefined> | undefined\n backendPort: ServicePortInfo\n protocol: \"TCP\" | \"UDP\"\n routeName: string\n}): Promise<number> {\n if (!requestedPort) {\n return backendPort.port\n }\n\n const resolved = await toPromise(requestedPort)\n\n if (resolved === undefined || resolved === null) {\n return backendPort.port\n }\n\n if (!Number.isInteger(resolved)) {\n throw new Error(\n `Gateway route \"${routeName}\" must use integer listener ports for ${protocol.toLowerCase()} traffic.`,\n )\n }\n\n const port = Number(resolved)\n\n if (port < 1 || port > 65535) {\n throw new Error(\n `Gateway route \"${routeName}\" specified listener port ${port}, which is outside the valid range 1-65535.`,\n )\n }\n\n return port\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Certificate } from '../chunk-4YC2SLCU.js';
1
+ import { Certificate } from '../chunk-2F2IID7N.js';
2
2
  import '../chunk-VMEJWYK2.js';
3
3
  import { getProvider, Namespace } from '../chunk-WGMJCZSK.js';
4
4
  import '../chunk-PZ5AY32C.js';
@@ -20,7 +20,7 @@ var createCertificate = tlsCertificateMediator.implement(
20
20
  name: data.clusterIssuerName,
21
21
  kind: "ClusterIssuer"
22
22
  },
23
- secretName: `hs.certificate.${name}`
23
+ secretName: `hs-certificate-${name}`
24
24
  },
25
25
  { ...opts, provider }
26
26
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/impl/tls-certificate.ts"],"names":[],"mappings":";;;;;;;AAMO,IAAM,oBAAoB,sBAAA,CAAuB,SAAA;AAAA,EACtD,GAAA,CAAI,mBAAA;AAAA,EACJ,CAAC,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,IAAQ,IAAA,KAAS;AAC9B,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAEzC,IAAA,MAAM,SAAA,GACJ,IAAA,CAAK,UAAA,YAAsB,SAAA,GACvB,KAAK,UAAA,GACL,SAAA,CAAU,GAAA,CAAI,cAAA,EAAgB,EAAE,IAAA,EAAM,cAAA,EAAgB,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA;AAEnF,IAAA,OAAO,WAAA,CAAY,MAAA;AAAA,MACjB,IAAA;AAAA,MACA;AAAA,QACE,SAAA;AAAA,QAEA,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,SAAA,EAAW;AAAA,UACT,MAAM,IAAA,CAAK,iBAAA;AAAA,UACX,IAAA,EAAM;AAAA,SACR;AAAA,QACA,UAAA,EAAY,kBAAkB,IAAI,CAAA;AAAA,OACpC;AAAA,MACA,EAAE,GAAG,IAAA,EAAM,QAAA;AAAS,KACtB;AAAA,EACF;AACF","file":"tls-certificate.js","sourcesContent":["import { tlsCertificateMediator } from \"@highstate/common\"\nimport { k8s } from \"@highstate/library\"\nimport { Namespace } from \"../namespace\"\nimport { getProvider } from \"../shared\"\nimport { Certificate } from \"../tls\"\n\nexport const createCertificate = tlsCertificateMediator.implement(\n k8s.tlsIssuerDataSchema,\n ({ name, spec, opts }, data) => {\n const provider = getProvider(data.cluster)\n\n const namespace =\n spec.nativeData instanceof Namespace\n ? spec.nativeData\n : Namespace.get(\"cert-manager\", { name: \"cert-manager\", cluster: data.cluster })\n\n return Certificate.create(\n name,\n {\n namespace,\n\n commonName: spec.commonName,\n dnsNames: spec.dnsNames,\n issuerRef: {\n name: data.clusterIssuerName,\n kind: \"ClusterIssuer\",\n },\n secretName: `hs.certificate.${name}`,\n },\n { ...opts, provider },\n )\n },\n)\n"]}
1
+ {"version":3,"sources":["../../src/impl/tls-certificate.ts"],"names":[],"mappings":";;;;;;;AAMO,IAAM,oBAAoB,sBAAA,CAAuB,SAAA;AAAA,EACtD,GAAA,CAAI,mBAAA;AAAA,EACJ,CAAC,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,IAAQ,IAAA,KAAS;AAC9B,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAEzC,IAAA,MAAM,SAAA,GACJ,IAAA,CAAK,UAAA,YAAsB,SAAA,GACvB,KAAK,UAAA,GACL,SAAA,CAAU,GAAA,CAAI,cAAA,EAAgB,EAAE,IAAA,EAAM,cAAA,EAAgB,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA;AAEnF,IAAA,OAAO,WAAA,CAAY,MAAA;AAAA,MACjB,IAAA;AAAA,MACA;AAAA,QACE,SAAA;AAAA,QAEA,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,SAAA,EAAW;AAAA,UACT,MAAM,IAAA,CAAK,iBAAA;AAAA,UACX,IAAA,EAAM;AAAA,SACR;AAAA,QACA,UAAA,EAAY,kBAAkB,IAAI,CAAA;AAAA,OACpC;AAAA,MACA,EAAE,GAAG,IAAA,EAAM,QAAA;AAAS,KACtB;AAAA,EACF;AACF","file":"tls-certificate.js","sourcesContent":["import { tlsCertificateMediator } from \"@highstate/common\"\nimport { k8s } from \"@highstate/library\"\nimport { Namespace } from \"../namespace\"\nimport { getProvider } from \"../shared\"\nimport { Certificate } from \"../tls\"\n\nexport const createCertificate = tlsCertificateMediator.implement(\n k8s.tlsIssuerDataSchema,\n ({ name, spec, opts }, data) => {\n const provider = getProvider(data.cluster)\n\n const namespace =\n spec.nativeData instanceof Namespace\n ? spec.nativeData\n : Namespace.get(\"cert-manager\", { name: \"cert-manager\", cluster: data.cluster })\n\n return Certificate.create(\n name,\n {\n namespace,\n\n commonName: spec.commonName,\n dnsNames: spec.dnsNames,\n issuerRef: {\n name: data.clusterIssuerName,\n kind: \"ClusterIssuer\",\n },\n secretName: `hs-certificate-${name}`,\n },\n { ...opts, provider },\n )\n },\n)\n"]}
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
- export { Gateway, HttpRoute, mapHttpRouteRuleMatch, resolveBackendRef } from './chunk-XYJNM2EN.js';
2
- export { Chart, RenderedChart, getChartService, getChartServiceOutput, resolveHelmChart } from './chunk-64LNVTHJ.js';
1
+ export { Gateway, HttpRoute, TcpRoute, UdpRoute, mapHttpRouteRuleMatch, resolveBackendRef } from './chunk-OEOMZP2C.js';
2
+ export { Certificate } from './chunk-2F2IID7N.js';
3
+ export { Chart, RenderedChart, getChartService, getChartServiceOutput, resolveHelmChart } from './chunk-6FUARTRJ.js';
3
4
  export { dns01SolverMediator } from './chunk-HH2JJELM.js';
4
5
  import { ClusterAccessScope } from './chunk-FKJLPM3M.js';
5
6
  export { ClusterAccessScope } from './chunk-FKJLPM3M.js';
6
- export { Deployment } from './chunk-2FKGGWPJ.js';
7
- export { StatefulSet } from './chunk-ARG3I734.js';
8
- import { Workload, getWorkloadComponents, ConfigMap } from './chunk-HOARC4LU.js';
9
- export { ConfigMap, ExposableWorkload, NativeNetworkPolicy, NetworkPolicy, PersistentVolumeClaim, Workload, exposableWorkloadExtraArgs, getAutoVolumeName, getBestEndpoint, getExposableWorkloadComponents, getWorkloadComponents, getWorkloadVolumeResourceUuid, mapContainerEnvironment, mapContainerToRaw, mapEnvironmentSource, mapVolumeMount, mapWorkloadVolume, networkPolicyMediator, podSpecDefaults, requireBestEndpoint, workloadExtraArgs } from './chunk-HOARC4LU.js';
7
+ export { Deployment } from './chunk-6IVLEA6D.js';
8
+ export { StatefulSet } from './chunk-WJQSKV2K.js';
9
+ import { Workload, getWorkloadComponents, ConfigMap } from './chunk-GEXFRUDO.js';
10
+ export { ConfigMap, ExposableWorkload, NativeNetworkPolicy, NetworkPolicy, PersistentVolumeClaim, Workload, exposableWorkloadExtraArgs, getAutoVolumeName, getBestEndpoint, getExposableWorkloadComponents, getFallbackContainerName, getWorkloadComponents, getWorkloadVolumeResourceUuid, mapContainerEnvironment, mapContainerToRaw, mapEnvironmentSource, mapVolumeMount, mapWorkloadVolume, networkPolicyMediator, podSpecDefaults, requireBestEndpoint, workloadExtraArgs } from './chunk-GEXFRUDO.js';
10
11
  export { Service, getServiceType, isEndpointFromCluster, l4EndpointToServicePort, mapContainerPortToServicePort, mapServiceToLabelSelector } from './chunk-SI7X6N46.js';
11
12
  export { Secret } from './chunk-VMEJWYK2.js';
12
13
  export { createK8sTerminal, detectExternalIps } from './chunk-O3ZNJMTN.js';