update crds

This commit is contained in:
2026-08-18 19:18:31 +01:00
parent 717d09d1f3
commit bb5fc11402
268 changed files with 88606 additions and 1644 deletions
@@ -0,0 +1,763 @@
{
"description": "AttuneDefaults is the Schema for the attunedefaults API.\nIt defines cluster-scoped default values for AttunePolicy resources.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "AttuneDefaultsSpec defines cluster-scoped default values for AttunePolicy resources.",
"properties": {
"costPricing": {
"description": "CostPricing configures the per-unit pricing used to compute\nEstimatedMonthlySavings. If omitted, defaults to standard\non-demand Linux pricing ($0.031/vCPU-hour, $0.004/GiB-hour).",
"properties": {
"cpuPerCoreHour": {
"description": "CPUPerCoreHour is the cost per vCPU-hour (e.g. \"0.031\").\nDefaults to 0.031 if not specified.",
"type": "string"
},
"memoryPerGiBHour": {
"description": "MemoryPerGiBHour is the cost per GiB-hour (e.g. \"0.004\").\nDefaults to 0.004 if not specified.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"cpu": {
"description": "CPU configures default CPU resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"excludeKnownSidecars": {
"description": "ExcludeKnownSidecars, when true (the default when unset on both\ndefaults and policy), automatically skips well-known mesh and\nsidecar container names. Set to false cluster-wide to restore\nexclude-only-via-excludedContainers behavior for policies that\ndo not set the field themselves.",
"type": "boolean"
},
"memory": {
"description": "Memory configures default memory resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"metricsSource": {
"description": "MetricsSource configures default metrics source settings.",
"properties": {
"cloudwatch": {
"description": "CloudWatch configures an Amazon CloudWatch Container Insights metrics source.",
"properties": {
"clusterName": {
"description": "ClusterName is the EKS cluster name for Container Insights metrics.\nRequired for metric filtering.",
"type": "string"
},
"region": {
"description": "Region is the AWS region (e.g. \"us-east-1\"). Required.",
"type": "string"
},
"roleArn": {
"description": "RoleARN is an optional IAM role ARN to assume for cross-account access.\nIf not set, uses the pod's service account IAM role (IRSA/Pod Identity).",
"type": "string"
}
},
"required": [
"clusterName",
"region"
],
"type": "object",
"additionalProperties": false
},
"cpuRecordingMetric": {
"description": "CPURecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of rate(container_cpu_usage_seconds_total). Labels must include\nnamespace, pod, and container. When set, the operator does not wrap the\nmetric in rate(). Pair with MemoryRecordingMetric for a recording-rules-only path.",
"type": "string"
},
"datadog": {
"description": "Datadog configures a Datadog metrics source.",
"properties": {
"apiKeySecretRef": {
"description": "APIKeySecretRef references a Secret containing the Datadog API key.\nThe Secret must contain an \"api-key\" key and optionally an \"app-key\" key.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"site": {
"default": "datadoghq.com",
"description": "Site is the Datadog site (e.g. \"datadoghq.com\", \"datadoghq.eu\", \"us5.datadoghq.com\").\nDefaults to \"datadoghq.com\".",
"type": "string"
}
},
"required": [
"apiKeySecretRef"
],
"type": "object",
"additionalProperties": false
},
"historyWindow": {
"description": "HistoryWindow is the time window for historical metrics data.\nDefaults to 7d (168h) if not specified.",
"type": "string"
},
"memoryRecordingMetric": {
"description": "MemoryRecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of container_memory_working_set_bytes. Same label requirements\nas CPURecordingMetric.",
"type": "string"
},
"minimumDataPoints": {
"description": "MinimumDataPoints is the minimum number of data points required\nbefore generating recommendations. Minimum 1, default 48 samples.\nWith the default queryStep of 5m, 48 samples is about 4 hours of data.\nDefaults to 48 if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"format": "int32",
"minimum": 1,
"type": "integer"
},
"podAggregation": {
"description": "PodAggregation controls how multi-pod series are reduced in Prometheus\nrange queries for this policy.\n Max (default): max by (container) \u2014 size for the busiest pod; O(containers) series.\n Avg: avg by (container) across pods.\n None: no aggregation (one series per pod; expensive for high replica counts).\nDatadog and CloudWatch already group by container; this field applies to Prometheus.",
"enum": [
"Max",
"Avg",
"None"
],
"type": "string"
},
"prometheus": {
"description": "Prometheus configures a Prometheus metrics source.",
"properties": {
"address": {
"description": "Address is the URL of the Prometheus-compatible query endpoint.",
"type": "string"
},
"bearerTokenSecret": {
"description": "BearerTokenSecret references a Kubernetes Secret containing a bearer\ntoken for authenticating with managed Prometheus services.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"headers": {
"additionalProperties": {
"type": "string"
},
"description": "Headers are custom HTTP headers added to every query request.\nUse for non-secret tenant or routing headers (e.g. \"X-Scope-OrgID\"\nfor Mimir). Do not put credentials here; use BearerTokenSecret for\nauthentication tokens.",
"type": "object"
},
"queryParameters": {
"additionalProperties": {
"type": "string"
},
"description": "QueryParameters are appended to every query request URL.\nUse for backend-specific settings such as Thanos deduplication\n(e.g. {\"dedup\": \"true\", \"partial_response\": \"true\"}). Reserved\nquery keys controlled by the operator (`query`, `start`, `end`, `step`,\n`time`, `timeout`) are rejected.",
"type": "object"
},
"tls": {
"description": "TLS configures TLS settings for the connection.",
"properties": {
"insecureSkipVerify": {
"description": "InsecureSkipVerify disables TLS certificate verification.\nUse only for self-signed certificates in development.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"address"
],
"type": "object",
"additionalProperties": false
},
"queryStep": {
"description": "QueryStep is the step interval for Prometheus range queries and ETA\ncalculations. Should match your Prometheus scrape interval for\naccurate time estimates. Minimum 10s, maximum 1h. Default 5m.",
"type": "string"
},
"rateWindow": {
"description": "RateWindow is the window used in the PromQL rate() function for CPU\nqueries. Defaults to queryStep if not set. Must be >= 30s and <= historyWindow.\nAdvanced users may set this independently to control CPU rate smoothing\n(e.g. a short rateWindow for responsive tracking with a longer queryStep).",
"type": "string"
},
"vpa": {
"description": "VPA configures consumption of existing VerticalPodAutoscaler recommendations.",
"properties": {
"name": {
"description": "Name is the name of the VerticalPodAutoscaler object.",
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the VPA. Defaults to the policy's namespace.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"updateStrategy": {
"description": "UpdateStrategy configures default update strategy settings.",
"properties": {
"autoRevert": {
"description": "AutoRevert automatically reverts changes if degradation is detected.\nDefaults to true if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"type": "boolean"
},
"canary": {
"description": "Canary configures canary rollout behavior when Type is Canary.",
"properties": {
"autoPromote": {
"description": "AutoPromote controls whether the operator automatically promotes the\nresize to all pods after the observation period passes without safety\nviolations. When false (default), the user must manually switch the\nmode to Auto to resize the remaining pods.",
"type": "boolean"
},
"observationPeriod": {
"description": "ObservationPeriod is how long to observe canary pods before proceeding.",
"type": "string"
},
"percentage": {
"description": "Percentage is the percentage of pods to resize first.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
"required": [
"observationPeriod",
"percentage"
],
"type": "object",
"additionalProperties": false
},
"cooldown": {
"description": "Cooldown is the minimum time between successive resize operations.\nDefaults to 1h if not specified.",
"type": "string"
},
"export": {
"description": "Export configures how recommendations are exported for external\nconsumption (e.g. GitOps workflows with ArgoCD or Flux).",
"properties": {
"configMap": {
"description": "ConfigMap enables exporting recommendations to ConfigMaps.",
"type": "boolean"
},
"pullRequest": {
"description": "PullRequest enables opt-in GitOps PR automation (default off).\nRequires a token Secret and repository identity. Never logs the token.",
"properties": {
"apiUrl": {
"description": "APIURL overrides the API base URL (Enterprise GitHub or self-hosted GitLab).\nDefaults: https://api.github.com or https://gitlab.com/api/v4.",
"type": "string"
},
"baseBranch": {
"description": "BaseBranch is the PR target branch. Defaults to \"main\".",
"type": "string"
},
"cooldown": {
"description": "Cooldown is the minimum time between PR create/update attempts for this\npolicy. Defaults to 24h.",
"type": "string"
},
"dryRun": {
"description": "DryRun logs the intended PR and updates status without calling the\nremote API. Useful for CI and first enablement.",
"type": "boolean"
},
"enabled": {
"description": "Enabled turns on PR automation. Default false.",
"type": "boolean"
},
"labels": {
"description": "Labels are applied to the pull request when supported by the provider.",
"items": {
"type": "string"
},
"maxItems": 20,
"type": "array"
},
"minChangePercent": {
"description": "MinChangePercent is the minimum absolute percent change (per container\nresource vs template) required to open or update a PR. Defaults to 10.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"provider": {
"description": "Provider is \"github\" or \"gitlab\". Default \"github\".",
"enum": [
"github",
"gitlab"
],
"type": "string"
},
"repository": {
"description": "Repository is \"owner/name\" (GitHub) or \"group/project\" (GitLab path).\nRequired when Enabled is true.",
"type": "string"
},
"tokenSecretRef": {
"description": "TokenSecretRef references a Secret key holding a PAT / project token.\nGitHub: repo contents + pull requests. GitLab: api scope on the project.\nRequired when Enabled is true.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"includeExplanationsInStatus": {
"description": "IncludeExplanationsInStatus controls whether recommendation explanation\nchains are written to status. Set to false on large policies to shrink\nCR size. Default: true.",
"type": "boolean"
},
"initialSizing": {
"description": "InitialSizing enables a mutating admission webhook that sets resource\nrequests/limits on new pods at creation time, based on existing\nrecommendations. This eliminates the \"deploy with bad defaults, wait\nfor first reconcile\" gap. Requires the namespace label\nattune.io/initial-sizing=enabled. Defaults to false.",
"type": "boolean"
},
"maxConcurrentResizes": {
"default": 1,
"description": "MaxConcurrentResizes is the maximum number of pods to resize\nconcurrently within a single reconcile cycle. Default: 1 (serial).",
"format": "int32",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"maxStatusRecommendations": {
"description": "MaxStatusRecommendations caps how many workload recommendations are\nwritten to status.recommendations. Resizes still use the full in-memory\nset. When the cap is hit, entries with the largest absolute CPU+memory\nrequest change are kept. Default: 100 (operator may override via flag).",
"format": "int32",
"maximum": 500,
"minimum": 1,
"type": "integer"
},
"maxTotalCpuIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalCPUIncrease is the maximum aggregate CPU increase allowed\nacross all pods in a single reconcile cycle (e.g. \"2000m\", \"4\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxTotalMemoryIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalMemoryIncrease is the maximum aggregate memory increase\nallowed across all pods in a single reconcile cycle (e.g. \"4Gi\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"resizeMethod": {
"description": "ResizeMethod controls what happens when an in-place resize fails.\n InPlaceOnly (default): skip the pod and retry next cycle.\n InPlaceOrRecreate: fall back to pod eviction if in-place resize\n fails or is marked Infeasible by kubelet. The owning controller\n recreates the pod with updated resources. Evictions respect\n PodDisruptionBudgets and never evict the last replica.\nDefaults to InPlaceOnly if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"enum": [
"InPlaceOnly",
"InPlaceOrRecreate"
],
"type": "string"
},
"safetyObservationPeriod": {
"description": "SafetyObservationPeriod is how long to observe a pod after resize before\nconcluding the resize is safe. Applies to all modes (Auto, OneShot, Canary).\nTakes precedence over canary.observationPeriod when set. Must be >= 1m.\nDefaults to 5m if neither this nor canary.observationPeriod is set.",
"type": "string"
},
"schedule": {
"description": "Schedule restricts when resize operations can occur. Recommendations\nare always computed; only resize execution is gated. If omitted,\nresizes can occur at any time (current behavior).",
"properties": {
"daysOfWeek": {
"description": "DaysOfWeek restricts resizes to specific days. Values: Monday through Sunday.\nIf omitted, all days are allowed.",
"items": {
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
],
"type": "string"
},
"type": "array"
},
"timezone": {
"default": "UTC",
"description": "Timezone for interpreting window start/end times. Must be a valid\nIANA timezone name (e.g. \"America/New_York\"). Default: \"UTC\".",
"type": "string"
},
"windows": {
"description": "Windows defines time-of-day ranges when resizes are allowed.\nIf multiple windows are specified, resizes are allowed during any of them.",
"items": {
"description": "TimeWindow defines a daily time range.",
"properties": {
"end": {
"description": "End time in HH:MM format (24-hour). If end < start, the window\nwraps past midnight (e.g. start=22:00, end=06:00).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
},
"start": {
"description": "Start time in HH:MM format (24-hour).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"sloGuardrails": {
"description": "SLOGuardrails defines application-level SLO metrics to check after\na resize. If any metric breaches its threshold during the safety\nobservation period, the resize is automatically reverted.\nRequires a Prometheus-compatible metrics source.",
"items": {
"description": "SLOGuardrail defines an application-level metric that is checked after\na resize to detect degradation. If the metric breaches the threshold,\nthe safety monitor triggers an automatic revert.",
"properties": {
"comparison": {
"default": "above",
"description": "Comparison is \"above\" or \"below\". \"above\" reverts when value > threshold.",
"enum": [
"above",
"below"
],
"type": "string"
},
"evaluationWindow": {
"description": "EvaluationWindow is how long after resize to check. Defaults to 5m.",
"type": "string"
},
"name": {
"description": "Name identifies this guardrail for logging and status reporting.",
"type": "string"
},
"query": {
"description": "Query is a PromQL query that returns a scalar value.\nTemplate variables: {{ .Namespace }}, {{ .WorkloadName }}, {{ .PodName }}",
"type": "string"
},
"threshold": {
"description": "Threshold is the value that triggers a revert.",
"type": "string"
}
},
"required": [
"name",
"query",
"threshold"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 10,
"type": "array"
},
"templatePersistence": {
"description": "TemplatePersistence optionally writes recommended resources into the\nworkload pod template (Deployment/StatefulSet) so new pods start\ncorrectly sized. Default off. Do not enable under unmanaged GitOps\nsync without adopting recommendations in Git; prefer export or\ninitialSizing in that case.",
"properties": {
"enabled": {
"description": "Enabled turns on template persistence. When false or unset, templates\nare never mutated.",
"type": "boolean"
},
"when": {
"description": "When selects the trigger. Defaults to AfterSuccessfulResize when\nEnabled is true and When is empty.",
"enum": [
"AfterSuccessfulResize",
"OnRecommendation"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": {
"description": "Mode determines the update behavior, graduated from safe to automated:\n Recommend: collects metrics and writes recommendations to status, no pod changes.\n OneShot: resizes one pod per reconcile cycle.\n Canary: resizes a percentage of pods first, then the rest after observation.\n Auto: resizes all eligible pods each cycle.\n Observe: collects metrics and tracks data points but does not surface recommendations or savings.\nStart with Recommend in production and promote after reviewing status.\nDefaults to Recommend if not set (applied by the controller, not the webhook,\nso that AttuneDefaults cluster configuration can override it).",
"enum": [
"Observe",
"Recommend",
"OneShot",
"Canary",
"Auto"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
@@ -0,0 +1,763 @@
{
"description": "AttuneNamespaceDefaults is the Schema for namespace-scoped defaults.\nValues here override cluster-scoped AttuneDefaults but are overridden\nby per-policy values. Precedence: policy > namespace defaults > cluster defaults.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "AttuneDefaultsSpec defines cluster-scoped default values for AttunePolicy resources.",
"properties": {
"costPricing": {
"description": "CostPricing configures the per-unit pricing used to compute\nEstimatedMonthlySavings. If omitted, defaults to standard\non-demand Linux pricing ($0.031/vCPU-hour, $0.004/GiB-hour).",
"properties": {
"cpuPerCoreHour": {
"description": "CPUPerCoreHour is the cost per vCPU-hour (e.g. \"0.031\").\nDefaults to 0.031 if not specified.",
"type": "string"
},
"memoryPerGiBHour": {
"description": "MemoryPerGiBHour is the cost per GiB-hour (e.g. \"0.004\").\nDefaults to 0.004 if not specified.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"cpu": {
"description": "CPU configures default CPU resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"excludeKnownSidecars": {
"description": "ExcludeKnownSidecars, when true (the default when unset on both\ndefaults and policy), automatically skips well-known mesh and\nsidecar container names. Set to false cluster-wide to restore\nexclude-only-via-excludedContainers behavior for policies that\ndo not set the field themselves.",
"type": "boolean"
},
"memory": {
"description": "Memory configures default memory resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"metricsSource": {
"description": "MetricsSource configures default metrics source settings.",
"properties": {
"cloudwatch": {
"description": "CloudWatch configures an Amazon CloudWatch Container Insights metrics source.",
"properties": {
"clusterName": {
"description": "ClusterName is the EKS cluster name for Container Insights metrics.\nRequired for metric filtering.",
"type": "string"
},
"region": {
"description": "Region is the AWS region (e.g. \"us-east-1\"). Required.",
"type": "string"
},
"roleArn": {
"description": "RoleARN is an optional IAM role ARN to assume for cross-account access.\nIf not set, uses the pod's service account IAM role (IRSA/Pod Identity).",
"type": "string"
}
},
"required": [
"clusterName",
"region"
],
"type": "object",
"additionalProperties": false
},
"cpuRecordingMetric": {
"description": "CPURecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of rate(container_cpu_usage_seconds_total). Labels must include\nnamespace, pod, and container. When set, the operator does not wrap the\nmetric in rate(). Pair with MemoryRecordingMetric for a recording-rules-only path.",
"type": "string"
},
"datadog": {
"description": "Datadog configures a Datadog metrics source.",
"properties": {
"apiKeySecretRef": {
"description": "APIKeySecretRef references a Secret containing the Datadog API key.\nThe Secret must contain an \"api-key\" key and optionally an \"app-key\" key.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"site": {
"default": "datadoghq.com",
"description": "Site is the Datadog site (e.g. \"datadoghq.com\", \"datadoghq.eu\", \"us5.datadoghq.com\").\nDefaults to \"datadoghq.com\".",
"type": "string"
}
},
"required": [
"apiKeySecretRef"
],
"type": "object",
"additionalProperties": false
},
"historyWindow": {
"description": "HistoryWindow is the time window for historical metrics data.\nDefaults to 7d (168h) if not specified.",
"type": "string"
},
"memoryRecordingMetric": {
"description": "MemoryRecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of container_memory_working_set_bytes. Same label requirements\nas CPURecordingMetric.",
"type": "string"
},
"minimumDataPoints": {
"description": "MinimumDataPoints is the minimum number of data points required\nbefore generating recommendations. Minimum 1, default 48 samples.\nWith the default queryStep of 5m, 48 samples is about 4 hours of data.\nDefaults to 48 if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"format": "int32",
"minimum": 1,
"type": "integer"
},
"podAggregation": {
"description": "PodAggregation controls how multi-pod series are reduced in Prometheus\nrange queries for this policy.\n Max (default): max by (container) \u2014 size for the busiest pod; O(containers) series.\n Avg: avg by (container) across pods.\n None: no aggregation (one series per pod; expensive for high replica counts).\nDatadog and CloudWatch already group by container; this field applies to Prometheus.",
"enum": [
"Max",
"Avg",
"None"
],
"type": "string"
},
"prometheus": {
"description": "Prometheus configures a Prometheus metrics source.",
"properties": {
"address": {
"description": "Address is the URL of the Prometheus-compatible query endpoint.",
"type": "string"
},
"bearerTokenSecret": {
"description": "BearerTokenSecret references a Kubernetes Secret containing a bearer\ntoken for authenticating with managed Prometheus services.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"headers": {
"additionalProperties": {
"type": "string"
},
"description": "Headers are custom HTTP headers added to every query request.\nUse for non-secret tenant or routing headers (e.g. \"X-Scope-OrgID\"\nfor Mimir). Do not put credentials here; use BearerTokenSecret for\nauthentication tokens.",
"type": "object"
},
"queryParameters": {
"additionalProperties": {
"type": "string"
},
"description": "QueryParameters are appended to every query request URL.\nUse for backend-specific settings such as Thanos deduplication\n(e.g. {\"dedup\": \"true\", \"partial_response\": \"true\"}). Reserved\nquery keys controlled by the operator (`query`, `start`, `end`, `step`,\n`time`, `timeout`) are rejected.",
"type": "object"
},
"tls": {
"description": "TLS configures TLS settings for the connection.",
"properties": {
"insecureSkipVerify": {
"description": "InsecureSkipVerify disables TLS certificate verification.\nUse only for self-signed certificates in development.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"address"
],
"type": "object",
"additionalProperties": false
},
"queryStep": {
"description": "QueryStep is the step interval for Prometheus range queries and ETA\ncalculations. Should match your Prometheus scrape interval for\naccurate time estimates. Minimum 10s, maximum 1h. Default 5m.",
"type": "string"
},
"rateWindow": {
"description": "RateWindow is the window used in the PromQL rate() function for CPU\nqueries. Defaults to queryStep if not set. Must be >= 30s and <= historyWindow.\nAdvanced users may set this independently to control CPU rate smoothing\n(e.g. a short rateWindow for responsive tracking with a longer queryStep).",
"type": "string"
},
"vpa": {
"description": "VPA configures consumption of existing VerticalPodAutoscaler recommendations.",
"properties": {
"name": {
"description": "Name is the name of the VerticalPodAutoscaler object.",
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the VPA. Defaults to the policy's namespace.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"updateStrategy": {
"description": "UpdateStrategy configures default update strategy settings.",
"properties": {
"autoRevert": {
"description": "AutoRevert automatically reverts changes if degradation is detected.\nDefaults to true if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"type": "boolean"
},
"canary": {
"description": "Canary configures canary rollout behavior when Type is Canary.",
"properties": {
"autoPromote": {
"description": "AutoPromote controls whether the operator automatically promotes the\nresize to all pods after the observation period passes without safety\nviolations. When false (default), the user must manually switch the\nmode to Auto to resize the remaining pods.",
"type": "boolean"
},
"observationPeriod": {
"description": "ObservationPeriod is how long to observe canary pods before proceeding.",
"type": "string"
},
"percentage": {
"description": "Percentage is the percentage of pods to resize first.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
"required": [
"observationPeriod",
"percentage"
],
"type": "object",
"additionalProperties": false
},
"cooldown": {
"description": "Cooldown is the minimum time between successive resize operations.\nDefaults to 1h if not specified.",
"type": "string"
},
"export": {
"description": "Export configures how recommendations are exported for external\nconsumption (e.g. GitOps workflows with ArgoCD or Flux).",
"properties": {
"configMap": {
"description": "ConfigMap enables exporting recommendations to ConfigMaps.",
"type": "boolean"
},
"pullRequest": {
"description": "PullRequest enables opt-in GitOps PR automation (default off).\nRequires a token Secret and repository identity. Never logs the token.",
"properties": {
"apiUrl": {
"description": "APIURL overrides the API base URL (Enterprise GitHub or self-hosted GitLab).\nDefaults: https://api.github.com or https://gitlab.com/api/v4.",
"type": "string"
},
"baseBranch": {
"description": "BaseBranch is the PR target branch. Defaults to \"main\".",
"type": "string"
},
"cooldown": {
"description": "Cooldown is the minimum time between PR create/update attempts for this\npolicy. Defaults to 24h.",
"type": "string"
},
"dryRun": {
"description": "DryRun logs the intended PR and updates status without calling the\nremote API. Useful for CI and first enablement.",
"type": "boolean"
},
"enabled": {
"description": "Enabled turns on PR automation. Default false.",
"type": "boolean"
},
"labels": {
"description": "Labels are applied to the pull request when supported by the provider.",
"items": {
"type": "string"
},
"maxItems": 20,
"type": "array"
},
"minChangePercent": {
"description": "MinChangePercent is the minimum absolute percent change (per container\nresource vs template) required to open or update a PR. Defaults to 10.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"provider": {
"description": "Provider is \"github\" or \"gitlab\". Default \"github\".",
"enum": [
"github",
"gitlab"
],
"type": "string"
},
"repository": {
"description": "Repository is \"owner/name\" (GitHub) or \"group/project\" (GitLab path).\nRequired when Enabled is true.",
"type": "string"
},
"tokenSecretRef": {
"description": "TokenSecretRef references a Secret key holding a PAT / project token.\nGitHub: repo contents + pull requests. GitLab: api scope on the project.\nRequired when Enabled is true.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"includeExplanationsInStatus": {
"description": "IncludeExplanationsInStatus controls whether recommendation explanation\nchains are written to status. Set to false on large policies to shrink\nCR size. Default: true.",
"type": "boolean"
},
"initialSizing": {
"description": "InitialSizing enables a mutating admission webhook that sets resource\nrequests/limits on new pods at creation time, based on existing\nrecommendations. This eliminates the \"deploy with bad defaults, wait\nfor first reconcile\" gap. Requires the namespace label\nattune.io/initial-sizing=enabled. Defaults to false.",
"type": "boolean"
},
"maxConcurrentResizes": {
"default": 1,
"description": "MaxConcurrentResizes is the maximum number of pods to resize\nconcurrently within a single reconcile cycle. Default: 1 (serial).",
"format": "int32",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"maxStatusRecommendations": {
"description": "MaxStatusRecommendations caps how many workload recommendations are\nwritten to status.recommendations. Resizes still use the full in-memory\nset. When the cap is hit, entries with the largest absolute CPU+memory\nrequest change are kept. Default: 100 (operator may override via flag).",
"format": "int32",
"maximum": 500,
"minimum": 1,
"type": "integer"
},
"maxTotalCpuIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalCPUIncrease is the maximum aggregate CPU increase allowed\nacross all pods in a single reconcile cycle (e.g. \"2000m\", \"4\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxTotalMemoryIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalMemoryIncrease is the maximum aggregate memory increase\nallowed across all pods in a single reconcile cycle (e.g. \"4Gi\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"resizeMethod": {
"description": "ResizeMethod controls what happens when an in-place resize fails.\n InPlaceOnly (default): skip the pod and retry next cycle.\n InPlaceOrRecreate: fall back to pod eviction if in-place resize\n fails or is marked Infeasible by kubelet. The owning controller\n recreates the pod with updated resources. Evictions respect\n PodDisruptionBudgets and never evict the last replica.\nDefaults to InPlaceOnly if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"enum": [
"InPlaceOnly",
"InPlaceOrRecreate"
],
"type": "string"
},
"safetyObservationPeriod": {
"description": "SafetyObservationPeriod is how long to observe a pod after resize before\nconcluding the resize is safe. Applies to all modes (Auto, OneShot, Canary).\nTakes precedence over canary.observationPeriod when set. Must be >= 1m.\nDefaults to 5m if neither this nor canary.observationPeriod is set.",
"type": "string"
},
"schedule": {
"description": "Schedule restricts when resize operations can occur. Recommendations\nare always computed; only resize execution is gated. If omitted,\nresizes can occur at any time (current behavior).",
"properties": {
"daysOfWeek": {
"description": "DaysOfWeek restricts resizes to specific days. Values: Monday through Sunday.\nIf omitted, all days are allowed.",
"items": {
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
],
"type": "string"
},
"type": "array"
},
"timezone": {
"default": "UTC",
"description": "Timezone for interpreting window start/end times. Must be a valid\nIANA timezone name (e.g. \"America/New_York\"). Default: \"UTC\".",
"type": "string"
},
"windows": {
"description": "Windows defines time-of-day ranges when resizes are allowed.\nIf multiple windows are specified, resizes are allowed during any of them.",
"items": {
"description": "TimeWindow defines a daily time range.",
"properties": {
"end": {
"description": "End time in HH:MM format (24-hour). If end < start, the window\nwraps past midnight (e.g. start=22:00, end=06:00).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
},
"start": {
"description": "Start time in HH:MM format (24-hour).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"sloGuardrails": {
"description": "SLOGuardrails defines application-level SLO metrics to check after\na resize. If any metric breaches its threshold during the safety\nobservation period, the resize is automatically reverted.\nRequires a Prometheus-compatible metrics source.",
"items": {
"description": "SLOGuardrail defines an application-level metric that is checked after\na resize to detect degradation. If the metric breaches the threshold,\nthe safety monitor triggers an automatic revert.",
"properties": {
"comparison": {
"default": "above",
"description": "Comparison is \"above\" or \"below\". \"above\" reverts when value > threshold.",
"enum": [
"above",
"below"
],
"type": "string"
},
"evaluationWindow": {
"description": "EvaluationWindow is how long after resize to check. Defaults to 5m.",
"type": "string"
},
"name": {
"description": "Name identifies this guardrail for logging and status reporting.",
"type": "string"
},
"query": {
"description": "Query is a PromQL query that returns a scalar value.\nTemplate variables: {{ .Namespace }}, {{ .WorkloadName }}, {{ .PodName }}",
"type": "string"
},
"threshold": {
"description": "Threshold is the value that triggers a revert.",
"type": "string"
}
},
"required": [
"name",
"query",
"threshold"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 10,
"type": "array"
},
"templatePersistence": {
"description": "TemplatePersistence optionally writes recommended resources into the\nworkload pod template (Deployment/StatefulSet) so new pods start\ncorrectly sized. Default off. Do not enable under unmanaged GitOps\nsync without adopting recommendations in Git; prefer export or\ninitialSizing in that case.",
"properties": {
"enabled": {
"description": "Enabled turns on template persistence. When false or unset, templates\nare never mutated.",
"type": "boolean"
},
"when": {
"description": "When selects the trigger. Defaults to AfterSuccessfulResize when\nEnabled is true and When is empty.",
"enum": [
"AfterSuccessfulResize",
"OnRecommendation"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": {
"description": "Mode determines the update behavior, graduated from safe to automated:\n Recommend: collects metrics and writes recommendations to status, no pod changes.\n OneShot: resizes one pod per reconcile cycle.\n Canary: resizes a percentage of pods first, then the rest after observation.\n Auto: resizes all eligible pods each cycle.\n Observe: collects metrics and tracks data points but does not surface recommendations or savings.\nStart with Recommend in production and promote after reviewing status.\nDefaults to Recommend if not set (applied by the controller, not the webhook,\nso that AttuneDefaults cluster configuration can override it).",
"enum": [
"Observe",
"Recommend",
"OneShot",
"Canary",
"Auto"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,733 @@
{
"description": "CloudflareAccessApplication binds Gateway API targets to reusable Cloudflare Access policies.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "CloudflareAccessApplicationSpec defines Gateway API target bindings to reusable Access policies.",
"properties": {
"application": {
"description": "Application defines Access Application settings shared by generated apps.\nThe path field overrides any path derived from HTTPRoute rules.",
"properties": {
"allowedIdps": {
"description": "AllowedIdps restricts which identity providers can authenticate.\nValues are Cloudflare Identity Provider UUIDs.\nWhen empty, all IdPs configured in the account are allowed.",
"items": {
"type": "string"
},
"maxItems": 25,
"type": "array"
},
"appLauncherVisible": {
"default": true,
"description": "AppLauncherVisible controls whether the application appears in the\nCloudflare App Launcher dashboard. Use pointer to distinguish\nexplicit false (hidden) from absent (default visible).",
"type": "boolean"
},
"autoRedirectToIdentity": {
"description": "AutoRedirectToIdentity auto-redirects to the identity provider\nwhen a single IdP is configured in allowedIdps. Skips the IdP\nselection page.",
"type": "boolean"
},
"corsHeaders": {
"description": "CORSHeaders configures CORS for browser-based APIs behind Access.\nWhen set, Cloudflare responds to OPTIONS preflight on behalf of the origin.\nMutually exclusive with optionsPreflightBypass.",
"properties": {
"allowAllHeaders": {
"description": "AllowAllHeaders allows all HTTP request headers.",
"type": "boolean"
},
"allowAllMethods": {
"description": "AllowAllMethods allows all HTTP request methods.",
"type": "boolean"
},
"allowAllOrigins": {
"description": "AllowAllOrigins allows all origins.",
"type": "boolean"
},
"allowCredentials": {
"description": "AllowCredentials includes credentials (cookies, authorization headers,\nor TLS client certificates) with CORS requests.",
"type": "boolean"
},
"allowedHeaders": {
"description": "AllowedHeaders lists specific allowed HTTP request headers.\nIgnored when allowAllHeaders is true.",
"items": {
"type": "string"
},
"maxItems": 50,
"type": "array"
},
"allowedMethods": {
"description": "AllowedMethods lists specific allowed HTTP request methods.\nIgnored when allowAllMethods is true.",
"items": {
"description": "CORSAllowedMethod is an HTTP method allowed for CORS requests.",
"enum": [
"GET",
"POST",
"HEAD",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH"
],
"type": "string"
},
"maxItems": 9,
"type": "array"
},
"allowedOrigins": {
"description": "AllowedOrigins lists specific allowed origins.\nIgnored when allowAllOrigins is true.",
"items": {
"type": "string"
},
"maxItems": 50,
"type": "array"
},
"maxAge": {
"description": "MaxAge is the maximum number of seconds preflight results can be cached.",
"maximum": 86400,
"minimum": 0,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"customDenyMessage": {
"description": "CustomDenyMessage shown when access is denied.",
"maxLength": 1024,
"type": "string"
},
"customDenyUrl": {
"description": "CustomDenyURL redirects to this URL when denied (instead of message).",
"type": "string"
},
"customNonIdentityDenyUrl": {
"description": "CustomNonIdentityDenyURL is the URL users are redirected to when\ndenied by a non-identity (service auth) policy. Separate from\ncustomDenyUrl which handles identity-based denials.",
"maxLength": 1024,
"type": "string"
},
"domain": {
"description": "Domain is the protected domain (auto-generated from routes if omitted).\nMax 253: RFC 1035 section 2.3.4 FQDN presentation-format limit.",
"maxLength": 253,
"type": "string",
"x-kubernetes-validations": [
{
"message": "each DNS label must not exceed 63 octets (RFC 1035 section 2.3.4)",
"rule": "self == '' || self.split('.').all(s, size(s) <= 63)"
}
]
},
"enableBindingCookie": {
"default": false,
"description": "EnableBindingCookie enables binding cookies for sticky sessions.",
"type": "boolean"
},
"httpOnlyCookieAttribute": {
"default": true,
"description": "HttpOnlyCookieAttribute adds HttpOnly to session cookies.",
"type": "boolean"
},
"logoUrl": {
"description": "LogoURL is the application logo in dashboard.",
"maxLength": 1024,
"type": "string"
},
"name": {
"description": "Name is the display name in Cloudflare dashboard.\nDefaults to CR name if omitted.",
"maxLength": 255,
"type": "string"
},
"optionsPreflightBypass": {
"description": "OptionsPreflightBypass allows OPTIONS preflight requests to bypass\nAccess authentication and go directly to the origin. Enabling this\nremoves all CORS header settings. Mutually exclusive with corsHeaders.",
"type": "boolean"
},
"path": {
"description": "Path restricts protection to a specific absolute path prefix.\nCloudflare Access paths must not include query strings or fragments.",
"maxLength": 1024,
"pattern": "^/[^?#]*$",
"type": "string"
},
"pathCookieAttribute": {
"description": "PathCookieAttribute scopes the Access JWT cookie to the application\npath instead of the hostname. When enabled, users must re-authenticate\nfor different paths on the same hostname.",
"type": "boolean"
},
"readServiceTokensFromHeader": {
"description": "ReadServiceTokensFromHeader enables reading service tokens from a\nsingle custom HTTP header instead of the standard CF-Access-Client-Id\nand CF-Access-Client-Secret header pair. The value is the header name.\nThe header value must contain a JSON object with \"cf-access-client-id\"\nand \"cf-access-client-secret\" keys.",
"maxLength": 256,
"type": "string"
},
"sameSiteCookieAttribute": {
"default": "lax",
"description": "SameSiteCookieAttribute controls cross-site cookie behavior.",
"enum": [
"strict",
"lax",
"none"
],
"type": "string"
},
"serviceAuth401Redirect": {
"description": "ServiceAuth401Redirect returns a 401 status code instead of\nredirecting to the Access login page when a request is blocked by a\nService Auth (non_identity) policy. Enable for API consumers.",
"type": "boolean"
},
"sessionDuration": {
"default": "24h",
"description": "SessionDuration controls session cookie lifetime.",
"pattern": "^([0-9]+(ns|us|ms|s|m|h))+$",
"type": "string"
},
"skipInterstitial": {
"default": false,
"description": "SkipInterstitial bypasses the Access login page for API requests.",
"type": "boolean"
},
"type": {
"default": "self_hosted",
"description": "Type is the application type.",
"enum": [
"self_hosted"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "corsHeaders and optionsPreflightBypass are mutually exclusive",
"rule": "!(has(self.corsHeaders) && has(self.optionsPreflightBypass) && self.optionsPreflightBypass)"
}
],
"additionalProperties": false
},
"cloudflareRef": {
"description": "CloudflareRef references Cloudflare credentials. When omitted, credentials\nare inherited from each target's route -> Gateway -> CloudflareTunnel chain.\nMultiple targets must inherit the same Cloudflare account.",
"properties": {
"accountId": {
"description": "AccountID is the Cloudflare account ID.",
"maxLength": 32,
"type": "string"
},
"accountName": {
"description": "AccountName is the Cloudflare account name (looked up via API).",
"maxLength": 255,
"type": "string"
},
"name": {
"description": "Name of the secret containing credentials.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret (defaults to policy namespace).",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"policyRefs": {
"description": "PolicyRefs lists reusable CloudflareAccessPolicy resources to attach.",
"items": {
"description": "AccessPolicyReference references a reusable CloudflareAccessPolicy.",
"properties": {
"name": {
"description": "Name is the CloudflareAccessPolicy name.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"default": "",
"description": "Namespace is the CloudflareAccessPolicy namespace. Empty defaults to application namespace.\nCross-namespace references require ReferenceGrant.",
"maxLength": 253,
"type": "string"
},
"precedence": {
"description": "Precedence determines policy evaluation order for the application. Lower values run first.\nWhen omitted, the controller uses list order starting at 1.",
"maximum": 9999,
"minimum": 1,
"type": "integer"
}
},
"required": [
"name",
"namespace"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"name",
"namespace"
],
"x-kubernetes-list-type": "map"
},
"targetRef": {
"description": "TargetRef identifies a single Gateway API target.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the API group of the target resource.",
"maxLength": 253,
"type": "string"
},
"kind": {
"description": "Kind is the kind of the target resource.",
"enum": [
"Gateway",
"HTTPRoute"
],
"maxLength": 63,
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the target resource.\nCross-namespace targeting requires ReferenceGrant.",
"maxLength": 253,
"type": "string"
},
"sectionName": {
"description": "SectionName targets specific listener (Gateway) or rule (Route).",
"maxLength": 253,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "group must be gateway.networking.k8s.io",
"rule": "self.group == 'gateway.networking.k8s.io'"
},
{
"message": "kind must be Gateway or HTTPRoute",
"rule": "self.kind in ['Gateway', 'HTTPRoute']"
}
],
"additionalProperties": false
},
"targetRefs": {
"description": "TargetRefs identifies multiple Gateway API targets.",
"items": {
"description": "PolicyTargetReference identifies a Gateway API resource for Access application attachment.\n\nPolicyTargetReference follows the Gateway API LocalPolicyTargetReferenceWithSectionName\npattern. It targets Gateway API Gateway and HTTPRoute resources and extracts\nhostnames and paths from those resources to create corresponding Cloudflare Access\napplications.\n\nCross-namespace references require a ReferenceGrant in the target namespace that permits\nCloudflareAccessApplication resources from the application's namespace.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the API group of the target resource.",
"maxLength": 253,
"type": "string"
},
"kind": {
"description": "Kind is the kind of the target resource.",
"enum": [
"Gateway",
"HTTPRoute"
],
"maxLength": 63,
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the target resource.\nCross-namespace targeting requires ReferenceGrant.",
"maxLength": 253,
"type": "string"
},
"sectionName": {
"description": "SectionName targets specific listener (Gateway) or rule (Route).",
"maxLength": 253,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "group must be gateway.networking.k8s.io",
"rule": "self.group == 'gateway.networking.k8s.io'"
},
{
"message": "kind must be Gateway or HTTPRoute",
"rule": "self.kind in ['Gateway', 'HTTPRoute']"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array"
}
},
"required": [
"policyRefs"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "either targetRef or targetRefs must be specified",
"rule": "has(self.targetRef) || has(self.targetRefs)"
},
{
"message": "targetRef and targetRefs are mutually exclusive",
"rule": "!(has(self.targetRef) && has(self.targetRefs))"
},
{
"message": "policyRefs must either all omit precedence or all specify precedence",
"rule": "self.policyRefs.all(p, !has(p.precedence)) || self.policyRefs.all(p, has(p.precedence))"
},
{
"message": "policyRefs precedence values must be unique",
"rule": "self.policyRefs.all(p, !has(p.precedence)) || self.policyRefs.all(p, has(p.precedence) && self.policyRefs.exists_one(q, has(q.precedence) && q.precedence == p.precedence))"
}
],
"additionalProperties": false
},
"status": {
"description": "CloudflareAccessApplicationStatus defines observed Access application state.",
"properties": {
"accountId": {
"description": "AccountID is the resolved Cloudflare account ID used for Access application cleanup.",
"maxLength": 32,
"type": "string"
},
"ancestors": {
"description": "Ancestors contains status for each targetRef.",
"items": {
"description": "PolicyAncestorStatus describes the policy attachment status for a specific target.\n\nPolicyAncestorStatus follows the Gateway API PolicyAncestorStatus pattern to report\nper-target attachment status. Each target reference in the spec has a corresponding\nancestor status entry showing whether the policy was successfully attached.",
"properties": {
"ancestorRef": {
"description": "AncestorRef identifies the target.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the API group of the target resource.",
"maxLength": 253,
"type": "string"
},
"kind": {
"description": "Kind is the kind of the target resource.",
"enum": [
"Gateway",
"HTTPRoute"
],
"maxLength": 63,
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the target resource.\nCross-namespace targeting requires ReferenceGrant.",
"maxLength": 253,
"type": "string"
},
"sectionName": {
"description": "SectionName targets specific listener (Gateway) or rule (Route).",
"maxLength": 253,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "group must be gateway.networking.k8s.io",
"rule": "self.group == 'gateway.networking.k8s.io'"
},
{
"message": "kind must be Gateway or HTTPRoute",
"rule": "self.kind in ['Gateway', 'HTTPRoute']"
}
],
"additionalProperties": false
},
"conditions": {
"description": "Conditions for this specific target.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array"
},
"controllerName": {
"description": "ControllerName identifies the controller managing this attachment.",
"maxLength": 253,
"type": "string"
}
},
"required": [
"ancestorRef",
"controllerName"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array"
},
"applications": {
"description": "Applications are Cloudflare Access Applications managed by this resource.",
"items": {
"description": "AccessApplicationObserved records a Cloudflare Access Application created for one host/path target.",
"properties": {
"aud": {
"description": "AUD is the Application Audience Tag.",
"maxLength": 255,
"type": "string"
},
"domain": {
"description": "Domain is the protected hostname/path in Cloudflare.",
"maxLength": 1024,
"type": "string"
},
"id": {
"description": "ID is the Cloudflare Access Application ID.",
"maxLength": 36,
"type": "string"
},
"targetRef": {
"description": "TargetRef identifies the Gateway API target that produced this application.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the API group of the target resource.",
"maxLength": 253,
"type": "string"
},
"kind": {
"description": "Kind is the kind of the target resource.",
"enum": [
"Gateway",
"HTTPRoute"
],
"maxLength": 63,
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the target resource.\nCross-namespace targeting requires ReferenceGrant.",
"maxLength": 253,
"type": "string"
},
"sectionName": {
"description": "SectionName targets specific listener (Gateway) or rule (Route).",
"maxLength": 253,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "group must be gateway.networking.k8s.io",
"rule": "self.group == 'gateway.networking.k8s.io'"
},
{
"message": "kind must be Gateway or HTTPRoute",
"rule": "self.kind in ['Gateway', 'HTTPRoute']"
}
],
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array"
},
"attachedTargets": {
"description": "AttachedTargets is the count of successfully attached Gateway API targets.",
"format": "int32",
"type": "integer"
},
"conditions": {
"description": "Conditions describe current state.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"credentialSecretRef": {
"description": "CredentialSecretRef is the resolved credentials Secret used for cleanup.\nThe namespace is always stored explicitly.",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the resource's namespace if empty.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"observedGeneration": {
"description": "ObservedGeneration is the last generation processed.",
"format": "int64",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,591 @@
{
"description": "CloudflareDNS is the Schema for the cloudflarednses API.\n\nCloudflareDNS manages DNS record synchronization independently from CloudflareTunnel resources.\nIt supports two target modes: tunnel references (for tunnel-based CNAME records) and external\ntargets (for non-tunnel DNS management). DNS records can be sourced from Gateway API routes\nor explicitly defined.\n\nCloudflareDNS implements ownership tracking via TXT records (aligned with external-dns patterns)\nto enable safe multi-cluster deployments and prevent accidental deletion of records created\nby other installations.\n\nStatus conditions:\n - Ready: DNS sync is fully operational\n - CredentialsValid: Cloudflare credentials have been validated\n - ZonesResolved: All configured zones have been resolved via API\n - RecordsSynced: DNS records have been synchronized to Cloudflare\n - OwnershipVerified: TXT ownership records have been verified, when enabled",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "CloudflareDNSSpec defines the desired state of a CloudflareDNS resource.\n\nCloudflareDNSSpec configures DNS record synchronization, including the target\n(tunnel or external), zones to manage, hostname sources, and ownership tracking.\nEither tunnelRef or externalTarget must be specified (mutually exclusive).",
"properties": {
"cleanupPolicy": {
"description": "CleanupPolicy defines cleanup behavior for records.",
"properties": {
"deleteOnResourceRemoval": {
"description": "DeleteOnResourceRemoval deletes records when CloudflareDNS resource is deleted.\nnil defaults to true.",
"type": "boolean"
},
"deleteOnRouteRemoval": {
"description": "DeleteOnRouteRemoval deletes records when the source route is deleted.\nnil defaults to true.",
"type": "boolean"
},
"onlyManaged": {
"description": "OnlyManaged only deletes records that were created by cfgate (verified via ownership).\nnil defaults to true.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
},
"cloudflare": {
"description": "Cloudflare API credentials (required when using externalTarget).\nWhen using tunnelRef, credentials are inherited from the tunnel.",
"properties": {
"accountId": {
"description": "AccountID is the Cloudflare Account ID.",
"maxLength": 32,
"type": "string"
},
"accountName": {
"description": "AccountName is the Cloudflare Account name. Will be looked up via API.",
"maxLength": 255,
"type": "string"
},
"secretKeys": {
"description": "SecretKeys defines the key mappings within the secret.",
"properties": {
"apiToken": {
"default": "CLOUDFLARE_API_TOKEN",
"description": "APIToken is the key name for the Cloudflare API token.",
"maxLength": 253,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"secretRef": {
"description": "SecretRef references the Secret containing Cloudflare API credentials.\nThe secret must contain an API token (not tunnel token).",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the tunnel's namespace.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"secretRef"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "either accountId or accountName must be specified",
"rule": "has(self.accountId) || has(self.accountName)"
},
{
"message": "accountId must be a 32-character hex string",
"rule": "!has(self.accountId) || self.accountId.matches('^[a-f0-9]{32}$')"
}
],
"additionalProperties": false
},
"defaults": {
"description": "Defaults defines default settings for DNS records.",
"properties": {
"proxied": {
"default": true,
"description": "Proxied enables Cloudflare proxy by default.",
"type": "boolean"
},
"ttl": {
"default": 1,
"description": "TTL is the default DNS record TTL in seconds.\nValid values: 1 (auto) or 60-86400 (explicit).",
"format": "int32",
"maximum": 86400,
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "TTL must be 1 (auto) or between 60 and 86400 seconds",
"rule": "!has(self.ttl) || self.ttl == 1 || (self.ttl >= 60 && self.ttl <= 86400)"
}
],
"additionalProperties": false
},
"externalTarget": {
"description": "ExternalTarget specifies a non-tunnel DNS target.",
"properties": {
"type": {
"allOf": [
{
"enum": [
"CNAME",
"A",
"AAAA"
]
},
{
"enum": [
"CNAME",
"A",
"AAAA"
]
}
],
"description": "Type is the DNS record type.",
"type": "string"
},
"value": {
"description": "Value is the target value (domain for CNAME, IP for A/AAAA).\nMax 253: RFC 1035 section 2.3.4 FQDN presentation-format limit.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"type",
"value"
],
"type": "object",
"additionalProperties": false
},
"fallbackCredentialsRef": {
"description": "FallbackCredentialsRef references fallback Cloudflare API credentials.\nUsed during deletion when primary credentials are unavailable.",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the resource's namespace if empty.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"ownership": {
"description": "Ownership defines how to track record ownership.",
"properties": {
"comment": {
"description": "Comment configures comment-based ownership.\n\nDeprecated: since v0.1.0-alpha.13. All fields are ignored. Will be removed in a future cleanup release.",
"properties": {
"enabled": {
"default": false,
"description": "Enabled enables comment-based ownership tracking.\n\nDeprecated: since v0.1.0-alpha.13. This field is ignored. The controller always\nwrites a \"managed by cfgate\" comment. Will be removed in a future cleanup release.",
"type": "boolean"
},
"template": {
"default": "managed by cfgate",
"description": "Template is the comment template.\n\nDeprecated: since v0.1.0-alpha.13. This field is ignored. The controller always\nuses \"managed by cfgate\" as the comment. Will be removed in a future cleanup release.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"ownerId": {
"description": "OwnerID is the cluster/installation identifier used in TXT ownership records.\nUsed to distinguish records created by different cfgate installations.\nDefaults to the CloudflareDNS resource's namespace/name if not specified.",
"maxLength": 253,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(/[a-z0-9]([-a-z0-9]*[a-z0-9])?)?$",
"type": "string"
},
"txtRecord": {
"description": "TXTRecord configures TXT record-based ownership.",
"properties": {
"enabled": {
"description": "Enabled enables TXT record ownership tracking.\nnil defaults to true.",
"type": "boolean"
},
"prefix": {
"default": "_cfgate",
"description": "Prefix is the prefix for TXT record names.",
"maxLength": 63,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"policy": {
"allOf": [
{
"enum": [
"sync",
"upsert-only",
"create-only"
]
},
{
"enum": [
"sync",
"upsert-only",
"create-only"
]
}
],
"default": "sync",
"description": "Policy controls DNS record lifecycle.",
"type": "string"
},
"source": {
"description": "Source defines where to get hostnames to sync.",
"properties": {
"explicit": {
"description": "Explicit defines explicit hostnames to sync.",
"items": {
"description": "DNSExplicitHostname defines an explicit hostname to sync with optional per-hostname configuration.\n\nDNSExplicitHostname provides direct specification of DNS hostnames without depending on\nGateway API route discovery. The Target field supports the template\nvariable for dynamic resolution when using tunnelRef.",
"properties": {
"hostname": {
"description": "Hostname is the DNS hostname to create.\nMax 253: RFC 1035 section 2.3.4 FQDN presentation-format limit.",
"maxLength": 253,
"minLength": 1,
"type": "string",
"x-kubernetes-validations": [
{
"message": "each DNS label must not exceed 63 octets (RFC 1035 section 2.3.4)",
"rule": "self.split('.').all(s, size(s) <= 63)"
}
]
},
"proxied": {
"description": "Proxied enables Cloudflare proxy for this record.\nnil inherits from zone or defaults.",
"type": "boolean"
},
"target": {
"description": "Target overrides the resolved record target for this hostname.\nSupports template variable when tunnelRef is used.\nDefaults to the resource-level resolved target when omitted.\nMax 253: RFC 1035 section 2.3.4 FQDN presentation-format limit.",
"maxLength": 253,
"type": "string"
},
"ttl": {
"default": 1,
"description": "TTL is the DNS record TTL in seconds. 1 means auto (Cloudflare managed).\nValid values: 1 (auto) or 60-86400 (explicit).",
"format": "int32",
"maximum": 86400,
"minimum": 1,
"type": "integer"
}
},
"required": [
"hostname"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "TTL must be 1 (auto) or between 60 and 86400 seconds",
"rule": "!has(self.ttl) || self.ttl == 1 || (self.ttl >= 60 && self.ttl <= 86400)"
}
],
"additionalProperties": false
},
"maxItems": 100,
"type": "array"
},
"gatewayRoutes": {
"description": "GatewayRoutes configures watching Gateway API routes.",
"properties": {
"annotationFilter": {
"description": "AnnotationFilter only syncs routes with this annotation.",
"maxLength": 255,
"type": "string"
},
"enabled": {
"default": true,
"description": "Enabled enables watching Gateway API routes.",
"type": "boolean"
},
"namespaceSelector": {
"description": "NamespaceSelector limits route discovery to specific namespaces.",
"properties": {
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"description": "MatchLabels selects namespaces with matching labels.",
"maxProperties": 10,
"type": "object"
},
"matchNames": {
"description": "MatchNames selects namespaces by name.",
"items": {
"type": "string"
},
"maxItems": 50,
"type": "array"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "at least one selector must be specified",
"rule": "has(self.matchLabels) || has(self.matchNames)"
}
],
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"tunnelRef": {
"description": "TunnelRef references a CloudflareTunnel for CNAME target resolution.",
"properties": {
"name": {
"description": "Name is the name of the CloudflareTunnel.",
"maxLength": 63,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the CloudflareTunnel.\nDefaults to the CloudflareDNS's namespace.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"zones": {
"description": "Zones defines the DNS zones to manage.",
"items": {
"description": "DNSZoneConfig defines a DNS zone where records will be managed.\n\nDNSZoneConfig identifies a Cloudflare DNS zone either by name (requiring API lookup)\nor by explicit zone ID. The optional Proxied field sets the default proxy behavior\nfor all records in this zone.",
"properties": {
"id": {
"description": "ID is the optional explicit zone ID (skips API lookup).",
"maxLength": 32,
"pattern": "^[a-f0-9]{32}$",
"type": "string"
},
"name": {
"description": "Name is the zone domain name (e.g., example.com).\nMax 253: RFC 1035 section 2.3.4 FQDN presentation-format limit.",
"maxLength": 253,
"minLength": 1,
"type": "string",
"x-kubernetes-validations": [
{
"message": "each DNS label must not exceed 63 octets (RFC 1035 section 2.3.4)",
"rule": "self.split('.').all(s, size(s) <= 63)"
}
]
},
"proxied": {
"description": "Proxied sets the default proxied setting for this zone.\nnil inherits from spec.defaults.proxied.",
"type": "boolean"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 10,
"minItems": 1,
"type": "array"
}
},
"required": [
"zones"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "either tunnelRef or externalTarget must be specified",
"rule": "has(self.tunnelRef) || has(self.externalTarget)"
},
{
"message": "tunnelRef and externalTarget are mutually exclusive",
"rule": "!(has(self.tunnelRef) && has(self.externalTarget))"
},
{
"message": "cloudflare credentials required when using externalTarget",
"rule": "has(self.tunnelRef) || has(self.cloudflare)"
}
],
"additionalProperties": false
},
"status": {
"description": "CloudflareDNSStatus defines the observed state of a CloudflareDNS resource.\n\nCloudflareDNSStatus captures the synchronization state of all DNS records, including\ncounts of synced, pending, and failed records. The ResolvedTarget field shows the\nactual CNAME target being used (either from tunnel or external target).",
"properties": {
"conditions": {
"description": "Conditions represent the latest available observations.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"failedRecords": {
"description": "FailedRecords is the number of records that failed to sync.",
"format": "int32",
"type": "integer"
},
"lastSyncTime": {
"description": "LastSyncTime is the last time records were synced.",
"format": "date-time",
"type": "string"
},
"observedGeneration": {
"description": "ObservedGeneration is the generation observed by the controller.",
"format": "int64",
"type": "integer"
},
"pendingRecords": {
"description": "PendingRecords is the number of records pending sync.",
"format": "int32",
"type": "integer"
},
"records": {
"description": "Records contains the status of individual DNS records.",
"items": {
"description": "DNSRecordSyncStatus represents the synchronization status of a single DNS record.\n\nDNSRecordSyncStatus tracks individual DNS record state including the Cloudflare record ID,\ncurrent configuration, and sync status. The Status field indicates: Synced (successfully\nsynchronized), Pending (awaiting sync), or Failed (sync failed, see Error field).",
"properties": {
"error": {
"description": "Error contains the error message if status is Failed.",
"type": "string"
},
"hostname": {
"description": "Hostname is the DNS hostname.",
"type": "string"
},
"proxied": {
"description": "Proxied indicates if Cloudflare proxy is enabled.",
"type": "boolean"
},
"recordId": {
"description": "RecordID is the Cloudflare record ID.",
"type": "string"
},
"status": {
"description": "Status is the sync status: Synced, Pending, Failed.",
"type": "string"
},
"target": {
"description": "Target is the record target/content.",
"type": "string"
},
"ttl": {
"description": "TTL is the record TTL.",
"format": "int32",
"type": "integer"
},
"type": {
"description": "Type is the DNS record type (CNAME, A, AAAA).",
"type": "string"
},
"zoneId": {
"description": "ZoneID is the Cloudflare zone ID where the record was created.",
"type": "string"
}
},
"required": [
"hostname",
"proxied",
"status",
"target",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 1000,
"type": "array"
},
"resolvedTarget": {
"description": "ResolvedTarget is the resolved CNAME target (tunnel domain or external value).",
"type": "string"
},
"syncedRecords": {
"description": "SyncedRecords is the number of successfully synced records.",
"format": "int32",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
@@ -0,0 +1,483 @@
{
"description": "CloudflareTunnel is the Schema for the cloudflaretunnels API.\n\nCloudflareTunnel manages the lifecycle of a Cloudflare Tunnel and its cloudflared daemon\ndeployment. It handles tunnel creation or adoption, credential management, and deploys\ncloudflared pods that establish secure connections to Cloudflare's edge network.\n\nCloudflareTunnel follows a composable architecture where tunnel lifecycle is separate from\nDNS management. Use CloudflareDNS with a tunnelRef to create DNS records pointing to this\ntunnel's domain.\n\nStatus conditions:\n - Ready: tunnel is fully operational\n - CredentialsValid: API credentials have been validated\n - TunnelReady: tunnel exists in Cloudflare\n - ConfigurationSynced: ingress configuration is synced\n - CloudflaredDeployed: cloudflared pods are running",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "CloudflareTunnelSpec defines the desired state of a CloudflareTunnel resource.\n\nCloudflareTunnelSpec configures the tunnel identity, Cloudflare credentials, cloudflared\ndeployment settings, and origin connection defaults. The tunnel manages lifecycle only;\nDNS records are managed separately via CloudflareDNS resources.",
"properties": {
"cloudflare": {
"description": "Cloudflare defines the Cloudflare API credentials.",
"properties": {
"accountId": {
"description": "AccountID is the Cloudflare Account ID.",
"maxLength": 32,
"type": "string"
},
"accountName": {
"description": "AccountName is the Cloudflare Account name. Will be looked up via API.",
"maxLength": 255,
"type": "string"
},
"secretKeys": {
"description": "SecretKeys defines the key mappings within the secret.",
"properties": {
"apiToken": {
"default": "CLOUDFLARE_API_TOKEN",
"description": "APIToken is the key name for the Cloudflare API token.",
"maxLength": 253,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"secretRef": {
"description": "SecretRef references the Secret containing Cloudflare API credentials.\nThe secret must contain an API token (not tunnel token).",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the tunnel's namespace.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"secretRef"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "either accountId or accountName must be specified",
"rule": "has(self.accountId) || has(self.accountName)"
},
{
"message": "accountId must be a 32-character hex string",
"rule": "!has(self.accountId) || self.accountId.matches('^[a-f0-9]{32}$')"
}
],
"additionalProperties": false
},
"cloudflared": {
"description": "Cloudflared defines the cloudflared deployment configuration.",
"properties": {
"extraArgs": {
"description": "ExtraArgs are additional arguments to pass to cloudflared.",
"items": {
"type": "string"
},
"maxItems": 20,
"type": "array"
},
"image": {
"default": "ghcr.io/inherent-design/cloudflared:2026.5.0-h2c.1",
"description": "Image is the cloudflared container image.",
"maxLength": 255,
"type": "string"
},
"imagePullPolicy": {
"default": "IfNotPresent",
"description": "ImagePullPolicy is the pull policy for the cloudflared image.",
"enum": [
"Always",
"Never",
"IfNotPresent"
],
"type": "string"
},
"metrics": {
"description": "Metrics configures the cloudflared metrics endpoint.",
"properties": {
"enabled": {
"default": true,
"description": "Enabled enables the metrics endpoint.",
"type": "boolean"
},
"port": {
"default": 44483,
"description": "Port is the port for the metrics endpoint.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"nodeSelector": {
"additionalProperties": {
"type": "string"
},
"description": "NodeSelector is a selector for nodes to run cloudflared on.",
"maxProperties": 50,
"type": "object"
},
"podAnnotations": {
"additionalProperties": {
"type": "string"
},
"description": "PodAnnotations are annotations to add to cloudflared pods.",
"maxProperties": 50,
"type": "object"
},
"protocol": {
"default": "auto",
"description": "Protocol is the tunnel transport protocol: auto, quic, http2.",
"enum": [
"auto",
"quic",
"http2"
],
"type": "string"
},
"replicas": {
"default": 2,
"description": "Replicas is the number of cloudflared replicas.",
"format": "int32",
"maximum": 10,
"minimum": 1,
"type": "integer"
},
"resources": {
"description": "Resources are the resource requirements for cloudflared containers.",
"properties": {
"claims": {
"description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\nThis field depends on the\nDynamicResourceAllocation feature gate.\n\nThis field is immutable. It can only be set for containers.",
"items": {
"description": "ResourceClaim references one entry in PodSpec.ResourceClaims.",
"properties": {
"name": {
"description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.",
"type": "string"
},
"request": {
"description": "Request is the name chosen for a request in the referenced claim.\nIf empty, everything from the claim is made available, otherwise\nonly the result of this request.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
"limits": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/",
"type": "object"
},
"requests": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/",
"type": "object"
}
},
"type": "object",
"additionalProperties": false
},
"tolerations": {
"description": "Tolerations are tolerations for the cloudflared pods.",
"items": {
"description": "The pod this Toleration is attached to tolerates any taint that matches\nthe triple <key,value,effect> using the matching operator <operator>.",
"properties": {
"effect": {
"description": "Effect indicates the taint effect to match. Empty means match all taint effects.\nWhen specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.",
"type": "string"
},
"key": {
"description": "Key is the taint key that the toleration applies to. Empty means match all taint keys.\nIf the key is empty, operator must be Exists; this combination means to match all values and all keys.",
"type": "string"
},
"operator": {
"description": "Operator represents a key's relationship to the value.\nValid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.\nExists is equivalent to wildcard for value, so that a pod can\ntolerate all taints of a particular category.\nLt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).",
"type": "string"
},
"tolerationSeconds": {
"description": "TolerationSeconds represents the period of time the toleration (which must be\nof effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\nit is not set, which means tolerate the taint forever (do not evict). Zero and\nnegative values will be treated as 0 (evict immediately) by the system.",
"format": "int64",
"type": "integer"
},
"value": {
"description": "Value is the taint value the toleration matches to.\nIf the operator is Exists, the value should be empty, otherwise just a regular string.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"maxItems": 20,
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"fallbackCredentialsRef": {
"description": "FallbackCredentialsRef references a secret containing fallback Cloudflare API credentials.\nUsed during deletion when primary credentials (in Cloudflare.SecretRef) are unavailable.\nThis enables cleanup of Cloudflare resources even if the per-tunnel secret is deleted.\nThe secret must contain the same keys as the primary credentials secret.",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the resource's namespace if empty.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"fallbackTarget": {
"default": "http_status:404",
"description": "FallbackTarget is the service for unmatched requests.",
"maxLength": 255,
"type": "string"
},
"originDefaults": {
"description": "OriginDefaults defines default settings for origin connections.",
"properties": {
"caPoolSecretRef": {
"description": "CAPoolSecretRef references a Secret containing CA certificates for origin verification.",
"properties": {
"key": {
"default": "ca.crt",
"description": "Key is the key within the secret data.",
"maxLength": 253,
"type": "string"
},
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"connectTimeout": {
"default": "30s",
"description": "ConnectTimeout is the timeout for connecting to the origin.",
"pattern": "^[0-9]+(s|m|h)$",
"type": "string"
},
"h2cOrigin": {
"default": false,
"description": "H2cOrigin enables HTTP/2 cleartext (h2c) for origin connections.\nUse this for origins that speak HTTP/2 without TLS (e.g., gRPC services).\nMutually exclusive with http2Origin (TLS-based HTTP/2).",
"type": "boolean"
},
"http2Origin": {
"default": false,
"description": "HTTP2Origin enables HTTP/2 for origin connections.",
"type": "boolean"
},
"noTLSVerify": {
"default": false,
"description": "NoTLSVerify disables TLS verification for origin connections.",
"type": "boolean"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "http2Origin and h2cOrigin are mutually exclusive",
"rule": "!(self.http2Origin && self.h2cOrigin)"
}
],
"additionalProperties": false
},
"tunnel": {
"description": "Tunnel defines the tunnel identity configuration.",
"properties": {
"name": {
"description": "Name is the tunnel name in Cloudflare. If tunnel with this name exists, adopt it.\nIf not, create it. Tunnel ID is stored in status after resolution/creation.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"cloudflare",
"tunnel"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "CloudflareTunnelStatus defines the observed state of a CloudflareTunnel resource.\n\nCloudflareTunnelStatus captures the tunnel's Cloudflare-assigned identifiers, deployment\nstatus, and reconciliation state. The TunnelDomain field provides the CNAME target\n({tunnelId}.cfargotunnel.com) that CloudflareDNS uses for DNS record creation.",
"properties": {
"accountId": {
"description": "AccountID is the resolved Cloudflare account ID.",
"type": "string"
},
"conditions": {
"description": "Conditions represent the latest available observations of the tunnel's state.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"connectedRouteCount": {
"description": "ConnectedRouteCount is the number of routes connected to this tunnel.",
"format": "int32",
"type": "integer"
},
"lastSyncTime": {
"description": "LastSyncTime is the last time the configuration was synced to Cloudflare.",
"format": "date-time",
"type": "string"
},
"observedGeneration": {
"description": "ObservedGeneration is the generation observed by the controller.",
"format": "int64",
"type": "integer"
},
"readyReplicas": {
"description": "ReadyReplicas is the number of ready cloudflared replicas.",
"format": "int32",
"type": "integer"
},
"replicas": {
"description": "Replicas is the total number of cloudflared replicas.",
"format": "int32",
"type": "integer"
},
"tunnelDomain": {
"description": "TunnelDomain is the tunnel's CNAME target domain (e.g., {tunnelId}.cfargotunnel.com).",
"type": "string"
},
"tunnelId": {
"description": "TunnelID is the Cloudflare tunnel ID.",
"type": "string"
},
"tunnelName": {
"description": "TunnelName is the Cloudflare tunnel name.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
@@ -387,9 +387,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -398,18 +398,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -593,13 +597,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -622,14 +631,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -637,14 +638,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -770,57 +763,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -829,9 +771,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -1248,9 +1190,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -1259,18 +1201,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -1369,13 +1315,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -1798,9 +1749,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -1809,18 +1760,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -2060,13 +2015,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -2089,14 +2049,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -2104,14 +2056,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -2237,57 +2181,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -2296,9 +2189,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -2566,9 +2459,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -2577,18 +2470,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -2743,13 +2640,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -2775,13 +2677,13 @@
"labels": { "labels": {
"description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.", "description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.",
"items": { "items": {
"description": "Label is the Cilium's representation of a container label.", "description": "Label is Cilium's representation of a label.",
"properties": { "properties": {
"key": { "key": {
"type": "string" "type": "string"
}, },
"source": { "source": {
"description": "Source can be one of the above values (e.g.: LabelSourceContainer).", "description": "Source can be one of the above values (e.g.: LabelSourceK8s).",
"type": "string" "type": "string"
}, },
"value": { "value": {
@@ -3246,9 +3148,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -3257,18 +3159,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -3452,13 +3358,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -3481,14 +3392,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -3496,14 +3399,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -3629,57 +3524,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -3688,9 +3532,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -4107,9 +3951,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -4118,18 +3962,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -4228,13 +4076,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -4657,9 +4510,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -4668,18 +4521,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -4919,13 +4776,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -4948,14 +4810,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -4963,14 +4817,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -5096,57 +4942,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -5155,9 +4950,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -5425,9 +5220,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -5436,18 +5231,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -5602,13 +5401,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -5634,13 +5438,13 @@
"labels": { "labels": {
"description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.", "description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.",
"items": { "items": {
"description": "Label is the Cilium's representation of a container label.", "description": "Label is Cilium's representation of a label.",
"properties": { "properties": {
"key": { "key": {
"type": "string" "type": "string"
}, },
"source": { "source": {
"description": "Source can be one of the above values (e.g.: LabelSourceContainer).", "description": "Source can be one of the above values (e.g.: LabelSourceK8s).",
"type": "string" "type": "string"
}, },
"value": { "value": {
@@ -5819,5 +5623,11 @@
"required": [ "required": [
"metadata" "metadata"
], ],
"type": "object" "type": "object",
"x-kubernetes-validations": [
{
"message": "spec or specs must be provided",
"rule": "has(self.spec) || has(self.specs)"
}
]
} }
@@ -1,5 +1,5 @@
{ {
"description": "CiliumLoadBalancerIPPool is a Kubernetes third-party resource which\nis used to defined pools of IPs which the operator can use to to allocate\nand advertise IPs for Services of type LoadBalancer.", "description": "CiliumLoadBalancerIPPool is a Kubernetes third-party resource which\nis used to defined pools of IPs which the operator can use to allocate\nand advertise IPs for Services of type LoadBalancer.",
"properties": { "properties": {
"apiVersion": { "apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
@@ -1,5 +1,5 @@
{ {
"description": "CiliumLoadBalancerIPPool is a Kubernetes third-party resource which\nis used to defined pools of IPs which the operator can use to to allocate\nand advertise IPs for Services of type LoadBalancer.", "description": "CiliumLoadBalancerIPPool is a Kubernetes third-party resource which\nis used to defined pools of IPs which the operator can use to allocate\nand advertise IPs for Services of type LoadBalancer.",
"properties": { "properties": {
"apiVersion": { "apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
@@ -387,9 +387,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -398,18 +398,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -593,13 +597,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -622,14 +631,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -637,14 +638,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -770,57 +763,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -829,9 +771,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -1248,9 +1190,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -1259,18 +1201,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -1369,13 +1315,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -1798,9 +1749,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -1809,18 +1760,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -2060,13 +2015,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -2089,14 +2049,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -2104,14 +2056,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -2237,57 +2181,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -2296,9 +2189,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -2566,9 +2459,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -2577,18 +2470,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -2743,13 +2640,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -2775,13 +2677,13 @@
"labels": { "labels": {
"description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.", "description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.",
"items": { "items": {
"description": "Label is the Cilium's representation of a container label.", "description": "Label is Cilium's representation of a label.",
"properties": { "properties": {
"key": { "key": {
"type": "string" "type": "string"
}, },
"source": { "source": {
"description": "Source can be one of the above values (e.g.: LabelSourceContainer).", "description": "Source can be one of the above values (e.g.: LabelSourceK8s).",
"type": "string" "type": "string"
}, },
"value": { "value": {
@@ -3246,9 +3148,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -3257,18 +3159,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -3452,13 +3358,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -3481,14 +3392,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -3496,14 +3399,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -3629,57 +3524,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -3688,9 +3532,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -4107,9 +3951,9 @@
"type": "array" "type": "array"
}, },
"toGroups": { "toGroups": {
"description": "ToGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "ToGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nToGroups entries are functionally equivalent to toCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\ntoGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -4118,18 +3962,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -4228,13 +4076,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -4657,9 +4510,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -4668,18 +4521,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -4919,13 +4776,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -4948,14 +4810,6 @@
"http" "http"
] ]
}, },
{
"properties": {
"kafka": {}
},
"required": [
"kafka"
]
},
{ {
"properties": { "properties": {
"dns": {} "dns": {}
@@ -4963,14 +4817,6 @@
"required": [ "required": [
"dns" "dns"
] ]
},
{
"properties": {
"l7proto": {}
},
"required": [
"l7proto"
]
} }
], ],
"properties": { "properties": {
@@ -5096,57 +4942,6 @@
"additionalProperties": false "additionalProperties": false
}, },
"type": "array" "type": "array"
},
"kafka": {
"description": "Kafka-specific rules.\nDeprecated: This beta feature is deprecated and will be removed in a future release.",
"items": {
"description": "PortRule is a list of Kafka protocol constraints. All fields are\noptional, if all fields are empty or missing, the rule will match all\nKafka messages.",
"properties": {
"apiKey": {
"description": "APIKey is a case-insensitive string matched against the key of a\nrequest, e.g. \"produce\", \"fetch\", \"createtopic\", \"deletetopic\", et al\nReference: https://kafka.apache.org/protocol#protocol_api_keys\n\nIf omitted or empty, and if Role is not specified, then all keys are allowed.",
"type": "string"
},
"apiVersion": {
"description": "APIVersion is the version matched against the api version of the\nKafka message. If set, it has to be a string representing a positive\ninteger.\n\nIf omitted or empty, all versions are allowed.",
"type": "string"
},
"clientID": {
"description": "ClientID is the client identifier as provided in the request.\n\nFrom Kafka protocol documentation:\nThis is a user supplied identifier for the client application. The\nuser can use any identifier they like and it will be used when\nlogging errors, monitoring aggregates, etc. For example, one might\nwant to monitor not just the requests per second overall, but the\nnumber coming from each client application (each of which could\nreside on multiple servers). This id acts as a logical grouping\nacross all requests from a particular client.\n\nIf omitted or empty, all client identifiers are allowed.",
"type": "string"
},
"role": {
"description": "Role is a case-insensitive string and describes a group of API keys\nnecessary to perform certain higher-level Kafka operations such as \"produce\"\nor \"consume\". A Role automatically expands into all APIKeys required\nto perform the specified higher-level operation.\n\nThe following values are supported:\n - \"produce\": Allow producing to the topics specified in the rule\n - \"consume\": Allow consuming from the topics specified in the rule\n\nThis field is incompatible with the APIKey field, i.e APIKey and Role\ncannot both be specified in the same rule.\n\nIf omitted or empty, and if APIKey is not specified, then all keys are\nallowed.",
"enum": [
"produce",
"consume"
],
"type": "string"
},
"topic": {
"description": "Topic is the topic name contained in the message. If a Kafka request\ncontains multiple topics, then all topics must be allowed or the\nmessage will be rejected.\n\nThis constraint is ignored if the matched request message type\ndoesn't contain any topic. Maximum size of Topic can be 249\ncharacters as per recent Kafka spec and allowed characters are\na-z, A-Z, 0-9, -, . and _.\n\nOlder Kafka versions had longer topic lengths of 255, but in Kafka 0.10\nversion the length was changed from 255 to 249. For compatibility\nreasons we are using 255.\n\nIf omitted or empty, all topics are allowed.",
"maxLength": 255,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"l7": {
"description": "Key-value pair rules.",
"items": {
"additionalProperties": {
"type": "string"
},
"description": "PortRuleL7 is a list of key-value pairs interpreted by a L7 protocol as\nprotocol constraints. All fields are optional, if all fields are empty or\nmissing, the rule does not have any effect.",
"type": "object"
},
"type": "array"
},
"l7proto": {
"description": "Name of the L7 protocol for which the Key-value pair rules apply.",
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -5155,9 +4950,9 @@
"serverNames": { "serverNames": {
"description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.", "description": "ServerNames is a list of allowed TLS SNI values. If not empty, then\nTLS must be present and one of the provided SNIs must be indicated in the\nTLS handshake.",
"items": { "items": {
"description": "ServerName allows using prefix only wildcards to match DNS names.\n\n- \"*\" matches 0 or more DNS valid characters, and may only occur at the\nbeginning of the pattern. As a special case a \"*\" as the leftmost character,\nwithout a following \".\" matches all subdomains as well as the name to the right.\n\nExamples:\n - `*.cilium.io` matches exactly one subdomain of cilium at that level www.cilium.io and blog.cilium.io match, cilium.io and google.com do not.\n - `**.cilium.io` matches more than one subdomain of cilium, e.g. sub1.sub2.cilium.io and sub.cilium.io match, cilium.io do not.", "description": "ServerName allows using '*' wildcard specifier for matching server names with\nthe below semantics.\n\n- `*` matches 0 or more DNS valid characters, and may occur anywhere in the pattern.\n- `**.` is a special prefix which matches all multilevel subdomains in the prefix.\n\nAs a special case the name \"*\" matches all valid DNS names.\n\nExamples:\n 1. `*.cilium.io` matches subdomains of cilium at that level\n www.cilium.io and blog.cilium.io match, cilium.io and google.com do not\n 2. `*cilium.io` matches cilium.io and all subdomains ends with \"cilium.io\"\n except those containing \".\" separator, subcilium.io and sub-cilium.io match,\n www.cilium.io and blog.cilium.io does not\n 3. `sub*.cilium.io` matches subdomains of cilium where the subdomain component\n begins with \"sub\". sub.cilium.io and subdomain.cilium.io match while www.cilium.io,\n blog.cilium.io, cilium.io and google.com do not\n 4. `**.cilium.io` matches all multilevel subdomains of cilium.io.\n \"app.cilium.io\" and \"test.app.cilium.io\" match but not \"cilium.io\"",
"maxLength": 255, "maxLength": 255,
"pattern": "^(\\*?\\*\\.)?([-a-zA-Z0-9_]+\\.?)+$", "pattern": "^([-a-zA-Z0-9_*]+[.]?)+$",
"type": "string" "type": "string"
}, },
"minItems": 1, "minItems": 1,
@@ -5425,9 +5220,9 @@
"type": "array" "type": "array"
}, },
"fromGroups": { "fromGroups": {
"description": "FromGroups is a directive that allows the integration with multiple outside\nproviders. Currently, only AWS is supported, and the rule can select by\nmultiple sub directives:\n\nExample:\nFromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'", "description": "FromGroups allows policies to reference CIDRs provided by external integrations.\nCurrently, only AWS is supported, and the rule can select by multiple sub directives.\nFromGroups entries are functionally equivalent to FromCIDR, and have the same\nlimitiations. They cannot select traffic originating from within the cluster.\n\nExample:\nfromGroups:\n- aws:\n securityGroupsIds:\n - 'sg-XXXXXXXXXXXXX'",
"items": { "items": {
"description": "Groups structure to store all kinds of new integrations that needs a new\nderivative policy.", "description": "Groups allows referencing CIDRs that are resolved from an external integration.",
"properties": { "properties": {
"aws": { "aws": {
"description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration", "description": "AWSGroup is an structure that can be used to whitelisting information from AWS integration",
@@ -5436,18 +5231,22 @@
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
}, },
"description": "Labels selects AWS ENIs by labels.\nMultiple labels are AND-ed together.",
"type": "object" "type": "object"
}, },
"region": { "region": {
"description": "Deprecated: Region is unused.",
"type": "string" "type": "string"
}, },
"securityGroupsIds": { "securityGroupsIds": {
"description": "SecurityGroupsIds selects VPC SecurityGroups by IDs.\nIf multiple IDs are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any Names specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
}, },
"securityGroupsNames": { "securityGroupsNames": {
"description": "SecurityGroupsNames selects VPC SecurityGroups by name.\nIf multiple names are specified, they are OR-ed together.\n\nNote that this may be AND-ed with any IDs specified. Specifying both\nIDs and Names is not recommended.",
"items": { "items": {
"type": "string" "type": "string"
}, },
@@ -5602,13 +5401,18 @@
"type": "string" "type": "string"
}, },
"protocol": { "protocol": {
"description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"ANY\"\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.", "description": "Protocol is the L4 protocol. If \"ANY\", omitted or empty, any protocols\nwith transport ports (TCP, UDP, SCTP) match.\n\nAccepted values: \"TCP\", \"UDP\", \"SCTP\", \"VRRP\", \"IGMP\", \"GRE\", \"IPIP\",\n\"IPV6\", \"ESP\", \"AH\", \"ANY\"\n\nTunnel/encapsulation protocols (GRE, IPIP, IPV6, ESP, AH) and other\nextended IP protocols (VRRP, IGMP) require the --enable-extended-ip-protocols\nflag to be set. These protocols do not use transport-layer ports.\n\nMatching on ICMP is not supported.\n\nNamed port specified for a container may narrow this down, but may not\ncontradict this.",
"enum": [ "enum": [
"TCP", "TCP",
"UDP", "UDP",
"SCTP", "SCTP",
"VRRP", "VRRP",
"IGMP", "IGMP",
"GRE",
"IPIP",
"IPV6",
"ESP",
"AH",
"ANY" "ANY"
], ],
"type": "string" "type": "string"
@@ -5634,13 +5438,13 @@
"labels": { "labels": {
"description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.", "description": "Labels is a list of optional strings which can be used to\nre-identify the rule or to store metadata. It is possible to lookup\nor delete strings based on labels. Labels are not required to be\nunique, multiple rules can have overlapping or identical labels.",
"items": { "items": {
"description": "Label is the Cilium's representation of a container label.", "description": "Label is Cilium's representation of a label.",
"properties": { "properties": {
"key": { "key": {
"type": "string" "type": "string"
}, },
"source": { "source": {
"description": "Source can be one of the above values (e.g.: LabelSourceContainer).", "description": "Source can be one of the above values (e.g.: LabelSourceK8s).",
"type": "string" "type": "string"
}, },
"value": { "value": {
@@ -5819,5 +5623,11 @@
"required": [ "required": [
"metadata" "metadata"
], ],
"type": "object" "type": "object",
"x-kubernetes-validations": [
{
"message": "spec or specs must be provided",
"rule": "has(self.spec) || has(self.specs)"
}
]
} }
@@ -43,6 +43,7 @@
}, },
"cidr-block": { "cidr-block": {
"description": "CIDRBlock is vpc ipv4 CIDR", "description": "CIDRBlock is vpc ipv4 CIDR",
"format": "cidr",
"type": "string" "type": "string"
}, },
"instance-type": { "instance-type": {
@@ -138,33 +139,14 @@
"minimum": 0, "minimum": 0,
"type": "integer" "type": "integer"
}, },
"instance-id": {
"description": "InstanceID is the AWS InstanceId of the node. The InstanceID is used\nto retrieve AWS metadata for the node.\n\nOBSOLETE: This field is obsolete, please use Spec.InstanceID",
"type": "string"
},
"instance-type": { "instance-type": {
"description": "InstanceType is the AWS EC2 instance type, e.g. \"m5.large\"", "description": "InstanceType is the AWS EC2 instance type, e.g. \"m5.large\"",
"type": "string" "type": "string"
}, },
"max-above-watermark": {
"description": "MaxAboveWatermark is the maximum number of addresses to allocate\nbeyond the addresses needed to reach the PreAllocate watermark.\nGoing above the watermark can help reduce the number of API calls to\nallocate IPs, e.g. when a new ENI is allocated, as many secondary\nIPs as possible are allocated. Limiting the amount can help reduce\nwaste of IPs.\n\nOBSOLETE: This field is obsolete, please use Spec.IPAM.MaxAboveWatermark",
"minimum": 0,
"type": "integer"
},
"min-allocate": {
"description": "MinAllocate is the minimum number of IPs that must be allocated when\nthe node is first bootstrapped. It defines the minimum base socket\nof addresses that must be available. After reaching this watermark,\nthe PreAllocate and MaxAboveWatermark logic takes over to continue\nallocating IPs.\n\nOBSOLETE: This field is obsolete, please use Spec.IPAM.MinAllocate",
"minimum": 0,
"type": "integer"
},
"node-subnet-id": { "node-subnet-id": {
"description": "NodeSubnetID is the subnet of the primary ENI the instance was brought up\nwith. It is used as a sensible default subnet to create ENIs in.", "description": "NodeSubnetID is the subnet of the primary ENI the instance was brought up\nwith. It is used as a sensible default subnet to create ENIs in.",
"type": "string" "type": "string"
}, },
"pre-allocate": {
"description": "PreAllocate defines the number of IP addresses that must be\navailable for allocation in the IPAMspec. It defines the buffer of\naddresses available immediately without requiring cilium-operator to\nget involved.\n\nOBSOLETE: This field is obsolete, please use Spec.IPAM.PreAllocate",
"minimum": 0,
"type": "integer"
},
"security-group-tags": { "security-group-tags": {
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
@@ -277,6 +259,7 @@
"podCIDRs": { "podCIDRs": {
"description": "PodCIDRs is the list of CIDRs available to the node for allocation.\nWhen an IP is used, the IP will be added to Status.IPAM.Used", "description": "PodCIDRs is the list of CIDRs available to the node for allocation.\nWhen an IP is used, the IP will be added to Status.IPAM.Used",
"items": { "items": {
"format": "cidr",
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
@@ -308,10 +291,17 @@
"items": { "items": {
"description": "IPAMPoolAllocation describes an allocation of an IPAM pool from the operator to the\nnode. It contains the assigned PodCIDRs allocated from this pool", "description": "IPAMPoolAllocation describes an allocation of an IPAM pool from the operator to the\nnode. It contains the assigned PodCIDRs allocated from this pool",
"properties": { "properties": {
"allowFirstIP": {
"description": "AllowFirstIP allows the first IP of each allocated CIDR to be used.",
"type": "boolean"
},
"allowLastIP": {
"description": "AllowLastIP allows the last IP of each allocated CIDR to be used.",
"type": "boolean"
},
"cidrs": { "cidrs": {
"description": "CIDRs contains a list of pod CIDRs currently allocated from this pool", "description": "CIDRs contains a list of pod CIDRs currently allocated from this pool",
"items": { "items": {
"description": "IPAMPodCIDR is a pod CIDR",
"format": "cidr", "format": "cidr",
"type": "string" "type": "string"
}, },
@@ -369,7 +359,7 @@
"additionalProperties": false "additionalProperties": false
}, },
"pre-allocate": { "pre-allocate": {
"description": "PreAllocate defines the number of IP addresses that must be\navailable for allocation in the IPAMspec. It defines the buffer of\naddresses available immediately without requiring cilium-operator to\nget involved.", "description": "PreAllocate defines the number of IP addresses that must be\navailable for allocation in the IPAMSpec. It defines the buffer of\naddresses available immediately without requiring cilium-operator to\nget involved.",
"minimum": 0, "minimum": 0,
"type": "integer" "type": "integer"
}, },
@@ -383,11 +373,6 @@
}, },
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
},
"nodeidentity": {
"description": "NodeIdentity is the Cilium numeric identity allocated for the node, if any.",
"format": "int64",
"type": "integer"
} }
}, },
"type": "object", "type": "object",
@@ -459,15 +444,18 @@
"properties": { "properties": {
"cidr": { "cidr": {
"description": "CIDRBlock is the VPC IPv4 CIDR", "description": "CIDRBlock is the VPC IPv4 CIDR",
"format": "cidr",
"type": "string" "type": "string"
}, },
"ipv6-cidr": { "ipv6-cidr": {
"description": "IPv6CIDRBlock is the VPC IPv6 CIDR", "description": "IPv6CIDRBlock is the VPC IPv6 CIDR",
"format": "cidr",
"type": "string" "type": "string"
}, },
"secondary-cidrs": { "secondary-cidrs": {
"description": "SecondaryCIDRs is the list of Secondary CIDRs associated with the VPC", "description": "SecondaryCIDRs is the list of Secondary CIDRs associated with the VPC",
"items": { "items": {
"format": "cidr",
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
@@ -485,10 +473,12 @@
"properties": { "properties": {
"cidr": { "cidr": {
"description": "CIDRBlock is the vSwitch IPv4 CIDR", "description": "CIDRBlock is the vSwitch IPv4 CIDR",
"format": "cidr",
"type": "string" "type": "string"
}, },
"ipv6-cidr": { "ipv6-cidr": {
"description": "IPv6CIDRBlock is the vSwitch IPv6 CIDR", "description": "IPv6CIDRBlock is the vSwitch IPv6 CIDR",
"format": "cidr",
"type": "string" "type": "string"
}, },
"vswitch-id": { "vswitch-id": {
@@ -522,12 +512,8 @@
"items": { "items": {
"description": "AzureInterface represents an Azure Interface", "description": "AzureInterface represents an Azure Interface",
"properties": { "properties": {
"GatewayIP": {
"description": "GatewayIP is the interface's subnet's default route\n\nOBSOLETE: This field is obsolete, please use Gateway field instead.",
"type": "string"
},
"addresses": { "addresses": {
"description": "Addresses is the list of all IPs associated with the interface,\nincluding all secondary addresses", "description": "Addresses is the list of secondary IPs associated with the interface.\nThe primary IP is tracked separately in the IP field, but is also\nincluded here when the operator is configured to expose it for\nallocation.",
"items": { "items": {
"description": "AzureAddress is an IP address assigned to an AzureInterface", "description": "AzureAddress is an IP address assigned to an AzureInterface",
"properties": { "properties": {
@@ -540,7 +526,7 @@
"type": "string" "type": "string"
}, },
"subnet": { "subnet": {
"description": "Subnet is the subnet the address belongs to", "description": "Subnet is the subnet the address belongs to.\n\nDeprecated: use AzureInterface.Subnet.ID. Populated as a mirror for one\nrelease so external consumers of CiliumNode.Status.Azure can migrate.",
"type": "string" "type": "string"
} }
}, },
@@ -550,7 +536,8 @@
"type": "array" "type": "array"
}, },
"cidr": { "cidr": {
"description": "CIDR is the range that the interface belongs to.", "description": "CIDR is the range that the interface belongs to.\n\nDeprecated: use Subnet.CIDR. Retained for one release so agent/operator\nrolling upgrades work in either order.",
"format": "cidr",
"type": "string" "type": "string"
}, },
"gateway": { "gateway": {
@@ -561,6 +548,10 @@
"description": "ID is the identifier", "description": "ID is the identifier",
"type": "string" "type": "string"
}, },
"ip": {
"description": "IP is the primary IP of the interface",
"type": "string"
},
"mac": { "mac": {
"description": "MAC is the mac address", "description": "MAC is the mac address",
"type": "string" "type": "string"
@@ -576,6 +567,22 @@
"state": { "state": {
"description": "State is the provisioning state", "description": "State is the provisioning state",
"type": "string" "type": "string"
},
"subnet": {
"description": "Subnet is the subnet the interface is attached to.",
"properties": {
"cidr": {
"description": "CIDR is the CIDR range associated with the subnet",
"format": "cidr",
"type": "string"
},
"id": {
"description": "ID is the resource ID of the subnet",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
} }
}, },
"type": "object", "type": "object",
@@ -617,6 +624,14 @@
"description": "IP is the primary IP of the ENI", "description": "IP is the primary IP of the ENI",
"type": "string" "type": "string"
}, },
"ipv6-prefixes": {
"description": "IPv6Prefixes is the list of all IPv6 /80 delegated prefixes associated with the ENI",
"items": {
"format": "cidr",
"type": "string"
},
"type": "array"
},
"mac": { "mac": {
"description": "MAC is the mac address of the ENI", "description": "MAC is the mac address of the ENI",
"type": "string" "type": "string"
@@ -626,8 +641,9 @@
"type": "integer" "type": "integer"
}, },
"prefixes": { "prefixes": {
"description": "Prefixes is the list of all /28 prefixes associated with the ENI", "description": "Prefixes is the list of all IPv4 /28 delegated prefixes associated with the ENI",
"items": { "items": {
"format": "cidr",
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
@@ -648,6 +664,7 @@
"properties": { "properties": {
"cidr": { "cidr": {
"description": "CIDR is the CIDR range associated with the subnet", "description": "CIDR is the CIDR range associated with the subnet",
"format": "cidr",
"type": "string" "type": "string"
}, },
"id": { "id": {
@@ -671,6 +688,7 @@
"cidrs": { "cidrs": {
"description": "CIDRs is the list of CIDR ranges associated with the VPC", "description": "CIDRs is the list of CIDR ranges associated with the VPC",
"items": { "items": {
"format": "cidr",
"type": "string" "type": "string"
}, },
"type": "array" "type": "array"
@@ -681,6 +699,7 @@
}, },
"primary-cidr": { "primary-cidr": {
"description": "PrimaryCIDR is the primary CIDR of the VPC", "description": "PrimaryCIDR is the primary CIDR of the VPC",
"format": "cidr",
"type": "string" "type": "string"
} }
}, },
@@ -0,0 +1,330 @@
{
"description": "CiliumPodIPPool defines an IP pool that can be used for pooled IPAM (i.e. the multi-pool IPAM\nmode).",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"allowFirstIP": {
"default": false,
"description": "AllowFirstIP allows the first IP of each allocated CIDR to be used. If\nunset or false, this IP is reserved. This field is ignored for /{31,32}\nand /{127,128} CIDRs since reserving the first and last IPs would make\nthe CIDRs unusable. This field is immutable.",
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "allowFirstIP is immutable",
"rule": "self == oldSelf"
}
]
},
"allowLastIP": {
"default": false,
"description": "AllowLastIP allows the last IP of each allocated CIDR to be used. If\nunset or false, this IP is reserved. This field is ignored for /{31,32}\nand /{127,128} CIDRs since reserving the first and last IPs would make\nthe CIDRs unusable. This field is immutable.",
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "allowLastIP is immutable",
"rule": "self == oldSelf"
}
]
},
"ipv4": {
"description": "IPv4 specifies the IPv4 CIDRs and mask sizes of the pool",
"properties": {
"cidrs": {
"description": "CIDRs is a list of IPv4 CIDRs that are part of the pool.",
"items": {
"description": "PoolCIDR is an IP pool CIDR.",
"format": "cidr",
"type": "string"
},
"maxItems": 32,
"minItems": 1,
"type": "array"
},
"maskSize": {
"description": "MaskSize is the mask size of the pool.",
"maximum": 32,
"minimum": 1,
"type": "integer",
"x-kubernetes-validations": [
{
"message": "maskSize is immutable",
"rule": "self == oldSelf"
}
]
},
"pool": {
"description": "Pool contains per-CIDR configuration for a subset of CIDRs listed in CIDRs.\nEach entry must reference a CIDR in CIDRs.",
"items": {
"properties": {
"cidr": {
"description": "CIDR references one of the CIDRs listed in the parent pool spec.",
"format": "cidr",
"type": "string"
},
"reservedRanges": {
"description": "ReservedRanges is a list of IP ranges within CIDR that must not be allocated.",
"items": {
"properties": {
"end": {
"description": "The last IP in the reserved range.",
"type": "string"
},
"start": {
"description": "The first IP in the reserved range.",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
}
},
"required": [
"cidr"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-map-keys": [
"cidr"
],
"x-kubernetes-list-type": "map"
}
},
"required": [
"cidrs",
"maskSize"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "If pool is set, each pool entry must reference a CIDR from cidrs",
"rule": "!has(self.pool) || self.pool.all(p, p.cidr in self.cidrs)"
}
],
"additionalProperties": false
},
"ipv6": {
"description": "IPv6 specifies the IPv6 CIDRs and mask sizes of the pool",
"properties": {
"cidrs": {
"description": "CIDRs is a list of IPv6 CIDRs that are part of the pool.",
"items": {
"description": "PoolCIDR is an IP pool CIDR.",
"format": "cidr",
"type": "string"
},
"maxItems": 32,
"minItems": 1,
"type": "array"
},
"maskSize": {
"description": "MaskSize is the mask size of the pool.",
"maximum": 128,
"minimum": 1,
"type": "integer",
"x-kubernetes-validations": [
{
"message": "maskSize is immutable",
"rule": "self == oldSelf"
}
]
},
"pool": {
"description": "Pool contains per-CIDR configuration for a subset of CIDRs listed in CIDRs.\nEach entry must reference a CIDR in CIDRs.",
"items": {
"properties": {
"cidr": {
"description": "CIDR references one of the CIDRs listed in the parent pool spec.",
"format": "cidr",
"type": "string"
},
"reservedRanges": {
"description": "ReservedRanges is a list of IP ranges within CIDR that must not be allocated.",
"items": {
"properties": {
"end": {
"description": "The last IP in the reserved range.",
"type": "string"
},
"start": {
"description": "The first IP in the reserved range.",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
}
},
"required": [
"cidr"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-map-keys": [
"cidr"
],
"x-kubernetes-list-type": "map"
}
},
"required": [
"cidrs",
"maskSize"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "If pool is set, each pool entry must reference a CIDR from cidrs",
"rule": "!has(self.pool) || self.pool.all(p, p.cidr in self.cidrs)"
}
],
"additionalProperties": false
},
"namespaceSelector": {
"description": "NamespaceSelector selects the set of Namespaces that are eligible to use\nthis pool. If both PodSelector and NamespaceSelector are specified, a Pod\nmust match both selectors to be eligible for IP allocation from this pool.\n\nIf NamespaceSelector is empty, the pool can be used by Pods in any namespace\n(subject to PodSelector constraints).",
"properties": {
"matchExpressions": {
"description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
"items": {
"description": "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.",
"enum": [
"In",
"NotIn",
"Exists",
"DoesNotExist"
],
"type": "string"
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.",
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"description": "MatchLabelsValue represents the value from the MatchLabels {key,value} pair.",
"maxLength": 63,
"pattern": "^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$",
"type": "string"
},
"description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"additionalProperties": false
},
"podSelector": {
"description": "PodSelector selects the set of Pods that are eligible to receive IPs from\nthis pool when neither the Pod nor its Namespace specify an explicit\n`ipam.cilium.io/*` annotation.\n\nThe selector can match on regular Pod labels and on the following synthetic\nlabels that Cilium adds for convenience:\n\nio.kubernetes.pod.namespace \u2013 the Pod's namespace\nio.kubernetes.pod.name \u2013 the Pod's name\n\nA single Pod must not match more than one pool for the same IP family.\nIf multiple pools match, IP allocation fails for that Pod and a warning event\nis emitted in the namespace of the Pod.",
"properties": {
"matchExpressions": {
"description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
"items": {
"description": "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.",
"enum": [
"In",
"NotIn",
"Exists",
"DoesNotExist"
],
"type": "string"
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.",
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"description": "MatchLabelsValue represents the value from the MatchLabels {key,value} pair.",
"maxLength": 63,
"pattern": "^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$",
"type": "string"
},
"description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -14,6 +14,28 @@
}, },
"spec": { "spec": {
"properties": { "properties": {
"allowFirstIP": {
"default": false,
"description": "AllowFirstIP allows the first IP of each allocated CIDR to be used. If\nunset or false, this IP is reserved. This field is ignored for /{31,32}\nand /{127,128} CIDRs since reserving the first and last IPs would make\nthe CIDRs unusable. This field is immutable.",
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "allowFirstIP is immutable",
"rule": "self == oldSelf"
}
]
},
"allowLastIP": {
"default": false,
"description": "AllowLastIP allows the last IP of each allocated CIDR to be used. If\nunset or false, this IP is reserved. This field is ignored for /{31,32}\nand /{127,128} CIDRs since reserving the first and last IPs would make\nthe CIDRs unusable. This field is immutable.",
"type": "boolean",
"x-kubernetes-validations": [
{
"message": "allowLastIP is immutable",
"rule": "self == oldSelf"
}
]
},
"ipv4": { "ipv4": {
"description": "IPv4 specifies the IPv4 CIDRs and mask sizes of the pool", "description": "IPv4 specifies the IPv4 CIDRs and mask sizes of the pool",
"properties": { "properties": {
@@ -31,7 +53,13 @@
"description": "MaskSize is the mask size of the pool.", "description": "MaskSize is the mask size of the pool.",
"maximum": 32, "maximum": 32,
"minimum": 1, "minimum": 1,
"type": "integer" "type": "integer",
"x-kubernetes-validations": [
{
"message": "maskSize is immutable",
"rule": "self == oldSelf"
}
]
} }
}, },
"required": [ "required": [
@@ -58,7 +86,13 @@
"description": "MaskSize is the mask size of the pool.", "description": "MaskSize is the mask size of the pool.",
"maximum": 128, "maximum": 128,
"minimum": 1, "minimum": 1,
"type": "integer" "type": "integer",
"x-kubernetes-validations": [
{
"message": "maskSize is immutable",
"rule": "self == oldSelf"
}
]
} }
}, },
"required": [ "required": [
@@ -247,7 +247,7 @@
"type": "array" "type": "array"
}, },
"storage": { "storage": {
"description": "Storage defines if the source-controller shards\nshould use an emptyDir or a persistent volume claim for storage.\nAccepted values are 'ephemeral' or 'persistent', defaults to 'ephemeral'.\nFor 'persistent' to take effect, the '.spec.storage' field must be set.", "description": "Storage defines if the source-controller shards\nshould use an emptyDir or a persistent volume claim for storage.\nAccepted values are 'ephemeral' or 'persistent', defaults to 'ephemeral'.\nWhen set to 'persistent', the '.spec.storage' field must be set.",
"enum": [ "enum": [
"ephemeral", "ephemeral",
"persistent" "persistent"
@@ -314,7 +314,7 @@
"type": "string" "type": "string"
}, },
"provider": { "provider": {
"description": "Provider specifies OIDC provider for source authentication.\nFor OCIRepository and Bucket the provider can be set to 'aws', 'azure' or 'gcp'.\nfor GitRepository the accepted value can be set to 'azure' or 'github'.\nTo disable OIDC authentication the provider can be set to 'generic' or left empty.", "description": "Provider specifies OIDC provider for source authentication.\nFor OCIRepository and Bucket the provider can be set to 'aws', 'azure' or 'gcp'.\nFor GitRepository the provider can be set to 'aws' (requires Flux 2.9 or later),\n'azure' or 'github'.\nTo disable OIDC authentication the provider can be set to 'generic' or left empty.",
"enum": [ "enum": [
"generic", "generic",
"aws", "aws",
@@ -344,6 +344,16 @@
"url" "url"
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [
{
"message": "sync.provider 'gcp' is only supported for OCIRepository and Bucket",
"rule": "!has(self.provider) || self.provider != 'gcp' || self.kind == 'OCIRepository' || self.kind == 'Bucket'"
},
{
"message": "sync.provider 'github' is only supported for GitRepository",
"rule": "!has(self.provider) || self.provider != 'github' || self.kind == 'GitRepository'"
}
],
"additionalProperties": false "additionalProperties": false
}, },
"wait": { "wait": {
@@ -356,6 +366,12 @@
"distribution" "distribution"
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [
{
"message": ".spec.storage must be set when .spec.sharding.storage is 'persistent'",
"rule": "!has(self.sharding) || !has(self.sharding.storage) || self.sharding.storage != 'persistent' || has(self.storage)"
}
],
"additionalProperties": false "additionalProperties": false
}, },
"status": { "status": {
@@ -204,6 +204,7 @@
"resources": { "resources": {
"description": "Resources contains the list of Kubernetes resources to reconcile.", "description": "Resources contains the list of Kubernetes resources to reconcile.",
"items": { "items": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true "x-kubernetes-preserve-unknown-fields": true
}, },
"type": "array" "type": "array"
@@ -216,12 +217,73 @@
"description": "The name of the Kubernetes service account to impersonate\nwhen reconciling the generated resources.", "description": "The name of the Kubernetes service account to impersonate\nwhen reconciling the generated resources.",
"type": "string" "type": "string"
}, },
"steps": {
"description": "Steps contains an ordered list of named steps to reconcile in sequence.\nEach step's resources are applied and health-checked before the next\nstep starts. Mutually exclusive with Resources and ResourcesTemplate.",
"items": {
"description": "ResourceSetStep defines a named step in the ResourceSet reconciliation\nsequence. The step's resources are applied and health-checked before\nthe next step starts.",
"properties": {
"name": {
"description": "Name of the step, must be unique within the ResourceSet.",
"maxLength": 63,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"resources": {
"description": "Resources contains the list of Kubernetes resources to reconcile.",
"items": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"type": "array"
},
"resourcesTemplate": {
"description": "ResourcesTemplate is a Go template that generates the list of\nKubernetes resources to reconcile. The template is rendered\nas multi-document YAML, the resources should be separated by '---'.\nWhen both Resources and ResourcesTemplate are set, the resulting\nobjects are merged and deduplicated, with the ones from Resources taking precedence.",
"type": "string"
},
"timeout": {
"description": "Timeout is the maximum time to wait for the step's resources to\nbecome ready. When not set, the ResourceSet reconciliation\ntimeout is used.",
"pattern": "^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "at least one of resources or resourcesTemplate must be set",
"rule": "has(self.resources) || has(self.resourcesTemplate)"
}
],
"additionalProperties": false
},
"maxItems": 20,
"minItems": 1,
"type": "array",
"x-kubernetes-validations": [
{
"message": "step names must be unique",
"rule": "self.all(s, self.exists_one(t, t.name == s.name))"
}
]
},
"wait": { "wait": {
"description": "Wait instructs the controller to check the health\nof all the reconciled resources.", "description": "Wait instructs the controller to check the health\nof all the reconciled resources.",
"type": "boolean" "type": "boolean"
} }
}, },
"type": "object", "type": "object",
"x-kubernetes-validations": [
{
"message": "steps is mutually exclusive with resources and resourcesTemplate",
"rule": "!has(self.steps) || (!has(self.resources) && !has(self.resourcesTemplate))"
},
{
"message": "at least one of steps, resources or resourcesTemplate must be set",
"rule": "has(self.steps) || has(self.resources) || has(self.resourcesTemplate)"
}
],
"additionalProperties": false "additionalProperties": false
}, },
"status": { "status": {
@@ -162,6 +162,9 @@
"AzureDevOpsBranch", "AzureDevOpsBranch",
"AzureDevOpsTag", "AzureDevOpsTag",
"AzureDevOpsPullRequest", "AzureDevOpsPullRequest",
"AWSCodeCommitBranch",
"AWSCodeCommitTag",
"AWSCodeCommitPullRequest",
"GiteaBranch", "GiteaBranch",
"GiteaTag", "GiteaTag",
"GiteaPullRequest", "GiteaPullRequest",
@@ -197,8 +200,12 @@
"rule": "!self.type.startsWith('Git') || self.url.startsWith('http')" "rule": "!self.type.startsWith('Git') || self.url.startsWith('http')"
}, },
{ {
"message": "spec.url must start with 'http://' or 'https://' when spec.type is a Git provider", "message": "spec.url must start with 'http://' or 'https://' when spec.type is an AzureDevOps provider",
"rule": "!self.type.startsWith('AzureDevOps') || self.url.startsWith('http')" "rule": "!self.type.startsWith('AzureDevOps') || self.url.startsWith('http://') || self.url.startsWith('https://')"
},
{
"message": "spec.url must start with 'https://' when spec.type is a AWSCodeCommit provider",
"rule": "!self.type.startsWith('AWSCodeCommit') || self.url.startsWith('https://')"
}, },
{ {
"message": "spec.url must start with 'oci://' when spec.type is an OCI provider", "message": "spec.url must start with 'oci://' when spec.type is an OCI provider",
@@ -217,16 +224,16 @@
"rule": "self.type != 'ExternalService' || !self.url.startsWith('http://') || (has(self.insecure) && self.insecure)" "rule": "self.type != 'ExternalService' || !self.url.startsWith('http://') || (has(self.insecure) && self.insecure)"
}, },
{ {
"message": "cannot specify spec.serviceAccountName when spec.type is not one of AzureDevOps* or *ArtifactTag", "message": "cannot specify spec.serviceAccountName when spec.type is not one of AzureDevOps*, AWSCodeCommit* or *ArtifactTag",
"rule": "!has(self.serviceAccountName) || self.type.startsWith('AzureDevOps') || self.type.endsWith('ArtifactTag')" "rule": "!has(self.serviceAccountName) || self.type.startsWith('AzureDevOps') || self.type.startsWith('AWSCodeCommit') || self.type.endsWith('ArtifactTag')"
}, },
{ {
"message": "cannot specify spec.certSecretRef when spec.type is one of Static, AzureDevOps*, ACRArtifactTag, ECRArtifactTag or GARArtifactTag", "message": "cannot specify spec.certSecretRef when spec.type is one of Static, AzureDevOps*, AWSCodeCommit*, ACRArtifactTag, ECRArtifactTag or GARArtifactTag",
"rule": "!has(self.certSecretRef) || !(self.url == 'Static' || self.type.startsWith('AzureDevOps') || (self.type.endsWith('ArtifactTag') && self.type != 'OCIArtifactTag'))" "rule": "!has(self.certSecretRef) || !(self.type == 'Static' || self.type.startsWith('AzureDevOps') || self.type.startsWith('AWSCodeCommit') || (self.type.endsWith('ArtifactTag') && self.type != 'OCIArtifactTag'))"
}, },
{ {
"message": "cannot specify spec.secretRef when spec.type is one of Static, ACRArtifactTag, ECRArtifactTag or GARArtifactTag", "message": "cannot specify spec.secretRef when spec.type is one of Static, AWSCodeCommit*, ACRArtifactTag, ECRArtifactTag or GARArtifactTag",
"rule": "!has(self.secretRef) || !(self.url == 'Static' || (self.type.endsWith('ArtifactTag') && self.type != 'OCIArtifactTag'))" "rule": "!has(self.secretRef) || !(self.type == 'Static' || self.type.startsWith('AWSCodeCommit') || (self.type.endsWith('ArtifactTag') && self.type != 'OCIArtifactTag'))"
} }
], ],
"additionalProperties": false "additionalProperties": false
@@ -0,0 +1,418 @@
{
"description": "Backend allows the user to configure the endpoints of a backend and\nthe behavior of the connection from Envoy Proxy to the backend.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of Backend.",
"properties": {
"appProtocols": {
"description": "AppProtocols defines the application protocols to be supported when connecting to the backend.",
"items": {
"description": "AppProtocolType defines various backend applications protocols supported by Envoy Gateway",
"enum": [
"gateway.envoyproxy.io/h2c",
"gateway.envoyproxy.io/ws",
"gateway.envoyproxy.io/wss"
],
"type": "string"
},
"type": "array"
},
"endpoints": {
"description": "Endpoints defines the endpoints to be used when connecting to the backend.",
"items": {
"description": "BackendEndpoint describes a backend endpoint, which can be either a fully-qualified domain name, IP address or unix domain socket\ncorresponding to Envoy's Address: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address",
"properties": {
"fqdn": {
"description": "FQDN defines a FQDN endpoint",
"properties": {
"hostname": {
"description": "Hostname defines the FQDN hostname of the backend endpoint.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"port": {
"description": "Port defines the port of the backend endpoint.",
"format": "int32",
"maximum": 65535,
"minimum": 0,
"type": "integer"
}
},
"required": [
"hostname",
"port"
],
"type": "object",
"additionalProperties": false
},
"hostname": {
"description": "Hostname defines an optional hostname for the backend endpoint.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"ip": {
"description": "IP defines an IP endpoint. Supports both IPv4 and IPv6 addresses.",
"properties": {
"address": {
"description": "Address defines the IP address of the backend endpoint.\nSupports both IPv4 and IPv6 addresses.",
"maxLength": 45,
"minLength": 3,
"pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([0-9a-fA-F]{1,4}:){1,7}[0-9a-fA-F]{1,4}|::|(([0-9a-fA-F]{1,4}:){0,5})?(:[0-9a-fA-F]{1,4}){1,2})$",
"type": "string"
},
"port": {
"description": "Port defines the port of the backend endpoint.",
"format": "int32",
"maximum": 65535,
"minimum": 0,
"type": "integer"
}
},
"required": [
"address",
"port"
],
"type": "object",
"additionalProperties": false
},
"unix": {
"description": "Unix defines the unix domain socket endpoint",
"properties": {
"path": {
"description": "Path defines the unix domain socket path of the backend endpoint.\nThe path length must not exceed 108 characters.",
"type": "string",
"x-kubernetes-validations": [
{
"message": "unix domain socket path must not exceed 108 characters",
"rule": "size(self) <= 108"
}
]
}
},
"required": [
"path"
],
"type": "object",
"additionalProperties": false
},
"zone": {
"description": "Zone defines the service zone of the backend endpoint.",
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "one of fqdn, ip or unix must be specified",
"rule": "(has(self.fqdn) || has(self.ip) || has(self.unix))"
},
{
"message": "only one of fqdn, ip or unix can be specified",
"rule": "((has(self.fqdn) && !(has(self.ip) || has(self.unix))) || (has(self.ip) && !(has(self.fqdn) || has(self.unix))) || (has(self.unix) && !(has(self.ip) || has(self.fqdn))))"
}
],
"additionalProperties": false
},
"maxItems": 256,
"minItems": 1,
"type": "array",
"x-kubernetes-validations": [
{
"message": "fqdn addresses cannot be mixed with other address types",
"rule": "self.all(f, has(f.fqdn)) || !self.exists(f, has(f.fqdn))"
}
]
},
"fallback": {
"description": "Fallback indicates whether the backend is designated as a fallback.\nIt is highly recommended to configure active or passive health checks to ensure that failover can be detected\nwhen the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.\nThe overprovisioning factor is set to 1.4, meaning the fallback backends will only start receiving traffic when\nthe health of the active backends falls below 72%.",
"type": "boolean"
},
"tls": {
"description": "TLS defines the TLS settings for the backend.\nIf TLS is specified here and a BackendTLSPolicy is also configured for the backend, the final TLS settings will\nbe a merge of both configurations. In case of overlapping fields, the values defined in the BackendTLSPolicy will\ntake precedence.",
"properties": {
"alpnProtocols": {
"description": "ALPNProtocols supplies the list of ALPN protocols that should be\nexposed by the listener or used by the proxy to connect to the backend.\nDefaults:\n1. HTTPS Routes: h2 and http/1.1 are enabled in listener context.\n2. Other Routes: ALPN is disabled.\n3. Backends: proxy uses the appropriate ALPN options for the backend protocol.\nWhen an empty list is provided, the ALPN TLS extension is disabled.\n\nDefaults to [h2, http/1.1] if not specified.\n\nTypical Supported values are:\n- http/1.0\n- http/1.1\n- h2",
"items": {
"description": "ALPNProtocol specifies the protocol to be negotiated using ALPN",
"type": "string"
},
"type": "array"
},
"caCertificateRefs": {
"description": "CACertificateRefs contains one or more references to Kubernetes objects that\ncontain TLS certificates of the Certificate Authorities that can be used\nas a trust anchor to validate the certificates presented by the backend.\n\nA single reference to a Kubernetes ConfigMap or a Kubernetes Secret,\nwith the CA certificate in a key named `ca.crt` is currently supported.\n\nIf CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be\nspecified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,\nnot both.",
"items": {
"description": "LocalObjectReference identifies an API object within the namespace of the\nreferrer.\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"HTTPRoute\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array"
},
"ciphers": {
"description": "Ciphers specifies the set of cipher suites supported when\nnegotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3.\nFor Envoy TLS cipher suite configuration semantics and default cipher\nlists, see the Envoy documentation:\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlsparameters\nSupported cipher suite names:\n- ECDHE-ECDSA-AES128-GCM-SHA256\n- ECDHE-RSA-AES128-GCM-SHA256\n- ECDHE-ECDSA-AES256-GCM-SHA384\n- ECDHE-RSA-AES256-GCM-SHA384\n- ECDHE-ECDSA-CHACHA20-POLY1305\n- ECDHE-RSA-CHACHA20-POLY1305\n- ECDHE-ECDSA-AES128-SHA\n- ECDHE-RSA-AES128-SHA\n- AES128-GCM-SHA256\n- AES128-SHA\n- ECDHE-ECDSA-AES256-SHA\n- ECDHE-RSA-AES256-SHA\n- AES256-GCM-SHA384\n- AES256-SHA\nSupported IANA/RFC aliases:\n- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256\n- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA\n- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA\n- TLS_RSA_WITH_AES_128_GCM_SHA256\n- TLS_RSA_WITH_AES_128_CBC_SHA\n- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA\n- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA\n- TLS_RSA_WITH_AES_256_GCM_SHA384\n- TLS_RSA_WITH_AES_256_CBC_SHA\nIn non-FIPS Envoy Proxy builds the default cipher list is:\n- [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]\n- [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]\n- ECDHE-ECDSA-AES256-GCM-SHA384\n- ECDHE-RSA-AES256-GCM-SHA384\nIn builds using BoringSSL FIPS the default cipher list is:\n- ECDHE-ECDSA-AES128-GCM-SHA256\n- ECDHE-RSA-AES128-GCM-SHA256\n- ECDHE-ECDSA-AES256-GCM-SHA384\n- ECDHE-RSA-AES256-GCM-SHA384",
"items": {
"type": "string"
},
"type": "array"
},
"clientCertificateRef": {
"description": "ClientCertificateRef defines the reference to a Kubernetes Secret that contains\nthe client certificate and private key for Envoy to use when connecting to\nbackend services and external services, such as ExtAuth, ALS, OpenTelemetry, etc.\nThis secret should be located within the same namespace as the Envoy proxy resource that references it.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Secret",
"description": "Kind is kind of the referent. For example \"Secret\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"ecdhCurves": {
"description": "ECDHCurves specifies the set of supported ECDH curves.\nIn non-FIPS Envoy Proxy builds the default curves are:\n- X25519\n- P-256\nIn builds using BoringSSL FIPS the default curve is:\n- P-256",
"items": {
"type": "string"
},
"type": "array"
},
"fingerprints": {
"description": "Fingerprints specifies TLS client fingerprinting.\nWhen specified, a JAX fingerprint derived from the client\u2019s TLS handshake\nis generated. The fingerprint can be logged in access logs or\nforwarded to upstream services using request headers.\n\nFingerprinting is disabled if not specified.\n\nSupported values are:\n- JA3\n- JA4",
"items": {
"description": "TLSFingerprintType specifies the TLS client fingerprinting mode.",
"enum": [
"JA3",
"JA4"
],
"type": "string"
},
"type": "array"
},
"insecureSkipVerify": {
"default": false,
"description": "InsecureSkipVerify indicates whether the upstream's certificate verification\nshould be skipped. Defaults to \"false\".",
"type": "boolean"
},
"maxVersion": {
"description": "Max specifies the maximal TLS protocol version to allow\nThe default is TLS 1.3 if this is not specified.",
"enum": [
"Auto",
"1.0",
"1.1",
"1.2",
"1.3"
],
"type": "string"
},
"minVersion": {
"description": "Min specifies the minimal TLS protocol version to allow.\nThe default is TLS 1.2 if this is not specified.",
"enum": [
"Auto",
"1.0",
"1.1",
"1.2",
"1.3"
],
"type": "string"
},
"signatureAlgorithms": {
"description": "SignatureAlgorithms specifies which signature algorithms the listener should\nsupport.",
"items": {
"type": "string"
},
"type": "array"
},
"sni": {
"description": "SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.\n\nEnvoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:\n1. Backend resources that do not set SNI, or\n2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them\n\nWhen a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence\nover this value.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"wellKnownCACertificates": {
"description": "WellKnownCACertificates specifies whether system CA certificates may be used in\nthe TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\nmust be specified with at least one entry for a valid configuration. Only one of\nCACertificateRefs or WellKnownCACertificates may be specified, not both.",
"maxLength": 253,
"minLength": 1,
"pattern": "^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$",
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "must not contain both CACertificateRefs and WellKnownCACertificates",
"rule": "!(has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")"
},
{
"message": "must not contain either CACertificateRefs or WellKnownCACertificates when InsecureSkipVerify is enabled",
"rule": "!((has(self.insecureSkipVerify) && self.insecureSkipVerify) && ((has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0) || (has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")))"
},
{
"message": "setting ciphers has no effect if the minimum possible TLS version is 1.3",
"rule": "has(self.minVersion) && self.minVersion == '1.3' ? !has(self.ciphers) : true"
},
{
"message": "minVersion must be smaller or equal to maxVersion",
"rule": "has(self.minVersion) && has(self.maxVersion) ? {\"Auto\":0,\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4}[self.minVersion] <= {\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4,\"Auto\":5}[self.maxVersion] : !has(self.minVersion) && has(self.maxVersion) ? 3 <= {\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4,\"Auto\":5}[self.maxVersion] : true"
}
],
"additionalProperties": false
},
"type": {
"default": "Endpoints",
"description": "Type defines the type of the backend. Defaults to \"Endpoints\"",
"enum": [
"Endpoints",
"DynamicResolver"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "DynamicResolver type cannot have endpoints specified",
"rule": "self.type != 'DynamicResolver' || !has(self.endpoints)"
}
],
"additionalProperties": false
},
"status": {
"description": "Status defines the current status of Backend.",
"properties": {
"conditions": {
"description": "Conditions describe the current conditions of the Backend.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,292 @@
{
"description": "EnvoyPatchPolicy allows the user to modify the generated Envoy xDS\nresources by Envoy Gateway using this patch API",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of EnvoyPatchPolicy.",
"properties": {
"jsonPatches": {
"description": "JSONPatch defines the JSONPatch configuration.",
"items": {
"description": "EnvoyJSONPatchConfig defines the configuration for patching a Envoy xDS Resource\nusing JSONPatch semantic",
"properties": {
"name": {
"description": "Name is the name of the resource",
"type": "string"
},
"operation": {
"description": "Patch defines the JSON Patch Operation",
"properties": {
"from": {
"description": "From is the source location of the value to be copied or moved. Only valid\nfor move or copy operations\nRefer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.",
"type": "string"
},
"jsonPath": {
"description": "JSONPath is a JSONPath expression. Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.\nIt produces one or more JSONPointer expressions based on the given JSON document.\nIf no JSONPointer is found, it will result in an error.\nIf the 'Path' property is also set, it will be appended to the resulting JSONPointer expressions from the JSONPath evaluation.\nThis is useful when creating a property that does not yet exist in the JSON document.\nThe final JSONPointer expressions specifies the locations in the target document/field where the operation will be applied.",
"type": "string"
},
"op": {
"description": "Op is the type of operation to perform",
"enum": [
"add",
"remove",
"replace",
"move",
"copy",
"test"
],
"type": "string"
},
"path": {
"description": "Path is a JSONPointer expression. Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.\nIt specifies the location of the target document/field where the operation will be performed",
"type": "string"
},
"value": {
"description": "Value is the new value of the path location. The value is only used by\nthe `add` and `replace` operations.",
"x-kubernetes-preserve-unknown-fields": true
}
},
"required": [
"op"
],
"type": "object",
"additionalProperties": false
},
"type": {
"description": "Type is the typed URL of the Envoy xDS Resource",
"enum": [
"type.googleapis.com/envoy.config.listener.v3.Listener",
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
"type.googleapis.com/envoy.config.cluster.v3.Cluster",
"type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
],
"type": "string"
}
},
"required": [
"name",
"operation",
"type"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
},
"priority": {
"description": "Priority of the EnvoyPatchPolicy.\nIf multiple EnvoyPatchPolicies are applied to the same\nTargetRef, they will be applied in the ascending order of\nthe priority i.e. int32.min has the highest priority and\nint32.max has the lowest priority.\nDefaults to 0.",
"format": "int32",
"type": "integer"
},
"targetRef": {
"description": "TargetRef is the name of the Gateway API resource this policy\nis being attached to.\nBy default, attaching to Gateway is supported and\nwhen mergeGateways is enabled it should attach to GatewayClass.\nThis Policy and the TargetRef MUST be in the same namespace\nfor this Policy to have effect and be applied to the Gateway\nTargetRef",
"properties": {
"group": {
"description": "Group is the group of the target resource.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the target resource.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"type": {
"description": "Type decides the type of patch.\nValid EnvoyPatchType values are \"JSONPatch\".",
"enum": [
"JSONPatch"
],
"type": "string"
}
},
"required": [
"targetRef",
"type"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current status of EnvoyPatchPolicy.",
"properties": {
"ancestors": {
"description": "Ancestors is a list of ancestor resources (usually Gateways) that are\nassociated with the policy, and the status of the policy with respect to\neach ancestor. When this policy attaches to a parent, the controller that\nmanages the parent and the ancestors MUST add an entry to this list when\nthe controller first sees the policy and SHOULD update the entry as\nappropriate when the relevant ancestor is modified.\n\nNote that choosing the relevant ancestor is left to the Policy designers;\nan important part of Policy design is designing the right object level at\nwhich to namespace this status.\n\nNote also that implementations MUST ONLY populate ancestor status for\nthe Ancestor resources they are responsible for. Implementations MUST\nuse the ControllerName field to uniquely identify the entries in this list\nthat they are responsible for.\n\nNote that to achieve this, the list of PolicyAncestorStatus structs\nMUST be treated as a map with a composite key, made up of the AncestorRef\nand ControllerName fields combined.\n\nA maximum of 16 ancestors will be represented in this list. An empty list\nmeans the Policy is not relevant for any ancestors.\n\nIf this slice is full, implementations MUST NOT add further entries.\nInstead they MUST consider the policy unimplementable and signal that\non any related resources such as the ancestor that would be referenced\nhere. For example, if this list was full on BackendTLSPolicy, no\nadditional Gateways would be able to reference the Service targeted by\nthe BackendTLSPolicy.",
"items": {
"description": "PolicyAncestorStatus describes the status of a route with respect to an\nassociated Ancestor.\n\nAncestors refer to objects that are either the Target of a policy or above it\nin terms of object hierarchy. For example, if a policy targets a Service, the\nPolicy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\nthe GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\nuseful object to place Policy status on, so we recommend that implementations\nSHOULD use Gateway as the PolicyAncestorStatus object unless the designers\nhave a _very_ good reason otherwise.\n\nIn the context of policy attachment, the Ancestor is used to distinguish which\nresource results in a distinct application of this policy. For example, if a policy\ntargets a Service, it may have a distinct result per attached Gateway.\n\nPolicies targeting the same resource may have different effects depending on the\nancestors of those resources. For example, different Gateways targeting the same\nService may have different capabilities, especially if they have different underlying\nimplementations.\n\nFor example, in BackendTLSPolicy, the Policy attaches to a Service that is\nused as a backend in a HTTPRoute that is itself attached to a Gateway.\nIn this case, the relevant object for status is the Gateway, and that is the\nancestor object referred to in this status.\n\nNote that a parent is also an ancestor, so for objects where the parent is the\nrelevant object for status, this struct SHOULD still be used.\n\nThis struct is intended to be used in a slice that's effectively a map,\nwith a composite key made up of the AncestorRef and the ControllerName.",
"properties": {
"ancestorRef": {
"description": "AncestorRef corresponds with a ParentRef in the spec that this\nPolicyAncestorStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n<gateway:experimental:description>\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n</gateway:experimental:description>\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n<gateway:experimental:description>\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n</gateway:experimental:description>\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"conditions": {
"description": "Conditions describes the status of the Policy with respect to the given Ancestor.\n\n<gateway:util:excludeFromCRD>\n\nNotes for implementors:\n\nConditions are a listType `map`, which means that they function like a\nmap with a key of the `type` field _in the k8s apiserver_.\n\nThis means that implementations must obey some rules when updating this\nsection.\n\n* Implementations MUST perform a read-modify-write cycle on this field\n before modifying it. That is, when modifying this field, implementations\n must be confident they have fetched the most recent version of this field,\n and ensure that changes they make are on that recent version.\n* Implementations MUST NOT remove or reorder Conditions that they are not\n directly responsible for. For example, if an implementation sees a Condition\n with type `special.io/SomeField`, it MUST NOT remove, change or update that\n Condition.\n* Implementations MUST always _merge_ changes into Conditions of the same Type,\n rather than creating more than one Condition of the same Type.\n* Implementations MUST always update the `observedGeneration` field of the\n Condition to the `metadata.generation` of the Gateway at the time of update creation.\n* If the `observedGeneration` of a Condition is _greater than_ the value the\n implementation knows about, then it MUST NOT perform the update on that Condition,\n but must wait for a future reconciliation and status update. (The assumption is that\n the implementation's copy of the object is stale and an update will be re-triggered\n if relevant.)\n\n</gateway:util:excludeFromCRD>",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
}
},
"required": [
"ancestorRef",
"conditions",
"controllerName"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"ancestors"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,411 @@
{
"description": "HTTPRouteFilter is a custom Envoy Gateway HTTPRouteFilter which provides extended\ntraffic processing options such as path regex rewrite, direct response and more.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of HTTPRouteFilter.",
"properties": {
"credentialInjection": {
"description": "HTTPCredentialInjectionFilter defines the configuration to inject credentials into the request.\nThis is useful when the backend service requires credentials in the request, and the original\nrequest does not contain them. The filter can inject credentials into the request before forwarding\nit to the backend service.",
"properties": {
"credential": {
"description": "Credential is the credential to be injected.",
"properties": {
"valueRef": {
"description": "ValueRef is a reference to the secret containing the credentials to be injected.\nThis is an Opaque secret. The credential should be stored in the key\n\"credential\", and the value should be the credential to be injected.\nFor example, for basic authentication, the value should be \"Basic <base64 encoded username:password>\".\nfor bearer token, the value should be \"Bearer <token>\".",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Secret",
"description": "Kind is kind of the referent. For example \"Secret\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"valueRef"
],
"type": "object",
"additionalProperties": false
},
"header": {
"description": "Header is the name of the header where the credentials are injected.\nIf not specified, the credentials are injected into the Authorization header.",
"type": "string"
},
"overwrite": {
"description": "Whether to overwrite the value or not if the injected headers already exist.\nIf not specified, the default value is false.",
"type": "boolean"
}
},
"required": [
"credential"
],
"type": "object",
"additionalProperties": false
},
"directResponse": {
"description": "HTTPDirectResponseFilter defines the configuration to return a fixed response.",
"properties": {
"body": {
"description": "Body of the direct response.\nSupports Envoy command operators for dynamic content (see https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators).",
"properties": {
"inline": {
"description": "Inline contains the value as an inline string.",
"type": "string"
},
"type": {
"allOf": [
{
"enum": [
"Inline",
"ValueRef"
]
},
{
"enum": [
"Inline",
"ValueRef"
]
}
],
"default": "Inline",
"description": "Type is the type of method to use to read the body value.\nValid values are Inline and ValueRef, default is Inline.",
"type": "string"
},
"valueRef": {
"description": "ValueRef contains the contents of the body\nspecified as a local object reference.\nOnly a reference to ConfigMap is supported.\n\nThe value of key `response.body` in the ConfigMap will be used as the response body.\nIf the key is not found, the first value in the ConfigMap will be used.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"HTTPRoute\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "inline must be set for type Inline",
"rule": "(!has(self.type) || self.type == 'Inline')? has(self.inline) : true"
},
{
"message": "valueRef must be set for type ValueRef",
"rule": "(has(self.type) && self.type == 'ValueRef')? has(self.valueRef) : true"
},
{
"message": "only ConfigMap is supported for ValueRef",
"rule": "has(self.valueRef) ? self.valueRef.kind == 'ConfigMap' : true"
}
],
"additionalProperties": false
},
"contentType": {
"description": "Content Type of the direct response. This will be set in the Content-Type header.",
"type": "string"
},
"header": {
"description": "Header defines the headers of the direct response.",
"properties": {
"add": {
"description": "Add adds the given header(s) (name, value) to the request\nbefore the action. It appends to any existing values associated\nwith the header name.\n\nInput:\n GET /foo HTTP/1.1\n my-header: foo\n\nConfig:\n add:\n - name: \"my-header\"\n value: \"bar,baz\"\n\nOutput:\n GET /foo HTTP/1.1\n my-header: foo,bar,baz",
"items": {
"description": "HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.",
"properties": {
"name": {
"description": "Name is the name of the HTTP Header to be matched. Name matching MUST be\ncase-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\nIf multiple entries specify equivalent header names, the first entry with\nan equivalent name MUST be considered for a match. Subsequent entries\nwith an equivalent header name MUST be ignored. Due to the\ncase-insensitivity of header names, \"foo\" and \"Foo\" are considered\nequivalent.",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"value": {
"description": "Value is the value of HTTP Header to be matched.\n<gateway:experimental:description>\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n</gateway:experimental:description>\n\n<gateway:experimental:validation:Pattern=`^[!-~]+([\\t ]?[!-~]+)*$`>",
"maxLength": 4096,
"minLength": 1,
"type": "string"
}
},
"required": [
"name",
"value"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
"remove": {
"description": "Remove the given header(s) from the HTTP request before the action. The\nvalue of Remove is a list of HTTP header names. Note that the header\nnames are case-insensitive (see\nhttps://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\nInput:\n GET /foo HTTP/1.1\n my-header1: foo\n my-header2: bar\n my-header3: baz\n\nConfig:\n remove: [\"my-header1\", \"my-header3\"]\n\nOutput:\n GET /foo HTTP/1.1\n my-header2: bar",
"items": {
"type": "string"
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-type": "set"
},
"set": {
"description": "Set overwrites the request with the given header (name, value)\nbefore the action.\n\nInput:\n GET /foo HTTP/1.1\n my-header: foo\n\nConfig:\n set:\n - name: \"my-header\"\n value: \"bar\"\n\nOutput:\n GET /foo HTTP/1.1\n my-header: bar",
"items": {
"description": "HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.",
"properties": {
"name": {
"description": "Name is the name of the HTTP Header to be matched. Name matching MUST be\ncase-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\nIf multiple entries specify equivalent header names, the first entry with\nan equivalent name MUST be considered for a match. Subsequent entries\nwith an equivalent header name MUST be ignored. Due to the\ncase-insensitivity of header names, \"foo\" and \"Foo\" are considered\nequivalent.",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"value": {
"description": "Value is the value of HTTP Header to be matched.\n<gateway:experimental:description>\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n</gateway:experimental:description>\n\n<gateway:experimental:validation:Pattern=`^[!-~]+([\\t ]?[!-~]+)*$`>",
"maxLength": 4096,
"minLength": 1,
"type": "string"
}
},
"required": [
"name",
"value"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "header.remove is not supported for DirectResponse",
"rule": "!has(self.remove) || size(self.remove) == 0"
}
],
"additionalProperties": false
},
"statusCode": {
"description": "Status Code of the HTTP response\nIf unset, defaults to 200.",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"matches": {
"description": "Matches defines additional matching criteria for the HTTPRoute rule.\nAs with HTTPRouteRule.Matches, the rule is matched if any one match applies.\nWhen both HTTPRouteRule.Matches and HTTPRouteFilter.Matches are set, the\neffective matching is the logical AND of the two sets.",
"items": {
"description": "HTTPRouteMatchFilter defines additional matching criteria for the HTTPRoute rule.\nAt least one matcher must be specified.",
"minProperties": 1,
"properties": {
"cookies": {
"description": "Cookies is a list of cookie matchers evaluated against the HTTP request.\nAll specified matchers must match.",
"items": {
"description": "HTTPCookieMatch defines how to match a single cookie.",
"properties": {
"name": {
"description": "Name is the cookie name to evaluate.",
"maxLength": 256,
"minLength": 1,
"type": "string"
},
"type": {
"default": "Exact",
"description": "Type specifies how to match against the value of the cookie.",
"enum": [
"Exact",
"RegularExpression"
],
"type": "string"
},
"value": {
"description": "Value is the cookie value to be matched.",
"maxLength": 4096,
"minLength": 1,
"type": "string"
}
},
"required": [
"name",
"value"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array"
},
"urlRewrite": {
"description": "HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host",
"properties": {
"appendXForwardedHost": {
"description": "AppendXForwardedHost controls whether the original Host header value is\nappended to the X-Forwarded-Host header when hostname rewriting is configured.\nDefaults to true for backward compatibility.",
"type": "boolean"
},
"hostname": {
"description": "Hostname is the value to be used to replace the Host header value during\nforwarding.",
"properties": {
"header": {
"description": "Header is the name of the header whose value would be used to rewrite the Host header",
"type": "string"
},
"type": {
"description": "HTTPPathModifierType defines the type of Hostname rewrite.",
"enum": [
"Header",
"Backend"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "header must be nil if the type is not Header",
"rule": "!(has(self.header) && self.type != 'Header')"
},
{
"message": "header must be specified for Header type",
"rule": "!(!has(self.header) && self.type == 'Header')"
}
],
"additionalProperties": false
},
"path": {
"description": "Path defines a path rewrite.",
"properties": {
"replaceRegexMatch": {
"description": "ReplaceRegexMatch defines a path regex rewrite. The path portions matched by the regex pattern are replaced by the defined substitution.\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-regex-rewrite\nSome examples:\n(1) replaceRegexMatch:\n pattern: ^/service/([^/]+)(/.*)$\n substitution: \\2/instance/\\1\n Would transform /service/foo/v1/api into /v1/api/instance/foo.\n(2) replaceRegexMatch:\n pattern: one\n substitution: two\n Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/two/zzz.\n(3) replaceRegexMatch:\n pattern: ^(.*?)one(.*)$\n substitution: \\1two\\2\n Would transform /xxx/one/yyy/one/zzz into /xxx/two/yyy/one/zzz.\n(3) replaceRegexMatch:\n pattern: (?i)/xxx/\n substitution: /yyy/\n Would transform path /aaa/XxX/bbb into /aaa/yyy/bbb (case-insensitive).",
"properties": {
"pattern": {
"description": "Pattern matches a regular expression against the value of the HTTP Path.The regex string must\nadhere to the syntax documented in https://github.com/google/re2/wiki/Syntax.",
"minLength": 1,
"type": "string"
},
"substitution": {
"description": "Substitution is an expression that replaces the matched portion.The expression may include numbered\ncapture groups that adhere to syntax documented in https://github.com/google/re2/wiki/Syntax.",
"type": "string"
}
},
"required": [
"pattern",
"substitution"
],
"type": "object",
"additionalProperties": false
},
"type": {
"description": "HTTPPathModifierType defines the type of path redirect or rewrite.",
"enum": [
"ReplaceRegexMatch"
],
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "If HTTPPathModifier type is ReplaceRegexMatch, replaceRegexMatch field needs to be set.",
"rule": "self.type == 'ReplaceRegexMatch' ? has(self.replaceRegexMatch) : !has(self.replaceRegexMatch)"
}
],
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -27,7 +27,7 @@
"type": "object" "type": "object"
}, },
"targetRefs": { "targetRefs": {
"description": "TargetRefs identifies an API object to apply the policy to.\nOnly Services have Extended support. Implementations MAY support\nadditional objects, with Implementation Specific support.\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, and `name` must\n be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and\nsectionName, implementations MUST determine precedence using the\nfollowing criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n example, a policy with a creation timestamp of \"2021-07-15\n 01:02:03\" MUST be given precedence over a policy with a\n creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {name}.\n For example, a policy named `bar` is given precedence over a\n policy named `baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the\nimplementation MUST ensure the `Accepted` Condition is set to\n`status: False`, with Reason `Conflicted`.\n\nSupport: Extended for Kubernetes Service\n\nSupport: Implementation-specific for any other resource", "description": "TargetRefs identifies an API object to apply the policy to.\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, and `name` must\n be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and\nsectionName, implementations MUST determine precedence using the\nfollowing criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n example, a policy with a creation timestamp of \"2021-07-15\n 01:02:03\" MUST be given precedence over a policy with a\n creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {namespace}/{name}.\n For example, a policy named `foo/bar` is given precedence over a\n policy named `foo/baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the\nimplementation MUST ensure the `Accepted` Condition is set to\n`status: False`, with Reason `Conflicted`.\n\nImplementations SHOULD NOT support more than one targetRef at this\ntime. Although the API technically allows for this, the current guidance\nfor conflict resolution and status handling is lacking. Until that can be\nclarified in a future release, the safest approach is to support a single\ntargetRef.\n\nSupport Levels:\n\n* Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n* Implementation-Specific: Services not connected via HTTPRoute, and any\n other kind of backend. Implementations MAY use BackendTLSPolicy for:\n - Services not referenced by any Route (e.g., infrastructure services)\n - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n - Service mesh workload-to-service communication\n - Other resource types beyond Service\n\nImplementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\neven outside of the extended HTTPRoute -(backendRef) -> Service path.\nThey SHOULD clearly document how BackendTLSPolicy is interpreted in these\nscenarios, including:\n - Which resources beyond Service are supported\n - How the policy is discovered and applied\n - Any implementation-specific semantics or restrictions\n\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.",
"items": { "items": {
"description": "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\ndirect policy to. This should be used as part of Policy resources that can\ntarget single resources. For more information on how this policy attachment\nmode works, and a sample Policy resource, refer to the policy attachment\ndocumentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references\nto SectionName are actually needed. In all other cases,\nLocalPolicyTargetReference should be used.", "description": "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\ndirect policy to. This should be used as part of Policy resources that can\ntarget single resources. For more information on how this policy attachment\nmode works, and a sample Policy resource, refer to the policy attachment\ndocumentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references\nto SectionName are actually needed. In all other cases,\nLocalPolicyTargetReference should be used.",
"properties": { "properties": {
@@ -185,10 +185,10 @@
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"wellKnownCACertificates": { "wellKnownCACertificates": {
"description": "WellKnownCACertificates specifies whether system CA certificates may be used in\nthe TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\nmust be specified with at least one entry for a valid configuration. Only one of\nCACertificateRefs or WellKnownCACertificates may be specified, not both.\nIf an implementation does not support the WellKnownCACertificates field, or\nthe supplied value is not recognized, the implementation MUST ensure the\n`Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\na Reason `Invalid`.\n\nSupport: Implementation-specific", "description": "WellKnownCACertificates specifies whether a well-known set of CA certificates\nmay be used in the TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\nmust be specified with at least one entry for a valid configuration. Only one of\nCACertificateRefs or WellKnownCACertificates may be specified, not both.\nIf an implementation does not support the WellKnownCACertificates field, or\nthe supplied value is not recognized, the implementation MUST ensure the\n`Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\na Reason `Invalid`.\n\nValid values include:\n* \"System\" - indicates that well-known system CA certificates should be used.\n\nImplementations MAY define their own sets of CA certificates. Such definitions\nMUST use an implementation-specific, prefixed name, such as\n`mycompany.com/my-custom-ca-certificates`.\n\nSupport: Implementation-specific",
"enum": [ "maxLength": 253,
"System" "minLength": 1,
], "pattern": "^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$",
"type": "string" "type": "string"
} }
}, },
@@ -249,14 +249,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -27,7 +27,7 @@
"type": "object" "type": "object"
}, },
"targetRefs": { "targetRefs": {
"description": "TargetRefs identifies an API object to apply the policy to.\nOnly Services have Extended support. Implementations MAY support\nadditional objects, with Implementation Specific support.\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, and `name` must\n be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and\nsectionName, implementations MUST determine precedence using the\nfollowing criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n example, a policy with a creation timestamp of \"2021-07-15\n 01:02:03\" MUST be given precedence over a policy with a\n creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {name}.\n For example, a policy named `bar` is given precedence over a\n policy named `baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the\nimplementation MUST ensure the `Accepted` Condition is set to\n`status: False`, with Reason `Conflicted`.\n\nSupport: Extended for Kubernetes Service\n\nSupport: Implementation-specific for any other resource", "description": "TargetRefs identifies an API object to apply the policy to.\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, and `name` must\n be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and\nsectionName, implementations MUST determine precedence using the\nfollowing criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n example, a policy with a creation timestamp of \"2021-07-15\n 01:02:03\" MUST be given precedence over a policy with a\n creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {namespace}/{name}.\n For example, a policy named `foo/bar` is given precedence over a\n policy named `foo/baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the\nimplementation MUST ensure the `Accepted` Condition is set to\n`status: False`, with Reason `Conflicted`.\n\nImplementations SHOULD NOT support more than one targetRef at this\ntime. Although the API technically allows for this, the current guidance\nfor conflict resolution and status handling is lacking. Until that can be\nclarified in a future release, the safest approach is to support a single\ntargetRef.\n\nSupport Levels:\n\n* Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n* Implementation-Specific: Services not connected via HTTPRoute, and any\n other kind of backend. Implementations MAY use BackendTLSPolicy for:\n - Services not referenced by any Route (e.g., infrastructure services)\n - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n - Service mesh workload-to-service communication\n - Other resource types beyond Service\n\nImplementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\neven outside of the extended HTTPRoute -(backendRef) -> Service path.\nThey SHOULD clearly document how BackendTLSPolicy is interpreted in these\nscenarios, including:\n - Which resources beyond Service are supported\n - How the policy is discovered and applied\n - Any implementation-specific semantics or restrictions\n\nNote that this config applies to the entire referenced resource\nby default, but this default may change in the future to provide\na more granular application of the policy.",
"items": { "items": {
"description": "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\ndirect policy to. This should be used as part of Policy resources that can\ntarget single resources. For more information on how this policy attachment\nmode works, and a sample Policy resource, refer to the policy attachment\ndocumentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references\nto SectionName are actually needed. In all other cases,\nLocalPolicyTargetReference should be used.", "description": "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\ndirect policy to. This should be used as part of Policy resources that can\ntarget single resources. For more information on how this policy attachment\nmode works, and a sample Policy resource, refer to the policy attachment\ndocumentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references\nto SectionName are actually needed. In all other cases,\nLocalPolicyTargetReference should be used.",
"properties": { "properties": {
@@ -185,10 +185,10 @@
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"wellKnownCACertificates": { "wellKnownCACertificates": {
"description": "WellKnownCACertificates specifies whether system CA certificates may be used in\nthe TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\nmust be specified with at least one entry for a valid configuration. Only one of\nCACertificateRefs or WellKnownCACertificates may be specified, not both.\nIf an implementation does not support the WellKnownCACertificates field, or\nthe supplied value is not recognized, the implementation MUST ensure the\n`Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\na Reason `Invalid`.\n\nSupport: Implementation-specific", "description": "WellKnownCACertificates specifies whether a well-known set of CA certificates\nmay be used in the TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\nmust be specified with at least one entry for a valid configuration. Only one of\nCACertificateRefs or WellKnownCACertificates may be specified, not both.\nIf an implementation does not support the WellKnownCACertificates field, or\nthe supplied value is not recognized, the implementation MUST ensure the\n`Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\na Reason `Invalid`.\n\nValid values include:\n* \"System\" - indicates that well-known system CA certificates should be used.\n\nImplementations MAY define their own sets of CA certificates. Such definitions\nMUST use an implementation-specific, prefixed name, such as\n`mycompany.com/my-custom-ca-certificates`.\n\nSupport: Implementation-specific",
"enum": [ "maxLength": 253,
"System" "minLength": 1,
], "pattern": "^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$",
"type": "string" "type": "string"
} }
}, },
@@ -249,14 +249,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -89,6 +89,89 @@
} }
] ]
}, },
"allowedListeners": {
"description": "AllowedListeners defines which ListenerSets can be attached to this Gateway.\nThe default value is to allow no ListenerSets.",
"properties": {
"namespaces": {
"default": {
"from": "None"
},
"description": "Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\nThe default value is to allow no ListenerSets.",
"properties": {
"from": {
"default": "None",
"description": "From indicates where ListenerSets can attach to this Gateway. Possible\nvalues are:\n\n* Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n* Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n* All: ListenerSets in all namespaces may be attached to this Gateway.\n* None: Only listeners defined in the Gateway's spec are allowed\n\nThe default value None",
"enum": [
"All",
"Selector",
"Same",
"None"
],
"type": "string"
},
"selector": {
"description": "Selector must be specified when From is set to \"Selector\". In that case,\nonly ListenerSets in Namespaces matching this Selector will be selected by this\nGateway. This field is ignored for other values of \"From\".",
"properties": {
"matchExpressions": {
"description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
"items": {
"description": "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.",
"type": "string"
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.",
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"defaultScope": {
"description": "DefaultScope, when set, configures the Gateway as a default Gateway,\nmeaning it will dynamically and implicitly have Routes (e.g. HTTPRoute)\nattached to it, according to the scope configured here.\n\nIf unset (the default) or set to None, the Gateway will not act as a\ndefault Gateway; if set, the Gateway will claim any Route with a\nmatching scope set in its UseDefaultGateway field, subject to the usual\nrules about which routes the Gateway can attach to.\n\nThink carefully before using this functionality! While the normal rules\nabout which Route can apply are still enforced, it is simply easier for\nthe wrong Route to be accidentally attached to this Gateway in this\nconfiguration. If the Gateway operator is not also the operator in\ncontrol of the scope (e.g. namespace) with tight controls and checks on\nwhat kind of workloads and Routes get added in that scope, we strongly\nrecommend not using this just because it seems convenient, and instead\nstick to direct Route attachment.",
"enum": [
"All",
"None"
],
"type": "string"
},
"gatewayClassName": { "gatewayClassName": {
"description": "GatewayClassName used for this Gateway. This is the name of a\nGatewayClass resource.", "description": "GatewayClassName used for this Gateway. This is the name of a\nGatewayClass resource.",
"maxLength": 253, "maxLength": 253,
@@ -291,7 +374,7 @@
"additionalProperties": false "additionalProperties": false
}, },
"hostname": { "hostname": {
"description": "Hostname specifies the virtual hostname to match for protocol types that\ndefine this concept. When unspecified, all hostnames are matched. This\nfield is ignored for protocols that don't require hostname based\nmatching.\n\nImplementations MUST apply Hostname matching appropriately for each of\nthe following protocols:\n\n* TLS: The Listener Hostname MUST match the SNI.\n* HTTP: The Listener Hostname MUST match the Host header of the request.\n* HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n Note that this does not require the SNI and Host header to be the same.\n The semantics of this are described in more detail below.\n\nTo ensure security, Section 11.1 of RFC-6066 emphasizes that server\nimplementations that rely on SNI hostname matching MUST also verify\nhostnames within the application protocol.\n\nSection 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\nreuse of a connection by responding with the HTTP 421 Misdirected Request\nstatus code. This indicates that the origin server has rejected the\nrequest because it appears to have been misdirected.\n\nTo detect misdirected requests, Gateways SHOULD match the authority of\nthe requests with all the SNI hostname(s) configured across all the\nGateway Listeners on the same port and protocol:\n\n* If another Listener has an exact match or more specific wildcard entry,\n the Gateway SHOULD return a 421.\n* If the current Listener (selected by SNI matching during ClientHello)\n does not match the Host:\n * If another Listener does match the Host the Gateway SHOULD return a\n 421.\n * If no other Listener matches the Host, the Gateway MUST return a\n 404.\n\nFor HTTPRoute and TLSRoute resources, there is an interaction with the\n`spec.hostnames` array. When both listener and route specify hostnames,\nthere MUST be an intersection between the values for a Route to be\naccepted. For more information, refer to the Route specific Hostnames\ndocumentation.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted\nas a suffix match. That means that a match for `*.example.com` would match\nboth `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nSupport: Core", "description": "Hostname specifies the virtual hostname to match for protocol types that\ndefine this concept. When unspecified, all hostnames are matched. This\nfield is ignored for protocols that don't require hostname based\nmatching.\n\nImplementations MUST apply Hostname matching appropriately for each of\nthe following protocols:\n\n* TLS: The Listener Hostname MUST match the SNI.\n* HTTP: The Listener Hostname MUST match the Host header of the request.\n* HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n Note that this does not require the SNI and Host header to be the same.\n The semantics of this are described in more detail below.\n\nTo ensure security, Section 11.1 of RFC-6066 emphasizes that server\nimplementations that rely on SNI hostname matching MUST also verify\nhostnames within the application protocol.\n\nSection 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\nreuse of a connection by responding with the HTTP 421 Misdirected Request\nstatus code. This indicates that the origin server has rejected the\nrequest because it appears to have been misdirected.\n\nTo detect misdirected requests, Gateways SHOULD match the authority of\nthe requests with all the SNI hostname(s) configured across all the\nGateway Listeners on the same port and protocol:\n\n* If another Listener has an exact match or more specific wildcard entry,\n the Gateway SHOULD return a 421.\n* If the current Listener (selected by SNI matching during ClientHello)\n does not match the Host:\n * If another Listener does match the Host, the Gateway SHOULD return a\n 421.\n * If no other Listener matches the Host, the Gateway MUST return a\n 404.\n\nFor HTTPRoute and TLSRoute resources, there is an interaction with the\n`spec.hostnames` array. When both listener and route specify hostnames,\nthere MUST be an intersection between the values for a Route to be\naccepted. For more information, refer to the Route specific Hostnames\ndocumentation.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted\nas a suffix match. That means that a match for `*.example.com` would match\nboth `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nSupport: Core",
"maxLength": 253, "maxLength": 253,
"minLength": 1, "minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
@@ -420,6 +503,10 @@
"message": "tls mode must be Terminate for protocol HTTPS", "message": "tls mode must be Terminate for protocol HTTPS",
"rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)" "rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)"
}, },
{
"message": "tls mode must be set for protocol TLS",
"rule": "self.all(l, (l.protocol == 'TLS' ? has(l.tls) && has(l.tls.mode) && l.tls.mode != '' : true))"
},
{ {
"message": "hostname must not be specified for protocols ['TCP', 'UDP']", "message": "hostname must not be specified for protocols ['TCP', 'UDP']",
"rule": "self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)" "rule": "self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)"
@@ -433,6 +520,242 @@
"rule": "self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))" "rule": "self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
} }
] ]
},
"tls": {
"description": "TLS specifies frontend and backend tls configuration for entire gateway.\n\nSupport: Extended",
"properties": {
"backend": {
"description": "Backend describes TLS configuration for gateway when connecting\nto backends.\n\nNote that this contains only details for the Gateway as a TLS client,\nand does _not_ imply behavior about how to choose which backend should\nget a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\nSupport: Core",
"properties": {
"clientCertificateRef": {
"description": "ClientCertificateRef references an object that contains a client certificate\nand its associated private key. It can reference standard Kubernetes resources,\ni.e., Secret, or implementation-specific custom resources.\n\nA ClientCertificateRef is considered invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the referenced resource\n does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n and the Message of the Condition MUST indicate why the reference is invalid.\n\n* It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n in the target namespace that allows the certificate to be attached.\n If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the certificate\ncontent (e.g., checking expiry or enforcing specific formats). In such cases,\nan implementation-specific Reason and Message MUST be set.\n\nSupport: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\nSupport: Implementation-specific - Other resource kinds or Secrets with a\ndifferent type (e.g., `Opaque`).",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Secret",
"description": "Kind is kind of the referent. For example \"Secret\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"frontend": {
"description": "Frontend describes TLS config when client connects to Gateway.\nSupport: Core",
"properties": {
"default": {
"description": "Default specifies the default client certificate validation configuration\nfor all Listeners handling HTTPS traffic, unless a per-port configuration\nis defined.\n\nsupport: Core",
"properties": {
"validation": {
"description": "Validation holds configuration information for validating the frontend (client).\nSetting this field will result in mutual authentication when connecting to the gateway.\nIn browsers this may result in a dialog appearing\nthat requests a user to specify the client certificate.\nThe maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core",
"properties": {
"caCertificateRefs": {
"description": "CACertificateRefs contains one or more references to Kubernetes\nobjects that contain a PEM-encoded TLS CA certificate bundle, which\nis used as a trust anchor to validate the certificates presented by\nthe client.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the\n referenced resource does not exist) or is misconfigured (e.g., a\n ConfigMap does not contain a key named `ca.crt`). In this case, the\n Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this\n case, the Reason on all matching HTTPS listeners must be set to\n `InvalidCACertificateKind` and the Message of the Condition must explain\n which kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace UNLESS there is a\n ReferenceGrant in the target namespace that allows the CA\n certificate to be attached. If a ReferenceGrant does not allow this\n reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n MUST be set with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the\ncertificate content (e.g., checking expiry or enforcing specific formats).\nIn such cases, an implementation-specific Reason and Message MUST be set.\n\nIn all cases, the implementation MUST ensure that the `ResolvedRefs`\ncondition is set to `status: False` on all targeted listeners (i.e.,\nlisteners serving HTTPS on a matching port). The condition MUST\ninclude a Reason and Message that indicate the cause of the error. If\nALL CACertificateRefs are invalid, the implementation MUST also ensure\nthe `Accepted` condition on the listener is set to `status: False`, with\nthe Reason `NoValidCACertificate`.\nImplementations MAY choose to support attaching multiple CA certificates\nto a listener, but this behavior is implementation-specific.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap, with the\nCA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds\nof resources, or a single reference that includes multiple certificates.",
"items": {
"description": "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen set to the empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mode": {
"default": "AllowValidOnly",
"description": "FrontendValidationMode defines the mode for validating the client certificate.\nThere are two possible modes:\n\n- AllowValidOnly: In this mode, the gateway will accept connections only if\n the client presents a valid certificate. This certificate must successfully\n pass validation against the CA certificates specified in `CACertificateRefs`.\n- AllowInsecureFallback: In this mode, the gateway will accept connections\n even if the client certificate is not presented or fails verification.\n\n This approach delegates client authorization to the backend and introduce\n a significant security risk. It should be used in testing environments or\n on a temporary basis in non-testing environments.\n\nDefaults to AllowValidOnly.\n\nSupport: Core",
"enum": [
"AllowValidOnly",
"AllowInsecureFallback"
],
"type": "string"
}
},
"required": [
"caCertificateRefs"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"perPort": {
"description": "PerPort specifies tls configuration assigned per port.\nPer port configuration is optional. Once set this configuration overrides\nthe default configuration for all Listeners handling HTTPS traffic\nthat match this port.\nEach override port requires a unique TLS configuration.\n\nsupport: Core",
"items": {
"properties": {
"port": {
"description": "The Port indicates the Port Number to which the TLS configuration will be\napplied. This configuration will be applied to all Listeners handling HTTPS\ntraffic that match this port.\n\nSupport: Core",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"tls": {
"description": "TLS store the configuration that will be applied to all Listeners handling\nHTTPS traffic and matching given port.\n\nSupport: Core",
"properties": {
"validation": {
"description": "Validation holds configuration information for validating the frontend (client).\nSetting this field will result in mutual authentication when connecting to the gateway.\nIn browsers this may result in a dialog appearing\nthat requests a user to specify the client certificate.\nThe maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core",
"properties": {
"caCertificateRefs": {
"description": "CACertificateRefs contains one or more references to Kubernetes\nobjects that contain a PEM-encoded TLS CA certificate bundle, which\nis used as a trust anchor to validate the certificates presented by\nthe client.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the\n referenced resource does not exist) or is misconfigured (e.g., a\n ConfigMap does not contain a key named `ca.crt`). In this case, the\n Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this\n case, the Reason on all matching HTTPS listeners must be set to\n `InvalidCACertificateKind` and the Message of the Condition must explain\n which kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace UNLESS there is a\n ReferenceGrant in the target namespace that allows the CA\n certificate to be attached. If a ReferenceGrant does not allow this\n reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n MUST be set with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the\ncertificate content (e.g., checking expiry or enforcing specific formats).\nIn such cases, an implementation-specific Reason and Message MUST be set.\n\nIn all cases, the implementation MUST ensure that the `ResolvedRefs`\ncondition is set to `status: False` on all targeted listeners (i.e.,\nlisteners serving HTTPS on a matching port). The condition MUST\ninclude a Reason and Message that indicate the cause of the error. If\nALL CACertificateRefs are invalid, the implementation MUST also ensure\nthe `Accepted` condition on the listener is set to `status: False`, with\nthe Reason `NoValidCACertificate`.\nImplementations MAY choose to support attaching multiple CA certificates\nto a listener, but this behavior is implementation-specific.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap, with the\nCA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds\nof resources, or a single reference that includes multiple certificates.",
"items": {
"description": "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen set to the empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mode": {
"default": "AllowValidOnly",
"description": "FrontendValidationMode defines the mode for validating the client certificate.\nThere are two possible modes:\n\n- AllowValidOnly: In this mode, the gateway will accept connections only if\n the client presents a valid certificate. This certificate must successfully\n pass validation against the CA certificates specified in `CACertificateRefs`.\n- AllowInsecureFallback: In this mode, the gateway will accept connections\n even if the client certificate is not presented or fails verification.\n\n This approach delegates client authorization to the backend and introduce\n a significant security risk. It should be used in testing environments or\n on a temporary basis in non-testing environments.\n\nDefaults to AllowValidOnly.\n\nSupport: Core",
"enum": [
"AllowValidOnly",
"AllowInsecureFallback"
],
"type": "string"
}
},
"required": [
"caCertificateRefs"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"port",
"tls"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-map-keys": [
"port"
],
"x-kubernetes-list-type": "map",
"x-kubernetes-validations": [
{
"message": "Port for TLS configuration must be unique within the Gateway",
"rule": "self.all(t1, self.exists_one(t2, t1.port == t2.port))"
}
]
}
},
"required": [
"default"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
} }
}, },
"required": [ "required": [
@@ -531,6 +854,11 @@
"type": "array", "type": "array",
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"attachedListenerSets": {
"description": "AttachedListenerSets represents the total number of ListenerSets that have been\nsuccessfully attached to this Gateway.\n\nA ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n- The ListenerSet is selected by the Gateway's AllowedListeners field\n- The ListenerSet has a valid ParentRef selecting the Gateway\n- The ListenerSet's status has the condition \"Accepted: true\"\n\nUses for this field include troubleshooting AttachedListenerSets attachment and\nmeasuring blast radius/impact of changes to a Gateway.",
"format": "int32",
"type": "integer"
},
"conditions": { "conditions": {
"default": [ "default": [
{ {
@@ -614,7 +942,7 @@
"description": "ListenerStatus is the status associated with a Listener.", "description": "ListenerStatus is the status associated with a Listener.",
"properties": { "properties": {
"attachedRoutes": { "attachedRoutes": {
"description": "AttachedRoutes represents the total number of Routes that have been\nsuccessfully attached to this Listener.\n\nSuccessful attachment of a Route to a Listener is based solely on the\ncombination of the AllowedRoutes field on the corresponding Listener\nand the Route's ParentRefs field. A Route is successfully attached to\na Listener when it is selected by the Listener's AllowedRoutes field\nAND the Route has a valid ParentRef selecting the whole Gateway\nresource or a specific Listener as a parent resource (more detail on\nattachment semantics can be found in the documentation on the various\nRoute kinds ParentRefs fields). Listener or Route status does not impact\nsuccessful attachment, i.e. the AttachedRoutes field count MUST be set\nfor Listeners with condition Accepted: false and MUST count successfully\nattached Routes that may themselves have Accepted: false conditions.\n\nUses for this field include troubleshooting Route attachment and\nmeasuring blast radius/impact of changes to a Listener.", "description": "AttachedRoutes represents the total number of Routes that have been\nsuccessfully attached to this Listener.\n\nSuccessful attachment of a Route to a Listener is based solely on the\ncombination of the AllowedRoutes field on the corresponding Listener\nand the Route's ParentRefs field. A Route is successfully attached to\na Listener when it is selected by the Listener's AllowedRoutes field\nAND the Route has a valid ParentRef selecting the whole Gateway\nresource or a specific Listener as a parent resource (more detail on\nattachment semantics can be found in the documentation on the various\nRoute kinds ParentRefs fields). Listener or Route status does not impact\nsuccessful attachment, i.e. the AttachedRoutes field count MUST be set\nfor Listeners, even if the Accepted condition of an individual Listener is set\nto \"False\". The AttachedRoutes number represents the number of Routes with\nthe Accepted condition set to \"True\" that have been attached to this Listener.\nRoutes with any other value for the Accepted condition MUST NOT be included\nin this count.\n\nUses for this field include troubleshooting Route attachment and\nmeasuring blast radius/impact of changes to a Listener.",
"format": "int32", "format": "int32",
"type": "integer" "type": "integer"
}, },
@@ -687,7 +1015,7 @@
"type": "string" "type": "string"
}, },
"supportedKinds": { "supportedKinds": {
"description": "SupportedKinds is the list indicating the Kinds supported by this\nlistener. This MUST represent the kinds an implementation supports for\nthat Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT\nappear in this list and an implementation MUST set the \"ResolvedRefs\"\ncondition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\nand invalid Route kinds are specified, the implementation MUST\nreference the valid Route kinds that have been specified.", "description": "SupportedKinds is the list indicating the Kinds supported by this\nlistener. This MUST represent the kinds supported by an implementation for\nthat Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT\nappear in this list and an implementation MUST set the \"ResolvedRefs\"\ncondition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\nand invalid Route kinds are specified, the implementation MUST\nreference the valid Route kinds that have been specified.",
"items": { "items": {
"description": "RouteGroupKind indicates the group and kind of a Route resource.", "description": "RouteGroupKind indicates the group and kind of a Route resource.",
"properties": { "properties": {
@@ -720,8 +1048,7 @@
"required": [ "required": [
"attachedRoutes", "attachedRoutes",
"conditions", "conditions",
"name", "name"
"supportedKinds"
], ],
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
@@ -89,6 +89,89 @@
} }
] ]
}, },
"allowedListeners": {
"description": "AllowedListeners defines which ListenerSets can be attached to this Gateway.\nThe default value is to allow no ListenerSets.",
"properties": {
"namespaces": {
"default": {
"from": "None"
},
"description": "Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\nThe default value is to allow no ListenerSets.",
"properties": {
"from": {
"default": "None",
"description": "From indicates where ListenerSets can attach to this Gateway. Possible\nvalues are:\n\n* Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n* Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n* All: ListenerSets in all namespaces may be attached to this Gateway.\n* None: Only listeners defined in the Gateway's spec are allowed\n\nThe default value None",
"enum": [
"All",
"Selector",
"Same",
"None"
],
"type": "string"
},
"selector": {
"description": "Selector must be specified when From is set to \"Selector\". In that case,\nonly ListenerSets in Namespaces matching this Selector will be selected by this\nGateway. This field is ignored for other values of \"From\".",
"properties": {
"matchExpressions": {
"description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
"items": {
"description": "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.",
"type": "string"
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.",
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"defaultScope": {
"description": "DefaultScope, when set, configures the Gateway as a default Gateway,\nmeaning it will dynamically and implicitly have Routes (e.g. HTTPRoute)\nattached to it, according to the scope configured here.\n\nIf unset (the default) or set to None, the Gateway will not act as a\ndefault Gateway; if set, the Gateway will claim any Route with a\nmatching scope set in its UseDefaultGateway field, subject to the usual\nrules about which routes the Gateway can attach to.\n\nThink carefully before using this functionality! While the normal rules\nabout which Route can apply are still enforced, it is simply easier for\nthe wrong Route to be accidentally attached to this Gateway in this\nconfiguration. If the Gateway operator is not also the operator in\ncontrol of the scope (e.g. namespace) with tight controls and checks on\nwhat kind of workloads and Routes get added in that scope, we strongly\nrecommend not using this just because it seems convenient, and instead\nstick to direct Route attachment.",
"enum": [
"All",
"None"
],
"type": "string"
},
"gatewayClassName": { "gatewayClassName": {
"description": "GatewayClassName used for this Gateway. This is the name of a\nGatewayClass resource.", "description": "GatewayClassName used for this Gateway. This is the name of a\nGatewayClass resource.",
"maxLength": 253, "maxLength": 253,
@@ -291,7 +374,7 @@
"additionalProperties": false "additionalProperties": false
}, },
"hostname": { "hostname": {
"description": "Hostname specifies the virtual hostname to match for protocol types that\ndefine this concept. When unspecified, all hostnames are matched. This\nfield is ignored for protocols that don't require hostname based\nmatching.\n\nImplementations MUST apply Hostname matching appropriately for each of\nthe following protocols:\n\n* TLS: The Listener Hostname MUST match the SNI.\n* HTTP: The Listener Hostname MUST match the Host header of the request.\n* HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n Note that this does not require the SNI and Host header to be the same.\n The semantics of this are described in more detail below.\n\nTo ensure security, Section 11.1 of RFC-6066 emphasizes that server\nimplementations that rely on SNI hostname matching MUST also verify\nhostnames within the application protocol.\n\nSection 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\nreuse of a connection by responding with the HTTP 421 Misdirected Request\nstatus code. This indicates that the origin server has rejected the\nrequest because it appears to have been misdirected.\n\nTo detect misdirected requests, Gateways SHOULD match the authority of\nthe requests with all the SNI hostname(s) configured across all the\nGateway Listeners on the same port and protocol:\n\n* If another Listener has an exact match or more specific wildcard entry,\n the Gateway SHOULD return a 421.\n* If the current Listener (selected by SNI matching during ClientHello)\n does not match the Host:\n * If another Listener does match the Host the Gateway SHOULD return a\n 421.\n * If no other Listener matches the Host, the Gateway MUST return a\n 404.\n\nFor HTTPRoute and TLSRoute resources, there is an interaction with the\n`spec.hostnames` array. When both listener and route specify hostnames,\nthere MUST be an intersection between the values for a Route to be\naccepted. For more information, refer to the Route specific Hostnames\ndocumentation.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted\nas a suffix match. That means that a match for `*.example.com` would match\nboth `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nSupport: Core", "description": "Hostname specifies the virtual hostname to match for protocol types that\ndefine this concept. When unspecified, all hostnames are matched. This\nfield is ignored for protocols that don't require hostname based\nmatching.\n\nImplementations MUST apply Hostname matching appropriately for each of\nthe following protocols:\n\n* TLS: The Listener Hostname MUST match the SNI.\n* HTTP: The Listener Hostname MUST match the Host header of the request.\n* HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n Note that this does not require the SNI and Host header to be the same.\n The semantics of this are described in more detail below.\n\nTo ensure security, Section 11.1 of RFC-6066 emphasizes that server\nimplementations that rely on SNI hostname matching MUST also verify\nhostnames within the application protocol.\n\nSection 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\nreuse of a connection by responding with the HTTP 421 Misdirected Request\nstatus code. This indicates that the origin server has rejected the\nrequest because it appears to have been misdirected.\n\nTo detect misdirected requests, Gateways SHOULD match the authority of\nthe requests with all the SNI hostname(s) configured across all the\nGateway Listeners on the same port and protocol:\n\n* If another Listener has an exact match or more specific wildcard entry,\n the Gateway SHOULD return a 421.\n* If the current Listener (selected by SNI matching during ClientHello)\n does not match the Host:\n * If another Listener does match the Host, the Gateway SHOULD return a\n 421.\n * If no other Listener matches the Host, the Gateway MUST return a\n 404.\n\nFor HTTPRoute and TLSRoute resources, there is an interaction with the\n`spec.hostnames` array. When both listener and route specify hostnames,\nthere MUST be an intersection between the values for a Route to be\naccepted. For more information, refer to the Route specific Hostnames\ndocumentation.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted\nas a suffix match. That means that a match for `*.example.com` would match\nboth `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nSupport: Core",
"maxLength": 253, "maxLength": 253,
"minLength": 1, "minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
@@ -420,6 +503,10 @@
"message": "tls mode must be Terminate for protocol HTTPS", "message": "tls mode must be Terminate for protocol HTTPS",
"rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)" "rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)"
}, },
{
"message": "tls mode must be set for protocol TLS",
"rule": "self.all(l, (l.protocol == 'TLS' ? has(l.tls) && has(l.tls.mode) && l.tls.mode != '' : true))"
},
{ {
"message": "hostname must not be specified for protocols ['TCP', 'UDP']", "message": "hostname must not be specified for protocols ['TCP', 'UDP']",
"rule": "self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)" "rule": "self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)"
@@ -433,6 +520,242 @@
"rule": "self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))" "rule": "self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
} }
] ]
},
"tls": {
"description": "TLS specifies frontend and backend tls configuration for entire gateway.\n\nSupport: Extended",
"properties": {
"backend": {
"description": "Backend describes TLS configuration for gateway when connecting\nto backends.\n\nNote that this contains only details for the Gateway as a TLS client,\nand does _not_ imply behavior about how to choose which backend should\nget a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\nSupport: Core",
"properties": {
"clientCertificateRef": {
"description": "ClientCertificateRef references an object that contains a client certificate\nand its associated private key. It can reference standard Kubernetes resources,\ni.e., Secret, or implementation-specific custom resources.\n\nA ClientCertificateRef is considered invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the referenced resource\n does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n and the Message of the Condition MUST indicate why the reference is invalid.\n\n* It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n in the target namespace that allows the certificate to be attached.\n If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the certificate\ncontent (e.g., checking expiry or enforcing specific formats). In such cases,\nan implementation-specific Reason and Message MUST be set.\n\nSupport: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\nSupport: Implementation-specific - Other resource kinds or Secrets with a\ndifferent type (e.g., `Opaque`).",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Secret",
"description": "Kind is kind of the referent. For example \"Secret\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"frontend": {
"description": "Frontend describes TLS config when client connects to Gateway.\nSupport: Core",
"properties": {
"default": {
"description": "Default specifies the default client certificate validation configuration\nfor all Listeners handling HTTPS traffic, unless a per-port configuration\nis defined.\n\nsupport: Core",
"properties": {
"validation": {
"description": "Validation holds configuration information for validating the frontend (client).\nSetting this field will result in mutual authentication when connecting to the gateway.\nIn browsers this may result in a dialog appearing\nthat requests a user to specify the client certificate.\nThe maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core",
"properties": {
"caCertificateRefs": {
"description": "CACertificateRefs contains one or more references to Kubernetes\nobjects that contain a PEM-encoded TLS CA certificate bundle, which\nis used as a trust anchor to validate the certificates presented by\nthe client.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the\n referenced resource does not exist) or is misconfigured (e.g., a\n ConfigMap does not contain a key named `ca.crt`). In this case, the\n Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this\n case, the Reason on all matching HTTPS listeners must be set to\n `InvalidCACertificateKind` and the Message of the Condition must explain\n which kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace UNLESS there is a\n ReferenceGrant in the target namespace that allows the CA\n certificate to be attached. If a ReferenceGrant does not allow this\n reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n MUST be set with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the\ncertificate content (e.g., checking expiry or enforcing specific formats).\nIn such cases, an implementation-specific Reason and Message MUST be set.\n\nIn all cases, the implementation MUST ensure that the `ResolvedRefs`\ncondition is set to `status: False` on all targeted listeners (i.e.,\nlisteners serving HTTPS on a matching port). The condition MUST\ninclude a Reason and Message that indicate the cause of the error. If\nALL CACertificateRefs are invalid, the implementation MUST also ensure\nthe `Accepted` condition on the listener is set to `status: False`, with\nthe Reason `NoValidCACertificate`.\nImplementations MAY choose to support attaching multiple CA certificates\nto a listener, but this behavior is implementation-specific.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap, with the\nCA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds\nof resources, or a single reference that includes multiple certificates.",
"items": {
"description": "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen set to the empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mode": {
"default": "AllowValidOnly",
"description": "FrontendValidationMode defines the mode for validating the client certificate.\nThere are two possible modes:\n\n- AllowValidOnly: In this mode, the gateway will accept connections only if\n the client presents a valid certificate. This certificate must successfully\n pass validation against the CA certificates specified in `CACertificateRefs`.\n- AllowInsecureFallback: In this mode, the gateway will accept connections\n even if the client certificate is not presented or fails verification.\n\n This approach delegates client authorization to the backend and introduce\n a significant security risk. It should be used in testing environments or\n on a temporary basis in non-testing environments.\n\nDefaults to AllowValidOnly.\n\nSupport: Core",
"enum": [
"AllowValidOnly",
"AllowInsecureFallback"
],
"type": "string"
}
},
"required": [
"caCertificateRefs"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"perPort": {
"description": "PerPort specifies tls configuration assigned per port.\nPer port configuration is optional. Once set this configuration overrides\nthe default configuration for all Listeners handling HTTPS traffic\nthat match this port.\nEach override port requires a unique TLS configuration.\n\nsupport: Core",
"items": {
"properties": {
"port": {
"description": "The Port indicates the Port Number to which the TLS configuration will be\napplied. This configuration will be applied to all Listeners handling HTTPS\ntraffic that match this port.\n\nSupport: Core",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"tls": {
"description": "TLS store the configuration that will be applied to all Listeners handling\nHTTPS traffic and matching given port.\n\nSupport: Core",
"properties": {
"validation": {
"description": "Validation holds configuration information for validating the frontend (client).\nSetting this field will result in mutual authentication when connecting to the gateway.\nIn browsers this may result in a dialog appearing\nthat requests a user to specify the client certificate.\nThe maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core",
"properties": {
"caCertificateRefs": {
"description": "CACertificateRefs contains one or more references to Kubernetes\nobjects that contain a PEM-encoded TLS CA certificate bundle, which\nis used as a trust anchor to validate the certificates presented by\nthe client.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the\n referenced resource does not exist) or is misconfigured (e.g., a\n ConfigMap does not contain a key named `ca.crt`). In this case, the\n Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this\n case, the Reason on all matching HTTPS listeners must be set to\n `InvalidCACertificateKind` and the Message of the Condition must explain\n which kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace UNLESS there is a\n ReferenceGrant in the target namespace that allows the CA\n certificate to be attached. If a ReferenceGrant does not allow this\n reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n MUST be set with the Reason `RefNotPermitted`.\n\nImplementations MAY choose to perform further validation of the\ncertificate content (e.g., checking expiry or enforcing specific formats).\nIn such cases, an implementation-specific Reason and Message MUST be set.\n\nIn all cases, the implementation MUST ensure that the `ResolvedRefs`\ncondition is set to `status: False` on all targeted listeners (i.e.,\nlisteners serving HTTPS on a matching port). The condition MUST\ninclude a Reason and Message that indicate the cause of the error. If\nALL CACertificateRefs are invalid, the implementation MUST also ensure\nthe `Accepted` condition on the listener is set to `status: False`, with\nthe Reason `NoValidCACertificate`.\nImplementations MAY choose to support attaching multiple CA certificates\nto a listener, but this behavior is implementation-specific.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap, with the\nCA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds\nof resources, or a single reference that includes multiple certificates.",
"items": {
"description": "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen set to the empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mode": {
"default": "AllowValidOnly",
"description": "FrontendValidationMode defines the mode for validating the client certificate.\nThere are two possible modes:\n\n- AllowValidOnly: In this mode, the gateway will accept connections only if\n the client presents a valid certificate. This certificate must successfully\n pass validation against the CA certificates specified in `CACertificateRefs`.\n- AllowInsecureFallback: In this mode, the gateway will accept connections\n even if the client certificate is not presented or fails verification.\n\n This approach delegates client authorization to the backend and introduce\n a significant security risk. It should be used in testing environments or\n on a temporary basis in non-testing environments.\n\nDefaults to AllowValidOnly.\n\nSupport: Core",
"enum": [
"AllowValidOnly",
"AllowInsecureFallback"
],
"type": "string"
}
},
"required": [
"caCertificateRefs"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"port",
"tls"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-map-keys": [
"port"
],
"x-kubernetes-list-type": "map",
"x-kubernetes-validations": [
{
"message": "Port for TLS configuration must be unique within the Gateway",
"rule": "self.all(t1, self.exists_one(t2, t1.port == t2.port))"
}
]
}
},
"required": [
"default"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
} }
}, },
"required": [ "required": [
@@ -531,6 +854,11 @@
"type": "array", "type": "array",
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"attachedListenerSets": {
"description": "AttachedListenerSets represents the total number of ListenerSets that have been\nsuccessfully attached to this Gateway.\n\nA ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n- The ListenerSet is selected by the Gateway's AllowedListeners field\n- The ListenerSet has a valid ParentRef selecting the Gateway\n- The ListenerSet's status has the condition \"Accepted: true\"\n\nUses for this field include troubleshooting AttachedListenerSets attachment and\nmeasuring blast radius/impact of changes to a Gateway.",
"format": "int32",
"type": "integer"
},
"conditions": { "conditions": {
"default": [ "default": [
{ {
@@ -614,7 +942,7 @@
"description": "ListenerStatus is the status associated with a Listener.", "description": "ListenerStatus is the status associated with a Listener.",
"properties": { "properties": {
"attachedRoutes": { "attachedRoutes": {
"description": "AttachedRoutes represents the total number of Routes that have been\nsuccessfully attached to this Listener.\n\nSuccessful attachment of a Route to a Listener is based solely on the\ncombination of the AllowedRoutes field on the corresponding Listener\nand the Route's ParentRefs field. A Route is successfully attached to\na Listener when it is selected by the Listener's AllowedRoutes field\nAND the Route has a valid ParentRef selecting the whole Gateway\nresource or a specific Listener as a parent resource (more detail on\nattachment semantics can be found in the documentation on the various\nRoute kinds ParentRefs fields). Listener or Route status does not impact\nsuccessful attachment, i.e. the AttachedRoutes field count MUST be set\nfor Listeners with condition Accepted: false and MUST count successfully\nattached Routes that may themselves have Accepted: false conditions.\n\nUses for this field include troubleshooting Route attachment and\nmeasuring blast radius/impact of changes to a Listener.", "description": "AttachedRoutes represents the total number of Routes that have been\nsuccessfully attached to this Listener.\n\nSuccessful attachment of a Route to a Listener is based solely on the\ncombination of the AllowedRoutes field on the corresponding Listener\nand the Route's ParentRefs field. A Route is successfully attached to\na Listener when it is selected by the Listener's AllowedRoutes field\nAND the Route has a valid ParentRef selecting the whole Gateway\nresource or a specific Listener as a parent resource (more detail on\nattachment semantics can be found in the documentation on the various\nRoute kinds ParentRefs fields). Listener or Route status does not impact\nsuccessful attachment, i.e. the AttachedRoutes field count MUST be set\nfor Listeners, even if the Accepted condition of an individual Listener is set\nto \"False\". The AttachedRoutes number represents the number of Routes with\nthe Accepted condition set to \"True\" that have been attached to this Listener.\nRoutes with any other value for the Accepted condition MUST NOT be included\nin this count.\n\nUses for this field include troubleshooting Route attachment and\nmeasuring blast radius/impact of changes to a Listener.",
"format": "int32", "format": "int32",
"type": "integer" "type": "integer"
}, },
@@ -687,7 +1015,7 @@
"type": "string" "type": "string"
}, },
"supportedKinds": { "supportedKinds": {
"description": "SupportedKinds is the list indicating the Kinds supported by this\nlistener. This MUST represent the kinds an implementation supports for\nthat Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT\nappear in this list and an implementation MUST set the \"ResolvedRefs\"\ncondition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\nand invalid Route kinds are specified, the implementation MUST\nreference the valid Route kinds that have been specified.", "description": "SupportedKinds is the list indicating the Kinds supported by this\nlistener. This MUST represent the kinds supported by an implementation for\nthat Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT\nappear in this list and an implementation MUST set the \"ResolvedRefs\"\ncondition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\nand invalid Route kinds are specified, the implementation MUST\nreference the valid Route kinds that have been specified.",
"items": { "items": {
"description": "RouteGroupKind indicates the group and kind of a Route resource.", "description": "RouteGroupKind indicates the group and kind of a Route resource.",
"properties": { "properties": {
@@ -720,8 +1048,7 @@
"required": [ "required": [
"attachedRoutes", "attachedRoutes",
"conditions", "conditions",
"name", "name"
"supportedKinds"
], ],
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
@@ -29,7 +29,7 @@
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"parentRefs": { "parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.", "description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": { "items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.", "description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": { "properties": {
@@ -55,14 +55,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -87,12 +87,12 @@
"x-kubernetes-list-type": "atomic", "x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{ {
"message": "sectionName must be specified when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))" "rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
}, },
{ {
"message": "sectionName must be unique when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))" "rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
} }
] ]
}, },
@@ -104,7 +104,7 @@
"backendRefs": { "backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive an `UNAVAILABLE` status.\n\nSee the GRPCBackendRef definition for the rules about what makes a single\nGRPCBackendRef invalid.\n\nWhen a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive an `UNAVAILABLE` status.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.\nImplementations may choose how that 50 percent is determined.\n\nSupport: Core for Kubernetes Service\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core", "description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive an `UNAVAILABLE` status.\n\nSee the GRPCBackendRef definition for the rules about what makes a single\nGRPCBackendRef invalid.\n\nWhen a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive an `UNAVAILABLE` status.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.\nImplementations may choose how that 50 percent is determined.\n\nSupport: Core for Kubernetes Service\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core",
"items": { "items": {
"description": "GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.", "description": "GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.",
"properties": { "properties": {
"filters": { "filters": {
"description": "Filters defined at this level MUST be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in GRPCRouteRule.)", "description": "Filters defined at this level MUST be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in GRPCRouteRule.)",
@@ -158,9 +158,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -200,9 +201,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -341,9 +343,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -383,9 +386,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -584,9 +588,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -626,9 +631,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -767,9 +773,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -809,9 +816,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -901,7 +909,7 @@
"matches": { "matches": {
"description": "Matches define conditions used for matching the rule against incoming\ngRPC requests. Each match is independent, i.e. this rule will be matched\nif **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n```\nmatches:\n- method:\n service: foo.bar\n headers:\n values:\n version: 2\n- method:\n service: foo.bar.v2\n```\n\nFor a request to match against this rule, it MUST satisfy\nEITHER of the two conditions:\n\n- service of foo.bar AND contains the header `version: 2`\n- service of foo.bar.v2\n\nSee the documentation for GRPCRouteMatch on how to specify multiple\nmatch conditions to be ANDed together.\n\nIf no matches are specified, the implementation MUST match every gRPC request.\n\nProxy or Load Balancer routing configuration generated from GRPCRoutes\nMUST prioritize rules based on the following criteria, continuing on\nties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.\nPrecedence MUST be given to the rule with the largest number of:\n\n* Characters in a matching non-wildcard hostname.\n* Characters in a matching hostname.\n* Characters in a matching service.\n* Characters in a matching method.\n* Header matches.\n\nIf ties still exist across multiple Routes, matching precedence MUST be\ndetermined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp.\n* The Route appearing first in alphabetical order by\n \"{namespace}/{name}\".\n\nIf ties still exist within the Route that has been given precedence,\nmatching precedence MUST be granted to the first matching rule meeting\nthe above criteria.", "description": "Matches define conditions used for matching the rule against incoming\ngRPC requests. Each match is independent, i.e. this rule will be matched\nif **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n```\nmatches:\n- method:\n service: foo.bar\n headers:\n values:\n version: 2\n- method:\n service: foo.bar.v2\n```\n\nFor a request to match against this rule, it MUST satisfy\nEITHER of the two conditions:\n\n- service of foo.bar AND contains the header `version: 2`\n- service of foo.bar.v2\n\nSee the documentation for GRPCRouteMatch on how to specify multiple\nmatch conditions to be ANDed together.\n\nIf no matches are specified, the implementation MUST match every gRPC request.\n\nProxy or Load Balancer routing configuration generated from GRPCRoutes\nMUST prioritize rules based on the following criteria, continuing on\nties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.\nPrecedence MUST be given to the rule with the largest number of:\n\n* Characters in a matching non-wildcard hostname.\n* Characters in a matching hostname.\n* Characters in a matching service.\n* Characters in a matching method.\n* Header matches.\n\nIf ties still exist across multiple Routes, matching precedence MUST be\ndetermined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp.\n* The Route appearing first in alphabetical order by\n \"{namespace}/{name}\".\n\nIf ties still exist within the Route that has been given precedence,\nmatching precedence MUST be granted to the first matching rule meeting\nthe above criteria.",
"items": { "items": {
"description": "GRPCRouteMatch defines the predicate used to match requests to a given\naction. Multiple match types are ANDed together, i.e. the match will\nevaluate to true only if all conditions are satisfied.\n\nFor example, the match below will match a gRPC request only if its service\nis `foo` AND it contains the `version: v1` header:\n\n```\nmatches:\n - method:\n type: Exact\n service: \"foo\"\n headers:\n - name: \"version\"\n value \"v1\"\n\n```", "description": "GRPCRouteMatch defines the predicate used to match requests to a given\naction. Multiple match types are ANDed together, i.e. the match will\nevaluate to true only if all conditions are satisfied.\n\nFor example, the match below will match a gRPC request only if its service\nis `foo` AND it contains the `version: v1` header:\n\n```\nmatches:\n - method:\n type: Exact\n service: \"foo\"\n - headers:\n name: \"version\"\n value \"v1\"\n\n```",
"properties": { "properties": {
"headers": { "headers": {
"description": "Headers specifies gRPC request header matchers. Multiple match values are\nANDed together, meaning, a request MUST match all the specified headers\nto select the route.", "description": "Headers specifies gRPC request header matchers. Multiple match values are\nANDed together, meaning, a request MUST match all the specified headers\nto select the route.",
@@ -999,6 +1007,63 @@
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string" "type": "string"
},
"sessionPersistence": {
"description": "SessionPersistence defines and configures session persistence\nfor the route rule.\n\nSupport: Extended",
"properties": {
"absoluteTimeout": {
"description": "AbsoluteTimeout defines the absolute timeout of the persistent\nsession. Once the AbsoluteTimeout duration has elapsed, the\nsession becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"cookieConfig": {
"description": "CookieConfig provides configuration settings that are specific\nto cookie-based session persistence.\n\nSupport: Core",
"properties": {
"lifetimeType": {
"default": "Session",
"description": "LifetimeType specifies whether the cookie has a permanent or\nsession-based lifetime. A permanent cookie persists until its\nspecified expiry time, defined by the Expires or Max-Age cookie\nattributes, while a session cookie is deleted when the current\nsession ends.\n\nWhen set to \"Permanent\", AbsoluteTimeout indicates the\ncookie's lifetime via the Expires or Max-Age cookie attributes\nand is required.\n\nWhen set to \"Session\", AbsoluteTimeout indicates the\nabsolute lifetime of the cookie tracked by the gateway and\nis optional.\n\nDefaults to \"Session\".\n\nSupport: Core for \"Session\" type\n\nSupport: Extended for \"Permanent\" type",
"enum": [
"Permanent",
"Session"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"idleTimeout": {
"description": "IdleTimeout defines the idle timeout of the persistent session.\nOnce the session has been idle for more than the specified\nIdleTimeout duration, the session becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"sessionName": {
"description": "SessionName defines the name of the persistent session token\nwhich may be reflected in the cookie or the header. Users\nshould avoid reusing session names to prevent unintended\nconsequences, such as rejection or unpredictable behavior.\n\nSupport: Implementation-specific",
"maxLength": 128,
"type": "string"
},
"type": {
"default": "Cookie",
"description": "Type defines the type of session persistence such as through\nthe use of a header or cookie. Defaults to cookie based session\npersistence.\n\nSupport: Core for \"Cookie\" type\n\nSupport: Extended for \"Header\" type",
"enum": [
"Cookie",
"Header"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "AbsoluteTimeout must be specified when cookie lifetimeType is Permanent",
"rule": "!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType != 'Permanent' || has(self.absoluteTimeout)"
},
{
"message": "cookieConfig can only be set with type Cookie",
"rule": "!has(self.cookieConfig) || self.type == 'Cookie'"
}
],
"additionalProperties": false
} }
}, },
"type": "object", "type": "object",
@@ -1011,8 +1076,20 @@
{ {
"message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128", "message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",
"rule": "(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size() : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size() : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size() : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size() : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size() : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size() : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size() : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size() : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size() : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size() : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size() : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size() : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size() : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size() : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128" "rule": "(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size() : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size() : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size() : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size() : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size() : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size() : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size() : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size() : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size() : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size() : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size() : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size() : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size() : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size() : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128"
},
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
} }
] ]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -1027,7 +1104,7 @@
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.", "description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": { "properties": {
"conditions": { "conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace the controller does not have access to.", "description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": { "items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.", "description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": { "properties": {
@@ -1120,14 +1197,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -29,7 +29,7 @@
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"parentRefs": { "parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.", "description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": { "items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.", "description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": { "properties": {
@@ -55,14 +55,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -87,12 +87,12 @@
"x-kubernetes-list-type": "atomic", "x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{ {
"message": "sectionName must be specified when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))" "rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
}, },
{ {
"message": "sectionName must be unique when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))" "rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
} }
] ]
}, },
@@ -116,13 +116,109 @@
"backendRefs": { "backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive a 500 status code.\n\nSee the HTTPBackendRef definition for the rules about what makes a single\nHTTPBackendRef invalid.\n\nWhen a HTTPBackendRef is invalid, 500 status codes MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive a 500 status code.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic must receive a 500. Implementations may\nchoose how that 50 percent is determined.\n\nWhen a HTTPBackendRef refers to a Service that has no ready endpoints,\nimplementations SHOULD return a 503 for requests to that backend instead.\nIf an implementation chooses to do this, all of the above rules for 500 responses\nMUST also apply for responses that return a 503.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core", "description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive a 500 status code.\n\nSee the HTTPBackendRef definition for the rules about what makes a single\nHTTPBackendRef invalid.\n\nWhen a HTTPBackendRef is invalid, 500 status codes MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive a 500 status code.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic must receive a 500. Implementations may\nchoose how that 50 percent is determined.\n\nWhen a HTTPBackendRef refers to a Service that has no ready endpoints,\nimplementations SHOULD return a 503 for requests to that backend instead.\nIf an implementation chooses to do this, all of the above rules for 500 responses\nMUST also apply for responses that return a 503.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core",
"items": { "items": {
"description": "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.", "description": "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.",
"properties": { "properties": {
"filters": { "filters": {
"description": "Filters defined at this level should be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in HTTPRouteRule.)", "description": "Filters defined at this level should be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in HTTPRouteRule.)",
"items": { "items": {
"description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.", "description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.",
"properties": { "properties": {
"cors": {
"description": "CORS defines a schema for a filter that responds to the\ncross-origin request based on HTTP response header.\n\nSupport: Extended",
"properties": {
"allowCredentials": {
"description": "AllowCredentials indicates whether the actual cross-origin request allows\nto include credentials.\n\nWhen set to true, the gateway will include the `Access-Control-Allow-Credentials`\nresponse header with value true (case-sensitive).\n\nWhen set to false or omitted the gateway will omit the header\n`Access-Control-Allow-Credentials` entirely (this is the standard CORS\nbehavior).\n\nSupport: Extended",
"type": "boolean"
},
"allowHeaders": {
"description": "AllowHeaders indicates which HTTP request headers are supported for\naccessing the requested resource.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Allow-Headers`\nresponse header are separated by a comma (\",\").\n\nWhen the `AllowHeaders` field is configured with one or more headers, the\ngateway must return the `Access-Control-Allow-Headers` response header\nwhich value is present in the `AllowHeaders` field.\n\nIf any header name in the `Access-Control-Request-Headers` request header\nis not included in the list of header names specified by the response\nheader `Access-Control-Allow-Headers`, it will present an error on the\nclient side.\n\nIf any header name in the `Access-Control-Allow-Headers` response header\ndoes not recognize by the client, it will also occur an error on the\nclient side.\n\nA wildcard indicates that the requests with all HTTP headers are allowed.\nIf config contains the wildcard \"*\" in allowHeaders and the request is\nnot credentialed, the `Access-Control-Allow-Headers` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Headers from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Headers` response header. When\nalso the `AllowCredentials` field is true and `AllowHeaders` field\nis specified with the `*` wildcard, the gateway must specify one or more\nHTTP headers in the value of the `Access-Control-Allow-Headers` response\nheader. The value of the header `Access-Control-Allow-Headers` is same as\nthe `Access-Control-Request-Headers` header provided by the client. If\nthe header `Access-Control-Request-Headers` is not included in the\nrequest, the gateway will omit the `Access-Control-Allow-Headers`\nresponse header, instead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowHeaders cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowMethods": {
"description": "AllowMethods indicates which HTTP methods are supported for accessing the\nrequested resource.\n\nValid values are any method defined by RFC9110, along with the special\nvalue `*`, which represents all HTTP methods are allowed.\n\nMethod names are case-sensitive, so these values are also case-sensitive.\n(See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\nMultiple method names in the value of the `Access-Control-Allow-Methods`\nresponse header are separated by a comma (\",\").\n\nA CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n(See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\nCORS-safelisted methods are always allowed, regardless of whether they\nare specified in the `AllowMethods` field.\n\nWhen the `AllowMethods` field is configured with one or more methods, the\ngateway must return the `Access-Control-Allow-Methods` response header\nwhich value is present in the `AllowMethods` field.\n\nIf the HTTP method of the `Access-Control-Request-Method` request header\nis not included in the list of methods specified by the response header\n`Access-Control-Allow-Methods`, it will present an error on the client\nside.\n\nIf config contains the wildcard \"*\" in allowMethods and the request is\nnot credentialed, the `Access-Control-Allow-Methods` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Method from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Methods` response header. When\nalso the `AllowCredentials` field is true and `AllowMethods` field\nspecified with the `*` wildcard, the gateway must specify one HTTP method\nin the value of the Access-Control-Allow-Methods response header. The\nvalue of the header `Access-Control-Allow-Methods` is same as the\n`Access-Control-Request-Method` header provided by the client. If the\nheader `Access-Control-Request-Method` is not included in the request,\nthe gateway will omit the `Access-Control-Allow-Methods` response header,\ninstead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH",
"*"
],
"type": "string"
},
"maxItems": 9,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowMethods cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowOrigins": {
"description": "AllowOrigins indicates whether the response can be shared with requested\nresource from the given `Origin`.\n\nThe `Origin` consists of a scheme and a host, with an optional port, and\ntakes the form `<scheme>://<host>(:<port>)`.\n\nValid values for scheme are: `http` and `https`.\n\nValid values for port are any integer between 1 and 65535 (the list of\navailable TCP/UDP ports). Note that, if not included, port `80` is\nassumed for `http` scheme origins, and port `443` is assumed for `https`\norigins. This may affect origin matching.\n\nThe host part of the origin may contain the wildcard character `*`. These\nwildcard characters behave as follows:\n\n* `*` is a greedy match to the _left_, including any number of\n DNS labels to the left of its position. This also means that\n `*` will include any number of period `.` characters to the\n left of its position.\n* A wildcard by itself matches all hosts.\n\nAn origin value that includes _only_ the `*` character indicates requests\nfrom all `Origin`s are allowed.\n\nWhen the `AllowOrigins` field is configured with multiple origins, it\nmeans the server supports clients from multiple origins. If the request\n`Origin` matches the configured allowed origins, the gateway must return\nthe given `Origin` and sets value of the header\n`Access-Control-Allow-Origin` same as the `Origin` header provided by the\nclient.\n\nThe status code of a successful response to a \"preflight\" request is\nalways an OK status (i.e., 204 or 200).\n\nIf the request `Origin` does not match the configured allowed origins,\nthe gateway returns 204/200 response but doesn't set the relevant\ncross-origin response headers. Alternatively, the gateway responds with\n403 status to the \"preflight\" request is denied, coupled with omitting\nthe CORS headers. The cross-origin request fails on the client side.\nTherefore, the client doesn't attempt the actual cross-origin request.\n\nConversely, if the request `Origin` matches one of the configured\nallowed origins, the gateway sets the response header\n`Access-Control-Allow-Origin` to the same value as the `Origin`\nheader provided by the client.\n\nWhen config has the wildcard (\"*\") in allowOrigins, and the request\nis not credentialed (e.g., it is a preflight request), the\n`Access-Control-Allow-Origin` response header either contains the\nwildcard as well or the Origin from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Origin` response header. When\nalso the `AllowCredentials` field is true and `AllowOrigins` field\nspecified with the `*` wildcard, the gateway must return a single origin\nin the value of the `Access-Control-Allow-Origin` response header,\ninstead of specifying the `*` wildcard. The value of the header\n`Access-Control-Allow-Origin` is same as the `Origin` header provided by\nthe client.\n\nSupport: Extended",
"items": {
"description": "The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\nencoding rules specified in RFC3986. The CORSOrigin MUST include both a\nscheme (\"http\" or \"https\") and a scheme-specific-part, or it should be a single '*' character.\nURIs that include an authority MUST include a fully qualified domain name or\nIP address as the host.",
"maxLength": 253,
"minLength": 1,
"pattern": "(^\\*$)|(^(http(s)?):\\/\\/(((\\*\\.)?([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9-]+|\\*)(:([0-9]{1,5}))?)$)",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowOrigins cannot contain '*' alongside other origins",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"exposeHeaders": {
"description": "ExposeHeaders indicates which HTTP response headers can be exposed\nto client-side scripts in response to a cross-origin request.\n\nA CORS-safelisted response header is an HTTP header in a CORS response\nthat it is considered safe to expose to the client scripts.\nThe CORS-safelisted response headers include the following headers:\n`Cache-Control`\n`Content-Language`\n`Content-Length`\n`Content-Type`\n`Expires`\n`Last-Modified`\n`Pragma`\n(See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\nThe CORS-safelisted response headers are exposed to client by default.\n\nWhen an HTTP header name is specified using the `ExposeHeaders` field,\nthis additional header will be exposed as part of the response to the\nclient.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Expose-Headers`\nresponse header are separated by a comma (\",\").\n\nA wildcard indicates that the responses with all HTTP headers are exposed\nto clients. The `Access-Control-Expose-Headers` response header can only\nuse `*` wildcard as value when the request is not credentialed.\n\nWhen the `exposeHeaders` config field contains the \"*\" wildcard and\nthe request is credentialed, the gateway cannot use the `*` wildcard in\nthe `Access-Control-Expose-Headers` response header.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"maxAge": {
"default": 5,
"description": "MaxAge indicates the duration (in seconds) for the client to cache the\nresults of a \"preflight\" request.\n\nThe information provided by the `Access-Control-Allow-Methods` and\n`Access-Control-Allow-Headers` response headers can be cached by the\nclient until the time specified by `Access-Control-Max-Age` elapses.\n\nThe default value of `Access-Control-Max-Age` response header is 5\n(seconds).\n\nWhen the `MaxAge` field is unspecified, the gateway sets the response\nheader \"Access-Control-Max-Age: 5\" by default.",
"format": "int32",
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"extensionRef": { "extensionRef": {
"description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific", "description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific",
"properties": { "properties": {
@@ -154,6 +250,152 @@
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
}, },
"externalAuth": {
"description": "ExternalAuth configures settings related to sending request details\nto an external auth service. The external service MUST authenticate\nthe request, and MAY authorize the request as well.\n\nIf there is any problem communicating with the external service,\nthis filter MUST fail closed.\n\nSupport: Extended",
"properties": {
"backendRef": {
"description": "BackendRef is a reference to a backend to send authorization\nrequests to.\n\nThe backend must speak the selected protocol (GRPC or HTTP) on the\nreferenced port.\n\nIf the backend service requires TLS, use BackendTLSPolicy to tell the\nimplementation to supply the TLS details to be used to connect to that\nbackend.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"forwardBody": {
"description": "ForwardBody controls if requests to the authorization server should include\nthe body of the client request; and if so, how big that body is allowed\nto be.\n\nIt is expected that implementations will buffer the request body up to\n`forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n4xx series error (413 or 403 are common examples), and fail processing\nof the filter.\n\nIf unset, or `forwardBody.maxSize` is set to `0`, then the body will not\nbe forwarded.\n\nFeature Name: HTTPRouteExternalAuthForwardBody",
"properties": {
"maxSize": {
"description": "MaxSize specifies how large in bytes the largest body that will be buffered\nand sent to the authorization server. If the body size is larger than\n`maxSize`, then the body sent to the authorization server must be\ntruncated to `maxSize` bytes.\n\nExperimental note: This behavior needs to be checked against\nvarious dataplanes; it may need to be changed.\nSee https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\nfor more.\n\nIf 0, the body will not be sent to the authorization server.",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"grpc": {
"description": "GRPCAuthConfig contains configuration for communication with ext_authz\nprotocol-speaking backends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what headers from the client request\nwill be sent to the authorization server.\n\nIf this list is empty, then all headers must be sent.\n\nIf the list has entries, only those entries must be sent.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
}
},
"type": "object",
"additionalProperties": false
},
"http": {
"description": "HTTPAuthConfig contains configuration for communication with HTTP-speaking\nbackends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what additional headers from the client request\nwill be sent to the authorization server.\n\nThe following headers must always be sent to the authorization server,\nregardless of this setting:\n\n* `Host`\n* `Method`\n* `Path`\n* `Content-Length`\n* `Authorization`\n\nIf this list is empty, then only those headers must be sent.\n\nNote that `Content-Length` has a special behavior, in that the length\nsent must be correct for the actual request to the external authorization\nserver - that is, it must reflect the actual number of bytes sent in the\nbody of the request to the authorization server.\n\nSo if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\nto `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\nto anything other than `0`, then the `Content-Length` of the authorization\nrequest must be set to the actual number of bytes forwarded.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"allowedResponseHeaders": {
"description": "AllowedResponseHeaders specifies what headers from the authorization response\nwill be copied into the request to the backend.\n\nIf this list is empty, then all headers from the authorization server\nexcept Authority or Host must be copied.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"path": {
"description": "Path sets the prefix that paths from the client request will have added\nwhen forwarded to the authorization server.\n\nWhen empty or unspecified, no prefix is added.\n\nValid values are the same as the \"value\" regex for path values in the `match`\nstanza, and the validation regex will screen out invalid paths in the same way.\nEven with the validation, implementations MUST sanitize this input before using it\ndirectly.",
"maxLength": 1024,
"pattern": "^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"protocol": {
"description": "ExternalAuthProtocol describes which protocol to use when communicating with an\next_authz authorization server.\n\nWhen this is set to GRPC, each backend must use the Envoy ext_authz protocol\non the port specified in `backendRefs`. Requests and responses are defined\nin the protobufs explained at:\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\nWhen this is set to HTTP, each backend must respond with a `200` status\ncode in on a successful authorization. Any other code is considered\nan authorization failure.\n\nFeature Names:\nGRPC Support - HTTPRouteExternalAuthGRPC\nHTTP Support - HTTPRouteExternalAuthHTTP",
"enum": [
"HTTP",
"GRPC"
],
"type": "string"
}
},
"required": [
"backendRef",
"protocol"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "grpc must be specified when protocol is set to 'GRPC'",
"rule": "self.protocol == 'GRPC' ? has(self.grpc) : true"
},
{
"message": "protocol must be 'GRPC' when grpc is set",
"rule": "has(self.grpc) ? self.protocol == 'GRPC' : true"
},
{
"message": "http must be specified when protocol is set to 'HTTP'",
"rule": "self.protocol == 'HTTP' ? has(self.http) : true"
},
{
"message": "protocol must be 'HTTP' when http is set",
"rule": "has(self.http) ? self.protocol == 'HTTP' : true"
}
],
"additionalProperties": false
},
"requestHeaderModifier": { "requestHeaderModifier": {
"description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core", "description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core",
"properties": { "properties": {
@@ -170,9 +412,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -212,9 +455,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -413,7 +657,10 @@
"description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core", "description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core",
"enum": [ "enum": [
301, 301,
302 302,
303,
307,
308
], ],
"type": "integer" "type": "integer"
} }
@@ -437,9 +684,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -479,9 +727,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -511,7 +760,9 @@
"RequestMirror", "RequestMirror",
"RequestRedirect", "RequestRedirect",
"URLRewrite", "URLRewrite",
"ExtensionRef" "ExtensionRef",
"CORS",
"ExternalAuth"
], ],
"type": "string" "type": "string"
}, },
@@ -581,6 +832,14 @@
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{
"message": "filter.cors must be nil if the filter.type is not CORS",
"rule": "!(has(self.cors) && self.type != 'CORS')"
},
{
"message": "filter.cors must be specified for CORS filter.type",
"rule": "!(!has(self.cors) && self.type == 'CORS')"
},
{ {
"message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier", "message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier",
"rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')" "rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')"
@@ -628,6 +887,14 @@
{ {
"message": "filter.extensionRef must be specified for ExtensionRef filter.type", "message": "filter.extensionRef must be specified for ExtensionRef filter.type",
"rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')" "rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')"
},
{
"message": "filter.externalAuth must be nil if the filter.type is not ExternalAuth",
"rule": "!(has(self.externalAuth) && self.type != 'ExternalAuth')"
},
{
"message": "filter.externalAuth must be specified for ExternalAuth filter.type",
"rule": "!(!has(self.externalAuth) && self.type == 'ExternalAuth')"
} }
], ],
"additionalProperties": false "additionalProperties": false
@@ -640,6 +907,10 @@
"message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both", "message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",
"rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))" "rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
}, },
{
"message": "CORS filter cannot be repeated",
"rule": "self.filter(f, f.type == 'CORS').size() <= 1"
},
{ {
"message": "RequestHeaderModifier filter cannot be repeated", "message": "RequestHeaderModifier filter cannot be repeated",
"rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1" "rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
@@ -723,6 +994,102 @@
"items": { "items": {
"description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.", "description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.",
"properties": { "properties": {
"cors": {
"description": "CORS defines a schema for a filter that responds to the\ncross-origin request based on HTTP response header.\n\nSupport: Extended",
"properties": {
"allowCredentials": {
"description": "AllowCredentials indicates whether the actual cross-origin request allows\nto include credentials.\n\nWhen set to true, the gateway will include the `Access-Control-Allow-Credentials`\nresponse header with value true (case-sensitive).\n\nWhen set to false or omitted the gateway will omit the header\n`Access-Control-Allow-Credentials` entirely (this is the standard CORS\nbehavior).\n\nSupport: Extended",
"type": "boolean"
},
"allowHeaders": {
"description": "AllowHeaders indicates which HTTP request headers are supported for\naccessing the requested resource.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Allow-Headers`\nresponse header are separated by a comma (\",\").\n\nWhen the `AllowHeaders` field is configured with one or more headers, the\ngateway must return the `Access-Control-Allow-Headers` response header\nwhich value is present in the `AllowHeaders` field.\n\nIf any header name in the `Access-Control-Request-Headers` request header\nis not included in the list of header names specified by the response\nheader `Access-Control-Allow-Headers`, it will present an error on the\nclient side.\n\nIf any header name in the `Access-Control-Allow-Headers` response header\ndoes not recognize by the client, it will also occur an error on the\nclient side.\n\nA wildcard indicates that the requests with all HTTP headers are allowed.\nIf config contains the wildcard \"*\" in allowHeaders and the request is\nnot credentialed, the `Access-Control-Allow-Headers` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Headers from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Headers` response header. When\nalso the `AllowCredentials` field is true and `AllowHeaders` field\nis specified with the `*` wildcard, the gateway must specify one or more\nHTTP headers in the value of the `Access-Control-Allow-Headers` response\nheader. The value of the header `Access-Control-Allow-Headers` is same as\nthe `Access-Control-Request-Headers` header provided by the client. If\nthe header `Access-Control-Request-Headers` is not included in the\nrequest, the gateway will omit the `Access-Control-Allow-Headers`\nresponse header, instead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowHeaders cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowMethods": {
"description": "AllowMethods indicates which HTTP methods are supported for accessing the\nrequested resource.\n\nValid values are any method defined by RFC9110, along with the special\nvalue `*`, which represents all HTTP methods are allowed.\n\nMethod names are case-sensitive, so these values are also case-sensitive.\n(See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\nMultiple method names in the value of the `Access-Control-Allow-Methods`\nresponse header are separated by a comma (\",\").\n\nA CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n(See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\nCORS-safelisted methods are always allowed, regardless of whether they\nare specified in the `AllowMethods` field.\n\nWhen the `AllowMethods` field is configured with one or more methods, the\ngateway must return the `Access-Control-Allow-Methods` response header\nwhich value is present in the `AllowMethods` field.\n\nIf the HTTP method of the `Access-Control-Request-Method` request header\nis not included in the list of methods specified by the response header\n`Access-Control-Allow-Methods`, it will present an error on the client\nside.\n\nIf config contains the wildcard \"*\" in allowMethods and the request is\nnot credentialed, the `Access-Control-Allow-Methods` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Method from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Methods` response header. When\nalso the `AllowCredentials` field is true and `AllowMethods` field\nspecified with the `*` wildcard, the gateway must specify one HTTP method\nin the value of the Access-Control-Allow-Methods response header. The\nvalue of the header `Access-Control-Allow-Methods` is same as the\n`Access-Control-Request-Method` header provided by the client. If the\nheader `Access-Control-Request-Method` is not included in the request,\nthe gateway will omit the `Access-Control-Allow-Methods` response header,\ninstead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH",
"*"
],
"type": "string"
},
"maxItems": 9,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowMethods cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowOrigins": {
"description": "AllowOrigins indicates whether the response can be shared with requested\nresource from the given `Origin`.\n\nThe `Origin` consists of a scheme and a host, with an optional port, and\ntakes the form `<scheme>://<host>(:<port>)`.\n\nValid values for scheme are: `http` and `https`.\n\nValid values for port are any integer between 1 and 65535 (the list of\navailable TCP/UDP ports). Note that, if not included, port `80` is\nassumed for `http` scheme origins, and port `443` is assumed for `https`\norigins. This may affect origin matching.\n\nThe host part of the origin may contain the wildcard character `*`. These\nwildcard characters behave as follows:\n\n* `*` is a greedy match to the _left_, including any number of\n DNS labels to the left of its position. This also means that\n `*` will include any number of period `.` characters to the\n left of its position.\n* A wildcard by itself matches all hosts.\n\nAn origin value that includes _only_ the `*` character indicates requests\nfrom all `Origin`s are allowed.\n\nWhen the `AllowOrigins` field is configured with multiple origins, it\nmeans the server supports clients from multiple origins. If the request\n`Origin` matches the configured allowed origins, the gateway must return\nthe given `Origin` and sets value of the header\n`Access-Control-Allow-Origin` same as the `Origin` header provided by the\nclient.\n\nThe status code of a successful response to a \"preflight\" request is\nalways an OK status (i.e., 204 or 200).\n\nIf the request `Origin` does not match the configured allowed origins,\nthe gateway returns 204/200 response but doesn't set the relevant\ncross-origin response headers. Alternatively, the gateway responds with\n403 status to the \"preflight\" request is denied, coupled with omitting\nthe CORS headers. The cross-origin request fails on the client side.\nTherefore, the client doesn't attempt the actual cross-origin request.\n\nConversely, if the request `Origin` matches one of the configured\nallowed origins, the gateway sets the response header\n`Access-Control-Allow-Origin` to the same value as the `Origin`\nheader provided by the client.\n\nWhen config has the wildcard (\"*\") in allowOrigins, and the request\nis not credentialed (e.g., it is a preflight request), the\n`Access-Control-Allow-Origin` response header either contains the\nwildcard as well or the Origin from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Origin` response header. When\nalso the `AllowCredentials` field is true and `AllowOrigins` field\nspecified with the `*` wildcard, the gateway must return a single origin\nin the value of the `Access-Control-Allow-Origin` response header,\ninstead of specifying the `*` wildcard. The value of the header\n`Access-Control-Allow-Origin` is same as the `Origin` header provided by\nthe client.\n\nSupport: Extended",
"items": {
"description": "The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\nencoding rules specified in RFC3986. The CORSOrigin MUST include both a\nscheme (\"http\" or \"https\") and a scheme-specific-part, or it should be a single '*' character.\nURIs that include an authority MUST include a fully qualified domain name or\nIP address as the host.",
"maxLength": 253,
"minLength": 1,
"pattern": "(^\\*$)|(^(http(s)?):\\/\\/(((\\*\\.)?([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9-]+|\\*)(:([0-9]{1,5}))?)$)",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowOrigins cannot contain '*' alongside other origins",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"exposeHeaders": {
"description": "ExposeHeaders indicates which HTTP response headers can be exposed\nto client-side scripts in response to a cross-origin request.\n\nA CORS-safelisted response header is an HTTP header in a CORS response\nthat it is considered safe to expose to the client scripts.\nThe CORS-safelisted response headers include the following headers:\n`Cache-Control`\n`Content-Language`\n`Content-Length`\n`Content-Type`\n`Expires`\n`Last-Modified`\n`Pragma`\n(See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\nThe CORS-safelisted response headers are exposed to client by default.\n\nWhen an HTTP header name is specified using the `ExposeHeaders` field,\nthis additional header will be exposed as part of the response to the\nclient.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Expose-Headers`\nresponse header are separated by a comma (\",\").\n\nA wildcard indicates that the responses with all HTTP headers are exposed\nto clients. The `Access-Control-Expose-Headers` response header can only\nuse `*` wildcard as value when the request is not credentialed.\n\nWhen the `exposeHeaders` config field contains the \"*\" wildcard and\nthe request is credentialed, the gateway cannot use the `*` wildcard in\nthe `Access-Control-Expose-Headers` response header.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"maxAge": {
"default": 5,
"description": "MaxAge indicates the duration (in seconds) for the client to cache the\nresults of a \"preflight\" request.\n\nThe information provided by the `Access-Control-Allow-Methods` and\n`Access-Control-Allow-Headers` response headers can be cached by the\nclient until the time specified by `Access-Control-Max-Age` elapses.\n\nThe default value of `Access-Control-Max-Age` response header is 5\n(seconds).\n\nWhen the `MaxAge` field is unspecified, the gateway sets the response\nheader \"Access-Control-Max-Age: 5\" by default.",
"format": "int32",
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"extensionRef": { "extensionRef": {
"description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific", "description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific",
"properties": { "properties": {
@@ -754,6 +1121,152 @@
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
}, },
"externalAuth": {
"description": "ExternalAuth configures settings related to sending request details\nto an external auth service. The external service MUST authenticate\nthe request, and MAY authorize the request as well.\n\nIf there is any problem communicating with the external service,\nthis filter MUST fail closed.\n\nSupport: Extended",
"properties": {
"backendRef": {
"description": "BackendRef is a reference to a backend to send authorization\nrequests to.\n\nThe backend must speak the selected protocol (GRPC or HTTP) on the\nreferenced port.\n\nIf the backend service requires TLS, use BackendTLSPolicy to tell the\nimplementation to supply the TLS details to be used to connect to that\nbackend.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"forwardBody": {
"description": "ForwardBody controls if requests to the authorization server should include\nthe body of the client request; and if so, how big that body is allowed\nto be.\n\nIt is expected that implementations will buffer the request body up to\n`forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n4xx series error (413 or 403 are common examples), and fail processing\nof the filter.\n\nIf unset, or `forwardBody.maxSize` is set to `0`, then the body will not\nbe forwarded.\n\nFeature Name: HTTPRouteExternalAuthForwardBody",
"properties": {
"maxSize": {
"description": "MaxSize specifies how large in bytes the largest body that will be buffered\nand sent to the authorization server. If the body size is larger than\n`maxSize`, then the body sent to the authorization server must be\ntruncated to `maxSize` bytes.\n\nExperimental note: This behavior needs to be checked against\nvarious dataplanes; it may need to be changed.\nSee https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\nfor more.\n\nIf 0, the body will not be sent to the authorization server.",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"grpc": {
"description": "GRPCAuthConfig contains configuration for communication with ext_authz\nprotocol-speaking backends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what headers from the client request\nwill be sent to the authorization server.\n\nIf this list is empty, then all headers must be sent.\n\nIf the list has entries, only those entries must be sent.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
}
},
"type": "object",
"additionalProperties": false
},
"http": {
"description": "HTTPAuthConfig contains configuration for communication with HTTP-speaking\nbackends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what additional headers from the client request\nwill be sent to the authorization server.\n\nThe following headers must always be sent to the authorization server,\nregardless of this setting:\n\n* `Host`\n* `Method`\n* `Path`\n* `Content-Length`\n* `Authorization`\n\nIf this list is empty, then only those headers must be sent.\n\nNote that `Content-Length` has a special behavior, in that the length\nsent must be correct for the actual request to the external authorization\nserver - that is, it must reflect the actual number of bytes sent in the\nbody of the request to the authorization server.\n\nSo if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\nto `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\nto anything other than `0`, then the `Content-Length` of the authorization\nrequest must be set to the actual number of bytes forwarded.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"allowedResponseHeaders": {
"description": "AllowedResponseHeaders specifies what headers from the authorization response\nwill be copied into the request to the backend.\n\nIf this list is empty, then all headers from the authorization server\nexcept Authority or Host must be copied.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"path": {
"description": "Path sets the prefix that paths from the client request will have added\nwhen forwarded to the authorization server.\n\nWhen empty or unspecified, no prefix is added.\n\nValid values are the same as the \"value\" regex for path values in the `match`\nstanza, and the validation regex will screen out invalid paths in the same way.\nEven with the validation, implementations MUST sanitize this input before using it\ndirectly.",
"maxLength": 1024,
"pattern": "^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"protocol": {
"description": "ExternalAuthProtocol describes which protocol to use when communicating with an\next_authz authorization server.\n\nWhen this is set to GRPC, each backend must use the Envoy ext_authz protocol\non the port specified in `backendRefs`. Requests and responses are defined\nin the protobufs explained at:\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\nWhen this is set to HTTP, each backend must respond with a `200` status\ncode in on a successful authorization. Any other code is considered\nan authorization failure.\n\nFeature Names:\nGRPC Support - HTTPRouteExternalAuthGRPC\nHTTP Support - HTTPRouteExternalAuthHTTP",
"enum": [
"HTTP",
"GRPC"
],
"type": "string"
}
},
"required": [
"backendRef",
"protocol"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "grpc must be specified when protocol is set to 'GRPC'",
"rule": "self.protocol == 'GRPC' ? has(self.grpc) : true"
},
{
"message": "protocol must be 'GRPC' when grpc is set",
"rule": "has(self.grpc) ? self.protocol == 'GRPC' : true"
},
{
"message": "http must be specified when protocol is set to 'HTTP'",
"rule": "self.protocol == 'HTTP' ? has(self.http) : true"
},
{
"message": "protocol must be 'HTTP' when http is set",
"rule": "has(self.http) ? self.protocol == 'HTTP' : true"
}
],
"additionalProperties": false
},
"requestHeaderModifier": { "requestHeaderModifier": {
"description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core", "description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core",
"properties": { "properties": {
@@ -770,9 +1283,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -812,9 +1326,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1013,7 +1528,10 @@
"description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core", "description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core",
"enum": [ "enum": [
301, 301,
302 302,
303,
307,
308
], ],
"type": "integer" "type": "integer"
} }
@@ -1037,9 +1555,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1079,9 +1598,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1111,7 +1631,9 @@
"RequestMirror", "RequestMirror",
"RequestRedirect", "RequestRedirect",
"URLRewrite", "URLRewrite",
"ExtensionRef" "ExtensionRef",
"CORS",
"ExternalAuth"
], ],
"type": "string" "type": "string"
}, },
@@ -1181,6 +1703,14 @@
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{
"message": "filter.cors must be nil if the filter.type is not CORS",
"rule": "!(has(self.cors) && self.type != 'CORS')"
},
{
"message": "filter.cors must be specified for CORS filter.type",
"rule": "!(!has(self.cors) && self.type == 'CORS')"
},
{ {
"message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier", "message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier",
"rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')" "rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')"
@@ -1228,6 +1758,14 @@
{ {
"message": "filter.extensionRef must be specified for ExtensionRef filter.type", "message": "filter.extensionRef must be specified for ExtensionRef filter.type",
"rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')" "rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')"
},
{
"message": "filter.externalAuth must be nil if the filter.type is not ExternalAuth",
"rule": "!(has(self.externalAuth) && self.type != 'ExternalAuth')"
},
{
"message": "filter.externalAuth must be specified for ExternalAuth filter.type",
"rule": "!(!has(self.externalAuth) && self.type == 'ExternalAuth')"
} }
], ],
"additionalProperties": false "additionalProperties": false
@@ -1240,6 +1778,10 @@
"message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both", "message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",
"rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))" "rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
}, },
{
"message": "CORS filter cannot be repeated",
"rule": "self.filter(f, f.type == 'CORS').size() <= 1"
},
{ {
"message": "RequestHeaderModifier filter cannot be repeated", "message": "RequestHeaderModifier filter cannot be repeated",
"rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1" "rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
@@ -1293,9 +1835,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1458,6 +2001,90 @@
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string" "type": "string"
}, },
"retry": {
"description": "Retry defines the configuration for when to retry an HTTP request.\n\nSupport: Extended",
"properties": {
"attempts": {
"description": "Attempts specifies the maximum number of times an individual request\nfrom the gateway to a backend should be retried.\n\nIf the maximum number of retries has been attempted without a successful\nresponse from the backend, the Gateway MUST return an error.\n\nWhen this field is unspecified, the number of times to attempt to retry\na backend request is implementation-specific.\n\nSupport: Extended",
"type": "integer"
},
"backoff": {
"description": "Backoff specifies the minimum duration a Gateway should wait between\nretry attempts and is represented in Gateway API Duration formatting.\n\nFor example, setting the `rules[].retry.backoff` field to the value\n`100ms` will cause a backend request to first be retried approximately\n100 milliseconds after timing out or receiving a response code configured\nto be retriable.\n\nAn implementation MAY use an exponential or alternative backoff strategy\nfor subsequent retry attempts, MAY cap the maximum backoff duration to\nsome amount greater than the specified minimum, and MAY add arbitrary\njitter to stagger requests, as long as unsuccessful backend requests are\nnot retried before the configured minimum duration.\n\nIf a Request timeout (`rules[].timeouts.request`) is configured on the\nroute, the entire duration of the initial request and any retry attempts\nMUST not exceed the Request timeout duration. If any retry attempts are\nstill in progress when the Request timeout duration has been reached,\nthese SHOULD be canceled if possible and the Gateway MUST immediately\nreturn a timeout error.\n\nIf a BackendRequest timeout (`rules[].timeouts.backendRequest`) is\nconfigured on the route, any retry attempts which reach the configured\nBackendRequest timeout duration without a response SHOULD be canceled if\npossible and the Gateway should wait for at least the specified backoff\nduration before attempting to retry the backend request again.\n\nIf a BackendRequest timeout is _not_ configured on the route, retry\nattempts MAY time out after an implementation default duration, or MAY\nremain pending until a configured Request timeout or implementation\ndefault duration for total request time is reached.\n\nWhen this field is unspecified, the time to wait between retry attempts\nis implementation-specific.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"codes": {
"description": "Codes defines the HTTP response status codes for which a backend request\nshould be retried.\n\nSupport: Extended",
"items": {
"description": "HTTPRouteRetryStatusCode defines an HTTP response status code for\nwhich a backend request should be retried.\n\nImplementations MUST support the following status codes as retriable:\n\n* 500\n* 502\n* 503\n* 504\n\nImplementations MAY support specifying additional discrete values in the\n500-599 range.\n\nImplementations MAY support specifying discrete values in the 400-499 range,\nwhich are often inadvisable to retry.",
"maximum": 599,
"minimum": 400,
"type": "integer"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object",
"additionalProperties": false
},
"sessionPersistence": {
"description": "SessionPersistence defines and configures session persistence\nfor the route rule.\n\nSupport: Extended",
"properties": {
"absoluteTimeout": {
"description": "AbsoluteTimeout defines the absolute timeout of the persistent\nsession. Once the AbsoluteTimeout duration has elapsed, the\nsession becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"cookieConfig": {
"description": "CookieConfig provides configuration settings that are specific\nto cookie-based session persistence.\n\nSupport: Core",
"properties": {
"lifetimeType": {
"default": "Session",
"description": "LifetimeType specifies whether the cookie has a permanent or\nsession-based lifetime. A permanent cookie persists until its\nspecified expiry time, defined by the Expires or Max-Age cookie\nattributes, while a session cookie is deleted when the current\nsession ends.\n\nWhen set to \"Permanent\", AbsoluteTimeout indicates the\ncookie's lifetime via the Expires or Max-Age cookie attributes\nand is required.\n\nWhen set to \"Session\", AbsoluteTimeout indicates the\nabsolute lifetime of the cookie tracked by the gateway and\nis optional.\n\nDefaults to \"Session\".\n\nSupport: Core for \"Session\" type\n\nSupport: Extended for \"Permanent\" type",
"enum": [
"Permanent",
"Session"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"idleTimeout": {
"description": "IdleTimeout defines the idle timeout of the persistent session.\nOnce the session has been idle for more than the specified\nIdleTimeout duration, the session becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"sessionName": {
"description": "SessionName defines the name of the persistent session token\nwhich may be reflected in the cookie or the header. Users\nshould avoid reusing session names to prevent unintended\nconsequences, such as rejection or unpredictable behavior.\n\nSupport: Implementation-specific",
"maxLength": 128,
"type": "string"
},
"type": {
"default": "Cookie",
"description": "Type defines the type of session persistence such as through\nthe use of a header or cookie. Defaults to cookie based session\npersistence.\n\nSupport: Core for \"Cookie\" type\n\nSupport: Extended for \"Header\" type",
"enum": [
"Cookie",
"Header"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "AbsoluteTimeout must be specified when cookie lifetimeType is Permanent",
"rule": "!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType != 'Permanent' || has(self.absoluteTimeout)"
},
{
"message": "cookieConfig can only be set with type Cookie",
"rule": "!has(self.cookieConfig) || self.type == 'Cookie'"
}
],
"additionalProperties": false
},
"timeouts": { "timeouts": {
"description": "Timeouts defines the timeouts that can be configured for an HTTP request.\n\nSupport: Extended", "description": "Timeouts defines the timeouts that can be configured for an HTTP request.\n\nSupport: Extended",
"properties": { "properties": {
@@ -1508,14 +2135,27 @@
"additionalProperties": false "additionalProperties": false
}, },
"maxItems": 16, "maxItems": 16,
"minItems": 1,
"type": "array", "type": "array",
"x-kubernetes-list-type": "atomic", "x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{ {
"message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128", "message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",
"rule": "(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128" "rule": "(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128"
},
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
} }
] ]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -1530,7 +2170,7 @@
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.", "description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": { "properties": {
"conditions": { "conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace the controller does not have access to.", "description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": { "items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.", "description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": { "properties": {
@@ -1623,14 +2263,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -29,7 +29,7 @@
"x-kubernetes-list-type": "atomic" "x-kubernetes-list-type": "atomic"
}, },
"parentRefs": { "parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.", "description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": { "items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.", "description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": { "properties": {
@@ -55,14 +55,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -87,12 +87,12 @@
"x-kubernetes-list-type": "atomic", "x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{ {
"message": "sectionName must be specified when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))" "rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
}, },
{ {
"message": "sectionName must be unique when parentRefs includes 2 or more references to the same parent", "message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))" "rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
} }
] ]
}, },
@@ -116,13 +116,109 @@
"backendRefs": { "backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive a 500 status code.\n\nSee the HTTPBackendRef definition for the rules about what makes a single\nHTTPBackendRef invalid.\n\nWhen a HTTPBackendRef is invalid, 500 status codes MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive a 500 status code.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic must receive a 500. Implementations may\nchoose how that 50 percent is determined.\n\nWhen a HTTPBackendRef refers to a Service that has no ready endpoints,\nimplementations SHOULD return a 503 for requests to that backend instead.\nIf an implementation chooses to do this, all of the above rules for 500 responses\nMUST also apply for responses that return a 503.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core", "description": "BackendRefs defines the backend(s) where matching requests should be\nsent.\n\nFailure behavior here depends on how many BackendRefs are specified and\nhow many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters\nspecified in this route rule, *all* traffic which matches this rule MUST\nreceive a 500 status code.\n\nSee the HTTPBackendRef definition for the rules about what makes a single\nHTTPBackendRef invalid.\n\nWhen a HTTPBackendRef is invalid, 500 status codes MUST be returned for\nrequests that would have otherwise been routed to an invalid backend. If\nmultiple backends are specified, and some are invalid, the proportion of\nrequests that would otherwise have been routed to an invalid backend\nMUST receive a 500 status code.\n\nFor example, if two backends are specified with equal weights, and one is\ninvalid, 50 percent of traffic must receive a 500. Implementations may\nchoose how that 50 percent is determined.\n\nWhen a HTTPBackendRef refers to a Service that has no ready endpoints,\nimplementations SHOULD return a 503 for requests to that backend instead.\nIf an implementation chooses to do this, all of the above rules for 500 responses\nMUST also apply for responses that return a 503.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core",
"items": { "items": {
"description": "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.", "description": "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.",
"properties": { "properties": {
"filters": { "filters": {
"description": "Filters defined at this level should be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in HTTPRouteRule.)", "description": "Filters defined at this level should be executed if and only if the\nrequest is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the\nFilters field in HTTPRouteRule.)",
"items": { "items": {
"description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.", "description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.",
"properties": { "properties": {
"cors": {
"description": "CORS defines a schema for a filter that responds to the\ncross-origin request based on HTTP response header.\n\nSupport: Extended",
"properties": {
"allowCredentials": {
"description": "AllowCredentials indicates whether the actual cross-origin request allows\nto include credentials.\n\nWhen set to true, the gateway will include the `Access-Control-Allow-Credentials`\nresponse header with value true (case-sensitive).\n\nWhen set to false or omitted the gateway will omit the header\n`Access-Control-Allow-Credentials` entirely (this is the standard CORS\nbehavior).\n\nSupport: Extended",
"type": "boolean"
},
"allowHeaders": {
"description": "AllowHeaders indicates which HTTP request headers are supported for\naccessing the requested resource.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Allow-Headers`\nresponse header are separated by a comma (\",\").\n\nWhen the `AllowHeaders` field is configured with one or more headers, the\ngateway must return the `Access-Control-Allow-Headers` response header\nwhich value is present in the `AllowHeaders` field.\n\nIf any header name in the `Access-Control-Request-Headers` request header\nis not included in the list of header names specified by the response\nheader `Access-Control-Allow-Headers`, it will present an error on the\nclient side.\n\nIf any header name in the `Access-Control-Allow-Headers` response header\ndoes not recognize by the client, it will also occur an error on the\nclient side.\n\nA wildcard indicates that the requests with all HTTP headers are allowed.\nIf config contains the wildcard \"*\" in allowHeaders and the request is\nnot credentialed, the `Access-Control-Allow-Headers` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Headers from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Headers` response header. When\nalso the `AllowCredentials` field is true and `AllowHeaders` field\nis specified with the `*` wildcard, the gateway must specify one or more\nHTTP headers in the value of the `Access-Control-Allow-Headers` response\nheader. The value of the header `Access-Control-Allow-Headers` is same as\nthe `Access-Control-Request-Headers` header provided by the client. If\nthe header `Access-Control-Request-Headers` is not included in the\nrequest, the gateway will omit the `Access-Control-Allow-Headers`\nresponse header, instead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowHeaders cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowMethods": {
"description": "AllowMethods indicates which HTTP methods are supported for accessing the\nrequested resource.\n\nValid values are any method defined by RFC9110, along with the special\nvalue `*`, which represents all HTTP methods are allowed.\n\nMethod names are case-sensitive, so these values are also case-sensitive.\n(See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\nMultiple method names in the value of the `Access-Control-Allow-Methods`\nresponse header are separated by a comma (\",\").\n\nA CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n(See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\nCORS-safelisted methods are always allowed, regardless of whether they\nare specified in the `AllowMethods` field.\n\nWhen the `AllowMethods` field is configured with one or more methods, the\ngateway must return the `Access-Control-Allow-Methods` response header\nwhich value is present in the `AllowMethods` field.\n\nIf the HTTP method of the `Access-Control-Request-Method` request header\nis not included in the list of methods specified by the response header\n`Access-Control-Allow-Methods`, it will present an error on the client\nside.\n\nIf config contains the wildcard \"*\" in allowMethods and the request is\nnot credentialed, the `Access-Control-Allow-Methods` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Method from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Methods` response header. When\nalso the `AllowCredentials` field is true and `AllowMethods` field\nspecified with the `*` wildcard, the gateway must specify one HTTP method\nin the value of the Access-Control-Allow-Methods response header. The\nvalue of the header `Access-Control-Allow-Methods` is same as the\n`Access-Control-Request-Method` header provided by the client. If the\nheader `Access-Control-Request-Method` is not included in the request,\nthe gateway will omit the `Access-Control-Allow-Methods` response header,\ninstead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH",
"*"
],
"type": "string"
},
"maxItems": 9,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowMethods cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowOrigins": {
"description": "AllowOrigins indicates whether the response can be shared with requested\nresource from the given `Origin`.\n\nThe `Origin` consists of a scheme and a host, with an optional port, and\ntakes the form `<scheme>://<host>(:<port>)`.\n\nValid values for scheme are: `http` and `https`.\n\nValid values for port are any integer between 1 and 65535 (the list of\navailable TCP/UDP ports). Note that, if not included, port `80` is\nassumed for `http` scheme origins, and port `443` is assumed for `https`\norigins. This may affect origin matching.\n\nThe host part of the origin may contain the wildcard character `*`. These\nwildcard characters behave as follows:\n\n* `*` is a greedy match to the _left_, including any number of\n DNS labels to the left of its position. This also means that\n `*` will include any number of period `.` characters to the\n left of its position.\n* A wildcard by itself matches all hosts.\n\nAn origin value that includes _only_ the `*` character indicates requests\nfrom all `Origin`s are allowed.\n\nWhen the `AllowOrigins` field is configured with multiple origins, it\nmeans the server supports clients from multiple origins. If the request\n`Origin` matches the configured allowed origins, the gateway must return\nthe given `Origin` and sets value of the header\n`Access-Control-Allow-Origin` same as the `Origin` header provided by the\nclient.\n\nThe status code of a successful response to a \"preflight\" request is\nalways an OK status (i.e., 204 or 200).\n\nIf the request `Origin` does not match the configured allowed origins,\nthe gateway returns 204/200 response but doesn't set the relevant\ncross-origin response headers. Alternatively, the gateway responds with\n403 status to the \"preflight\" request is denied, coupled with omitting\nthe CORS headers. The cross-origin request fails on the client side.\nTherefore, the client doesn't attempt the actual cross-origin request.\n\nConversely, if the request `Origin` matches one of the configured\nallowed origins, the gateway sets the response header\n`Access-Control-Allow-Origin` to the same value as the `Origin`\nheader provided by the client.\n\nWhen config has the wildcard (\"*\") in allowOrigins, and the request\nis not credentialed (e.g., it is a preflight request), the\n`Access-Control-Allow-Origin` response header either contains the\nwildcard as well or the Origin from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Origin` response header. When\nalso the `AllowCredentials` field is true and `AllowOrigins` field\nspecified with the `*` wildcard, the gateway must return a single origin\nin the value of the `Access-Control-Allow-Origin` response header,\ninstead of specifying the `*` wildcard. The value of the header\n`Access-Control-Allow-Origin` is same as the `Origin` header provided by\nthe client.\n\nSupport: Extended",
"items": {
"description": "The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\nencoding rules specified in RFC3986. The CORSOrigin MUST include both a\nscheme (\"http\" or \"https\") and a scheme-specific-part, or it should be a single '*' character.\nURIs that include an authority MUST include a fully qualified domain name or\nIP address as the host.",
"maxLength": 253,
"minLength": 1,
"pattern": "(^\\*$)|(^(http(s)?):\\/\\/(((\\*\\.)?([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9-]+|\\*)(:([0-9]{1,5}))?)$)",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowOrigins cannot contain '*' alongside other origins",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"exposeHeaders": {
"description": "ExposeHeaders indicates which HTTP response headers can be exposed\nto client-side scripts in response to a cross-origin request.\n\nA CORS-safelisted response header is an HTTP header in a CORS response\nthat it is considered safe to expose to the client scripts.\nThe CORS-safelisted response headers include the following headers:\n`Cache-Control`\n`Content-Language`\n`Content-Length`\n`Content-Type`\n`Expires`\n`Last-Modified`\n`Pragma`\n(See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\nThe CORS-safelisted response headers are exposed to client by default.\n\nWhen an HTTP header name is specified using the `ExposeHeaders` field,\nthis additional header will be exposed as part of the response to the\nclient.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Expose-Headers`\nresponse header are separated by a comma (\",\").\n\nA wildcard indicates that the responses with all HTTP headers are exposed\nto clients. The `Access-Control-Expose-Headers` response header can only\nuse `*` wildcard as value when the request is not credentialed.\n\nWhen the `exposeHeaders` config field contains the \"*\" wildcard and\nthe request is credentialed, the gateway cannot use the `*` wildcard in\nthe `Access-Control-Expose-Headers` response header.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"maxAge": {
"default": 5,
"description": "MaxAge indicates the duration (in seconds) for the client to cache the\nresults of a \"preflight\" request.\n\nThe information provided by the `Access-Control-Allow-Methods` and\n`Access-Control-Allow-Headers` response headers can be cached by the\nclient until the time specified by `Access-Control-Max-Age` elapses.\n\nThe default value of `Access-Control-Max-Age` response header is 5\n(seconds).\n\nWhen the `MaxAge` field is unspecified, the gateway sets the response\nheader \"Access-Control-Max-Age: 5\" by default.",
"format": "int32",
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"extensionRef": { "extensionRef": {
"description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific", "description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific",
"properties": { "properties": {
@@ -154,6 +250,152 @@
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
}, },
"externalAuth": {
"description": "ExternalAuth configures settings related to sending request details\nto an external auth service. The external service MUST authenticate\nthe request, and MAY authorize the request as well.\n\nIf there is any problem communicating with the external service,\nthis filter MUST fail closed.\n\nSupport: Extended",
"properties": {
"backendRef": {
"description": "BackendRef is a reference to a backend to send authorization\nrequests to.\n\nThe backend must speak the selected protocol (GRPC or HTTP) on the\nreferenced port.\n\nIf the backend service requires TLS, use BackendTLSPolicy to tell the\nimplementation to supply the TLS details to be used to connect to that\nbackend.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"forwardBody": {
"description": "ForwardBody controls if requests to the authorization server should include\nthe body of the client request; and if so, how big that body is allowed\nto be.\n\nIt is expected that implementations will buffer the request body up to\n`forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n4xx series error (413 or 403 are common examples), and fail processing\nof the filter.\n\nIf unset, or `forwardBody.maxSize` is set to `0`, then the body will not\nbe forwarded.\n\nFeature Name: HTTPRouteExternalAuthForwardBody",
"properties": {
"maxSize": {
"description": "MaxSize specifies how large in bytes the largest body that will be buffered\nand sent to the authorization server. If the body size is larger than\n`maxSize`, then the body sent to the authorization server must be\ntruncated to `maxSize` bytes.\n\nExperimental note: This behavior needs to be checked against\nvarious dataplanes; it may need to be changed.\nSee https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\nfor more.\n\nIf 0, the body will not be sent to the authorization server.",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"grpc": {
"description": "GRPCAuthConfig contains configuration for communication with ext_authz\nprotocol-speaking backends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what headers from the client request\nwill be sent to the authorization server.\n\nIf this list is empty, then all headers must be sent.\n\nIf the list has entries, only those entries must be sent.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
}
},
"type": "object",
"additionalProperties": false
},
"http": {
"description": "HTTPAuthConfig contains configuration for communication with HTTP-speaking\nbackends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what additional headers from the client request\nwill be sent to the authorization server.\n\nThe following headers must always be sent to the authorization server,\nregardless of this setting:\n\n* `Host`\n* `Method`\n* `Path`\n* `Content-Length`\n* `Authorization`\n\nIf this list is empty, then only those headers must be sent.\n\nNote that `Content-Length` has a special behavior, in that the length\nsent must be correct for the actual request to the external authorization\nserver - that is, it must reflect the actual number of bytes sent in the\nbody of the request to the authorization server.\n\nSo if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\nto `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\nto anything other than `0`, then the `Content-Length` of the authorization\nrequest must be set to the actual number of bytes forwarded.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"allowedResponseHeaders": {
"description": "AllowedResponseHeaders specifies what headers from the authorization response\nwill be copied into the request to the backend.\n\nIf this list is empty, then all headers from the authorization server\nexcept Authority or Host must be copied.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"path": {
"description": "Path sets the prefix that paths from the client request will have added\nwhen forwarded to the authorization server.\n\nWhen empty or unspecified, no prefix is added.\n\nValid values are the same as the \"value\" regex for path values in the `match`\nstanza, and the validation regex will screen out invalid paths in the same way.\nEven with the validation, implementations MUST sanitize this input before using it\ndirectly.",
"maxLength": 1024,
"pattern": "^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"protocol": {
"description": "ExternalAuthProtocol describes which protocol to use when communicating with an\next_authz authorization server.\n\nWhen this is set to GRPC, each backend must use the Envoy ext_authz protocol\non the port specified in `backendRefs`. Requests and responses are defined\nin the protobufs explained at:\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\nWhen this is set to HTTP, each backend must respond with a `200` status\ncode in on a successful authorization. Any other code is considered\nan authorization failure.\n\nFeature Names:\nGRPC Support - HTTPRouteExternalAuthGRPC\nHTTP Support - HTTPRouteExternalAuthHTTP",
"enum": [
"HTTP",
"GRPC"
],
"type": "string"
}
},
"required": [
"backendRef",
"protocol"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "grpc must be specified when protocol is set to 'GRPC'",
"rule": "self.protocol == 'GRPC' ? has(self.grpc) : true"
},
{
"message": "protocol must be 'GRPC' when grpc is set",
"rule": "has(self.grpc) ? self.protocol == 'GRPC' : true"
},
{
"message": "http must be specified when protocol is set to 'HTTP'",
"rule": "self.protocol == 'HTTP' ? has(self.http) : true"
},
{
"message": "protocol must be 'HTTP' when http is set",
"rule": "has(self.http) ? self.protocol == 'HTTP' : true"
}
],
"additionalProperties": false
},
"requestHeaderModifier": { "requestHeaderModifier": {
"description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core", "description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core",
"properties": { "properties": {
@@ -170,9 +412,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -212,9 +455,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -413,7 +657,10 @@
"description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core", "description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core",
"enum": [ "enum": [
301, 301,
302 302,
303,
307,
308
], ],
"type": "integer" "type": "integer"
} }
@@ -437,9 +684,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -479,9 +727,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -511,7 +760,9 @@
"RequestMirror", "RequestMirror",
"RequestRedirect", "RequestRedirect",
"URLRewrite", "URLRewrite",
"ExtensionRef" "ExtensionRef",
"CORS",
"ExternalAuth"
], ],
"type": "string" "type": "string"
}, },
@@ -581,6 +832,14 @@
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{
"message": "filter.cors must be nil if the filter.type is not CORS",
"rule": "!(has(self.cors) && self.type != 'CORS')"
},
{
"message": "filter.cors must be specified for CORS filter.type",
"rule": "!(!has(self.cors) && self.type == 'CORS')"
},
{ {
"message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier", "message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier",
"rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')" "rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')"
@@ -628,6 +887,14 @@
{ {
"message": "filter.extensionRef must be specified for ExtensionRef filter.type", "message": "filter.extensionRef must be specified for ExtensionRef filter.type",
"rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')" "rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')"
},
{
"message": "filter.externalAuth must be nil if the filter.type is not ExternalAuth",
"rule": "!(has(self.externalAuth) && self.type != 'ExternalAuth')"
},
{
"message": "filter.externalAuth must be specified for ExternalAuth filter.type",
"rule": "!(!has(self.externalAuth) && self.type == 'ExternalAuth')"
} }
], ],
"additionalProperties": false "additionalProperties": false
@@ -640,6 +907,10 @@
"message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both", "message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",
"rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))" "rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
}, },
{
"message": "CORS filter cannot be repeated",
"rule": "self.filter(f, f.type == 'CORS').size() <= 1"
},
{ {
"message": "RequestHeaderModifier filter cannot be repeated", "message": "RequestHeaderModifier filter cannot be repeated",
"rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1" "rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
@@ -723,6 +994,102 @@
"items": { "items": {
"description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.", "description": "HTTPRouteFilter defines processing steps that must be completed during the\nrequest or response lifecycle. HTTPRouteFilters are meant as an extension\npoint to express processing that may be done in Gateway implementations. Some\nexamples include request or response modification, implementing\nauthentication strategies, rate-limiting, and traffic shaping. API\nguarantee/conformance is defined based on the type of the filter.",
"properties": { "properties": {
"cors": {
"description": "CORS defines a schema for a filter that responds to the\ncross-origin request based on HTTP response header.\n\nSupport: Extended",
"properties": {
"allowCredentials": {
"description": "AllowCredentials indicates whether the actual cross-origin request allows\nto include credentials.\n\nWhen set to true, the gateway will include the `Access-Control-Allow-Credentials`\nresponse header with value true (case-sensitive).\n\nWhen set to false or omitted the gateway will omit the header\n`Access-Control-Allow-Credentials` entirely (this is the standard CORS\nbehavior).\n\nSupport: Extended",
"type": "boolean"
},
"allowHeaders": {
"description": "AllowHeaders indicates which HTTP request headers are supported for\naccessing the requested resource.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Allow-Headers`\nresponse header are separated by a comma (\",\").\n\nWhen the `AllowHeaders` field is configured with one or more headers, the\ngateway must return the `Access-Control-Allow-Headers` response header\nwhich value is present in the `AllowHeaders` field.\n\nIf any header name in the `Access-Control-Request-Headers` request header\nis not included in the list of header names specified by the response\nheader `Access-Control-Allow-Headers`, it will present an error on the\nclient side.\n\nIf any header name in the `Access-Control-Allow-Headers` response header\ndoes not recognize by the client, it will also occur an error on the\nclient side.\n\nA wildcard indicates that the requests with all HTTP headers are allowed.\nIf config contains the wildcard \"*\" in allowHeaders and the request is\nnot credentialed, the `Access-Control-Allow-Headers` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Headers from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Headers` response header. When\nalso the `AllowCredentials` field is true and `AllowHeaders` field\nis specified with the `*` wildcard, the gateway must specify one or more\nHTTP headers in the value of the `Access-Control-Allow-Headers` response\nheader. The value of the header `Access-Control-Allow-Headers` is same as\nthe `Access-Control-Request-Headers` header provided by the client. If\nthe header `Access-Control-Request-Headers` is not included in the\nrequest, the gateway will omit the `Access-Control-Allow-Headers`\nresponse header, instead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowHeaders cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowMethods": {
"description": "AllowMethods indicates which HTTP methods are supported for accessing the\nrequested resource.\n\nValid values are any method defined by RFC9110, along with the special\nvalue `*`, which represents all HTTP methods are allowed.\n\nMethod names are case-sensitive, so these values are also case-sensitive.\n(See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\nMultiple method names in the value of the `Access-Control-Allow-Methods`\nresponse header are separated by a comma (\",\").\n\nA CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n(See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\nCORS-safelisted methods are always allowed, regardless of whether they\nare specified in the `AllowMethods` field.\n\nWhen the `AllowMethods` field is configured with one or more methods, the\ngateway must return the `Access-Control-Allow-Methods` response header\nwhich value is present in the `AllowMethods` field.\n\nIf the HTTP method of the `Access-Control-Request-Method` request header\nis not included in the list of methods specified by the response header\n`Access-Control-Allow-Methods`, it will present an error on the client\nside.\n\nIf config contains the wildcard \"*\" in allowMethods and the request is\nnot credentialed, the `Access-Control-Allow-Methods` response header\ncan either use the `*` wildcard or the value of\nAccess-Control-Request-Method from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Methods` response header. When\nalso the `AllowCredentials` field is true and `AllowMethods` field\nspecified with the `*` wildcard, the gateway must specify one HTTP method\nin the value of the Access-Control-Allow-Methods response header. The\nvalue of the header `Access-Control-Allow-Methods` is same as the\n`Access-Control-Request-Method` header provided by the client. If the\nheader `Access-Control-Request-Method` is not included in the request,\nthe gateway will omit the `Access-Control-Allow-Methods` response header,\ninstead of specifying the `*` wildcard.\n\nSupport: Extended",
"items": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH",
"*"
],
"type": "string"
},
"maxItems": 9,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowMethods cannot contain '*' alongside other methods",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"allowOrigins": {
"description": "AllowOrigins indicates whether the response can be shared with requested\nresource from the given `Origin`.\n\nThe `Origin` consists of a scheme and a host, with an optional port, and\ntakes the form `<scheme>://<host>(:<port>)`.\n\nValid values for scheme are: `http` and `https`.\n\nValid values for port are any integer between 1 and 65535 (the list of\navailable TCP/UDP ports). Note that, if not included, port `80` is\nassumed for `http` scheme origins, and port `443` is assumed for `https`\norigins. This may affect origin matching.\n\nThe host part of the origin may contain the wildcard character `*`. These\nwildcard characters behave as follows:\n\n* `*` is a greedy match to the _left_, including any number of\n DNS labels to the left of its position. This also means that\n `*` will include any number of period `.` characters to the\n left of its position.\n* A wildcard by itself matches all hosts.\n\nAn origin value that includes _only_ the `*` character indicates requests\nfrom all `Origin`s are allowed.\n\nWhen the `AllowOrigins` field is configured with multiple origins, it\nmeans the server supports clients from multiple origins. If the request\n`Origin` matches the configured allowed origins, the gateway must return\nthe given `Origin` and sets value of the header\n`Access-Control-Allow-Origin` same as the `Origin` header provided by the\nclient.\n\nThe status code of a successful response to a \"preflight\" request is\nalways an OK status (i.e., 204 or 200).\n\nIf the request `Origin` does not match the configured allowed origins,\nthe gateway returns 204/200 response but doesn't set the relevant\ncross-origin response headers. Alternatively, the gateway responds with\n403 status to the \"preflight\" request is denied, coupled with omitting\nthe CORS headers. The cross-origin request fails on the client side.\nTherefore, the client doesn't attempt the actual cross-origin request.\n\nConversely, if the request `Origin` matches one of the configured\nallowed origins, the gateway sets the response header\n`Access-Control-Allow-Origin` to the same value as the `Origin`\nheader provided by the client.\n\nWhen config has the wildcard (\"*\") in allowOrigins, and the request\nis not credentialed (e.g., it is a preflight request), the\n`Access-Control-Allow-Origin` response header either contains the\nwildcard as well or the Origin from the request.\n\nWhen the request is credentialed, the gateway must not specify the `*`\nwildcard in the `Access-Control-Allow-Origin` response header. When\nalso the `AllowCredentials` field is true and `AllowOrigins` field\nspecified with the `*` wildcard, the gateway must return a single origin\nin the value of the `Access-Control-Allow-Origin` response header,\ninstead of specifying the `*` wildcard. The value of the header\n`Access-Control-Allow-Origin` is same as the `Origin` header provided by\nthe client.\n\nSupport: Extended",
"items": {
"description": "The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\nencoding rules specified in RFC3986. The CORSOrigin MUST include both a\nscheme (\"http\" or \"https\") and a scheme-specific-part, or it should be a single '*' character.\nURIs that include an authority MUST include a fully qualified domain name or\nIP address as the host.",
"maxLength": 253,
"minLength": 1,
"pattern": "(^\\*$)|(^(http(s)?):\\/\\/(((\\*\\.)?([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9-]+|\\*)(:([0-9]{1,5}))?)$)",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set",
"x-kubernetes-validations": [
{
"message": "AllowOrigins cannot contain '*' alongside other origins",
"rule": "!('*' in self && self.size() > 1)"
}
]
},
"exposeHeaders": {
"description": "ExposeHeaders indicates which HTTP response headers can be exposed\nto client-side scripts in response to a cross-origin request.\n\nA CORS-safelisted response header is an HTTP header in a CORS response\nthat it is considered safe to expose to the client scripts.\nThe CORS-safelisted response headers include the following headers:\n`Cache-Control`\n`Content-Language`\n`Content-Length`\n`Content-Type`\n`Expires`\n`Last-Modified`\n`Pragma`\n(See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\nThe CORS-safelisted response headers are exposed to client by default.\n\nWhen an HTTP header name is specified using the `ExposeHeaders` field,\nthis additional header will be exposed as part of the response to the\nclient.\n\nHeader names are not case-sensitive.\n\nMultiple header names in the value of the `Access-Control-Expose-Headers`\nresponse header are separated by a comma (\",\").\n\nA wildcard indicates that the responses with all HTTP headers are exposed\nto clients. The `Access-Control-Expose-Headers` response header can only\nuse `*` wildcard as value when the request is not credentialed.\n\nWhen the `exposeHeaders` config field contains the \"*\" wildcard and\nthe request is credentialed, the gateway cannot use the `*` wildcard in\nthe `Access-Control-Expose-Headers` response header.\n\nSupport: Extended",
"items": {
"description": "HTTPHeaderName is the name of an HTTP header.\n\nValid values include:\n\n* \"Authorization\"\n* \"Set-Cookie\"\n\nInvalid values include:\n\n - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n headers are not currently supported by this type.\n - \"/invalid\" - \"/ \" is an invalid character",
"maxLength": 256,
"minLength": 1,
"pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"maxAge": {
"default": 5,
"description": "MaxAge indicates the duration (in seconds) for the client to cache the\nresults of a \"preflight\" request.\n\nThe information provided by the `Access-Control-Allow-Methods` and\n`Access-Control-Allow-Headers` response headers can be cached by the\nclient until the time specified by `Access-Control-Max-Age` elapses.\n\nThe default value of `Access-Control-Max-Age` response header is 5\n(seconds).\n\nWhen the `MaxAge` field is unspecified, the gateway sets the response\nheader \"Access-Control-Max-Age: 5\" by default.",
"format": "int32",
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"extensionRef": { "extensionRef": {
"description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific", "description": "ExtensionRef is an optional, implementation-specific extension to the\n\"filter\" behavior. For example, resource \"myroutefilter\" in group\n\"networking.example.net\"). ExtensionRef MUST NOT be used for core and\nextended filters.\n\nThis filter can be used multiple times within the same rule.\n\nSupport: Implementation-specific",
"properties": { "properties": {
@@ -754,6 +1121,152 @@
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
}, },
"externalAuth": {
"description": "ExternalAuth configures settings related to sending request details\nto an external auth service. The external service MUST authenticate\nthe request, and MAY authorize the request as well.\n\nIf there is any problem communicating with the external service,\nthis filter MUST fail closed.\n\nSupport: Extended",
"properties": {
"backendRef": {
"description": "BackendRef is a reference to a backend to send authorization\nrequests to.\n\nThe backend must speak the selected protocol (GRPC or HTTP) on the\nreferenced port.\n\nIf the backend service requires TLS, use BackendTLSPolicy to tell the\nimplementation to supply the TLS details to be used to connect to that\nbackend.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"forwardBody": {
"description": "ForwardBody controls if requests to the authorization server should include\nthe body of the client request; and if so, how big that body is allowed\nto be.\n\nIt is expected that implementations will buffer the request body up to\n`forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n4xx series error (413 or 403 are common examples), and fail processing\nof the filter.\n\nIf unset, or `forwardBody.maxSize` is set to `0`, then the body will not\nbe forwarded.\n\nFeature Name: HTTPRouteExternalAuthForwardBody",
"properties": {
"maxSize": {
"description": "MaxSize specifies how large in bytes the largest body that will be buffered\nand sent to the authorization server. If the body size is larger than\n`maxSize`, then the body sent to the authorization server must be\ntruncated to `maxSize` bytes.\n\nExperimental note: This behavior needs to be checked against\nvarious dataplanes; it may need to be changed.\nSee https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\nfor more.\n\nIf 0, the body will not be sent to the authorization server.",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"grpc": {
"description": "GRPCAuthConfig contains configuration for communication with ext_authz\nprotocol-speaking backends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what headers from the client request\nwill be sent to the authorization server.\n\nIf this list is empty, then all headers must be sent.\n\nIf the list has entries, only those entries must be sent.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
}
},
"type": "object",
"additionalProperties": false
},
"http": {
"description": "HTTPAuthConfig contains configuration for communication with HTTP-speaking\nbackends.\n\nIf unset, implementations must assume the default behavior for each\nincluded field is intended.",
"properties": {
"allowedHeaders": {
"description": "AllowedRequestHeaders specifies what additional headers from the client request\nwill be sent to the authorization server.\n\nThe following headers must always be sent to the authorization server,\nregardless of this setting:\n\n* `Host`\n* `Method`\n* `Path`\n* `Content-Length`\n* `Authorization`\n\nIf this list is empty, then only those headers must be sent.\n\nNote that `Content-Length` has a special behavior, in that the length\nsent must be correct for the actual request to the external authorization\nserver - that is, it must reflect the actual number of bytes sent in the\nbody of the request to the authorization server.\n\nSo if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\nto `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\nto anything other than `0`, then the `Content-Length` of the authorization\nrequest must be set to the actual number of bytes forwarded.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"allowedResponseHeaders": {
"description": "AllowedResponseHeaders specifies what headers from the authorization response\nwill be copied into the request to the backend.\n\nIf this list is empty, then all headers from the authorization server\nexcept Authority or Host must be copied.",
"items": {
"type": "string"
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "set"
},
"path": {
"description": "Path sets the prefix that paths from the client request will have added\nwhen forwarded to the authorization server.\n\nWhen empty or unspecified, no prefix is added.\n\nValid values are the same as the \"value\" regex for path values in the `match`\nstanza, and the validation regex will screen out invalid paths in the same way.\nEven with the validation, implementations MUST sanitize this input before using it\ndirectly.",
"maxLength": 1024,
"pattern": "^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"protocol": {
"description": "ExternalAuthProtocol describes which protocol to use when communicating with an\next_authz authorization server.\n\nWhen this is set to GRPC, each backend must use the Envoy ext_authz protocol\non the port specified in `backendRefs`. Requests and responses are defined\nin the protobufs explained at:\nhttps://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\nWhen this is set to HTTP, each backend must respond with a `200` status\ncode in on a successful authorization. Any other code is considered\nan authorization failure.\n\nFeature Names:\nGRPC Support - HTTPRouteExternalAuthGRPC\nHTTP Support - HTTPRouteExternalAuthHTTP",
"enum": [
"HTTP",
"GRPC"
],
"type": "string"
}
},
"required": [
"backendRef",
"protocol"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "grpc must be specified when protocol is set to 'GRPC'",
"rule": "self.protocol == 'GRPC' ? has(self.grpc) : true"
},
{
"message": "protocol must be 'GRPC' when grpc is set",
"rule": "has(self.grpc) ? self.protocol == 'GRPC' : true"
},
{
"message": "http must be specified when protocol is set to 'HTTP'",
"rule": "self.protocol == 'HTTP' ? has(self.http) : true"
},
{
"message": "protocol must be 'HTTP' when http is set",
"rule": "has(self.http) ? self.protocol == 'HTTP' : true"
}
],
"additionalProperties": false
},
"requestHeaderModifier": { "requestHeaderModifier": {
"description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core", "description": "RequestHeaderModifier defines a schema for a filter that modifies request\nheaders.\n\nSupport: Core",
"properties": { "properties": {
@@ -770,9 +1283,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -812,9 +1326,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1013,7 +1528,10 @@
"description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core", "description": "StatusCode is the HTTP status code to be used in response.\n\nNote that values may be added to this enum, implementations\nmust ensure that unknown values will not cause a crash.\n\nUnknown values here must result in the implementation setting the\nAccepted Condition for the Route to `status: False`, with a\nReason of `UnsupportedValue`.\n\nSupport: Core",
"enum": [ "enum": [
301, 301,
302 302,
303,
307,
308
], ],
"type": "integer" "type": "integer"
} }
@@ -1037,9 +1555,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1079,9 +1598,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1111,7 +1631,9 @@
"RequestMirror", "RequestMirror",
"RequestRedirect", "RequestRedirect",
"URLRewrite", "URLRewrite",
"ExtensionRef" "ExtensionRef",
"CORS",
"ExternalAuth"
], ],
"type": "string" "type": "string"
}, },
@@ -1181,6 +1703,14 @@
], ],
"type": "object", "type": "object",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{
"message": "filter.cors must be nil if the filter.type is not CORS",
"rule": "!(has(self.cors) && self.type != 'CORS')"
},
{
"message": "filter.cors must be specified for CORS filter.type",
"rule": "!(!has(self.cors) && self.type == 'CORS')"
},
{ {
"message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier", "message": "filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier",
"rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')" "rule": "!(has(self.requestHeaderModifier) && self.type != 'RequestHeaderModifier')"
@@ -1228,6 +1758,14 @@
{ {
"message": "filter.extensionRef must be specified for ExtensionRef filter.type", "message": "filter.extensionRef must be specified for ExtensionRef filter.type",
"rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')" "rule": "!(!has(self.extensionRef) && self.type == 'ExtensionRef')"
},
{
"message": "filter.externalAuth must be nil if the filter.type is not ExternalAuth",
"rule": "!(has(self.externalAuth) && self.type != 'ExternalAuth')"
},
{
"message": "filter.externalAuth must be specified for ExternalAuth filter.type",
"rule": "!(!has(self.externalAuth) && self.type == 'ExternalAuth')"
} }
], ],
"additionalProperties": false "additionalProperties": false
@@ -1240,6 +1778,10 @@
"message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both", "message": "May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",
"rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))" "rule": "!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
}, },
{
"message": "CORS filter cannot be repeated",
"rule": "self.filter(f, f.type == 'CORS').size() <= 1"
},
{ {
"message": "RequestHeaderModifier filter cannot be repeated", "message": "RequestHeaderModifier filter cannot be repeated",
"rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1" "rule": "self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
@@ -1293,9 +1835,10 @@
"type": "string" "type": "string"
}, },
"value": { "value": {
"description": "Value is the value of HTTP Header to be matched.", "description": "Value is the value of HTTP Header to be matched.\n\nMust consist of printable US-ASCII characters, optionally separated\nby single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2",
"maxLength": 4096, "maxLength": 4096,
"minLength": 1, "minLength": 1,
"pattern": "^[!-~]+([\\t ]?[!-~]+)*$",
"type": "string" "type": "string"
} }
}, },
@@ -1458,6 +2001,90 @@
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string" "type": "string"
}, },
"retry": {
"description": "Retry defines the configuration for when to retry an HTTP request.\n\nSupport: Extended",
"properties": {
"attempts": {
"description": "Attempts specifies the maximum number of times an individual request\nfrom the gateway to a backend should be retried.\n\nIf the maximum number of retries has been attempted without a successful\nresponse from the backend, the Gateway MUST return an error.\n\nWhen this field is unspecified, the number of times to attempt to retry\na backend request is implementation-specific.\n\nSupport: Extended",
"type": "integer"
},
"backoff": {
"description": "Backoff specifies the minimum duration a Gateway should wait between\nretry attempts and is represented in Gateway API Duration formatting.\n\nFor example, setting the `rules[].retry.backoff` field to the value\n`100ms` will cause a backend request to first be retried approximately\n100 milliseconds after timing out or receiving a response code configured\nto be retriable.\n\nAn implementation MAY use an exponential or alternative backoff strategy\nfor subsequent retry attempts, MAY cap the maximum backoff duration to\nsome amount greater than the specified minimum, and MAY add arbitrary\njitter to stagger requests, as long as unsuccessful backend requests are\nnot retried before the configured minimum duration.\n\nIf a Request timeout (`rules[].timeouts.request`) is configured on the\nroute, the entire duration of the initial request and any retry attempts\nMUST not exceed the Request timeout duration. If any retry attempts are\nstill in progress when the Request timeout duration has been reached,\nthese SHOULD be canceled if possible and the Gateway MUST immediately\nreturn a timeout error.\n\nIf a BackendRequest timeout (`rules[].timeouts.backendRequest`) is\nconfigured on the route, any retry attempts which reach the configured\nBackendRequest timeout duration without a response SHOULD be canceled if\npossible and the Gateway should wait for at least the specified backoff\nduration before attempting to retry the backend request again.\n\nIf a BackendRequest timeout is _not_ configured on the route, retry\nattempts MAY time out after an implementation default duration, or MAY\nremain pending until a configured Request timeout or implementation\ndefault duration for total request time is reached.\n\nWhen this field is unspecified, the time to wait between retry attempts\nis implementation-specific.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"codes": {
"description": "Codes defines the HTTP response status codes for which a backend request\nshould be retried.\n\nSupport: Extended",
"items": {
"description": "HTTPRouteRetryStatusCode defines an HTTP response status code for\nwhich a backend request should be retried.\n\nImplementations MUST support the following status codes as retriable:\n\n* 500\n* 502\n* 503\n* 504\n\nImplementations MAY support specifying additional discrete values in the\n500-599 range.\n\nImplementations MAY support specifying discrete values in the 400-499 range,\nwhich are often inadvisable to retry.",
"maximum": 599,
"minimum": 400,
"type": "integer"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object",
"additionalProperties": false
},
"sessionPersistence": {
"description": "SessionPersistence defines and configures session persistence\nfor the route rule.\n\nSupport: Extended",
"properties": {
"absoluteTimeout": {
"description": "AbsoluteTimeout defines the absolute timeout of the persistent\nsession. Once the AbsoluteTimeout duration has elapsed, the\nsession becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"cookieConfig": {
"description": "CookieConfig provides configuration settings that are specific\nto cookie-based session persistence.\n\nSupport: Core",
"properties": {
"lifetimeType": {
"default": "Session",
"description": "LifetimeType specifies whether the cookie has a permanent or\nsession-based lifetime. A permanent cookie persists until its\nspecified expiry time, defined by the Expires or Max-Age cookie\nattributes, while a session cookie is deleted when the current\nsession ends.\n\nWhen set to \"Permanent\", AbsoluteTimeout indicates the\ncookie's lifetime via the Expires or Max-Age cookie attributes\nand is required.\n\nWhen set to \"Session\", AbsoluteTimeout indicates the\nabsolute lifetime of the cookie tracked by the gateway and\nis optional.\n\nDefaults to \"Session\".\n\nSupport: Core for \"Session\" type\n\nSupport: Extended for \"Permanent\" type",
"enum": [
"Permanent",
"Session"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"idleTimeout": {
"description": "IdleTimeout defines the idle timeout of the persistent session.\nOnce the session has been idle for more than the specified\nIdleTimeout duration, the session becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"sessionName": {
"description": "SessionName defines the name of the persistent session token\nwhich may be reflected in the cookie or the header. Users\nshould avoid reusing session names to prevent unintended\nconsequences, such as rejection or unpredictable behavior.\n\nSupport: Implementation-specific",
"maxLength": 128,
"type": "string"
},
"type": {
"default": "Cookie",
"description": "Type defines the type of session persistence such as through\nthe use of a header or cookie. Defaults to cookie based session\npersistence.\n\nSupport: Core for \"Cookie\" type\n\nSupport: Extended for \"Header\" type",
"enum": [
"Cookie",
"Header"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "AbsoluteTimeout must be specified when cookie lifetimeType is Permanent",
"rule": "!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType != 'Permanent' || has(self.absoluteTimeout)"
},
{
"message": "cookieConfig can only be set with type Cookie",
"rule": "!has(self.cookieConfig) || self.type == 'Cookie'"
}
],
"additionalProperties": false
},
"timeouts": { "timeouts": {
"description": "Timeouts defines the timeouts that can be configured for an HTTP request.\n\nSupport: Extended", "description": "Timeouts defines the timeouts that can be configured for an HTTP request.\n\nSupport: Extended",
"properties": { "properties": {
@@ -1508,14 +2135,27 @@
"additionalProperties": false "additionalProperties": false
}, },
"maxItems": 16, "maxItems": 16,
"minItems": 1,
"type": "array", "type": "array",
"x-kubernetes-list-type": "atomic", "x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [ "x-kubernetes-validations": [
{ {
"message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128", "message": "While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",
"rule": "(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128" "rule": "(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128"
},
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
} }
] ]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
} }
}, },
"type": "object", "type": "object",
@@ -1530,7 +2170,7 @@
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.", "description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": { "properties": {
"conditions": { "conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace the controller does not have access to.", "description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": { "items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.", "description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": { "properties": {
@@ -1623,14 +2263,14 @@
"type": "string" "type": "string"
}, },
"namespace": { "namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\nSupport: Core", "description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63, "maxLength": 63,
"minLength": 1, "minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string" "type": "string"
}, },
"port": { "port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended", "description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32", "format": "int32",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
@@ -0,0 +1,556 @@
{
"description": "ListenerSet defines a set of additional listeners to attach to an existing Gateway.\nThis resource provides a mechanism to merge multiple listeners into a single Gateway.\n\nThe parent Gateway must explicitly allow ListenerSet attachment through its\nAllowedListeners configuration. By default, Gateways do not allow ListenerSet\nattachment.\n\nRoutes can attach to a ListenerSet by specifying it as a parentRef, and can\noptionally target specific listeners using the sectionName field.\n\nPolicy Attachment:\n- Policies that attach to a ListenerSet apply to all listeners defined in that resource\n- Policies do not impact listeners in the parent Gateway\n- Different ListenerSets attached to the same Gateway can have different policies\n- If an implementation cannot apply a policy to specific listeners, it should reject the policy\n\nReferenceGrant Semantics:\n- ReferenceGrants applied to a Gateway are not inherited by child ListenerSets\n- ReferenceGrants applied to a ListenerSet do not grant permission to the parent Gateway's listeners\n- A ListenerSet can reference secrets/backends in its own namespace without a ReferenceGrant\n\nGateway Integration:\n - The parent Gateway's status will include \"AttachedListenerSets\"\n which is the count of ListenerSets that have successfully attached to a Gateway\n A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n - The ListenerSet is selected by the Gateway's AllowedListeners field\n - The ListenerSet has a valid ParentRef selecting the Gateway\n - The ListenerSet's status has the condition \"Accepted: true\"",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of ListenerSet.",
"properties": {
"listeners": {
"description": "Listeners associated with this ListenerSet. Listeners define\nlogical endpoints that are bound on this referenced parent Gateway's addresses.\n\nListeners in a `Gateway` and their attached `ListenerSets` are concatenated\nas a list when programming the underlying infrastructure. Each listener\nname does not need to be unique across the Gateway and ListenerSets.\nSee ListenerEntry.Name for more details.\n\nImplementations MUST treat the parent Gateway as having the merged\nlist of all listeners from itself and attached ListenerSets using\nthe following precedence:\n\n1. \"parent\" Gateway\n2. ListenerSet ordered by creation time (oldest first)\n3. ListenerSet ordered alphabetically by \"{namespace}/{name}\".\n\nAn implementation MAY reject listeners by setting the ListenerEntryStatus\n`Accepted` condition to False with the Reason `TooManyListeners`\n\nIf a listener has a conflict, this will be reported in the\nStatus.ListenerEntryStatus setting the `Conflicted` condition to True.\n\nImplementations SHOULD be cautious about what information from the\nparent or siblings are reported to avoid accidentally leaking\nsensitive information that the child would not otherwise have access\nto. This can include contents of secrets etc.",
"items": {
"properties": {
"allowedRoutes": {
"default": {
"namespaces": {
"from": "Same"
}
},
"description": "AllowedRoutes defines the types of routes that MAY be attached to a\nListener and the trusted namespaces where those Route resources MAY be\npresent.\n\nAlthough a client request may match multiple route rules, only one rule\nmay ultimately receive the request. Matching precedence MUST be\ndetermined in order of the following criteria:\n\n* The most specific match as defined by the Route type.\n* The oldest Route based on creation timestamp. For example, a Route with\n a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n* If everything else is equivalent, the Route appearing first in\n alphabetical order (namespace/name) should be given precedence. For\n example, foo/bar is given precedence over foo/baz.\n\nAll valid rules within a Route attached to this Listener should be\nimplemented. Invalid Route rules can be ignored (sometimes that will mean\nthe full Route). If a Route rule transitions from valid to invalid,\nsupport for that Route rule should be dropped to ensure consistency. For\nexample, even if a filter specified by a Route rule is invalid, the rest\nof the rules within that Route should still be supported.",
"properties": {
"kinds": {
"description": "Kinds specifies the groups and kinds of Routes that are allowed to bind\nto this Gateway Listener. When unspecified or empty, the kinds of Routes\nselected are determined using the Listener protocol.\n\nA RouteGroupKind MUST correspond to kinds of Routes that are compatible\nwith the application protocol specified in the Listener's Protocol field.\nIf an implementation does not support or recognize this resource type, it\nMUST set the \"ResolvedRefs\" condition to False for this Listener with the\n\"InvalidRouteKinds\" reason.\n\nSupport: Core",
"items": {
"description": "RouteGroupKind indicates the group and kind of a Route resource.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the Route.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is the kind of the Route.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"namespaces": {
"default": {
"from": "Same"
},
"description": "Namespaces indicates namespaces from which Routes may be attached to this\nListener. This is restricted to the namespace of this Gateway by default.\n\nSupport: Core",
"properties": {
"from": {
"default": "Same",
"description": "From indicates where Routes will be selected for this Gateway. Possible\nvalues are:\n\n* All: Routes in all namespaces may be used by this Gateway.\n* Selector: Routes in namespaces selected by the selector may be used by\n this Gateway.\n* Same: Only Routes in the same namespace may be used by this Gateway.\n\nSupport: Core",
"enum": [
"All",
"Selector",
"Same"
],
"type": "string"
},
"selector": {
"description": "Selector must be specified when From is set to \"Selector\". In that case,\nonly Routes in Namespaces matching this Selector will be selected by this\nGateway. This field is ignored for other values of \"From\".\n\nSupport: Core",
"properties": {
"matchExpressions": {
"description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
"items": {
"description": "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.",
"properties": {
"key": {
"description": "key is the label key that the selector applies to.",
"type": "string"
},
"operator": {
"description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.",
"type": "string"
},
"values": {
"description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.",
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"hostname": {
"description": "Hostname specifies the virtual hostname to match for protocol types that\ndefine this concept. When unspecified, all hostnames are matched. This\nfield is ignored for protocols that don't require hostname based\nmatching.\n\nImplementations MUST apply Hostname matching appropriately for each of\nthe following protocols:\n\n* TLS: The Listener Hostname MUST match the SNI.\n* HTTP: The Listener Hostname MUST match the Host header of the request.\n* HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP\n protocol layers as described above. If an implementation does not\n ensure that both the SNI and Host header match the Listener hostname,\n it MUST clearly document that.\n\nFor HTTPRoute and TLSRoute resources, there is an interaction with the\n`spec.hostnames` array. When both listener and route specify hostnames,\nthere MUST be an intersection between the values for a Route to be\naccepted. For more information, refer to the Route specific Hostnames\ndocumentation.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted\nas a suffix match. That means that a match for `*.example.com` would match\nboth `test.example.com`, and `foo.test.example.com`, but not `example.com`.",
"maxLength": 253,
"minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"name": {
"description": "Name is the name of the Listener. This name MUST be unique within a\nListenerSet.\n\nName is not required to be unique across a Gateway and ListenerSets.\nRoutes can attach to a Listener by having a ListenerSet as a parentRef\nand setting the SectionName",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"port": {
"description": "Port is the network port. Multiple listeners may use the\nsame port, subject to the Listener compatibility rules.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"protocol": {
"description": "Protocol specifies the network protocol this listener expects to receive.",
"maxLength": 255,
"minLength": 1,
"pattern": "^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$",
"type": "string"
},
"tls": {
"description": "TLS is the TLS configuration for the Listener. This field is required if\nthe Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\nif the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\nThe association of SNIs to Certificate defined in ListenerTLSConfig is\ndefined based on the Hostname field for this listener.\n\nThe GatewayClass MUST use the longest matching SNI out of all\navailable certificates for any TLS handshake.",
"properties": {
"certificateRefs": {
"description": "CertificateRefs contains a series of references to Kubernetes objects that\ncontains TLS certificates and private keys. These certificates are used to\nestablish a TLS handshake for requests that match the hostname of the\nassociated listener.\n\nA single CertificateRef to a Kubernetes Secret has \"Core\" support.\nImplementations MAY choose to support attaching multiple certificates to\na Listener, but this behavior is implementation-specific.\n\nReferences to a resource in different namespace are invalid UNLESS there\nis a ReferenceGrant in the target namespace that allows the certificate\nto be attached. If a ReferenceGrant does not allow this reference, the\n\"ResolvedRefs\" condition MUST be set to False for this listener with the\n\"RefNotPermitted\" reason.\n\nThis field is required to have at least one element when the mode is set\nto \"Terminate\" (default) and is optional otherwise.\n\nCertificateRefs can reference to standard Kubernetes resources, i.e.\nSecret, or implementation-specific custom resources.\n\nSupport: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\nSupport: Implementation-specific (More than one reference or other resource types)",
"items": {
"description": "SecretObjectReference identifies an API object including its namespace,\ndefaulting to Secret.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.\n\nReferences to objects with invalid Group and Kind are not valid, and must\nbe rejected by the implementation, with appropriate Conditions set\non the containing object.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Secret",
"description": "Kind is kind of the referent. For example \"Secret\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referenced object. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mode": {
"default": "Terminate",
"description": "Mode defines the TLS behavior for the TLS session initiated by the client.\nThere are two possible modes:\n\n- Terminate: The TLS session between the downstream client and the\n Gateway is terminated at the Gateway. This mode requires certificates\n to be specified in some way, such as populating the certificateRefs\n field.\n- Passthrough: The TLS session is NOT terminated by the Gateway. This\n implies that the Gateway can't decipher the TLS stream except for\n the ClientHello message of the TLS protocol. The certificateRefs field\n is ignored in this mode.\n\nSupport: Core",
"enum": [
"Terminate",
"Passthrough"
],
"type": "string"
},
"options": {
"additionalProperties": {
"description": "AnnotationValue is the value of an annotation in Gateway API. This is used\nfor validation of maps such as TLS options. This roughly matches Kubernetes\nannotation validation, although the length validation in that case is based\non the entire size of the annotations struct.",
"maxLength": 4096,
"minLength": 0,
"type": "string"
},
"description": "Options are a list of key/value pairs to enable extended TLS\nconfiguration for each implementation. For example, configuring the\nminimum TLS version or supported cipher suites.\n\nA set of common keys MAY be defined by the API in the future. To avoid\nany ambiguity, implementation-specific definitions MUST use\ndomain-prefixed names, such as `example.com/my-custom-option`.\nUn-prefixed names are reserved for key names defined by Gateway API.\n\nSupport: Implementation-specific",
"maxProperties": 16,
"type": "object"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "certificateRefs or options must be specified when mode is Terminate",
"rule": "self.mode == 'Terminate' ? size(self.certificateRefs) > 0 || size(self.options) > 0 : true"
}
],
"additionalProperties": false
}
},
"required": [
"name",
"port",
"protocol"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map",
"x-kubernetes-validations": [
{
"message": "tls must not be specified for protocols ['HTTP', 'TCP', 'UDP']",
"rule": "self.all(l, l.protocol in ['HTTP', 'TCP', 'UDP'] ? !has(l.tls) : true)"
},
{
"message": "tls mode must be Terminate for protocol HTTPS",
"rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)"
},
{
"message": "tls mode must be set for protocol TLS",
"rule": "self.all(l, (l.protocol == 'TLS' ? has(l.tls) && has(l.tls.mode) && l.tls.mode != '' : true))"
},
{
"message": "hostname must not be specified for protocols ['TCP', 'UDP']",
"rule": "self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)"
},
{
"message": "Listener name must be unique within the Gateway",
"rule": "self.all(l1, self.exists_one(l2, l1.name == l2.name))"
},
{
"message": "Combination of port, protocol and hostname must be unique for each listener",
"rule": "self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port) && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
}
]
},
"parentRef": {
"description": "ParentRef references the Gateway that the listeners are attached to.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent. For example \"Gateway\".",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. If not present,\nthe namespace of the referent is assumed to be the same as\nthe namespace of the referring object.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"listeners",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"status": {
"default": {
"conditions": [
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Accepted"
},
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Programmed"
}
]
},
"description": "Status defines the current state of ListenerSet.",
"properties": {
"conditions": {
"default": [
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Accepted"
},
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Programmed"
}
],
"description": "Conditions describe the current conditions of the ListenerSet.\n\nImplementations MUST express ListenerSet conditions using the\n`ListenerSetConditionType` and `ListenerSetConditionReason`\nconstants so that operators and tools can converge on a common\nvocabulary to describe ListenerSet state.\n\nKnown condition types are:\n\n* \"Accepted\"\n* \"Programmed\"",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"listeners": {
"description": "Listeners provide status for each unique listener port defined in the Spec.",
"items": {
"description": "ListenerStatus is the status associated with a Listener.",
"properties": {
"attachedRoutes": {
"description": "AttachedRoutes represents the total number of Routes that have been\nsuccessfully attached to this Listener.\n\nSuccessful attachment of a Route to a Listener is based solely on the\ncombination of the AllowedRoutes field on the corresponding Listener\nand the Route's ParentRefs field. A Route is successfully attached to\na Listener when it is selected by the Listener's AllowedRoutes field\nAND the Route has a valid ParentRef selecting the whole Gateway\nresource or a specific Listener as a parent resource (more detail on\nattachment semantics can be found in the documentation on the various\nRoute kinds ParentRefs fields). Listener status does not impact\nsuccessful attachment, i.e. the AttachedRoutes field count MUST be set\nfor Listeners, even if the Accepted condition of an individual Listener is set\nto \"False\". The AttachedRoutes number represents the number of Routes with\nthe Accepted condition set to \"True\" that have been attached to this Listener.\nRoutes with any other value for the Accepted condition MUST NOT be included\nin this count.\n\nUses for this field include troubleshooting Route attachment and\nmeasuring blast radius/impact of changes to a Listener.",
"format": "int32",
"type": "integer"
},
"conditions": {
"description": "Conditions describe the current condition of this listener.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"name": {
"description": "Name is the name of the Listener that this status corresponds to.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"supportedKinds": {
"description": "SupportedKinds is the list indicating the Kinds supported by this\nlistener. This MUST represent the kinds supported by an implementation for\nthat Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT\nappear in this list and an implementation MUST set the \"ResolvedRefs\"\ncondition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\nand invalid Route kinds are specified, the implementation MUST\nreference the valid Route kinds that have been specified.",
"items": {
"description": "RouteGroupKind indicates the group and kind of a Route resource.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the Route.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is the kind of the Route.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"attachedRoutes",
"conditions",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,104 @@
{
"description": "ReferenceGrant identifies kinds of resources in other namespaces that are\ntrusted to reference the specified kinds of resources in the same namespace\nas the policy.\n\nEach ReferenceGrant can be used to represent a unique trust relationship.\nAdditional Reference Grants can be used to add to the set of trusted\nsources of inbound references for the namespace they are defined within.\n\nAll cross-namespace references in Gateway API (with the exception of cross-namespace\nGateway-route attachment) require a ReferenceGrant.\n\nReferenceGrant is a form of runtime verification allowing users to assert\nwhich cross-namespace object references are permitted. Implementations that\nsupport ReferenceGrant MUST NOT permit cross-namespace references which have\nno grant, and MUST respond to the removal of a grant by revoking the access\nthat the grant allowed.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of ReferenceGrant.",
"properties": {
"from": {
"description": "From describes the trusted namespaces and kinds that can reference the\nresources described in \"To\". Each entry in this list MUST be considered\nto be an additional place that references can be valid from, or to put\nthis another way, entries MUST be combined using OR.\n\nSupport: Core",
"items": {
"description": "ReferenceGrantFrom describes trusted namespaces and kinds.",
"properties": {
"group": {
"description": "Group is the group of the referent.\nWhen empty, the Kubernetes core API group is inferred.\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is the kind of the referent. Although implementations may support\nadditional resources, the following types are part of the \"Core\"\nsupport level for this field.\n\nWhen used to permit a SecretObjectReference:\n\n* Gateway\n\nWhen used to permit a BackendObjectReference:\n\n* GRPCRoute\n* HTTPRoute\n* TCPRoute\n* TLSRoute\n* UDPRoute",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"namespace"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"to": {
"description": "To describes the resources that may be referenced by the resources\ndescribed in \"From\". Each entry in this list MUST be considered to be an\nadditional place that references can be valid to, or to put this another\nway, entries MUST be combined using OR.\n\nSupport: Core",
"items": {
"description": "ReferenceGrantTo describes what Kinds are allowed as targets of the\nreferences.",
"properties": {
"group": {
"description": "Group is the group of the referent.\nWhen empty, the Kubernetes core API group is inferred.\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is the kind of the referent. Although implementations may support\nadditional resources, the following types are part of the \"Core\"\nsupport level for this field:\n\n* Secret when used to permit a SecretObjectReference\n* Service when used to permit a BackendObjectReference",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent. When unspecified, this policy\nrefers to all resources of the specified Group and Kind in the local\nnamespace.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"group",
"kind"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"from",
"to"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
@@ -0,0 +1,351 @@
{
"description": "TCPRoute provides a way to route TCP requests. When combined with a Gateway\nlistener, it can be used to forward connections on the port specified by the\nlistener to a set of backends specified by the TCPRoute.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of TCPRoute.",
"properties": {
"parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
},
{
"message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
}
]
},
"rules": {
"description": "Rules are a list of TCP matchers and actions.",
"items": {
"description": "TCPRouteRule is the configuration for a given rule.",
"properties": {
"backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent. If unspecified or invalid (refers to a nonexistent resource or a\nService with no endpoints), the underlying implementation MUST actively\nreject connection attempts to this backend. Connection rejections must\nrespect weight; if an invalid backend is requested to have 80% of\nconnections, then 80% of connections must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
"items": {
"description": "BackendRef defines how a Route should forward a request to a Kubernetes\nresource.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\nNote that when the BackendTLSPolicy object is enabled by the implementation,\nthere are some extra rules about validity to consider here. See the fields\nwhere this struct is used for more information about the exact behavior.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"weight": {
"default": 1,
"description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
"format": "int32",
"maximum": 1000000,
"minimum": 0,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"name": {
"description": "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"backendRefs"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
}
]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
}
},
"required": [
"rules"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of TCPRoute.",
"properties": {
"parents": {
"description": "Parents is a list of parent resources (usually Gateways) that are\nassociated with the route, and the status of the route with respect to\neach parent. When this route attaches to a parent, the controller that\nmanages the parent must add an entry to this list when the controller\nfirst sees the route and should update the entry as appropriate when the\nroute or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation\nof this API will not be added to this list. Implementations of this API\ncan only populate Route status for the Gateways/parent resources they are\nresponsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list\nmeans the route has not been attached to any Gateway.",
"items": {
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": {
"conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
},
"parentRef": {
"description": "ParentRef corresponds with a ParentRef in the spec that this\nRouteParentStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"conditions",
"controllerName",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"parents"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,374 @@
{
"description": "The TLSRoute resource is similar to TCPRoute, but can be configured\nto match against TLS-specific metadata. This allows more flexibility\nin matching streams for a given TLS listener.\n\nIf you need to forward traffic to a single target for a TLS listener, you\ncould choose to use a TCPRoute with a TLS listener.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of TLSRoute.",
"properties": {
"hostnames": {
"description": "Hostnames defines a set of SNI hostnames that should match against the\nSNI attribute of TLS ClientHello message in TLS handshake. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed in SNI hostnames per RFC 6066.\n2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.",
"items": {
"description": "Hostname is the fully qualified domain name of a network host. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n 1. IPs are not allowed.\n 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.\n\nHostname can be \"precise\" which is a domain name without the terminating\ndot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\ndomain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\nNote that as per RFC1035 and RFC1123, a *label* must consist of lower case\nalphanumeric characters or '-', and must start and end with an alphanumeric\ncharacter. No other punctuation is allowed.",
"maxLength": 253,
"minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "Hostnames cannot contain an IP",
"rule": "self.all(h, !isIP(h))"
},
{
"message": "Hostnames must be valid based on RFC-1123",
"rule": "self.all(h, !h.contains('*') ? h.matches('^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$') : true)"
},
{
"message": "Wildcards on hostnames must be the first label, and the rest of hostname must be valid based on RFC-1123",
"rule": "self.all(h, h.contains('*') ? (h.startsWith('*.') && h.substring(2).matches('^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$')) : true)"
}
]
},
"parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
},
{
"message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
}
]
},
"rules": {
"description": "Rules are a list of actions.",
"items": {
"description": "TLSRouteRule is the configuration for a given rule.",
"properties": {
"backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent. If unspecified or invalid (refers to a nonexistent resource or\na Service with no endpoints), the rule performs no forwarding; if no\nfilters are specified that would result in a response being sent, the\nunderlying implementation must actively reject request attempts to this\nbackend, by rejecting the connection. Request rejections must respect\nweight; if an invalid backend is requested to have 80% of requests, then\n80% of requests must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
"items": {
"description": "BackendRef defines how a Route should forward a request to a Kubernetes\nresource.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\nNote that when the BackendTLSPolicy object is enabled by the implementation,\nthere are some extra rules about validity to consider here. See the fields\nwhere this struct is used for more information about the exact behavior.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"weight": {
"default": 1,
"description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
"format": "int32",
"maximum": 1000000,
"minimum": 0,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"name": {
"description": "Name is the name of the route rule. This name MUST be unique within a Route if it is set.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"backendRefs"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 1,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
}
},
"required": [
"hostnames",
"rules"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of TLSRoute.",
"properties": {
"parents": {
"description": "Parents is a list of parent resources (usually Gateways) that are\nassociated with the route, and the status of the route with respect to\neach parent. When this route attaches to a parent, the controller that\nmanages the parent must add an entry to this list when the controller\nfirst sees the route and should update the entry as appropriate when the\nroute or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation\nof this API will not be added to this list. Implementations of this API\ncan only populate Route status for the Gateways/parent resources they are\nresponsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list\nmeans the route has not been attached to any Gateway.",
"items": {
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": {
"conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
},
"parentRef": {
"description": "ParentRef corresponds with a ParentRef in the spec that this\nRouteParentStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"conditions",
"controllerName",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"parents"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,364 @@
{
"description": "The TLSRoute resource is similar to TCPRoute, but can be configured\nto match against TLS-specific metadata. This allows more flexibility\nin matching streams for a given TLS listener.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of TLSRoute.",
"properties": {
"hostnames": {
"description": "Hostnames defines a set of SNI names that should match against the\nSNI attribute of TLS ClientHello message in TLS handshake. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed in SNI names per RFC 6066.\n2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.\n\nIf a hostname is specified by both the Listener and TLSRoute, there\nmust be at least one intersecting hostname for the TLSRoute to be\nattached to the Listener. For example:\n\n* A Listener with `test.example.com` as the hostname matches TLSRoutes\n that have either not specified any hostnames, or have specified at\n least one of `test.example.com` or `*.example.com`.\n* A Listener with `*.example.com` as the hostname matches TLSRoutes\n that have either not specified any hostnames or have specified at least\n one hostname that matches the Listener hostname. For example,\n `test.example.com` and `*.example.com` would both match. On the other\n hand, `example.com` and `test.example.net` would not match.\n\nIf both the Listener and TLSRoute have specified hostnames, any\nTLSRoute hostnames that do not match the Listener hostname MUST be\nignored. For example, if a Listener specified `*.example.com`, and the\nTLSRoute specified `test.example.com` and `test.example.net`,\n`test.example.net` must not be considered for a match.\n\nIf both the Listener and TLSRoute have specified hostnames, and none\nmatch with the criteria above, then the TLSRoute is not accepted. The\nimplementation must raise an 'Accepted' Condition with a status of\n`False` in the corresponding RouteParentStatus.\n\nSupport: Core",
"items": {
"description": "Hostname is the fully qualified domain name of a network host. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n 1. IPs are not allowed.\n 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.\n\nHostname can be \"precise\" which is a domain name without the terminating\ndot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\ndomain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\nNote that as per RFC1035 and RFC1123, a *label* must consist of lower case\nalphanumeric characters or '-', and must start and end with an alphanumeric\ncharacter. No other punctuation is allowed.",
"maxLength": 253,
"minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
},
{
"message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
}
]
},
"rules": {
"description": "Rules are a list of TLS matchers and actions.",
"items": {
"description": "TLSRouteRule is the configuration for a given rule.",
"properties": {
"backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent. If unspecified or invalid (refers to a nonexistent resource or\na Service with no endpoints), the rule performs no forwarding; if no\nfilters are specified that would result in a response being sent, the\nunderlying implementation must actively reject request attempts to this\nbackend, by rejecting the connection. Request rejections must respect\nweight; if an invalid backend is requested to have 80% of requests, then\n80% of requests must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
"items": {
"description": "BackendRef defines how a Route should forward a request to a Kubernetes\nresource.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\nNote that when the BackendTLSPolicy object is enabled by the implementation,\nthere are some extra rules about validity to consider here. See the fields\nwhere this struct is used for more information about the exact behavior.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"weight": {
"default": 1,
"description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
"format": "int32",
"maximum": 1000000,
"minimum": 0,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"name": {
"description": "Name is the name of the route rule. This name MUST be unique within a Route if it is set.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"backendRefs"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
}
]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
}
},
"required": [
"rules"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of TLSRoute.",
"properties": {
"parents": {
"description": "Parents is a list of parent resources (usually Gateways) that are\nassociated with the route, and the status of the route with respect to\neach parent. When this route attaches to a parent, the controller that\nmanages the parent must add an entry to this list when the controller\nfirst sees the route and should update the entry as appropriate when the\nroute or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation\nof this API will not be added to this list. Implementations of this API\ncan only populate Route status for the Gateways/parent resources they are\nresponsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list\nmeans the route has not been attached to any Gateway.",
"items": {
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": {
"conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
},
"parentRef": {
"description": "ParentRef corresponds with a ParentRef in the spec that this\nRouteParentStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"conditions",
"controllerName",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"parents"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,374 @@
{
"description": "The TLSRoute resource is similar to TCPRoute, but can be configured\nto match against TLS-specific metadata. This allows more flexibility\nin matching streams for a given TLS listener.\n\nIf you need to forward traffic to a single target for a TLS listener, you\ncould choose to use a TCPRoute with a TLS listener.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of TLSRoute.",
"properties": {
"hostnames": {
"description": "Hostnames defines a set of SNI hostnames that should match against the\nSNI attribute of TLS ClientHello message in TLS handshake. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed in SNI hostnames per RFC 6066.\n2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.",
"items": {
"description": "Hostname is the fully qualified domain name of a network host. This matches\nthe RFC 1123 definition of a hostname with 2 notable exceptions:\n\n 1. IPs are not allowed.\n 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n label must appear by itself as the first label.\n\nHostname can be \"precise\" which is a domain name without the terminating\ndot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\ndomain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\nNote that as per RFC1035 and RFC1123, a *label* must consist of lower case\nalphanumeric characters or '-', and must start and end with an alphanumeric\ncharacter. No other punctuation is allowed.",
"maxLength": 253,
"minLength": 1,
"pattern": "^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "Hostnames cannot contain an IP",
"rule": "self.all(h, !isIP(h))"
},
{
"message": "Hostnames must be valid based on RFC-1123",
"rule": "self.all(h, !h.contains('*') ? h.matches('^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$') : true)"
},
{
"message": "Wildcards on hostnames must be the first label, and the rest of hostname must be valid based on RFC-1123",
"rule": "self.all(h, h.contains('*') ? (h.startsWith('*.') && h.substring(2).matches('^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$')) : true)"
}
]
},
"parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
},
{
"message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
}
]
},
"rules": {
"description": "Rules are a list of actions.",
"items": {
"description": "TLSRouteRule is the configuration for a given rule.",
"properties": {
"backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent. If unspecified or invalid (refers to a nonexistent resource or\na Service with no endpoints), the rule performs no forwarding; if no\nfilters are specified that would result in a response being sent, the\nunderlying implementation must actively reject request attempts to this\nbackend, by rejecting the connection. Request rejections must respect\nweight; if an invalid backend is requested to have 80% of requests, then\n80% of requests must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
"items": {
"description": "BackendRef defines how a Route should forward a request to a Kubernetes\nresource.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\nNote that when the BackendTLSPolicy object is enabled by the implementation,\nthere are some extra rules about validity to consider here. See the fields\nwhere this struct is used for more information about the exact behavior.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"weight": {
"default": 1,
"description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
"format": "int32",
"maximum": 1000000,
"minimum": 0,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"name": {
"description": "Name is the name of the route rule. This name MUST be unique within a Route if it is set.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"backendRefs"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 1,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
}
},
"required": [
"hostnames",
"rules"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of TLSRoute.",
"properties": {
"parents": {
"description": "Parents is a list of parent resources (usually Gateways) that are\nassociated with the route, and the status of the route with respect to\neach parent. When this route attaches to a parent, the controller that\nmanages the parent must add an entry to this list when the controller\nfirst sees the route and should update the entry as appropriate when the\nroute or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation\nof this API will not be added to this list. Implementations of this API\ncan only populate Route status for the Gateways/parent resources they are\nresponsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list\nmeans the route has not been attached to any Gateway.",
"items": {
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": {
"conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
},
"parentRef": {
"description": "ParentRef corresponds with a ParentRef in the spec that this\nRouteParentStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"conditions",
"controllerName",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"parents"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,351 @@
{
"description": "UDPRoute provides a way to route UDP traffic. When combined with a Gateway\nlistener, it can be used to forward traffic on the port specified by the\nlistener to a set of backends specified by the UDPRoute.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of UDPRoute.",
"properties": {
"parentRefs": {
"description": "ParentRefs references the resources (usually Gateways) that a Route wants\nto be attached to. Note that the referenced parent resource needs to\nallow this for the attachment to be complete. For Gateways, that means\nthe Gateway needs to allow attachment from Routes of this kind and\nnamespace. For Services, that means the Service must either be in the same\nnamespace for a \"producer\" route, or the mesh implementation must support\nand allow \"consumer\" routes for the referenced Service. ReferenceGrant is\nnot applicable for governing ParentRefs to Services - it is not possible to\ncreate a \"producer\" route for a Service in a different namespace from the\nRoute.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects. If this is the case, then parentRef\n entries are distinct. In terms of fields, this means that the\n multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n each ParentRef that selects the same object must set the same set of\n optional fields to different values. If one ParentRef sets a\n combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may\nbe collapsed by an implementation. For example, some implementations may\nchoose to merge compatible Gateway Listeners together. If that is the\ncase, the list of routes attached to those resources should also be\nmerged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific\nrules. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example,\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable other kinds of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.",
"items": {
"description": "ParentReference identifies an API object (usually a Gateway) that can be considered\na parent of this resource (usually a route). There are two kinds of parent resources\nwith \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent\nresources.\n\nThe API object must be valid in the cluster; the Group and Kind must\nbe registered in the cluster for this reference to be valid.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))"
},
{
"message": "sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",
"rule": "self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))"
}
]
},
"rules": {
"description": "Rules are a list of UDP matchers and actions.",
"items": {
"description": "UDPRouteRule is the configuration for a given rule.",
"properties": {
"backendRefs": {
"description": "BackendRefs defines the backend(s) where matching requests should be\nsent. If unspecified or invalid (refers to a nonexistent resource or a\nService with no endpoints), the underlying implementation MUST actively\nreject connection attempts to this backend. Packet drops must\nrespect weight; if an invalid backend is requested to have 80% of\nthe packets, then 80% of packets must be dropped instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
"items": {
"description": "BackendRef defines how a Route should forward a request to a Kubernetes\nresource.\n\nNote that when a namespace different than the local namespace is specified, a\nReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\n\nWhen the BackendRef points to a Kubernetes Service, implementations SHOULD\nhonor the appProtocol field if it is set for the target Service Port.\n\nImplementations supporting appProtocol SHOULD recognize the Kubernetes\nStandard Application Protocols defined in KEP-3726.\n\nIf a Service appProtocol isn't specified, an implementation MAY infer the\nbackend protocol through its own means. Implementations MAY infer the\nprotocol from the Route type referring to the backend Service.\n\nIf a Route is not able to send traffic to the backend using the specified\nprotocol then the backend is considered invalid. Implementations MUST set the\n\"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\nNote that when the BackendTLSPolicy object is enabled by the implementation,\nthere are some extra rules about validity to consider here. See the fields\nwhere this struct is used for more information about the exact behavior.",
"properties": {
"group": {
"default": "",
"description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Service",
"description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"weight": {
"default": 1,
"description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
"format": "int32",
"maximum": 1000000,
"minimum": 0,
"type": "integer"
}
},
"required": [
"name"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "Must have port for Service reference",
"rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
}
],
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"name": {
"description": "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"backendRefs"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-type": "atomic",
"x-kubernetes-validations": [
{
"message": "Rule name must be unique within the route",
"rule": "self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))"
}
]
},
"useDefaultGateways": {
"description": "UseDefaultGateways indicates the default Gateway scope to use for this\nRoute. If unset (the default) or set to None, the Route will not be\nattached to any default Gateway; if set, it will be attached to any\ndefault Gateway supporting the named scope, subject to the usual rules\nabout which Routes a Gateway is allowed to claim.\n\nThink carefully before using this functionality! The set of default\nGateways supporting the requested scope can change over time without\nany notice to the Route author, and in many situations it will not be\nappropriate to request a default Gateway for a given Route -- for\nexample, a Route with specific security requirements should almost\ncertainly not use a default Gateway.",
"enum": [
"All",
"None"
],
"type": "string"
}
},
"required": [
"rules"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of UDPRoute.",
"properties": {
"parents": {
"description": "Parents is a list of parent resources (usually Gateways) that are\nassociated with the route, and the status of the route with respect to\neach parent. When this route attaches to a parent, the controller that\nmanages the parent must add an entry to this list when the controller\nfirst sees the route and should update the entry as appropriate when the\nroute or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation\nof this API will not be added to this list. Implementations of this API\ncan only populate Route status for the Gateways/parent resources they are\nresponsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list\nmeans the route has not been attached to any Gateway.",
"items": {
"description": "RouteParentStatus describes the status of a route with respect to an\nassociated Parent.",
"properties": {
"conditions": {
"description": "Conditions describes the status of the route with respect to the Gateway.\nNote that the route's availability is also subject to the Gateway's own\nstatus conditions and listener status.\n\nIf the Route's ParentRef specifies an existing Gateway that supports\nRoutes of this kind AND that Gateway's controller has sufficient access,\nthen that Gateway's controller MUST set the \"Accepted\" condition on the\nRoute, to indicate whether the route has been accepted or rejected by the\nGateway, and why.\n\nA Route MUST be considered \"Accepted\" if at least one of the Route's\nrules is implemented by the Gateway.\n\nThere are a number of cases where the \"Accepted\" condition may not be set\ndue to lack of controller visibility, that includes when:\n\n* The Route refers to a nonexistent parent.\n* The Route is of a type that the controller does not support.\n* The Route is in a namespace to which the controller does not have access.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
},
"parentRef": {
"description": "ParentRef corresponds with a ParentRef in the spec that this\nRouteParentStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"conditions",
"controllerName",
"parentRef"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 32,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"parents"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,344 @@
{
"description": "XBackendTrafficPolicy defines the configuration for how traffic to a\ntarget backend should be handled.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of BackendTrafficPolicy.",
"properties": {
"retryConstraint": {
"description": "RetryConstraint defines the configuration for when to allow or prevent\nfurther retries to a target backend, by dynamically calculating a 'retry\nbudget'. This budget is calculated based on the percentage of incoming\ntraffic composed of retries over a given time interval. Once the budget\nis exceeded, additional retries will be rejected.\n\nFor example, if the retry budget interval is 10 seconds, there have been\n1000 active requests in the past 10 seconds, and the allowed percentage\nof requests that can be retried is 20% (the default), then 200 of those\nrequests may be composed of retries. Active requests will only be\nconsidered for the duration of the interval when calculating the retry\nbudget. Retrying the same original request multiple times within the\nretry budget interval will lead to each retry being counted towards\ncalculating the budget.\n\nConfiguring a RetryConstraint in BackendTrafficPolicy is compatible with\nHTTPRoute Retry settings for each HTTPRouteRule that targets the same\nbackend. While the HTTPRouteRule Retry stanza can specify whether a\nrequest will be retried, and the number of retry attempts each client\nmay perform, RetryConstraint helps prevent cascading failures such as\nretry storms during periods of consistent failures.\n\nAfter the retry budget has been exceeded, additional retries to the\nbackend MUST return a 503 response to the client.\n\nAdditional configurations for defining a constraint on retries MAY be\ndefined in the future.\n\nSupport: Extended",
"properties": {
"budget": {
"default": {
"interval": "10s",
"percent": 20
},
"description": "Budget holds the details of the retry budget configuration.",
"properties": {
"interval": {
"default": "10s",
"description": "Interval defines the duration in which requests will be considered\nfor calculating the budget for retries.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "interval cannot be greater than one hour or less than one second",
"rule": "!(duration(self) < duration('1s') || duration(self) > duration('1h'))"
}
]
},
"percent": {
"default": 20,
"description": "Percent defines the maximum percentage of active requests that may\nbe made up of retries.\n\nSupport: Extended",
"maximum": 100,
"minimum": 0,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"minRetryRate": {
"default": {
"count": 10,
"interval": "1s"
},
"description": "MinRetryRate defines the minimum rate of retries that will be allowable\nover a specified duration of time.\n\nThe effective overall minimum rate of retries targeting the backend\nservice may be much higher, as there can be any number of clients which\nare applying this setting locally.\n\nThis ensures that requests can still be retried during periods of low\ntraffic, where the budget for retries may be calculated as a very low\nvalue.\n\nSupport: Extended",
"properties": {
"count": {
"description": "Count specifies the number of requests per time interval.\n\nSupport: Extended",
"maximum": 1000000,
"minimum": 1,
"type": "integer"
},
"interval": {
"description": "Interval specifies the divisor of the rate of requests, the amount of\ntime during which the given count of requests occur.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "interval cannot be greater than one hour",
"rule": "!(duration(self) == duration('0s') || duration(self) > duration('1h'))"
}
]
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"sessionPersistence": {
"description": "SessionPersistence defines and configures session persistence\nfor the backend.\n\nSupport: Extended",
"properties": {
"absoluteTimeout": {
"description": "AbsoluteTimeout defines the absolute timeout of the persistent\nsession. Once the AbsoluteTimeout duration has elapsed, the\nsession becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"cookieConfig": {
"description": "CookieConfig provides configuration settings that are specific\nto cookie-based session persistence.\n\nSupport: Core",
"properties": {
"lifetimeType": {
"default": "Session",
"description": "LifetimeType specifies whether the cookie has a permanent or\nsession-based lifetime. A permanent cookie persists until its\nspecified expiry time, defined by the Expires or Max-Age cookie\nattributes, while a session cookie is deleted when the current\nsession ends.\n\nWhen set to \"Permanent\", AbsoluteTimeout indicates the\ncookie's lifetime via the Expires or Max-Age cookie attributes\nand is required.\n\nWhen set to \"Session\", AbsoluteTimeout indicates the\nabsolute lifetime of the cookie tracked by the gateway and\nis optional.\n\nDefaults to \"Session\".\n\nSupport: Core for \"Session\" type\n\nSupport: Extended for \"Permanent\" type",
"enum": [
"Permanent",
"Session"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"idleTimeout": {
"description": "IdleTimeout defines the idle timeout of the persistent session.\nOnce the session has been idle for more than the specified\nIdleTimeout duration, the session becomes invalid.\n\nSupport: Extended",
"pattern": "^([0-9]{1,5}(h|m|s|ms)){1,4}$",
"type": "string"
},
"sessionName": {
"description": "SessionName defines the name of the persistent session token\nwhich may be reflected in the cookie or the header. Users\nshould avoid reusing session names to prevent unintended\nconsequences, such as rejection or unpredictable behavior.\n\nSupport: Implementation-specific",
"maxLength": 128,
"type": "string"
},
"type": {
"default": "Cookie",
"description": "Type defines the type of session persistence such as through\nthe use of a header or cookie. Defaults to cookie based session\npersistence.\n\nSupport: Core for \"Cookie\" type\n\nSupport: Extended for \"Header\" type",
"enum": [
"Cookie",
"Header"
],
"type": "string"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "AbsoluteTimeout must be specified when cookie lifetimeType is Permanent",
"rule": "!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType != 'Permanent' || has(self.absoluteTimeout)"
},
{
"message": "cookieConfig can only be set with type Cookie",
"rule": "!has(self.cookieConfig) || self.type == 'Cookie'"
}
],
"additionalProperties": false
},
"targetRefs": {
"description": "TargetRefs identifies API object(s) to apply this policy to.\nCurrently, Backends (A grouping of like endpoints such as Service,\nServiceImport, or any implementation-specific backendRef) are the only\nvalid API target references.\n\nCurrently, a TargetRef cannot be scoped to a specific port on a\nService.",
"items": {
"description": "LocalPolicyTargetReference identifies an API object to apply a direct or\ninherited policy to. This should be used as part of Policy resources\nthat can target Gateway API resources. For more information on how this\npolicy attachment model works, and a sample Policy resource, refer to\nthe policy attachment documentation for Gateway API.",
"properties": {
"group": {
"description": "Group is the group of the target resource.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the target resource.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the target resource.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"group",
"kind",
"name"
],
"x-kubernetes-list-type": "map"
}
},
"required": [
"targetRefs"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status defines the current state of BackendTrafficPolicy.",
"properties": {
"ancestors": {
"description": "Ancestors is a list of ancestor resources (usually Gateways) that are\nassociated with the policy, and the status of the policy with respect to\neach ancestor. When this policy attaches to a parent, the controller that\nmanages the parent and the ancestors MUST add an entry to this list when\nthe controller first sees the policy and SHOULD update the entry as\nappropriate when the relevant ancestor is modified.\n\nNote that choosing the relevant ancestor is left to the Policy designers;\nan important part of Policy design is designing the right object level at\nwhich to namespace this status.\n\nNote also that implementations MUST ONLY populate ancestor status for\nthe Ancestor resources they are responsible for. Implementations MUST\nuse the ControllerName field to uniquely identify the entries in this list\nthat they are responsible for.\n\nNote that to achieve this, the list of PolicyAncestorStatus structs\nMUST be treated as a map with a composite key, made up of the AncestorRef\nand ControllerName fields combined.\n\nA maximum of 16 ancestors will be represented in this list. An empty list\nmeans the Policy is not relevant for any ancestors.\n\nIf this slice is full, implementations MUST NOT add further entries.\nInstead they MUST consider the policy unimplementable and signal that\non any related resources such as the ancestor that would be referenced\nhere. For example, if this list was full on BackendTLSPolicy, no\nadditional Gateways would be able to reference the Service targeted by\nthe BackendTLSPolicy.",
"items": {
"description": "PolicyAncestorStatus describes the status of a route with respect to an\nassociated Ancestor.\n\nAncestors refer to objects that are either the Target of a policy or above it\nin terms of object hierarchy. For example, if a policy targets a Service, the\nPolicy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\nthe GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\nuseful object to place Policy status on, so we recommend that implementations\nSHOULD use Gateway as the PolicyAncestorStatus object unless the designers\nhave a _very_ good reason otherwise.\n\nIn the context of policy attachment, the Ancestor is used to distinguish which\nresource results in a distinct application of this policy. For example, if a policy\ntargets a Service, it may have a distinct result per attached Gateway.\n\nPolicies targeting the same resource may have different effects depending on the\nancestors of those resources. For example, different Gateways targeting the same\nService may have different capabilities, especially if they have different underlying\nimplementations.\n\nFor example, in BackendTLSPolicy, the Policy attaches to a Service that is\nused as a backend in a HTTPRoute that is itself attached to a Gateway.\nIn this case, the relevant object for status is the Gateway, and that is the\nancestor object referred to in this status.\n\nNote that a parent is also an ancestor, so for objects where the parent is the\nrelevant object for status, this struct SHOULD still be used.\n\nThis struct is intended to be used in a slice that's effectively a map,\nwith a composite key made up of the AncestorRef and the ControllerName.",
"properties": {
"ancestorRef": {
"description": "AncestorRef corresponds with a ParentRef in the spec that this\nPolicyAncestorStatus struct describes the status of.",
"properties": {
"group": {
"default": "gateway.networking.k8s.io",
"description": "Group is the group of the referent.\nWhen unspecified, \"gateway.networking.k8s.io\" is inferred.\nTo set the core API group (such as for a \"Service\" kind referent),\nGroup must be explicitly set to \"\" (empty string).\n\nSupport: Core",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"default": "Gateway",
"description": "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile)\n* Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent. When unspecified, this refers\nto the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace\nboundaries. Cross-namespace references are only valid if they are explicitly\nallowed by something in the namespace they are referring to. For example:\nGateway has the AllowedRoutes field, and ReferenceGrant provides a\ngeneric way to enable any other kind of cross-namespace reference.\n\n\nParentRefs from a Route to a Service in the same namespace are \"producer\"\nroutes, which apply default routing rules to inbound connections from\nany namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are\n\"consumer\" routes, and these routing rules are only applied to outbound\nconnections originating from the same namespace as the Route, for which\nthe intended destination of the connections are a Service targeted as a\nParentRef of the Route.\n\n\nSupport: Core",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
},
"port": {
"description": "Port is the network port this Route targets. It can be interpreted\ndifferently based on the type of parent resource.\n\nWhen the parent resource is a Gateway, this targets all listeners\nlistening on the specified port that also support this kind of Route(and\nselect this Route). It's not recommended to set `Port` unless the\nnetworking behaviors specified in a Route must apply to a specific port\nas opposed to a listener(s) whose port(s) may be changed. When both Port\nand SectionName are specified, the name and port of the selected listener\nmust match both specified values.\n\n\nWhen the parent resource is a Service, this targets a specific port in the\nService spec. When both Port (experimental) and SectionName are specified,\nthe name and port of the selected port must match both specified values.\n\n\nImplementations MAY choose to support other parent resources.\nImplementations supporting other types of parent resources MUST clearly\ndocument how/if Port is interpreted.\n\nFor the purpose of status, an attachment is considered successful as\nlong as the parent resource accepts it partially. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment\nfrom the referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route,\nthe Route MUST be considered detached from the Gateway.\n\nSupport: Extended",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"sectionName": {
"description": "SectionName is the name of a section within the target resource. In the\nfollowing resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n* Service: Port name. When both Port (experimental) and SectionName\nare specified, the name and port of the selected listener must match\nboth specified values.\n\nImplementations MAY choose to support attaching Routes to other resources.\nIf that is the case, they MUST clearly document how SectionName is\ninterpreted.\n\nWhen unspecified (empty string), this will reference the entire resource.\nFor the purpose of status, an attachment is considered successful if at\nleast one section in the parent resource accepts it. For example, Gateway\nlisteners can restrict which Routes can attach to them by Route kind,\nnamespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\nthe referencing Route, the Route MUST be considered successfully\nattached. If no Gateway listeners accept attachment from this Route, the\nRoute MUST be considered detached from the Gateway.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"conditions": {
"description": "Conditions describes the status of the Policy with respect to the given Ancestor.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"controllerName": {
"description": "ControllerName is a domain/path string that indicates the name of the\ncontroller that wrote this status. This corresponds with the\ncontrollerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\nvalid Kubernetes names\n(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that\nentries to status populated with their ControllerName are cleaned up when they are no\nlonger necessary.",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string"
}
},
"required": [
"ancestorRef",
"conditions",
"controllerName"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 16,
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"ancestors"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,203 @@
{
"description": "XMesh defines mesh-wide characteristics of a GAMMA-compliant service mesh.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the desired state of XMesh.",
"properties": {
"controllerName": {
"description": "ControllerName is the name of a controller that is managing Gateway API\nresources for mesh traffic management. The value of this field MUST be a\ndomain prefixed path.\n\nExample: \"example.com/awesome-mesh\".\n\nThis field is not mutable and cannot be empty.\n\nSupport: Core",
"maxLength": 253,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$",
"type": "string",
"x-kubernetes-validations": [
{
"message": "Value is immutable",
"rule": "self == oldSelf"
}
]
},
"description": {
"description": "Description optionally provides a human-readable description of a Mesh.",
"maxLength": 64,
"type": "string"
},
"parametersRef": {
"description": "ParametersRef is an optional reference to a resource that contains\nimplementation-specific configuration for this Mesh. If no\nimplementation-specific parameters are needed, this field MUST be\nomitted.\n\nParametersRef can reference a standard Kubernetes resource, i.e.\nConfigMap, or an implementation-specific custom resource. The resource\ncan be cluster-scoped or namespace-scoped.\n\nIf the referent cannot be found, refers to an unsupported kind, or when\nthe data within that resource is malformed, the Mesh MUST be rejected\nwith the \"Accepted\" status condition set to \"False\" and an\n\"InvalidParameters\" reason.\n\nSupport: Implementation-specific",
"properties": {
"group": {
"description": "Group is the group of the referent.",
"maxLength": 253,
"pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
"type": "string"
},
"kind": {
"description": "Kind is kind of the referent.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
"type": "string"
},
"name": {
"description": "Name is the name of the referent.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the referent.\nThis field is required when referring to a Namespace-scoped resource and\nMUST be unset when referring to a Cluster-scoped resource.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"group",
"kind",
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"controllerName"
],
"type": "object",
"additionalProperties": false
},
"status": {
"default": {
"conditions": [
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Accepted"
}
]
},
"description": "Status defines the current state of XMesh.",
"properties": {
"conditions": {
"default": [
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Accepted"
},
{
"lastTransitionTime": "1970-01-01T00:00:00Z",
"message": "Waiting for controller",
"reason": "Pending",
"status": "Unknown",
"type": "Programmed"
}
],
"description": "Conditions is the current status from the controller for\nthis Mesh.\n\nControllers should prefer to publish conditions using values\nof MeshConditionType for the type of each Condition.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 8,
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"supportedFeatures": {
"description": "SupportedFeatures is the set of features the Mesh support.\nIt MUST be sorted in ascending alphabetical order by the Name key.",
"items": {
"properties": {
"name": {
"description": "FeatureName is used to describe distinct features that are covered by\nconformance tests.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 64,
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"spec"
],
"type": "object"
}
@@ -0,0 +1,95 @@
{
"description": "PolicyFilter represents a Pomerium policy that can be attached to a particular route defined\nvia the Kubernetes Gateway API.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "Spec defines the content of the policy.",
"properties": {
"ppl": {
"description": "Policy rules in Pomerium Policy Language (PPL) syntax. May be expressed\nin either YAML or JSON format.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"status": {
"description": "Status contains the status of the policy (e.g. is the policy valid).",
"properties": {
"conditions": {
"description": "Conditions describe the current state of the PolicyFilter.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path .status.conditions. For example,\n\n\n\ttype FooStatus struct{\n\t // Represents the observations of a foo's current state.\n\t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t // other fields\n\t}",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.",
"format": "date-time",
"type": "string"
},
"message": {
"description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"description": "status of the condition, one of True, False, Unknown.",
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n---\nMany .condition.type values are consistent across resources like Available, but because arbitrary conditions can be\nuseful (see .node.status.conditions), the ability to deconflict is important.\nThe regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)",
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}
@@ -162,7 +162,7 @@
}, },
"maxRetries": { "maxRetries": {
"default": 3, "default": 3,
"description": "MaxRetries defines the number of retries for introspection requests.", "description": "MaxRetries defines the maximum number of retry attempts for failed requests.",
"type": "integer" "type": "integer"
}, },
"timeoutSeconds": { "timeoutSeconds": {
@@ -171,14 +171,14 @@
"type": "integer" "type": "integer"
}, },
"tls": { "tls": {
"description": "TLS configures TLS communication with the Authorization Server.", "description": "TLS configures TLS for the HTTP client.",
"properties": { "properties": {
"ca": { "ca": {
"description": "CA sets the CA bundle used to sign the Authorization Server certificate.", "description": "CA sets the CA bundle used to verify the server certificate.",
"type": "string" "type": "string"
}, },
"insecureSkipVerify": { "insecureSkipVerify": {
"description": "InsecureSkipVerify skips the Authorization Server certificate validation.\nFor testing purposes only, do not use in production.", "description": "InsecureSkipVerify skips the server certificate validation.\nFor testing purposes only, do not use in production.",
"type": "boolean" "type": "boolean"
} }
}, },
@@ -208,6 +208,11 @@
} }
] ]
}, },
"refreshInterval": {
"description": "RefreshInterval defines the rate at which the OpenAPI specification is refreshed.",
"format": "duration",
"type": "string"
},
"url": { "url": {
"description": "URL is a Traefik Hub agent accessible URL for obtaining the OpenAPI specification.\nThe URL must be accessible via a GET request method and should serve a YAML or JSON document containing the OpenAPI specification.", "description": "URL is a Traefik Hub agent accessible URL for obtaining the OpenAPI specification.\nThe URL must be accessible via a GET request method and should serve a YAML or JSON document containing the OpenAPI specification.",
"type": "string", "type": "string",
@@ -59,6 +59,38 @@
"description": "AppIDClaim is the name of the claim holding the identifier of the application.\nThis field is sometimes named `client_id`.", "description": "AppIDClaim is the name of the claim holding the identifier of the application.\nThis field is sometimes named `client_id`.",
"type": "string" "type": "string"
}, },
"clientConfig": {
"description": "ClientConfig configures the HTTP client used to fetch the JWKS from the JWKS URL or the trusted issuers.",
"properties": {
"maxRetries": {
"default": 3,
"description": "MaxRetries defines the maximum number of retry attempts for failed requests.",
"type": "integer"
},
"timeoutSeconds": {
"default": 5,
"description": "TimeoutSeconds configures the maximum amount of seconds to wait before giving up on requests.",
"type": "integer"
},
"tls": {
"description": "TLS configures TLS for the HTTP client.",
"properties": {
"ca": {
"description": "CA sets the CA bundle used to verify the server certificate.",
"type": "string"
},
"insecureSkipVerify": {
"description": "InsecureSkipVerify skips the server certificate validation.\nFor testing purposes only, do not use in production.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"forwardHeaders": { "forwardHeaders": {
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
@@ -162,6 +162,38 @@
"type": "object", "type": "object",
"additionalProperties": false "additionalProperties": false
}, },
"clientConfig": {
"description": "ClientConfig configures the HTTP client used to communicate with the OIDC provider.",
"properties": {
"maxRetries": {
"default": 3,
"description": "MaxRetries defines the maximum number of retry attempts for failed requests.",
"type": "integer"
},
"timeoutSeconds": {
"default": 5,
"description": "TimeoutSeconds configures the maximum amount of seconds to wait before giving up on requests.",
"type": "integer"
},
"tls": {
"description": "TLS configures TLS for the HTTP client.",
"properties": {
"ca": {
"description": "CA sets the CA bundle used to verify the server certificate.",
"type": "string"
},
"insecureSkipVerify": {
"description": "InsecureSkipVerify skips the server certificate validation.\nFor testing purposes only, do not use in production.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"issuerUrl": { "issuerUrl": {
"description": "IssuerURL is the OIDC provider issuer URL.", "description": "IssuerURL is the OIDC provider issuer URL.",
"type": "string", "type": "string",
@@ -208,6 +208,11 @@
} }
] ]
}, },
"refreshInterval": {
"description": "RefreshInterval defines the rate at which the OpenAPI specification is refreshed.",
"format": "duration",
"type": "string"
},
"url": { "url": {
"description": "URL is a Traefik Hub agent accessible URL for obtaining the OpenAPI specification.\nThe URL must be accessible via a GET request method and should serve a YAML or JSON document containing the OpenAPI specification.", "description": "URL is a Traefik Hub agent accessible URL for obtaining the OpenAPI specification.\nThe URL must be accessible via a GET request method and should serve a YAML or JSON document containing the OpenAPI specification.",
"type": "string", "type": "string",
@@ -0,0 +1,744 @@
{
"description": "Pomerium define runtime-configurable Pomerium settings\nthat do not fall into the category of deployment parameters",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "PomeriumSpec defines Pomerium-specific configuration parameters.",
"properties": {
"accessLogFields": {
"description": "AccessLogFields sets the <a href=\"https://www.pomerium.com/docs/reference/access-log-fields\">access fields</a> to log.",
"items": {
"type": "string"
},
"type": "array"
},
"allowUpgrades": {
"description": "AllowUpgrades sets the allowed upgrade types.",
"items": {
"type": "string"
},
"type": "array"
},
"authenticate": {
"description": "Authenticate sets authenticate service parameters.\nIf not specified, a Pomerium-hosted authenticate service would be used.",
"properties": {
"url": {
"description": "AuthenticateURL is a dedicated domain URL\nthe non-authenticated persons would be referred to.\n\n<p><ul>\n <li>You do not need to create a dedicated <code>Ingress</code> for this\n\t\tvirtual route, as it is handled by Pomerium internally. </li>\n\t<li>You do need create a secret with corresponding TLS certificate for this route\n\t\tand reference it via <a href=\"#prop-certificates\"><code>certificates</code></a>.\n\t\tIf you use <code>cert-manager</code> with <code>HTTP01</code> challenge,\n\t\tyou may use <code>pomerium</code> <code>ingressClass</code> to solve it.</li>\n</ul></p>",
"format": "uri",
"pattern": "^https://",
"type": "string"
}
},
"required": [
"url"
],
"type": "object",
"additionalProperties": false
},
"authorizeLogFields": {
"description": "AuthorizeLogFields sets the <a href=\"https://www.pomerium.com/docs/reference/authorize-log-fields\">authorize fields</a> to log.",
"items": {
"type": "string"
},
"type": "array"
},
"bearerTokenFormat": {
"description": "BearerTokenFormat sets the <a href=\"https://www.pomerium.com/docs/reference/bearer-token-format\">Bearer Token Format</a>.",
"enum": [
"default",
"idp_access_token",
"idp_identity_token"
],
"type": "string"
},
"caSecrets": {
"description": "CASecret should refer to k8s secrets with key <code>ca.crt</code> containing a CA certificate.",
"items": {
"type": "string"
},
"type": "array"
},
"certificateAutoProvision": {
"description": "CertificateAutoProvision sets the certificate auto provision settings.\nThis is a fallback for routes that are not defined via Ingress or\nGateway resources. When configured, cert-manager certificate resources\nwill be created for any routes which have no matching TLS certificate.",
"properties": {
"clusterIssuer": {
"description": "The cert-manager ClusterIssuer that will be used for new certificates.\nCertificates will be created in the same namespace as the controller\npod.",
"minLength": 1,
"type": "string"
},
"issuer": {
"description": "The cert-manager Issuer that will be used for new certificates.\nCertificates will be created in the same namespace as the Issuer.",
"format": "namespace/name",
"minLength": 1,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"certificates": {
"description": "Certificates is a list of secrets of type TLS to use",
"format": "namespace/name",
"items": {
"type": "string"
},
"type": "array"
},
"circuitBreakerThresholds": {
"description": "CircuitBreakerThresholds sets the circuit breaker thresholds settings.",
"properties": {
"maxConnectionPools": {
"description": "MaxConnectionPools sets the maximum number of connection pools per\ncluster that Envoy will concurrently support at once. If not specified,\nthe default is unlimited. Set this for clusters which create a large\nnumber of connection pools.",
"format": "int32",
"type": "integer"
},
"maxConnections": {
"description": "MaxConnections sets the maximum number of connections that Envoy will\nmake to the upstream cluster. If not specified, the default is 1024.",
"format": "int32",
"type": "integer"
},
"maxPendingRequests": {
"description": "MaxPendingRequests sets the maximum number of pending requests that\nEnvoy will allow to the upstream cluster. If not specified, the\ndefault is 1024. This limit is applied as a connection limit for\nnon-HTTP traffic.",
"format": "int32",
"type": "integer"
},
"maxRequests": {
"description": "MaxRequests sets the maximum number of parallel requests that Envoy\nwill make to the upstream cluster. If not specified, the default is\n1024. This limit does not apply to non-HTTP traffic.",
"format": "int32",
"type": "integer"
},
"maxRetries": {
"description": "MaxRetries sets the maximum number of parallel retries that Envoy\nwill allow to the upstream cluster. If not specified, the default is 3.",
"format": "int32",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"codecType": {
"description": "CodecType sets the <a href=\"https://www.pomerium.com/docs/reference/codec-type\">Codec Type</a>.",
"enum": [
"auto",
"http1",
"http2",
"http3"
],
"type": "string"
},
"cookie": {
"description": "Cookie defines Pomerium session cookie options.",
"properties": {
"domain": {
"description": "Domain defaults to the same host that set the cookie.\nIf you specify the domain explicitly, then subdomains would also be included.",
"type": "string"
},
"expire": {
"description": "Expire sets cookie and Pomerium session expiration time.\nOnce session expires, users would have to re-login.\nIf you change this parameter, existing sessions are not affected.\n<p>See <a href=\"https://www.pomerium.com/docs/enterprise/about#session-management\">Session Management</a>\n(Enterprise) for a more fine-grained session controls.</p>\n<p>Defaults to 14 hours.</p>",
"format": "duration",
"type": "string"
},
"httpOnly": {
"description": "HTTPOnly if set to <code>false</code>, the cookie would be accessible from within the JavaScript.\nDefaults to <code>true</code>.",
"type": "boolean"
},
"name": {
"description": "Name sets the Pomerium session cookie name.\nDefaults to <code>_pomerium</code>",
"type": "string"
},
"sameSite": {
"description": "SameSite sets the SameSite option for cookies.\nDefaults to <code></code>.",
"enum": [
"strict",
"lax",
"none"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"dataBroker": {
"description": "DataBroker sets the databroker settings.",
"properties": {
"clusterLeaderId": {
"description": "ClusterLeaderID defines the cluster leader in a clustered databroker.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"dns": {
"description": "DNS sets the dns settings.",
"properties": {
"failureRefreshRate": {
"description": "FailureRefreshRate is the rate at which DNS lookups are refreshed when requests are failing.",
"format": "duration",
"type": "string"
},
"lookupFamily": {
"description": "LookupFamily is the DNS IP address resolution policy.",
"enum": [
"auto",
"v4_only",
"v6_only",
"v4_preferred",
"all"
],
"type": "string"
},
"queryTimeout": {
"description": "QueryTimeout is the amount of time each name server is given to respond to a query on the first try of any given server.",
"format": "duration",
"type": "string"
},
"queryTries": {
"description": "QueryTries is the maximum number of query attempts the resolver will make before giving up. Each attempt may use a different name server.",
"format": "int32",
"type": "integer"
},
"refreshRate": {
"description": "RefreshRate is the rate at which DNS lookups are refreshed.",
"format": "duration",
"type": "string"
},
"udpMaxQueries": {
"description": "UDPMaxQueries caps the number of UDP based DNS queries on a single port.",
"format": "int32",
"type": "integer"
},
"useTcp": {
"description": "UseTCP uses TCP for all DNS queries instead of the default protocol UDP.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
},
"downstreamMtls": {
"description": "DownstreamMTLS sets the <a href=\"https://www.pomerium.com/docs/reference/downstream-mtls-settings\">Downstream MTLS Settings</a>.",
"properties": {
"ca": {
"description": "CA is a bundle of PEM-encoded X.509 certificates that will be treated as trust anchors when verifying client certificates.",
"format": "byte",
"type": "string"
},
"crl": {
"description": "CRL is a bundle of PEM-encoded certificate revocation lists to be consulted during certificate validation.",
"format": "byte",
"type": "string"
},
"enforcement": {
"description": "Enforcement controls Pomerium's behavior when a client does not present a trusted client certificate.",
"enum": [
"policy_with_default_deny",
"policy",
"reject_connection"
],
"type": "string"
},
"matchSubjectAltNames": {
"description": "Match Subject Alt Names can be used to add an additional constraint when validating client certificates.",
"properties": {
"dns": {
"type": "string"
},
"email": {
"type": "string"
},
"ipAddress": {
"type": "string"
},
"uri": {
"type": "string"
},
"userPrincipalName": {
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"maxVerifyDepth": {
"description": "MaxVerifyDepth sets a limit on the depth of a certificate chain presented by the client.",
"format": "int32",
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"envoyDynamicExtensions": {
"description": "EnvoyDynamicExtensions file paths to the extensions to be loaded by Envoy at runtime.",
"items": {
"type": "string"
},
"type": "array"
},
"headersWithUnderscoresAction": {
"description": "HeadersWithUnderscoresAction controls the behavior for a request with a\nheader name containing an underscore character. The default behavior is\nreject_request.",
"enum": [
"allow",
"reject_request",
"drop_header"
],
"type": "string"
},
"identityProvider": {
"description": "IdentityProvider configure single-sign-on authentication and user identity details\nby integrating with your <a href=\"https://www.pomerium.com/docs/identity-providers/\">Identity Provider</a>",
"properties": {
"provider": {
"description": "Provider is the short-hand name of a built-in OpenID Connect (oidc) identity provider to be used for authentication.\nTo use a generic provider, set to <code>oidc</code>.",
"enum": [
"apple",
"auth0",
"azure",
"cognito",
"github",
"gitlab",
"google",
"hosted",
"oidc",
"okta",
"onelogin",
"ping"
],
"type": "string"
},
"refreshDirectory": {
"description": "RefreshDirectory is no longer supported,\nplease see <a href=\"https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync\">Upgrade Guide</a>.",
"properties": {
"interval": {
"description": "interval is the time that pomerium will sync your IDP directory.",
"format": "duration",
"type": "string"
},
"timeout": {
"description": "timeout is the maximum time allowed each run.",
"format": "duration",
"type": "string"
}
},
"required": [
"interval",
"timeout"
],
"type": "object",
"additionalProperties": false
},
"requestParams": {
"additionalProperties": {
"type": "string"
},
"description": "RequestParams to be added as part of a sign-in request using OAuth2 code flow.",
"format": "namespace/name",
"type": "object"
},
"requestParamsSecret": {
"description": "RequestParamsSecret is a reference to a secret for additional parameters you'd prefer not to provide in plaintext.",
"format": "namespace/name",
"type": "string"
},
"scopes": {
"description": "Scopes Identity provider scopes correspond to access privilege scopes\nas defined in Section 3.3 of OAuth 2.0 RFC6749.",
"items": {
"type": "string"
},
"type": "array"
},
"secret": {
"description": "Secret containing IdP provider specific parameters.\nand must contain at least <code>client_id</code> and <code>client_secret</code> values.",
"format": "namespace/name",
"minLength": 1,
"type": "string"
},
"serviceAccountFromSecret": {
"description": "ServiceAccountFromSecret is no longer supported,\nsee <a href=\"https://docs.pomerium.com/docs/overview/upgrading#idp-directory-sync\">Upgrade Guide</a>.",
"type": "string"
},
"url": {
"description": "URL is the base path to an identity provider's OpenID connect discovery document.\nSee <a href=\"https://pomerium.com/docs/identity-providers\">Identity Providers</a> guides for details.",
"format": "uri",
"pattern": "^https://",
"type": "string"
}
},
"required": [
"provider"
],
"type": "object",
"x-kubernetes-validations": [
{
"fieldPath": ".secret",
"message": "secret is required unless provider is 'hosted'",
"reason": "FieldValueRequired",
"rule": "self.provider != 'hosted' ? has(self.secret) : true"
}
],
"additionalProperties": false
},
"idpAccessTokenAllowedAudiences": {
"description": "IDPAccessTokenAllowedAudiences specifies the\n<a href=\"https://www.pomerium.com/docs/reference/idp-access-token-allowed-audiences\">idp access token allowed audiences</a>\nlist.",
"items": {
"type": "string"
},
"type": "array"
},
"jwtClaimHeaders": {
"additionalProperties": {
"type": "string"
},
"description": "JWTClaimHeaders convert claims from the assertion token\ninto HTTP headers and adds them into JWT assertion header.\nPlease make sure to read\n<a href=\"https://www.pomerium.com/docs/capabilities/getting-users-identity\">\nGetting User Identity</a> guide.",
"type": "object"
},
"mcpAllowedAsMetadataDomains": {
"description": "MCPAllowedASMetadataDomains specifies the allowed domains for upstream AS/PRM metadata URLs.\nSupports wildcard patterns like \"*.example.com\".\nThis restricts which domains Pomerium will contact during upstream OAuth discovery\n(resource_metadata from WWW-Authenticate, authorization_servers from PRM).\nSee <a href=\"https://www.pomerium.com/docs/reference/mcp\">MCP Settings</a>.",
"items": {
"type": "string"
},
"type": "array"
},
"mcpAllowedClientIdDomains": {
"description": "MCPAllowedClientIDDomains specifies the allowed domains for MCP client ID metadata URLs.\nThis is required when MCP is enabled.\nSee <a href=\"https://www.pomerium.com/docs/reference/mcp\">MCP Settings</a>.",
"items": {
"type": "string"
},
"type": "array"
},
"mergeSlashes": {
"description": "MergeSlashes controls whether adjacent slashes in the request URI path\nwill be merged into one. Defaults to true.",
"type": "boolean"
},
"normalizePath": {
"description": "NormalizePath controls whether request URI paths will be normalized\naccording to RFC 3986. Defaults to true.",
"type": "boolean"
},
"otel": {
"description": "OTEL sets the <a href=\"https://www.pomerium.com/docs/reference/tracing\">OpenTelemetry Tracing</a>.",
"properties": {
"bspMaxExportBatchSize": {
"description": "BSPMaxExportBatchSize sets the maximum number of spans to export in a single batch",
"format": "int32",
"type": "integer"
},
"bspScheduleDelay": {
"description": "BSPScheduleDelay sets interval between two consecutive exports",
"format": "duration",
"type": "string"
},
"endpoint": {
"description": "An OTLP/gRPC or OTLP/HTTP base endpoint URL with optional port.<br/>Example: `http://localhost:4318`",
"type": "string"
},
"headers": {
"additionalProperties": {
"type": "string"
},
"description": "Extra headers",
"type": "object"
},
"logLevel": {
"description": "LogLevel sets the log level for the OpenTelemetry SDK.",
"enum": [
"trace",
"debug",
"info",
"warn",
"error"
],
"type": "string"
},
"protocol": {
"description": "Valid values are `\"grpc\"` or `\"http/protobuf\"`.",
"enum": [
"grpc",
"http/protobuf"
],
"type": "string"
},
"resourceAttributes": {
"additionalProperties": {
"type": "string"
},
"description": "ResourceAttributes sets the additional attributes to be added to the trace.",
"type": "object"
},
"sampling": {
"description": "Sampling sets sampling probability between [0, 1].",
"format": "number",
"type": "string"
},
"timeout": {
"description": "Export request timeout duration",
"format": "duration",
"type": "string"
}
},
"required": [
"endpoint",
"protocol"
],
"type": "object",
"additionalProperties": false
},
"passIdentityHeaders": {
"description": "PassIdentityHeaders sets the <a href=\"https://www.pomerium.com/docs/reference/pass-identity-headers\">pass identity headers</a> option.",
"type": "boolean"
},
"pathWithEscapedSlashesAction": {
"description": "PathWithEscapedSlashesAction controls the behavior for a request with an\nescaped slash or backslash character in the URI path. This operation will\noccur before path normalization and the merge slashes operation. The\ndefault behavior is reject_request.",
"enum": [
"keep_unchanged",
"reject_request",
"unescape_and_redirect",
"unescape_and_forward"
],
"type": "string"
},
"programmaticRedirectDomains": {
"description": "ProgrammaticRedirectDomains specifies a list of domains that can be used for\n<a href=\"https://www.pomerium.com/docs/capabilities/programmatic-access\">programmatic redirects</a>.",
"items": {
"type": "string"
},
"type": "array"
},
"runtimeFlags": {
"additionalProperties": {
"type": "boolean"
},
"description": "RuntimeFlags sets the <a href=\"https://www.pomerium.com/docs/reference/runtime-flags\">runtime flags</a> to enable/disable certain features.",
"type": "object"
},
"secrets": {
"description": "Secrets references a Secret with Pomerium bootstrap parameters.\n\n<p>\n<ul>\n\t<li><a href=\"https://pomerium.com/docs/reference/shared-secret\"><code>shared_secret</code></a>\n\t\t- secures inter-Pomerium service communications.\n\t</li>\n\t<li><a href=\"https://pomerium.com/docs/reference/cookie-secret\"><code>cookie_secret</code></a>\n\t\t- encrypts Pomerium session browser cookie.\n\t\tSee also other <a href=\"#cookie\">Cookie</a> parameters.\n\t</li>\n\t<li><a href=\"https://pomerium.com/docs/reference/signing-key\"><code>signing_key</code></a>\n\t\tsigns Pomerium JWT assertion header. See\n\t\t<a href=\"https://www.pomerium.com/docs/capabilities/getting-users-identity\">Getting the user's identity</a>\n\t\tguide.\n\t</li>\n</ul>\n</p>\n<p>\nIn a default Pomerium installation manifest, they would be generated via a\n<a href=\"https://github.com/pomerium/ingress-controller/blob/main/config/gen_secrets/job.yaml\">one-time job</a>\nand stored in a <code>pomerium/bootstrap</code> Secret.\nYou may re-run the job to rotate the secrets, or update the Secret values manually.\n</p>\n<p>\nWhen defining the Secret in a manifest, put raw values in <code>stringData</code> so\nKubernetes base64-encodes them. Use <code>data</code> only when values are already\nbase64-encoded.\n</p>\n<p>\nExample: <code>stringData.shared_secret</code> and <code>stringData.cookie_secret</code> are\nraw strings, while <code>data.signing_key</code> is base64-encoded.\n</p>",
"format": "namespace/name",
"minLength": 1,
"type": "string"
},
"setResponseHeaders": {
"additionalProperties": {
"type": "string"
},
"description": "SetResponseHeaders specifies a mapping of HTTP Header to be added globally to all managed routes and pomerium's authenticate service.\nSee <a href=\"https://www.pomerium.com/docs/reference/set-response-headers\">Set Response Headers</a>",
"type": "object"
},
"ssh": {
"description": "SSH sets the ssh settings.",
"properties": {
"hostKeySecrets": {
"items": {
"type": "string"
},
"type": "array"
},
"userCaKeySecret": {
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"storage": {
"description": "Storage defines persistent storage for sessions and other data.\nSee <a href=\"https://www.pomerium.com/docs/internals/data-storage\">Storage</a> for details.\nIf no storage is specified, Pomerium would use a transient in-memory storage (not recommended for production).",
"properties": {
"file": {
"description": "File specifies file storage options.",
"properties": {
"path": {
"description": "Path defines the local file system path to store data.",
"minLength": 1,
"type": "string"
}
},
"required": [
"path"
],
"type": "object",
"additionalProperties": false
},
"postgres": {
"description": "Postgres specifies PostgreSQL database connection parameters",
"properties": {
"caSecret": {
"description": "CASecret should refer to a k8s secret with key <code>ca.crt</code> containing CA certificate\nthat, if specified, would be used to populate <code>sslrootcert</code> parameter of the connection string.",
"format": "namespace/name",
"minLength": 1,
"type": "string"
},
"secret": {
"description": "Secret specifies a name of a Secret that must contain\n<code>connection</code> key. See\n<a href=\"https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING\">DSN Format and Parameters</a>.\nDo not set <code>sslrootcert</code>, <code>sslcert</code> and <code>sslkey</code> via connection string,\nuse <code>tlsSecret</code> and <code>caSecret</code> CRD options instead.",
"format": "namespace/name",
"minLength": 1,
"type": "string"
},
"tlsSecret": {
"description": "TLSSecret should refer to a k8s secret of type <code>kubernetes.io/tls</code>\nand allows to specify an optional client certificate and key,\nby constructing <code>sslcert</code> and <code>sslkey</code> connection string\n<a href=\"https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS\">\nparameter values</a>.",
"format": "namespace/name",
"minLength": 1,
"type": "string"
}
},
"required": [
"secret"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"timeouts": {
"description": "Timeout specifies the <a href=\"https://www.pomerium.com/docs/reference/global-timeouts\">global timeouts</a> for all routes.",
"properties": {
"idle": {
"description": "Idle specifies the time at which a downstream or upstream connection will be terminated if there are no active streams.",
"format": "duration",
"type": "string"
},
"read": {
"description": "Read specifies the amount of time for the entire request stream to be received from the client.",
"format": "duration",
"type": "string"
},
"write": {
"description": "Write specifies max stream duration is the maximum time that a stream\u2019s lifetime will span.\nAn HTTP request/response exchange fully consumes a single stream.\nTherefore, this value must be greater than read_timeout as it covers both request and response time.",
"format": "duration",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"useProxyProtocol": {
"description": "UseProxyProtocol enables <a href=\"https://www.pomerium.com/docs/reference/use-proxy-protocol\">Proxy Protocol</a> support.",
"type": "boolean"
}
},
"required": [
"secrets"
],
"type": "object",
"x-kubernetes-validations": [
{
"fieldPath": ".authenticate",
"message": "authenticate is required if identityProvider is set",
"reason": "FieldValueRequired",
"rule": "!has(self.identityProvider) || has(self.authenticate)"
},
{
"fieldPath": ".identityProvider",
"message": "identityProvider is required if authenticate is set",
"reason": "FieldValueRequired",
"rule": "!has(self.authenticate) || has(self.identityProvider)"
}
],
"additionalProperties": false
},
"status": {
"description": "PomeriumStatus represents configuration and Ingress status.",
"properties": {
"certificateAutoProvisionStatus": {
"description": "Status of certificate auto provisioning.",
"properties": {
"dataBrokerLastUpdated": {
"format": "date-time",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"ingress": {
"additionalProperties": {
"description": "ResourceStatus represents the outcome of the latest attempt to reconcile\nrelevant Kubernetes resource with Pomerium.",
"properties": {
"error": {
"description": "Error that prevented latest observedGeneration to be synchronized with Pomerium.",
"type": "string"
},
"observedAt": {
"description": "ObservedAt is when last reconciliation attempt was made.",
"format": "date-time",
"type": "string"
},
"observedGeneration": {
"description": "ObservedGeneration represents the <code>.metadata.generation</code> that was last presented to Pomerium.",
"format": "int64",
"type": "integer"
},
"reconciled": {
"description": "Reconciled is whether this object generation was successfully synced with pomerium.",
"type": "boolean"
},
"warnings": {
"description": "Warnings while parsing the resource.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"reconciled"
],
"type": "object",
"additionalProperties": false
},
"description": "Routes provide per-Ingress status.",
"type": "object"
},
"settingsStatus": {
"description": "SettingsStatus represent most recent main configuration reconciliation status.",
"properties": {
"error": {
"description": "Error that prevented latest observedGeneration to be synchronized with Pomerium.",
"type": "string"
},
"observedAt": {
"description": "ObservedAt is when last reconciliation attempt was made.",
"format": "date-time",
"type": "string"
},
"observedGeneration": {
"description": "ObservedGeneration represents the <code>.metadata.generation</code> that was last presented to Pomerium.",
"format": "int64",
"type": "integer"
},
"reconciled": {
"description": "Reconciled is whether this object generation was successfully synced with pomerium.",
"type": "boolean"
},
"warnings": {
"description": "Warnings while parsing the resource.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"reconciled"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}

Some files were not shown because too many files have changed in this diff Show More