diff --git a/2.0/docs/apps/tokens.md b/2.0/docs/apps/tokens.md index 55a8ba81..14ad755f 100644 --- a/2.0/docs/apps/tokens.md +++ b/2.0/docs/apps/tokens.md @@ -104,6 +104,17 @@ environment identity and `env.type` for behavior that depends on an environment - `service.replicas`: app-service replica count - `service.secrets.env`: generated Kubernetes Secret name used for secret environment variables +Named endpoint ports are available as `service.endpoints.[endpoint-name].ports.[port-name].[field]`: + +- `number`: manifest-defined internal port number +- `protocol`: port protocol +- `publicPort`: assigned public port number, or an empty value while the port is unpublished +- `effectivePort`: assigned public port number when published, otherwise the manifest-defined internal number + +Use `effectivePort` when a chart needs one usable value before and after publication. When a chart renders its +Kubernetes Service port from this value, also configure the service port's +[`redeployOnPublicPortChange` and `routeToPublicPort`](../services/networking.md#dynamic-public-backend-ports) fields. + Legacy `service.helm.release` is still supported for backward compatibility. ## `helm` diff --git a/2.0/docs/services/helm.md b/2.0/docs/services/helm.md index c6016e02..c6d4dbff 100644 --- a/2.0/docs/services/helm.md +++ b/2.0/docs/services/helm.md @@ -99,6 +99,16 @@ Use `helm.valueMappings.nameOverride` only when the chart exposes this behavior operator charts do not receive a managed application name by default because their label commonly identifies the controller product. They can opt in by mapping a supported path explicitly. +Set `helm.valueMappings.disableNameOverride: true` when a third-party workload chart deliberately does not implement +this application-name label contract. Wodby then does not persist or pass a managed `nameOverride` and skips the +corresponding label check during import. The chart must still expose stable labels that let every declared workload +selector resolve unambiguously, such as the Helm release plus a component label. Do not combine `disableNameOverride` +with a custom `nameOverride` path. + +This opt-out is explicit because Helm commonly accepts an unused value without reporting that the chart ignored it. +Without the opt-out, Wodby treats an ineffective `nameOverride` as a broken chart mapping instead of silently weakening +the naming contract for every service. + The application name is selected when the app service is installed. Existing app services are not relabeled when this capability becomes available or when their stack is upgraded, because changing a Deployment or StatefulSet selector would require replacing the workload. Copies are new app services and select their own names. @@ -115,6 +125,11 @@ reconciles the HorizontalPodAutoscaler while the chart continues to render its o autoscaler must therefore remain disabled with the service manifest's Helm values. Wodby-maintained charts always render `spec.replicas` and do not expose chart-owned autoscaling values. +For a chart with multiple workloads, set `workloads[].helm.replicas` on every additional Deployment or StatefulSet +whose replicas must follow the app service. When a chart exposes replicas only through a mandatory chart HPA, use +`workloads[].helm.managedReplicas: true` instead. Wodby then writes the replica count to the rendered workload and +removes only the HPA that targets it. See [Workload-level Helm mappings](workloads.md#workload-level-helm-mappings). + Service-level `helm.values` are applied after the backend-managed defaults. Do not set the same paths there unless the service intentionally replaces the backend-managed value. Replica overrides and explicit service-account mappings that break the rendered workload contract are rejected by import validation. A stored application-name override is @@ -175,17 +190,20 @@ During service import, Wodby validates explicit Helm value paths against the cha are available. It also renders the chart with the same backend-managed values used during deployment. For the primary Deployment or StatefulSet, Wodby renders replica counts `0` and `1` and verifies that the matching -workload has the same `spec.replicas` value. Services marked as scalable are also rendered with `2` replicas and must +workload has the same `spec.replicas` value. It performs the same check for every additional workload that declares +`helm.replicas` or `helm.managedReplicas`. Services marked as scalable are also rendered with `2` replicas and must preserve that exact count. Fixed services may normalize values above one to a singleton. This semantic check detects -charts that accept a Helm value but do not use it, including charts that omit `spec.replicas` because autoscaling is -enabled by default. DaemonSets do not have a replica-count check. +charts that accept a Helm value but do not use it. DaemonSets do not have a replica-count check. -Validation rejects any HorizontalPodAutoscaler rendered with the service manifest's Helm values. A chart may expose a -dormant autoscaling option, but Wodby does not enable it because app-service autoscaling is managed by the backend. +Validation rejects any HorizontalPodAutoscaler rendered with the service manifest's Helm values. The exception is an +HPA that targets a workload with `helm.managedReplicas: true`; Wodby removes that HPA during post-rendering before +performing the same check. An HPA for any other workload remains an error because app-service autoscaling is managed by +Wodby. For services with managed application names, Wodby renders a sentinel `nameOverride` and verifies that `app.kubernetes.io/name` has that value in workload metadata labels, `spec.selector.matchLabels`, and pod-template labels. This checks the rendered behavior even when the conventional root value is not declared in `values.yaml`. +Services with `helm.valueMappings.disableNameOverride: true` deliberately skip this check. When `helm.valueMappings.serviceAccountName` is explicit, Wodby also renders a sentinel service account and verifies that it reaches `spec.template.spec.serviceAccountName`. If `serviceAccountCreate` is configured, validation also diff --git a/2.0/docs/services/networking.md b/2.0/docs/services/networking.md index ef85ed25..36d140ba 100644 --- a/2.0/docs/services/networking.md +++ b/2.0/docs/services/networking.md @@ -67,6 +67,41 @@ relationship between request and backend request timeouts. Inherited services me port name, and setting name; a child value replaces the matching base value. Derivative endpoints use the same port format and behavior. +### Dynamic public backend ports + +Most published TCP and UDP ports keep a fixed port inside Kubernetes and use a separately assigned public port. Some +charts instead use one value as both the advertised public port and the port rendered on their Kubernetes Service. +Those charts can opt in to public-port-driven deployment and routing: + +```yaml +endpoints: +- name: ssh + workload: shell + ports: + - name: ssh + number: 22 + protocol: tcp + redeployOnPublicPortChange: true + routeToPublicPort: true + +helm: + values: + - name: shell.port + value: "{{service.endpoints.ssh.ports.ssh.effectivePort}}" +``` + +`redeployOnPublicPortChange: true` schedules a partial deployment of the owning app service after this port is +published or unpublished. This lets the rendered chart consume the new assignment. The option is supported only for +non-private TCP and UDP ports. + +Add `routeToPublicPort: true` only when the chart also renders its Kubernetes Service port from the public assignment. +Wodby then targets the assigned number when it creates the TCP or UDP route. This option requires +`redeployOnPublicPortChange`, so the chart and route cannot keep different backend port numbers. When +`routeToPublicPort` is omitted, Wodby continues routing to the manifest's fixed `number`. + +The stable endpoint and port names provide access to the internal, public, and effective values through +[service endpoint-port tokens](../apps/tokens.md#service). + Endpoint names must follow the [general Kubernetes name rules](../naming.md#general-kubernetes-names). Port names must follow the [port name rules](../naming.md#port-names). Workload targeting and selectors are described in [service workloads](workloads.md). diff --git a/2.0/docs/services/template.md b/2.0/docs/services/template.md index d712ebdb..7a3353ae 100644 --- a/2.0/docs/services/template.md +++ b/2.0/docs/services/template.md @@ -445,6 +445,11 @@ Each workload declares: - optional workload-specific `deployment` settings - optional workload- and container-level Helm value mappings +`workloads[].helm.replicas` maps the app service's effective replica count to a chart value for that workload. +`workloads[].helm.managedReplicas` instead applies the count directly to the rendered workload and removes a chart HPA +that targets it. The two fields are mutually exclusive, and `managedReplicas` is not supported for DaemonSets. See +[Workload-level Helm mappings](workloads.md#workload-level-helm-mappings). + If the service has multiple workloads, mark one as `primary`. The primary workload is the default target used by runtime features when no explicit workload is selected. @@ -553,6 +558,10 @@ Each `endpoints[].ports[]` item supports: - `protocol`: required protocol. Allowed values: `http`, `tcp`, `udp`. - `private`: optional boolean. - `main`: marks the main port within that endpoint. +- `redeployOnPublicPortChange`: redeploy the owning app service after this public TCP or UDP port is published or + unpublished. It is not supported for HTTP or private ports. +- `routeToPublicPort`: target the assigned public port number on the rendered Kubernetes Service. It requires + `redeployOnPublicPortChange`. - `routeDefaults`: optional map of [HTTP route setting](../apps/endpoints.md#route-settings) names to default string values. It is supported only when `protocol` is `http`. @@ -995,6 +1004,8 @@ The object supports: `infrastructure` and `operator`; those controller-oriented types opt in by mapping this property explicitly. Wodby uses the stack-local app-service name and verifies it reaches `app.kubernetes.io/name` in workload labels and selectors. +- `disableNameOverride`: disable managed application-name injection and validation for a third-party workload chart + that does not implement the `nameOverride` label contract. It cannot be combined with `nameOverride`. - `fullnameOverride`: resource-name override path. Defaults to `fullnameOverride`. - `serviceAccountName`: Kubernetes service-account name path. Defaults to `serviceAccountName`. - `serviceAccountCreate`: optional chart-owned service-account creation path. Wodby sets it to `false` when it supplies diff --git a/2.0/docs/services/workloads.md b/2.0/docs/services/workloads.md index cca3dddd..88407803 100644 --- a/2.0/docs/services/workloads.md +++ b/2.0/docs/services/workloads.md @@ -207,6 +207,8 @@ See also: [Service build](build.md). `workloads[].helm` supports: +- `replicas` +- `managedReplicas` - `labels` - `annotations` - `volumes` @@ -218,6 +220,33 @@ See also: [Service build](build.md). These are Helm value paths used when Wodby injects workload-scoped data. +Use `replicas` to map the app service's effective replica count to a value path for this workload. This is useful for a +multi-workload chart whose Deployments or StatefulSets have independent replica values: + +```yaml +workloads: +- name: web + kind: deployment + primary: true + helm: + replicas: web.replicas + +- name: worker + kind: deployment + helm: + replicas: worker.replicas +``` + +Wodby writes the same effective app-service replica count to every mapped path, including `0` while the app service is +disabled or its app environment is paused. Import validation verifies each mapped workload at the supported replica +counts. A workload can omit this mapping when its replica count intentionally remains controlled by the chart. + +Use `managedReplicas: true` only when the chart cannot expose an ordinary replica value without also creating its own +HorizontalPodAutoscaler. Wodby then writes `spec.replicas` directly to the rendered Deployment or StatefulSet and +removes only the chart HPA that targets that workload. Any unrelated chart HPA still fails import validation. + +`managedReplicas` cannot be combined with `replicas` on the same workload and is not supported for DaemonSets. + The four deployment paths are required for charts with multiple workloads when the corresponding setting needs to be passed to Helm. Service-level deployment mapping defaults apply only to single-workload services. See [Deployment value mappings](helm.md#deployment-value-mappings).