{ "$schema": "http://json-schema.org/draft-07/schema#", "properties": { "apiVersion": { "type": "string" }, "kind": { "type": "string" }, "metadata": { "type": "object" }, "spec": { "properties": { "addresses": { "items": { "oneOf": [ { "properties": { "type": { "enum": [ "IPAddress" ] }, "value": { "anyOf": [ { "format": "ipv4" }, { "format": "ipv6" } ] } } }, { "properties": { "type": { "not": { "enum": [ "IPAddress" ] } } } } ], "properties": { "type": { "default": "IPAddress", "maxLength": 253, "minLength": 1, "pattern": "^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$", "type": "string" }, "value": { "maxLength": 253, "type": "string" } }, "type": "object", "x-kubernetes-validations": [ { "message": "Hostname value must be empty or contain only valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)", "rule": "self.type == 'Hostname' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")): true" } ] }, "maxItems": 16, "type": "array", "x-kubernetes-list-type": "atomic", "x-kubernetes-validations": [ { "message": "IPAddress values must be unique", "rule": "self.all(a1, a1.type == 'IPAddress' && has(a1.value) ? self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value == a1.value) : true )" }, { "message": "Hostname values must be unique", "rule": "self.all(a1, a1.type == 'Hostname' && has(a1.value) ? self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value == a1.value) : true )" } ] }, "allowedListeners": { "properties": { "namespaces": { "default": { "from": "None" }, "properties": { "from": { "default": "None", "enum": [ "All", "Selector", "Same", "None" ], "type": "string" }, "selector": { "properties": { "matchExpressions": { "items": { "properties": { "key": { "type": "string" }, "operator": { "type": "string" }, "values": { "items": { "type": "string" }, "type": "array", "x-kubernetes-list-type": "atomic" } }, "required": [ "key", "operator" ], "type": "object" }, "type": "array", "x-kubernetes-list-type": "atomic" }, "matchLabels": { "additionalProperties": { "type": "string" }, "type": "object" } }, "type": "object", "x-kubernetes-map-type": "atomic" } }, "type": "object" } }, "type": "object" }, "gatewayClassName": { "maxLength": 253, "minLength": 1, "type": "string" }, "infrastructure": { "properties": { "annotations": { "additionalProperties": { "maxLength": 4096, "minLength": 0, "type": "string" }, "maxProperties": 8, "type": "object", "x-kubernetes-validations": [ { "message": "Annotation keys must be in the form of an optional DNS subdomain prefix followed by a required name segment of up to 63 characters.", "rule": "self.all(key, key.matches(r\"\"\"^([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]$\"\"\"))" }, { "message": "If specified, the annotation key's prefix must be a DNS subdomain not longer than 253 characters in total.", "rule": "self.all(key, key.split(\"/\")[0].size() < 253)" } ] }, "labels": { "additionalProperties": { "maxLength": 63, "minLength": 0, "pattern": "^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$", "type": "string" }, "maxProperties": 8, "type": "object", "x-kubernetes-validations": [ { "message": "Label keys must be in the form of an optional DNS subdomain prefix followed by a required name segment of up to 63 characters.", "rule": "self.all(key, key.matches(r\"\"\"^([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]$\"\"\"))" }, { "message": "If specified, the label key's prefix must be a DNS subdomain not longer than 253 characters in total.", "rule": "self.all(key, key.split(\"/\")[0].size() < 253)" } ] }, "parametersRef": { "properties": { "group": { "maxLength": 253, "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "type": "string" }, "kind": { "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" }, "name": { "maxLength": 253, "minLength": 1, "type": "string" } }, "required": [ "group", "kind", "name" ], "type": "object" } }, "type": "object" }, "listeners": { "items": { "properties": { "allowedRoutes": { "default": { "namespaces": { "from": "Same" } }, "properties": { "kinds": { "items": { "properties": { "group": { "default": "gateway.networking.k8s.io", "maxLength": 253, "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "type": "string" }, "kind": { "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" } }, "required": [ "kind" ], "type": "object" }, "maxItems": 8, "type": "array", "x-kubernetes-list-type": "atomic" }, "namespaces": { "default": { "from": "Same" }, "properties": { "from": { "default": "Same", "enum": [ "All", "Selector", "Same" ], "type": "string" }, "selector": { "properties": { "matchExpressions": { "items": { "properties": { "key": { "type": "string" }, "operator": { "type": "string" }, "values": { "items": { "type": "string" }, "type": "array", "x-kubernetes-list-type": "atomic" } }, "required": [ "key", "operator" ], "type": "object" }, "type": "array", "x-kubernetes-list-type": "atomic" }, "matchLabels": { "additionalProperties": { "type": "string" }, "type": "object" } }, "type": "object", "x-kubernetes-map-type": "atomic" } }, "type": "object" } }, "type": "object" }, "hostname": { "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": { "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": { "format": "int32", "maximum": 65535, "minimum": 1, "type": "integer" }, "protocol": { "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": { "properties": { "certificateRefs": { "items": { "properties": { "group": { "default": "", "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", "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" }, "name": { "maxLength": 253, "minLength": 1, "type": "string" }, "namespace": { "maxLength": 63, "minLength": 1, "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "type": "string" } }, "required": [ "name" ], "type": "object" }, "maxItems": 64, "type": "array", "x-kubernetes-list-type": "atomic" }, "mode": { "default": "Terminate", "enum": [ "Terminate", "Passthrough" ], "type": "string" }, "options": { "additionalProperties": { "maxLength": 4096, "minLength": 0, "type": "string" }, "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" } ] } }, "required": [ "name", "port", "protocol" ], "type": "object" }, "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, 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": { "properties": { "backend": { "properties": { "clientCertificateRef": { "properties": { "group": { "default": "", "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", "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" }, "name": { "maxLength": 253, "minLength": 1, "type": "string" }, "namespace": { "maxLength": 63, "minLength": 1, "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "type": "string" } }, "required": [ "name" ], "type": "object" } }, "type": "object" }, "frontend": { "properties": { "default": { "properties": { "validation": { "properties": { "caCertificateRefs": { "items": { "properties": { "group": { "maxLength": 253, "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "type": "string" }, "kind": { "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" }, "name": { "maxLength": 253, "minLength": 1, "type": "string" }, "namespace": { "maxLength": 63, "minLength": 1, "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "type": "string" } }, "required": [ "group", "kind", "name" ], "type": "object" }, "maxItems": 8, "minItems": 1, "type": "array", "x-kubernetes-list-type": "atomic" }, "mode": { "default": "AllowValidOnly", "enum": [ "AllowValidOnly", "AllowInsecureFallback" ], "type": "string" } }, "required": [ "caCertificateRefs" ], "type": "object" } }, "type": "object" }, "perPort": { "items": { "properties": { "port": { "format": "int32", "maximum": 65535, "minimum": 1, "type": "integer" }, "tls": { "properties": { "validation": { "properties": { "caCertificateRefs": { "items": { "properties": { "group": { "maxLength": 253, "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "type": "string" }, "kind": { "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" }, "name": { "maxLength": 253, "minLength": 1, "type": "string" }, "namespace": { "maxLength": 63, "minLength": 1, "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", "type": "string" } }, "required": [ "group", "kind", "name" ], "type": "object" }, "maxItems": 8, "minItems": 1, "type": "array", "x-kubernetes-list-type": "atomic" }, "mode": { "default": "AllowValidOnly", "enum": [ "AllowValidOnly", "AllowInsecureFallback" ], "type": "string" } }, "required": [ "caCertificateRefs" ], "type": "object" } }, "type": "object" } }, "required": [ "port", "tls" ], "type": "object" }, "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" } }, "type": "object" } }, "required": [ "gatewayClassName", "listeners" ], "type": "object" }, "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" } ] }, "properties": { "addresses": { "items": { "oneOf": [ { "properties": { "type": { "enum": [ "IPAddress" ] }, "value": { "anyOf": [ { "format": "ipv4" }, { "format": "ipv6" } ] } } }, { "properties": { "type": { "not": { "enum": [ "IPAddress" ] } } } } ], "properties": { "type": { "default": "IPAddress", "maxLength": 253, "minLength": 1, "pattern": "^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$", "type": "string" }, "value": { "maxLength": 253, "minLength": 1, "type": "string" } }, "required": [ "value" ], "type": "object", "x-kubernetes-validations": [ { "message": "Hostname value must only contain valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)", "rule": "self.type == 'Hostname' ? self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\"): true" } ] }, "maxItems": 16, "type": "array", "x-kubernetes-list-type": "atomic" }, "attachedListenerSets": { "format": "int32", "type": "integer" }, "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" } ], "items": { "properties": { "lastTransitionTime": { "format": "date-time", "type": "string" }, "message": { "maxLength": 32768, "type": "string" }, "observedGeneration": { "format": "int64", "minimum": 0, "type": "integer" }, "reason": { "maxLength": 1024, "minLength": 1, "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", "type": "string" }, "status": { "enum": [ "True", "False", "Unknown" ], "type": "string" }, "type": { "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" }, "maxItems": 8, "type": "array", "x-kubernetes-list-map-keys": [ "type" ], "x-kubernetes-list-type": "map" }, "listeners": { "items": { "properties": { "attachedRoutes": { "format": "int32", "type": "integer" }, "conditions": { "items": { "properties": { "lastTransitionTime": { "format": "date-time", "type": "string" }, "message": { "maxLength": 32768, "type": "string" }, "observedGeneration": { "format": "int64", "minimum": 0, "type": "integer" }, "reason": { "maxLength": 1024, "minLength": 1, "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", "type": "string" }, "status": { "enum": [ "True", "False", "Unknown" ], "type": "string" }, "type": { "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" }, "maxItems": 8, "type": "array", "x-kubernetes-list-map-keys": [ "type" ], "x-kubernetes-list-type": "map" }, "name": { "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": { "items": { "properties": { "group": { "default": "gateway.networking.k8s.io", "maxLength": 253, "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", "type": "string" }, "kind": { "maxLength": 63, "minLength": 1, "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$", "type": "string" } }, "required": [ "kind" ], "type": "object" }, "maxItems": 8, "type": "array", "x-kubernetes-list-type": "atomic" } }, "required": [ "attachedRoutes", "conditions", "name" ], "type": "object" }, "maxItems": 64, "type": "array", "x-kubernetes-list-map-keys": [ "name" ], "x-kubernetes-list-type": "map" } }, "type": "object" } }, "required": [ "spec" ], "type": "object" }