Wave Flow CRDs
These kinds configure Wave Flow in CRD Mode. Use WaveFlowPolicy for priority-based traffic protection, and WaveNetfunnelMapping + WaveNetfunnelConnection for NetFunnel integration.
WaveFlowPolicy
WaveFlowPolicy defines priority classes for incoming traffic and the traffic-protection behavior for each class. It targets one or more workloads by namespace and name; when under pressure, Wave enforces the configured shedding strategy per class.
Scope: cluster-scoped — no metadata.namespace required.
apiVersion: wavek8s.com/v1alpha1
kind: WaveFlowPolicy
metadata:
name: checkout-priority-policy
spec:
description: Priority policy for the checkout service.
enabled: true
priorityClasses:
- name: CRITICAL
shed: disabled # never shed — revenue-critical traffic must always pass
concurrencyLimit: 200
matchRules:
- headers:
- name: x-tier
value: premium
paths:
- prefix: /api/v1/checkout
methods:
- POST
- PUT
- name: IMPORTANT
shed: auto
matchRules:
- headers:
- name: x-tier
value: standard
- name: MODERATE
shed: auto
- name: BULK
shed: force # force = always reject — emergency block
targets:
- namespace: payment
name: checkout-apiSpec fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
description | string | No | — | Optional human-readable description of this policy. |
enabled | boolean | No | true | Whether this policy is currently active. Set to false to pause enforcement without deleting the CR. |
priorityClasses | array | No | [] | List of priority class configurations. Evaluated in order. |
priorityClasses[].name | string | Yes (per item) | — | Name of the priority class. Recommended values: CRITICAL, IMPORTANT, MODERATE, BULK. |
priorityClasses[].shed | string (enum) | No | disabled | Shedding strategy: disabled — never shed this class; auto — Wave decides based on load; force — always reject 100% of requests in this class, regardless of load (emergency block). |
priorityClasses[].shedBool | boolean | No | — | Optional boolean override for the shed decision. Takes precedence when set. |
priorityClasses[].concurrencyLimit | integer | No | — | Maximum concurrent requests allowed for this class. |
priorityClasses[].matchRules | array | No | — | Rules for matching requests to this class. Rules are evaluated with OR logic — a request matches if any rule matches. |
priorityClasses[].matchRules[].headers | array | No | [] | HTTP headers to match. All entries in this array must match (AND logic). |
priorityClasses[].matchRules[].headers[].name | string | Yes (per item) | — | Name of the HTTP header. |
priorityClasses[].matchRules[].headers[].value | string | Yes (per item) | — | Value to match against. |
priorityClasses[].matchRules[].paths | array | No | [] | HTTP path prefixes to match. All entries must match (AND logic). |
priorityClasses[].matchRules[].paths[].prefix | string | Yes (per item) | — | Path prefix to match (e.g. /api/v1/). |
priorityClasses[].matchRules[].methods | array | No | [] | HTTP methods to match (e.g. GET, POST). A request matches if its method is any of the listed values (OR logic). |
targets | array | No | [] | Workloads this policy applies to, each identified by namespace + name. |
targets[].namespace | string | Yes (per item) | — | Namespace of the target workload. |
targets[].name | string | Yes (per item) | — | Name of the target workload. |
Notes
- Cluster-scoped — a single
WaveFlowPolicycan target workloads across multiple namespaces viatargets[].namespace. priorityClassesdefaults to an empty list. A policy with no classes is valid but enforces nothing.- Within a
matchRule,headersandpathsentries must all match (AND logic);methodsmatches on any listed value (OR logic — a request has exactly one HTTP method). MultiplematchRuleswithin onepriorityClassesentry use OR logic — a request matches the class if any rule fully matches. - A target workload that does not exist yet succeeds at
kubectl applytime. Wave reportsTargetNotFoundin.status.conditionsand reconciles automatically when the workload appears. - Pruning (removing targets or classes from the CR) is a hard delete — rows absent from the current CR are removed on the next reconcile, not soft-disabled.
WaveNetfunnelMapping
WaveNetfunnelMapping binds a workload to NetFunnel project/segment rules. It enables Wave to pass traffic-control signals to the NetFunnel service for the named workload, optionally mapping the workload to one or more NetFunnel project–segment pairs.
Scope: namespaced — must be created in the same namespace as the target workload.
apiVersion: wavek8s.com/v1alpha1
kind: WaveNetfunnelMapping
metadata:
name: checkout-nf-mapping
namespace: payment
spec:
targetRef:
kind: Deployment
name: checkout-api
nfMapping:
- nfProjectId: nf-project-001
nfSegmentId: nf-segment-001
isSection: true
- nfProjectId: nf-project-001
nfSegmentId: nf-segment-002
rule:
nfEnabled: true
ruleCpu: 70.5
ruleMemory: 80.0
ruleMaxReplicas: true
cooldownPeriodSecs: 120Spec fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
targetRef | object | Yes | — | Workload to bind to NetFunnel. |
targetRef.kind | string | Yes | — | Deployment, Rollout (Argo Rollouts), or DeploymentConfig (OpenShift). |
targetRef.name | string | Yes | — | Name of the workload in the same namespace as the CR. |
rule | object | Yes | — | NetFunnel rule configuration for this workload. |
rule.nfEnabled | boolean | Yes | — | Whether NetFunnel control is active for this workload. Set to false to disable enforcement without removing the CR. |
rule.ruleCpu | number | No | — | CPU utilization threshold (%) that triggers NetFunnel signaling. |
rule.ruleMemory | number | No | — | Memory utilization threshold (%) that triggers NetFunnel signaling. |
rule.ruleMaxReplicas | boolean | No | — | Whether to signal NetFunnel when the workload reaches its maximum replica count. |
rule.cooldownPeriodSecs | integer | No | — | Minimum seconds between consecutive NetFunnel signals. |
nfMapping | array | No | [] | NetFunnel project–segment pairs this workload maps to. One entry per pair; multiple entries are supported. |
nfMapping[].nfProjectId | string | Yes (per item) | — | NetFunnel project identifier. Copy from the NetFunnel console (project → segment). |
nfMapping[].nfSegmentId | string | Yes (per item) | — | NetFunnel segment identifier. Copy from the NetFunnel console (project → segment). |
nfMapping[].isSection | boolean | No | false | Whether this mapping uses Section Control (advanced, section-based segment management) rather than Basic Control (simple on/off). |
Notes
- Namespaced — create the CR in the same namespace as the target workload.
targetRef.kindmust be one ofDeployment,Rollout(Argo Rollouts), orDeploymentConfig(OpenShift). - A workload that does not exist yet succeeds at
kubectl applytime. Wave reportsTargetNotFoundin.status.conditionsand reconciles automatically when the workload appears. nfMappingis whole-replace on each reconcile — entries absent from the current CR are soft-deleted. Include every project–segment pair you want active.- A missing
WaveNetfunnelConnectiondoes not block reconciliation of the mapping itself, but NetFunnel enforcement requires a working connection to take effect. - Deleting the CR sets
nfEnabled: falseand removes the workload's mapping entries — the rule is disabled, not erased.
WaveNetfunnelConnection
WaveNetfunnelConnection connects Wave to the NetFunnel service. It provides the API endpoint, tenant/organization identifiers, and Secret references for credentials. All WaveNetfunnelMapping CRs in the cluster share this single connection.
Scope: cluster-scoped — no metadata.namespace required.
First, create the credentials Secret in the wave-autoscale namespace:
apiVersion: v1
kind: Secret
metadata:
name: nf-credentials
namespace: wave-autoscale
type: Opaque
stringData:
clientId: <your-netfunnel-client-id>
secretKey: <your-netfunnel-secret-key>Then create the connection CR:
apiVersion: wavek8s.com/v1alpha1
kind: WaveNetfunnelConnection
metadata:
name: nf-connection
spec:
host: https://nf.example.com
tenantId: my-tenant-id
organizationId: my-org-id
nfApiType: saas
clientIdSecretRef:
name: nf-credentials
key: clientId
secretKeySecretRef:
name: nf-credentials
key: secretKey
enabled: trueSpec fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | Yes | — | NetFunnel API endpoint URL (e.g. https://nf.example.com). |
tenantId | string | Yes | — | NetFunnel tenant identifier. |
organizationId | string | Yes | — | NetFunnel organization identifier. |
nfApiType | string | Yes | — | NetFunnel deployment type. Currently saas is the only supported value. |
clientIdSecretRef | object | Yes | — | Reference to the Secret key that holds the NetFunnel client ID. Resolved from the wave-autoscale namespace. |
clientIdSecretRef.name | string | Yes | — | Name of the Secret. |
clientIdSecretRef.key | string | Yes | — | Key within the Secret whose value is the client ID. |
secretKeySecretRef | object | Yes | — | Reference to the Secret key that holds the NetFunnel secret key. Resolved from the wave-autoscale namespace. |
secretKeySecretRef.name | string | Yes | — | Name of the Secret. |
secretKeySecretRef.key | string | Yes | — | Key within the Secret whose value is the secret key. |
enabled | boolean | No | true | Whether this connection is active. Set to false to disable without deleting the CR. |
Deleting this CR disables the connection, not erases it. Wave has no delete-config operation for the NetFunnel connection. When the CR is removed, Wave flips the connection to enabled: false in its internal state rather than deleting it. To re-enable the connection, re-apply the CR. This is the documented exception to the standard prune-to-default behavior described in CRD Mode.
Notes
- Cluster-scoped — one CR serves all
WaveNetfunnelMappingCRs in the cluster. - Credentials are never stored in the CR. Wave reads the Secret values at reconcile time from the
wave-autoscalenamespace. A missing or inaccessible Secret reportsSecretNotFoundin.status.conditions. - Singleton: only one
WaveNetfunnelConnectionmay be active per cluster. If a second CR is applied, it reportsConflictedin.status.conditionsand is skipped. The first CR reconciled retains the active connection.