diff --git a/config.sample.yaml b/config.sample.yaml index 155ceb6..67af9a6 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -5,7 +5,7 @@ credentials: hosts: - hostname: t1-disk-lt-k8s-test-master-01 - ip: "10.100.20.49" + ip: "10.100.20.47" roles: [control_plane, etcd] - hostname: t1-disk-lt-k8s-test-slave-01 @@ -13,24 +13,45 @@ hosts: roles: [node] - hostname: t1-disk-lt-k8s-test-slave-02 - ip: "10.100.20.47" + ip: "10.100.20.49" roles: [node] orchestrator: - version: v1.29.0 + version: v1.30.3 cluster_name: cluster.local - kubelet_dir: "/var/lib/kubelet" + kubelet_dir: "/app/k8s/kubelet" container_engine: install: true type: "containerd" - data_dir: "/var/lib/containerd" - state_dir: "/run/containerd" + data_dir: "/app/containerd" + state_dir: "/app/containerd-state" dns: servers: - 8.8.8.8 - 8.8.4.4 - 1.1.1.1 disable_host_nameservers: false + coredns_external_zones: + [] + # - zones: + # - example.com + # - example.io:1053 + # nameservers: + # - 1.1.1.1 + # - 2.2.2.2 + # cache: 5 + # - zones: + # - https://mycompany.local:4453 + # nameservers: + # - 192.168.0.53 + # cache: 0 + # - zones: + # - mydomain.tld + # nameservers: + # - 10.233.0.3 + # cache: 5 + # rewrite: + # - name website.tld website.namespace.svc.cluster.local ping_access_ip: true auto_renew_certificates: true pod_security_policy_enabled: true @@ -41,6 +62,20 @@ orchestrator: skip_verify: false modules: + admin_password: changeit + + observability: + enabled: false + + cicd: + enabled: false + + secrets_storage: + enabled: false + + registry: + enabled: false + additional: cert_manager: enabled: true diff --git a/internal/config/orchestrator.go b/internal/config/orchestrator.go index 5d7272d..b04be0f 100644 --- a/internal/config/orchestrator.go +++ b/internal/config/orchestrator.go @@ -1,8 +1,9 @@ package config type Dns struct { - Servers []string `yaml:"servers" env-default:"8.8.8.8,8.8.4.4"` - DisableHostNameservers bool `yaml:"disable_host_nameservers"` + Servers []string `yaml:"servers" env-default:"8.8.8.8,8.8.4.4"` + DisableHostNameservers bool `yaml:"disable_host_nameservers"` + CoreDNSExternalZones []interface{} `yaml:"coredns_external_zones"` } type RegistryMirror struct { diff --git a/internal/resources/templates/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml.tmpl b/internal/resources/templates/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml.tmpl index 85f1cb9..3acaf5f 100644 --- a/internal/resources/templates/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml.tmpl +++ b/internal/resources/templates/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml.tmpl @@ -183,7 +183,10 @@ nodelocaldns_health_port: 9254 nodelocaldns_second_health_port: 9256 nodelocaldns_bind_metrics_host_ip: false nodelocaldns_secondary_skew_seconds: 5 -# nodelocaldns_external_zones: +{{- if .Orchestrator.Dns.CoreDNSExternalZones }} +coredns_external_zones: + {{- .Orchestrator.Dns.CoreDNSExternalZones | toYaml | nindent 2 }} +{{- end }} # - zones: # - example.com # - example.io:1053 diff --git a/kubespray/env/cmdline b/kubespray/env/cmdline deleted file mode 100644 index 3a4cee0..0000000 --- a/kubespray/env/cmdline +++ /dev/null @@ -1 +0,0 @@ --b -v --become \ No newline at end of file diff --git a/kubespray/env/extravars b/kubespray/env/extravars deleted file mode 100644 index ea5601b..0000000 --- a/kubespray/env/extravars +++ /dev/null @@ -1,2 +0,0 @@ ---- -ansible_sudo_pass: nF5S8nuKi87Dh42Jnjik \ No newline at end of file diff --git a/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml b/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml index 5aa3291..72e8986 100644 --- a/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml +++ b/kubespray/inventory/group_vars/k8s_cluster/k8s-cluster.yml @@ -17,7 +17,7 @@ kube_token_dir: "{{ kube_config_dir }}/tokens" kube_api_anonymous_auth: true ## Change this to use another Kubernetes version, e.g. a current beta release -kube_version: v1.29.0 +kube_version: v1.30.3 # Where the binaries will be downloaded. # Note: ensure that you've enough disk space (about 1G) @@ -179,7 +179,6 @@ nodelocaldns_health_port: 9254 nodelocaldns_second_health_port: 9256 nodelocaldns_bind_metrics_host_ip: false nodelocaldns_secondary_skew_seconds: 5 -# nodelocaldns_external_zones: # - zones: # - example.com # - example.io:1053 diff --git a/kubespray/inventory/hosts b/kubespray/inventory/hosts index 236f44b..b10172d 100644 --- a/kubespray/inventory/hosts +++ b/kubespray/inventory/hosts @@ -1,31 +1,17 @@ -t1-disk-lt-k8s-master-01 ansible_host=10.100.20.43 ip=10.100.20.43 -t1-disk-lt-k8s-master-02 ansible_host=10.100.20.38 ip=10.100.20.38 -t1-disk-lt-k8s-master-03 ansible_host=10.100.20.42 ip=10.100.20.42 -t1-disk-lt-k8s-slave-01 ansible_host=10.100.20.40 ip=10.100.20.40 -t1-disk-lt-k8s-slave-02 ansible_host=10.100.20.41 ip=10.100.20.41 -t1-disk-lt-k8s-slave-03 ansible_host=10.100.20.39 ip=10.100.20.39 -t1-disk-lt-k8s-slave-04 ansible_host=10.100.20.45 ip=10.100.20.45 -t1-disk-lt-k8s-slave-05 ansible_host=10.100.20.44 ip=10.100.20.44 -t1-disk-lt-k8s-slave-06 ansible_host=10.100.20.50 ip=10.100.20.50 +t1-disk-lt-k8s-test-master-01 ansible_host=10.100.20.47 ip=10.100.20.47 +t1-disk-lt-k8s-test-slave-01 ansible_host=10.100.20.48 ip=10.100.20.48 +t1-disk-lt-k8s-test-slave-02 ansible_host=10.100.20.49 ip=10.100.20.49 [kube_control_plane] -t1-disk-lt-k8s-master-01 -t1-disk-lt-k8s-master-02 -t1-disk-lt-k8s-master-03 +t1-disk-lt-k8s-test-master-01 [etcd] -t1-disk-lt-k8s-master-01 -t1-disk-lt-k8s-master-02 -t1-disk-lt-k8s-master-03 +t1-disk-lt-k8s-test-master-01 [kube_node] -t1-disk-lt-k8s-slave-01 -t1-disk-lt-k8s-slave-02 -t1-disk-lt-k8s-slave-03 -t1-disk-lt-k8s-slave-04 -t1-disk-lt-k8s-slave-05 -t1-disk-lt-k8s-slave-06 +t1-disk-lt-k8s-test-slave-01 +t1-disk-lt-k8s-test-slave-02 [k8s_cluster:children] kube_control_plane diff --git a/kubespray/project/ansible_version.yml b/kubespray/project/ansible_version.yml index d5a83bd..009183f 100644 --- a/kubespray/project/ansible_version.yml +++ b/kubespray/project/ansible_version.yml @@ -2,10 +2,10 @@ - name: Check Ansible version hosts: all gather_facts: false - become: no + become: false run_once: true vars: - minimal_ansible_version: 2.15.5 # 2.15 versions before 2.15.5 are known to be buggy for kubespray + minimal_ansible_version: 2.16.4 maximal_ansible_version: 2.17.0 tags: always tasks: @@ -25,7 +25,6 @@ tags: - check - # CentOS 7 provides too old jinja version - name: "Check that jinja is not too old (install via pip)" assert: msg: "Your Jinja version is too old, install via pip" diff --git a/kubespray/project/boilerplate.yml b/kubespray/project/boilerplate.yml index 137a4c2..eafa9b4 100644 --- a/kubespray/project/boilerplate.yml +++ b/kubespray/project/boilerplate.yml @@ -51,7 +51,7 @@ - name: Install bastion ssh config hosts: bastion[0] - gather_facts: False + gather_facts: false environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } diff --git a/kubespray/project/cluster.yml b/kubespray/project/cluster.yml index 4cd0714..ca67a28 100644 --- a/kubespray/project/cluster.yml +++ b/kubespray/project/cluster.yml @@ -7,17 +7,13 @@ - name: Prepare for etcd install hosts: k8s_cluster:etcd - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - { role: kubernetes/preinstall, tags: preinstall } - - { - role: "container-engine", - tags: "container-engine", - when: deploy_container_engine, - } + - { role: "container-engine", tags: "container-engine", when: deploy_container_engine } - { role: download, tags: download, when: "not skip_downloads" } - name: Install etcd @@ -25,7 +21,7 @@ - name: Install Kubernetes nodes hosts: k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -34,7 +30,7 @@ - name: Install the control plane hosts: kube_control_plane - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -45,12 +41,12 @@ - name: Invoke kubeadm and install a CNI hosts: k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - - { role: kubernetes/kubeadm, tags: kubeadm } + - { role: kubernetes/kubeadm, tags: kubeadm} - { role: kubernetes/node-label, tags: node-label } - { role: kubernetes/node-taint, tags: node-taint } - { role: network_plugin, tags: network } @@ -58,50 +54,41 @@ - name: Install Calico Route Reflector hosts: calico_rr - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - - { role: network_plugin/calico/rr, tags: ["network", "calico_rr"] } + - { role: network_plugin/calico/rr, tags: ['network', 'calico_rr'] } - name: Patch Kubernetes for Windows hosts: kube_control_plane[0] - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - { role: win_nodes/kubernetes_patch, tags: ["master", "win_nodes"] } -- name: Install Kubernetes and Helm apps +- name: Install Kubernetes apps hosts: kube_control_plane - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - - { - role: kubernetes-apps/external_cloud_controller, - tags: external-cloud-controller, - } + - { role: kubernetes-apps/external_cloud_controller, tags: external-cloud-controller } - { role: kubernetes-apps/network_plugin, tags: network } - { role: kubernetes-apps/policy_controller, tags: policy-controller } - { role: kubernetes-apps/ingress_controller, tags: ingress-controller } - { role: kubernetes-apps/external_provisioner, tags: external-provisioner } - { role: kubernetes-apps, tags: apps } - # - { role: helm-apps, tags: helm-apps } - name: Apply resolv.conf changes now that cluster DNS is up hosts: k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults } - - { - role: kubernetes/preinstall, - when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", - tags: resolvconf, - dns_late: true, - } + - { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf, dns_late: true } diff --git a/kubespray/project/facts.yml b/kubespray/project/facts.yml index 77823ac..d35eea8 100644 --- a/kubespray/project/facts.yml +++ b/kubespray/project/facts.yml @@ -15,7 +15,7 @@ - name: Gather facts hosts: k8s_cluster:etcd:calico_rr - gather_facts: False + gather_facts: false tags: always tasks: - name: Gather minimal facts diff --git a/kubespray/project/install_etcd.yml b/kubespray/project/install_etcd.yml index b8e4d1d..1f58511 100644 --- a/kubespray/project/install_etcd.yml +++ b/kubespray/project/install_etcd.yml @@ -16,7 +16,7 @@ - name: Install etcd hosts: etcd:kube_control_plane:_kubespray_needs_etcd - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: diff --git a/kubespray/project/remove_node.yml b/kubespray/project/remove_node.yml index e013389..f994dae 100644 --- a/kubespray/project/remove_node.yml +++ b/kubespray/project/remove_node.yml @@ -4,13 +4,13 @@ - name: Confirm node removal hosts: "{{ node | default('etcd:k8s_cluster:calico_rr') }}" - gather_facts: no + gather_facts: false tasks: - name: Confirm Execution pause: prompt: "Are you sure you want to delete nodes state? Type 'yes' to delete nodes." register: pause_result - run_once: True + run_once: true when: - not (skip_confirmation | default(false) | bool) @@ -25,7 +25,7 @@ - name: Reset node hosts: "{{ node | default('kube_node') }}" - gather_facts: no + gather_facts: false environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults, when: reset_nodes | default(True) | bool } @@ -36,7 +36,7 @@ # Currently cannot remove first master or etcd - name: Post node removal hosts: "{{ node | default('kube_control_plane[1:]:etcd[1:]') }}" - gather_facts: no + gather_facts: false environment: "{{ proxy_disable_env }}" roles: - { role: kubespray-defaults, when: reset_nodes | default(True) | bool } diff --git a/kubespray/project/reset.yml b/kubespray/project/reset.yml index 5742bd8..6fa18c0 100644 --- a/kubespray/project/reset.yml +++ b/kubespray/project/reset.yml @@ -7,13 +7,13 @@ - name: Reset cluster hosts: etcd:k8s_cluster:calico_rr - gather_facts: False + gather_facts: false pre_tasks: - name: Reset Confirmation pause: prompt: "Are you sure you want to reset cluster state? Type 'yes' to reset your cluster." register: reset_confirmation_prompt - run_once: True + run_once: true when: - not (skip_confirmation | default(false) | bool) - reset_confirmation is not defined diff --git a/kubespray/project/roles/adduser/defaults/main.yml b/kubespray/project/roles/adduser/defaults/main.yml index df3fc2d..3307032 100644 --- a/kubespray/project/roles/adduser/defaults/main.yml +++ b/kubespray/project/roles/adduser/defaults/main.yml @@ -7,14 +7,14 @@ addusers: etcd: name: etcd comment: "Etcd user" - create_home: no - system: yes + create_home: false + system: true shell: /sbin/nologin kube: name: kube comment: "Kubernetes user" - create_home: no - system: yes + create_home: false + system: true shell: /sbin/nologin group: "{{ kube_cert_group }}" diff --git a/kubespray/project/roles/adduser/vars/coreos.yml b/kubespray/project/roles/adduser/vars/coreos.yml index 5c258df..60fb05c 100644 --- a/kubespray/project/roles/adduser/vars/coreos.yml +++ b/kubespray/project/roles/adduser/vars/coreos.yml @@ -3,6 +3,6 @@ addusers: - name: kube comment: "Kubernetes user" shell: /sbin/nologin - system: yes + system: true group: "{{ kube_cert_group }}" - create_home: no + create_home: false diff --git a/kubespray/project/roles/adduser/vars/debian.yml b/kubespray/project/roles/adduser/vars/debian.yml index 99e5b38..b14b861 100644 --- a/kubespray/project/roles/adduser/vars/debian.yml +++ b/kubespray/project/roles/adduser/vars/debian.yml @@ -2,14 +2,14 @@ addusers: - name: etcd comment: "Etcd user" - create_home: yes + create_home: true home: "{{ etcd_data_dir }}" - system: yes + system: true shell: /sbin/nologin - name: kube comment: "Kubernetes user" - create_home: no - system: yes + create_home: false + system: true shell: /sbin/nologin group: "{{ kube_cert_group }}" diff --git a/kubespray/project/roles/adduser/vars/redhat.yml b/kubespray/project/roles/adduser/vars/redhat.yml index 99e5b38..b14b861 100644 --- a/kubespray/project/roles/adduser/vars/redhat.yml +++ b/kubespray/project/roles/adduser/vars/redhat.yml @@ -2,14 +2,14 @@ addusers: - name: etcd comment: "Etcd user" - create_home: yes + create_home: true home: "{{ etcd_data_dir }}" - system: yes + system: true shell: /sbin/nologin - name: kube comment: "Kubernetes user" - create_home: no - system: yes + create_home: false + system: true shell: /sbin/nologin group: "{{ kube_cert_group }}" diff --git a/kubespray/project/roles/bastion-ssh-config/molecule/default/converge.yml b/kubespray/project/roles/bastion-ssh-config/molecule/default/converge.yml index 54a6247..a896155 100644 --- a/kubespray/project/roles/bastion-ssh-config/molecule/default/converge.yml +++ b/kubespray/project/roles/bastion-ssh-config/molecule/default/converge.yml @@ -12,4 +12,4 @@ dest: "{{ ssh_bastion_confing__name }}" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" - mode: 0644 + mode: "0644" diff --git a/kubespray/project/roles/bastion-ssh-config/tasks/main.yml b/kubespray/project/roles/bastion-ssh-config/tasks/main.yml index 920763e..99847ef 100644 --- a/kubespray/project/roles/bastion-ssh-config/tasks/main.yml +++ b/kubespray/project/roles/bastion-ssh-config/tasks/main.yml @@ -19,4 +19,4 @@ template: src: "{{ ssh_bastion_confing__name }}.j2" dest: "{{ playbook_dir }}/{{ ssh_bastion_confing__name }}" - mode: 0640 + mode: "0640" diff --git a/kubespray/project/roles/bootstrap-os/defaults/main.yml b/kubespray/project/roles/bootstrap-os/defaults/main.yml index 9b31456..bb7ca1f 100644 --- a/kubespray/project/roles/bootstrap-os/defaults/main.yml +++ b/kubespray/project/roles/bootstrap-os/defaults/main.yml @@ -11,6 +11,10 @@ coreos_locksmithd_disable: false # Install public repo on Oracle Linux use_oracle_public_repo: true +## Ubuntu specific variables +# Disable unattended-upgrades for Linux kernel and all packages start with linux- on Ubuntu +ubuntu_kernel_unattended_upgrades_disabled: false + fedora_coreos_packages: - python - python3-libselinux diff --git a/kubespray/project/roles/bootstrap-os/molecule/default/converge.yml b/kubespray/project/roles/bootstrap-os/molecule/default/converge.yml index 1f44ec9..89a8325 100644 --- a/kubespray/project/roles/bootstrap-os/molecule/default/converge.yml +++ b/kubespray/project/roles/bootstrap-os/molecule/default/converge.yml @@ -1,6 +1,6 @@ --- - name: Converge hosts: all - gather_facts: no + gather_facts: false roles: - role: bootstrap-os diff --git a/kubespray/project/roles/bootstrap-os/molecule/default/molecule.yml b/kubespray/project/roles/bootstrap-os/molecule/default/molecule.yml index 76e5b7a..9fa29ae 100644 --- a/kubespray/project/roles/bootstrap-os/molecule/default/molecule.yml +++ b/kubespray/project/roles/bootstrap-os/molecule/default/molecule.yml @@ -19,12 +19,6 @@ platforms: memory: 1024 provider_options: driver: kvm - - name: centos7 - box: centos/7 - cpus: 1 - memory: 512 - provider_options: - driver: kvm - name: almalinux8 box: almalinux/8 cpus: 1 diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-amazon.yml b/kubespray/project/roles/bootstrap-os/tasks/amzn.yml similarity index 60% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-amazon.yml rename to kubespray/project/roles/bootstrap-os/tasks/amzn.yml index 2b4d665..8a473a0 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-amazon.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/amzn.yml @@ -1,13 +1,16 @@ --- +- name: Enable selinux-ng repo for Amazon Linux for container-selinux + command: amazon-linux-extras enable selinux-ng + - name: Enable EPEL repo for Amazon Linux yum_repository: name: epel file: epel description: Extra Packages for Enterprise Linux 7 - $basearch baseurl: http://download.fedoraproject.org/pub/epel/7/$basearch - gpgcheck: yes + gpgcheck: true gpgkey: http://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 - skip_if_unavailable: yes - enabled: yes - repo_gpgcheck: no + skip_if_unavailable: true + enabled: true + repo_gpgcheck: false when: epel_enabled diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-coreos.yml b/kubespray/project/roles/bootstrap-os/tasks/bootstrap-coreos.yml deleted file mode 100644 index 737a7ec..0000000 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-coreos.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -# CoreOS ships without Python installed - -- name: Check if bootstrap is needed - raw: stat /opt/bin/.bootstrapped - register: need_bootstrap - failed_when: false - changed_when: false - tags: - - facts - -- name: Force binaries directory for Container Linux by CoreOS and Flatcar - set_fact: - bin_dir: "/opt/bin" - tags: - - facts - -- name: Run bootstrap.sh - script: bootstrap.sh - become: true - environment: "{{ proxy_env }}" - when: - - need_bootstrap.rc != 0 - -- name: Set the ansible_python_interpreter fact - set_fact: - ansible_python_interpreter: "{{ bin_dir }}/python" - tags: - - facts - -- name: Disable auto-upgrade - systemd: - name: locksmithd.service - masked: true - state: stopped - when: - - coreos_locksmithd_disable diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-centos.yml b/kubespray/project/roles/bootstrap-os/tasks/centos.yml similarity index 89% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-centos.yml rename to kubespray/project/roles/bootstrap-os/tasks/centos.yml index 5d543ae..93816ff 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-centos.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/centos.yml @@ -12,7 +12,7 @@ value: "{{ http_proxy | default(omit) }}" state: "{{ http_proxy | default(False) | ternary('present', 'absent') }}" no_extra_spaces: true - mode: 0644 + mode: "0644" become: true when: not skip_http_proxy_on_os_packages @@ -21,7 +21,7 @@ get_url: url: https://yum.oracle.com/public-yum-ol7.repo dest: /etc/yum.repos.d/public-yum-ol7.repo - mode: 0644 + mode: "0644" when: - use_oracle_public_repo | default(true) - '''ID="ol"'' in os_release.stdout_lines' @@ -34,7 +34,7 @@ section: "{{ item }}" option: enabled value: "1" - mode: 0644 + mode: "0644" with_items: - ol7_latest - ol7_addons @@ -59,7 +59,7 @@ section: "ol{{ ansible_distribution_major_version }}_addons" option: "{{ item.option }}" value: "{{ item.value }}" - mode: 0644 + mode: "0644" with_items: - { option: "name", value: "ol{{ ansible_distribution_major_version }}_addons" } - { option: "enabled", value: "1" } @@ -75,12 +75,12 @@ section: "extras" option: "{{ item.option }}" value: "{{ item.value }}" - mode: 0644 + mode: "0644" with_items: - { option: "name", value: "CentOS-{{ ansible_distribution_major_version }} - Extras" } - { option: "enabled", value: "1" } - { option: "gpgcheck", value: "0" } - - { option: "baseurl", value: "http://mirror.centos.org/{{ 'altarch' if (ansible_distribution_major_version | int) <= 7 and ansible_architecture == 'aarch64' else 'centos' }}/{{ ansible_distribution_major_version }}/extras/$basearch/{% if ansible_distribution_major_version | int > 7 %}os/{% endif %}" } + - { option: "baseurl", value: "http://mirror.centos.org/centos/{{ ansible_distribution_major_version }}/extras/$basearch/os/" } when: - use_oracle_public_repo | default(true) - '''ID="ol"'' in os_release.stdout_lines' @@ -92,9 +92,9 @@ - name: Check presence of fastestmirror.conf stat: path: /etc/yum/pluginconf.d/fastestmirror.conf - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: fastestmirror # the fastestmirror plugin can actually slow down Ansible deployments diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-clearlinux.yml b/kubespray/project/roles/bootstrap-os/tasks/clearlinux.yml similarity index 94% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-clearlinux.yml rename to kubespray/project/roles/bootstrap-os/tasks/clearlinux.yml index de42e3c..2e41eaa 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-clearlinux.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/clearlinux.yml @@ -7,7 +7,7 @@ state: present - name: Make sure docker service is enabled - systemd: + systemd_service: name: docker masked: false enabled: true diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-debian.yml b/kubespray/project/roles/bootstrap-os/tasks/debian.yml similarity index 80% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-debian.yml rename to kubespray/project/roles/bootstrap-os/tasks/debian.yml index 47bad20..9b18baa 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-debian.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/debian.yml @@ -55,22 +55,10 @@ raw: apt-get update --allow-releaseinfo-change become: true when: - - '''ID=debian'' in os_release.stdout_lines' - - '''VERSION_ID="10"'' in os_release.stdout_lines or ''VERSION_ID="11"'' in os_release.stdout_lines' + - os_release_dict['ID'] == 'debian' + - os_release_dict['VERSION_ID'] in ["10", "11"] register: bootstrap_update_apt_result changed_when: - '"changed its" in bootstrap_update_apt_result.stdout' - '"value from" in bootstrap_update_apt_result.stdout' ignore_errors: true - -- name: Set the ansible_python_interpreter fact - set_fact: - ansible_python_interpreter: "/usr/bin/python3" - -# Workaround for https://github.com/ansible/ansible/issues/25543 -- name: Install dbus for the hostname module - package: - name: dbus - state: present - use: apt - become: true diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora-coreos.yml b/kubespray/project/roles/bootstrap-os/tasks/fedora-coreos.yml similarity index 88% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora-coreos.yml rename to kubespray/project/roles/bootstrap-os/tasks/fedora-coreos.yml index 91dc020..3062a5a 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora-coreos.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/fedora-coreos.yml @@ -28,7 +28,7 @@ raw: "nohup bash -c 'sleep 5s && shutdown -r now'" become: true ignore_errors: true # noqa ignore-errors - ignore_unreachable: yes + ignore_unreachable: true when: need_bootstrap.rc != 0 - name: Wait for the reboot to complete @@ -38,9 +38,3 @@ delay: 5 sleep: 5 when: need_bootstrap.rc != 0 - -- name: Store the fact if this is an fedora core os host - set_fact: - is_fedora_coreos: True - tags: - - facts diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora.yml b/kubespray/project/roles/bootstrap-os/tasks/fedora.yml similarity index 79% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora.yml rename to kubespray/project/roles/bootstrap-os/tasks/fedora.yml index 4ce77b4..d4a43c3 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-fedora.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/fedora.yml @@ -17,20 +17,14 @@ value: "{{ http_proxy | default(omit) }}" state: "{{ http_proxy | default(False) | ternary('present', 'absent') }}" no_extra_spaces: true - mode: 0644 + mode: "0644" become: true when: not skip_http_proxy_on_os_packages -- name: Install python3 on fedora - raw: "dnf install --assumeyes --quiet python3" +# libselinux-python3 is required on SELinux enabled hosts +# See https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#managed-node-requirements +- name: Install ansible requirements + raw: "dnf install --assumeyes python3 python3-dnf libselinux-python3" become: true when: - need_bootstrap.rc != 0 - -# libselinux-python3 is required on SELinux enabled hosts -# See https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#managed-node-requirements -- name: Install libselinux-python3 - package: - name: libselinux-python3 - state: present - become: true diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-flatcar.yml b/kubespray/project/roles/bootstrap-os/tasks/flatcar.yml similarity index 52% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-flatcar.yml rename to kubespray/project/roles/bootstrap-os/tasks/flatcar.yml index b0f3a9e..be74150 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-flatcar.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/flatcar.yml @@ -9,12 +9,6 @@ tags: - facts -- name: Force binaries directory for Flatcar Container Linux by Kinvolk - set_fact: - bin_dir: "/opt/bin" - tags: - - facts - - name: Run bootstrap.sh script: bootstrap.sh become: true @@ -22,14 +16,17 @@ when: - need_bootstrap.rc != 0 -- name: Set the ansible_python_interpreter fact +# Workaround ansible https://github.com/ansible/ansible/pull/82821 +# We set the interpreter rather than ansible_python_interpreter to allow +# - using virtual env with task level ansible_python_interpreter later +# - let users specify an ansible_python_interpreter in group_vars + +- name: Make interpreter discovery works on Flatcar set_fact: - ansible_python_interpreter: "{{ bin_dir }}/python" - tags: - - facts + ansible_interpreter_python_fallback: "{{ ansible_interpreter_python_fallback + [ '/opt/bin/python' ] }}" - name: Disable auto-upgrade - systemd: + systemd_service: name: locksmithd.service masked: true state: stopped diff --git a/kubespray/project/roles/bootstrap-os/tasks/main.yml b/kubespray/project/roles/bootstrap-os/tasks/main.yml index 73c9e06..c16fe1b 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/main.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/main.yml @@ -6,57 +6,39 @@ # This command should always run, even in check mode check_mode: false -- name: Bootstrap CentOS - include_tasks: bootstrap-centos.yml - when: '''ID="centos"'' in os_release.stdout_lines or ''ID="ol"'' in os_release.stdout_lines or ''ID="almalinux"'' in os_release.stdout_lines or ''ID="rocky"'' in os_release.stdout_lines or ''ID="kylin"'' in os_release.stdout_lines or ''ID="uos"'' in os_release.stdout_lines or ''ID="openEuler"'' in os_release.stdout_lines' +- name: Include distro specifics vars and tasks + vars: + os_release_dict: "{{ os_release.stdout_lines | select('regex', '^.+=.*$') | map('regex_replace', '\"', '') | + map('split', '=') | community.general.dict }}" + block: + - name: Include vars + include_vars: "{{ item }}" + tags: + - facts + with_first_found: + - &search + files: + - "{{ os_release_dict['ID'] }}-{{ os_release_dict['VARIANT_ID'] }}.yml" + - "{{ os_release_dict['ID'] }}.yml" + paths: + - vars/ + skip: true + - name: Include tasks + include_tasks: "{{ included_tasks_file }}" + with_first_found: + - <<: *search + paths: [] + loop_control: + loop_var: included_tasks_file -- name: Bootstrap Amazon - include_tasks: bootstrap-amazon.yml - when: '''ID="amzn"'' in os_release.stdout_lines' - -- name: Bootstrap RedHat - include_tasks: bootstrap-redhat.yml - when: '''ID="rhel"'' in os_release.stdout_lines' - -- name: Bootstrap Clear Linux - include_tasks: bootstrap-clearlinux.yml - when: '''ID=clear-linux-os'' in os_release.stdout_lines' - -# Fedora CoreOS -- name: Bootstrap Fedora CoreOS - include_tasks: bootstrap-fedora-coreos.yml - when: - - '''ID=fedora'' in os_release.stdout_lines' - - '''VARIANT_ID=coreos'' in os_release.stdout_lines' - -- name: Bootstrap Flatcar - include_tasks: bootstrap-flatcar.yml - when: '''ID=flatcar'' in os_release.stdout_lines' - -- name: Bootstrap Debian - include_tasks: bootstrap-debian.yml - when: '''ID=debian'' in os_release.stdout_lines or ''ID=ubuntu'' in os_release.stdout_lines' - -# Fedora "classic" -- name: Boostrap Fedora - include_tasks: bootstrap-fedora.yml - when: - - '''ID=fedora'' in os_release.stdout_lines' - - '''VARIANT_ID=coreos'' not in os_release.stdout_lines' - -- name: Bootstrap OpenSUSE - include_tasks: bootstrap-opensuse.yml - when: '''ID="opensuse-leap"'' in os_release.stdout_lines or ''ID="opensuse-tumbleweed"'' in os_release.stdout_lines' - name: Create remote_tmp for it is used by another module file: path: "{{ ansible_remote_tmp | default('~/.ansible/tmp') }}" state: directory - mode: 0700 + mode: "0700" -# Workaround for https://github.com/ansible/ansible/issues/42726 -# (1/3) -- name: Gather host facts to get ansible_os_family +- name: Gather facts setup: gather_subset: '!all' filter: ansible_* @@ -64,39 +46,12 @@ - name: Assign inventory name to unconfigured hostnames (non-CoreOS, non-Flatcar, Suse and ClearLinux, non-Fedora) hostname: name: "{{ inventory_hostname }}" - when: - - override_system_hostname - - ansible_os_family not in ['Suse', 'Flatcar', 'Flatcar Container Linux by Kinvolk', 'ClearLinux'] - - not ansible_distribution == "Fedora" - - not is_fedora_coreos - -# (2/3) -- name: Assign inventory name to unconfigured hostnames (CoreOS, Flatcar, Suse, ClearLinux and Fedora only) - command: "hostnamectl set-hostname {{ inventory_hostname }}" - register: hostname_changed - become: true - changed_when: false - when: > - override_system_hostname - and (ansible_os_family in ['Suse', 'Flatcar', 'Flatcar Container Linux by Kinvolk', 'ClearLinux'] - or is_fedora_coreos - or ansible_distribution == "Fedora") - -# (3/3) -- name: Update hostname fact (CoreOS, Flatcar, Suse, ClearLinux and Fedora only) - setup: - gather_subset: '!all' - filter: ansible_hostname - when: > - override_system_hostname - and (ansible_os_family in ['Suse', 'Flatcar', 'Flatcar Container Linux by Kinvolk', 'ClearLinux'] - or is_fedora_coreos - or ansible_distribution == "Fedora") + when: override_system_hostname - name: Install ceph-commmon package package: name: - - ceph-common + - ceph-common state: present when: rbd_provisioner_enabled | default(false) @@ -106,4 +61,4 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" diff --git a/kubespray/project/roles/bootstrap-os/tasks/openEuler.yml b/kubespray/project/roles/bootstrap-os/tasks/openEuler.yml new file mode 100644 index 0000000..4255133 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/tasks/openEuler.yml @@ -0,0 +1,3 @@ +--- +- name: Import Centos boostrap for openEuler + import_tasks: centos.yml diff --git a/kubespray/project/roles/bootstrap-os/tasks/opensuse-leap.yml b/kubespray/project/roles/bootstrap-os/tasks/opensuse-leap.yml new file mode 100644 index 0000000..233f848 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/tasks/opensuse-leap.yml @@ -0,0 +1,3 @@ +--- +- name: Import Opensuse bootstrap + import_tasks: opensuse.yml diff --git a/kubespray/project/roles/bootstrap-os/tasks/opensuse-tumbleweed.yml b/kubespray/project/roles/bootstrap-os/tasks/opensuse-tumbleweed.yml new file mode 100644 index 0000000..233f848 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/tasks/opensuse-tumbleweed.yml @@ -0,0 +1,3 @@ +--- +- name: Import Opensuse bootstrap + import_tasks: opensuse.yml diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-opensuse.yml b/kubespray/project/roles/bootstrap-os/tasks/opensuse.yml similarity index 96% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-opensuse.yml rename to kubespray/project/roles/bootstrap-os/tasks/opensuse.yml index 9b69dcd..5a4f9de 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-opensuse.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/opensuse.yml @@ -8,9 +8,9 @@ - name: Check that /etc/sysconfig/proxy file exists stat: path: /etc/sysconfig/proxy - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: stat_result - name: Create the /etc/sysconfig/proxy empty file diff --git a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-redhat.yml b/kubespray/project/roles/bootstrap-os/tasks/redhat.yml similarity index 87% rename from kubespray/project/roles/bootstrap-os/tasks/bootstrap-redhat.yml rename to kubespray/project/roles/bootstrap-os/tasks/redhat.yml index c362146..2bf508d 100644 --- a/kubespray/project/roles/bootstrap-os/tasks/bootstrap-redhat.yml +++ b/kubespray/project/roles/bootstrap-os/tasks/redhat.yml @@ -12,7 +12,7 @@ value: "{{ http_proxy | default(omit) }}" state: "{{ http_proxy | default(False) | ternary('present', 'absent') }}" no_extra_spaces: true - mode: 0644 + mode: "0644" become: true when: not skip_http_proxy_on_os_packages @@ -62,17 +62,6 @@ - rh_subscription_username is defined - rh_subscription_status.changed -# container-selinux is in extras repo -- name: Enable RHEL 7 repos - community.general.rhsm_repository: - name: - - "rhel-7-server-rpms" - - "rhel-7-server-extras-rpms" - state: "{{ 'enabled' if (rhel_enable_repos | default(True) | bool) else 'disabled' }}" - when: - - ansible_distribution_major_version == "7" - - (not rh_subscription_status.changed) or (rh_subscription_username is defined) or (rh_subscription_org_id is defined) - # container-selinux is in appstream repo - name: Enable RHEL 8 repos community.general.rhsm_repository: @@ -87,9 +76,9 @@ - name: Check presence of fastestmirror.conf stat: path: /etc/yum/pluginconf.d/fastestmirror.conf - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: fastestmirror # the fastestmirror plugin can actually slow down Ansible deployments diff --git a/kubespray/project/roles/bootstrap-os/tasks/ubuntu.yml b/kubespray/project/roles/bootstrap-os/tasks/ubuntu.yml new file mode 100644 index 0000000..545de94 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/tasks/ubuntu.yml @@ -0,0 +1,21 @@ +--- +- name: Import Debian bootstrap + import_tasks: debian.yml + +- name: Check unattended-upgrades file exist + stat: + path: /etc/apt/apt.conf.d/50unattended-upgrades + register: unattended_upgrades_file_stat + when: + - ubuntu_kernel_unattended_upgrades_disabled + +- name: Disable kernel unattended-upgrades + lineinfile: + path: "{{ unattended_upgrades_file_stat.stat.path }}" + insertafter: "Unattended-Upgrade::Package-Blacklist" + line: '"linux-";' + state: present + become: true + when: + - ubuntu_kernel_unattended_upgrades_disabled + - unattended_upgrades_file_stat.stat.exists diff --git a/kubespray/project/roles/bootstrap-os/vars/fedora-coreos.yml b/kubespray/project/roles/bootstrap-os/vars/fedora-coreos.yml new file mode 100644 index 0000000..37e4c46 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/vars/fedora-coreos.yml @@ -0,0 +1,2 @@ +--- +is_fedora_coreos: true diff --git a/kubespray/project/roles/bootstrap-os/vars/flatcar.yml b/kubespray/project/roles/bootstrap-os/vars/flatcar.yml new file mode 100644 index 0000000..f18bec5 --- /dev/null +++ b/kubespray/project/roles/bootstrap-os/vars/flatcar.yml @@ -0,0 +1,2 @@ +--- +bin_dir: "/opt/bin" diff --git a/kubespray/project/roles/container-engine/containerd-common/tasks/main.yml b/kubespray/project/roles/container-engine/containerd-common/tasks/main.yml index d0cf1f1..c5b8968 100644 --- a/kubespray/project/roles/container-engine/containerd-common/tasks/main.yml +++ b/kubespray/project/roles/container-engine/containerd-common/tasks/main.yml @@ -2,9 +2,9 @@ - name: Containerd-common | check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree - name: Containerd-common | set is_ostree diff --git a/kubespray/project/roles/container-engine/containerd/defaults/main.yml b/kubespray/project/roles/container-engine/containerd/defaults/main.yml index 9ecace9..f04bb92 100644 --- a/kubespray/project/roles/container-engine/containerd/defaults/main.yml +++ b/kubespray/project/roles/container-engine/containerd/defaults/main.yml @@ -46,7 +46,11 @@ containerd_base_runtime_specs: containerd_grpc_max_recv_message_size: 16777216 containerd_grpc_max_send_message_size: 16777216 +containerd_debug_address: "" containerd_debug_level: "info" +containerd_debug_format: "" +containerd_debug_uid: 0 +containerd_debug_gid: 0 containerd_metrics_address: "" @@ -66,6 +70,12 @@ containerd_enable_unprivileged_ports: false # If enabled it will allow non root users to use icmp sockets containerd_enable_unprivileged_icmp: false +containerd_enable_selinux: false +containerd_disable_apparmor: false +containerd_tolerate_missing_hugetlb_controller: true +containerd_disable_hugetlb_controller: true +containerd_image_pull_progress_timeout: 5m + containerd_cfg_dir: /etc/containerd # Extra config to be put in {{ containerd_cfg_dir }}/config.toml literally @@ -109,3 +119,11 @@ containerd_supported_distributions: # Enable container device interface enable_cdi: false + +# For containerd tracing configuration please check out the official documentation: +# https://github.com/containerd/containerd/blob/main/docs/tracing.md +containerd_tracing_enabled: false +containerd_tracing_endpoint: "0.0.0.0:4317" +containerd_tracing_protocol: "grpc" +containerd_tracing_sampling_ratio: 1.0 +containerd_tracing_service_name: "containerd" diff --git a/kubespray/project/roles/container-engine/containerd/handlers/main.yml b/kubespray/project/roles/container-engine/containerd/handlers/main.yml index 1959dc9..6a024fd 100644 --- a/kubespray/project/roles/container-engine/containerd/handlers/main.yml +++ b/kubespray/project/roles/container-engine/containerd/handlers/main.yml @@ -1,11 +1,11 @@ --- - name: Containerd | restart containerd - systemd: + systemd_service: name: containerd state: restarted - enabled: yes - daemon-reload: yes - masked: no + enabled: true + daemon-reload: true + masked: false listen: Restart containerd - name: Containerd | wait for containerd diff --git a/kubespray/project/roles/container-engine/containerd/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/containerd/molecule/default/prepare.yml index ddc9c04..a3d09ad 100644 --- a/kubespray/project/roles/container-engine/containerd/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/containerd/molecule/default/prepare.yml @@ -1,7 +1,7 @@ --- - name: Prepare hosts: all - gather_facts: False + gather_facts: false become: true vars: ignore_assert_errors: true @@ -19,7 +19,7 @@ - name: Prepare CNI hosts: all - gather_facts: False + gather_facts: false become: true vars: ignore_assert_errors: true diff --git a/kubespray/project/roles/container-engine/containerd/tasks/main.yml b/kubespray/project/roles/container-engine/containerd/tasks/main.yml index f1b9777..8b8c12c 100644 --- a/kubespray/project/roles/container-engine/containerd/tasks/main.yml +++ b/kubespray/project/roles/container-engine/containerd/tasks/main.yml @@ -35,8 +35,8 @@ unarchive: src: "{{ downloads.containerd.dest }}" dest: "{{ containerd_bin_dir }}" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true extra_opts: - --strip-components=1 notify: Restart containerd @@ -60,7 +60,7 @@ template: src: containerd.service.j2 dest: /etc/systemd/system/containerd.service - mode: 0644 + mode: "0644" validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:containerd.service'" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 @@ -70,7 +70,7 @@ file: dest: "{{ item }}" state: directory - mode: 0755 + mode: "0755" owner: root group: root with_items: @@ -83,7 +83,7 @@ template: src: http-proxy.conf.j2 dest: "{{ containerd_systemd_dir }}/http-proxy.conf" - mode: 0644 + mode: "0644" notify: Restart containerd when: http_proxy is defined or https_proxy is defined @@ -102,7 +102,7 @@ content: "{{ item.value }}" dest: "{{ containerd_cfg_dir }}/{{ item.key }}" owner: "root" - mode: 0644 + mode: "0644" with_dict: "{{ containerd_base_runtime_specs | default({}) }}" notify: Restart containerd @@ -111,7 +111,7 @@ src: config.toml.j2 dest: "{{ containerd_cfg_dir }}/config.toml" owner: "root" - mode: 0640 + mode: "0640" notify: Restart containerd - name: Containerd | Configure containerd registries @@ -121,13 +121,13 @@ file: path: "{{ containerd_cfg_dir }}/certs.d/{{ item.prefix }}" state: directory - mode: 0755 + mode: "0755" loop: "{{ containerd_registries_mirrors }}" - name: Containerd | Write hosts.toml file template: src: hosts.toml.j2 dest: "{{ containerd_cfg_dir }}/certs.d/{{ item.prefix }}/hosts.toml" - mode: 0640 + mode: "0640" loop: "{{ containerd_registries_mirrors }}" # you can sometimes end up in a state where everything is installed @@ -136,8 +136,8 @@ meta: flush_handlers - name: Containerd | Ensure containerd is started and enabled - systemd: + systemd_service: name: containerd - daemon_reload: yes - enabled: yes + daemon_reload: true + enabled: true state: started diff --git a/kubespray/project/roles/container-engine/containerd/templates/config.toml.j2 b/kubespray/project/roles/container-engine/containerd/templates/config.toml.j2 index 30773aa..3f65ef5 100644 --- a/kubespray/project/roles/container-engine/containerd/templates/config.toml.j2 +++ b/kubespray/project/roles/container-engine/containerd/templates/config.toml.j2 @@ -3,12 +3,20 @@ root = "{{ containerd_storage_dir }}" state = "{{ containerd_state_dir }}" oom_score = {{ containerd_oom_score }} +{% if containerd_extra_args is defined %} +{{ containerd_extra_args }} +{% endif %} + [grpc] max_recv_message_size = {{ containerd_grpc_max_recv_message_size }} max_send_message_size = {{ containerd_grpc_max_send_message_size }} [debug] + address = "{{ containerd_debug_address }}" level = "{{ containerd_debug_level }}" + format = "{{ containerd_debug_format }}" + uid = {{ containerd_debug_uid }} + gid = {{ containerd_debug_gid }} [metrics] address = "{{ containerd_metrics_address }}" @@ -20,6 +28,11 @@ oom_score = {{ containerd_oom_score }} max_container_log_line_size = {{ containerd_max_container_log_line_size }} enable_unprivileged_ports = {{ containerd_enable_unprivileged_ports | lower }} enable_unprivileged_icmp = {{ containerd_enable_unprivileged_icmp | lower }} + enable_selinux = {{ containerd_enable_selinux | lower }} + disable_apparmor = {{ containerd_disable_apparmor | lower }} + tolerate_missing_hugetlb_controller = {{ containerd_tolerate_missing_hugetlb_controller | lower }} + disable_hugetlb_controller = {{ containerd_disable_hugetlb_controller | lower }} + image_pull_progress_timeout = "{{ containerd_image_pull_progress_timeout }}" {% if enable_cdi %} enable_cdi = true cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"] @@ -92,6 +105,14 @@ oom_score = {{ containerd_oom_score }} disable = false {% endif %} -{% if containerd_extra_args is defined %} -{{ containerd_extra_args }} +{% if containerd_tracing_enabled %} + [plugins."io.containerd.tracing.processor.v1.otlp"] + endpoint = "{{ containerd_tracing_endpoint }}" + protocol = "{{ containerd_tracing_protocol }}" +{% if containerd_tracing_protocol == "grpc" %} + insecure = false +{% endif %} + [plugins."io.containerd.internal.v1.tracing"] + sampling_ratio = {{ containerd_tracing_sampling_ratio }} + service_name = "{{ containerd_tracing_service_name }}" {% endif %} diff --git a/kubespray/project/roles/container-engine/containerd/templates/hosts.toml.j2 b/kubespray/project/roles/container-engine/containerd/templates/hosts.toml.j2 index ea003ed..ef63ff1 100644 --- a/kubespray/project/roles/container-engine/containerd/templates/hosts.toml.j2 +++ b/kubespray/project/roles/container-engine/containerd/templates/hosts.toml.j2 @@ -1,4 +1,4 @@ -server = "https://{{ item.prefix }}" +server = "{{ item.server | default("https://" + item.prefix) }}" {% for mirror in item.mirrors %} [host."{{ mirror.host }}"] capabilities = ["{{ ([ mirror.capabilities ] | flatten ) | join('","') }}"] diff --git a/kubespray/project/roles/container-engine/cri-dockerd/handlers/main.yml b/kubespray/project/roles/container-engine/cri-dockerd/handlers/main.yml index 3a24979..f60f28f 100644 --- a/kubespray/project/roles/container-engine/cri-dockerd/handlers/main.yml +++ b/kubespray/project/roles/container-engine/cri-dockerd/handlers/main.yml @@ -1,9 +1,9 @@ --- - name: Cri-dockerd | reload systemd - systemd: + systemd_service: name: cri-dockerd daemon_reload: true - masked: no + masked: false listen: Restart and enable cri-dockerd - name: Cri-dockerd | restart docker.service @@ -27,5 +27,5 @@ - name: Cri-dockerd | enable cri-dockerd service service: name: cri-dockerd.service - enabled: yes + enabled: true listen: Restart and enable cri-dockerd diff --git a/kubespray/project/roles/container-engine/cri-dockerd/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/cri-dockerd/molecule/default/prepare.yml index 83449f8..b532842 100644 --- a/kubespray/project/roles/container-engine/cri-dockerd/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/cri-dockerd/molecule/default/prepare.yml @@ -28,7 +28,7 @@ src: "{{ item }}" dest: "/tmp/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - container.json - sandbox.json @@ -37,12 +37,12 @@ path: /etc/cni/net.d state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" - name: Setup CNI copy: src: "{{ item }}" dest: "/etc/cni/net.d/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - 10-mynet.conf diff --git a/kubespray/project/roles/container-engine/cri-dockerd/tasks/main.yml b/kubespray/project/roles/container-engine/cri-dockerd/tasks/main.yml index 730e379..f7d1b18 100644 --- a/kubespray/project/roles/container-engine/cri-dockerd/tasks/main.yml +++ b/kubespray/project/roles/container-engine/cri-dockerd/tasks/main.yml @@ -8,7 +8,7 @@ copy: src: "{{ local_release_dir }}/cri-dockerd" dest: "{{ bin_dir }}/cri-dockerd" - mode: 0755 + mode: "0755" remote_src: true notify: - Restart and enable cri-dockerd @@ -17,7 +17,7 @@ template: src: "{{ item }}.j2" dest: "/etc/systemd/system/{{ item }}" - mode: 0644 + mode: "0644" validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:{{ item }}'" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 diff --git a/kubespray/project/roles/container-engine/cri-o/handlers/main.yml b/kubespray/project/roles/container-engine/cri-o/handlers/main.yml index b0c5951..0595e4f 100644 --- a/kubespray/project/roles/container-engine/cri-o/handlers/main.yml +++ b/kubespray/project/roles/container-engine/cri-o/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: CRI-O | reload systemd - systemd: + systemd_service: daemon_reload: true listen: Restart crio @@ -8,5 +8,5 @@ service: name: crio state: restarted - enabled: yes + enabled: true listen: Restart crio diff --git a/kubespray/project/roles/container-engine/cri-o/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/cri-o/molecule/default/prepare.yml index 103b0d3..55ad517 100644 --- a/kubespray/project/roles/container-engine/cri-o/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/cri-o/molecule/default/prepare.yml @@ -1,7 +1,7 @@ --- - name: Prepare hosts: all - gather_facts: False + gather_facts: false become: true vars: ignore_assert_errors: true @@ -19,7 +19,7 @@ - name: Prepare CNI hosts: all - gather_facts: False + gather_facts: false become: true vars: ignore_assert_errors: true @@ -33,7 +33,7 @@ src: "{{ item }}" dest: "/tmp/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - container.json - sandbox.json @@ -42,12 +42,12 @@ path: /etc/cni/net.d state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" - name: Setup CNI copy: src: "{{ item }}" dest: "/etc/cni/net.d/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - 10-mynet.conf diff --git a/kubespray/project/roles/container-engine/cri-o/tasks/main.yaml b/kubespray/project/roles/container-engine/cri-o/tasks/main.yaml index 99a3ed2..bde2e07 100644 --- a/kubespray/project/roles/container-engine/cri-o/tasks/main.yaml +++ b/kubespray/project/roles/container-engine/cri-o/tasks/main.yaml @@ -5,9 +5,9 @@ - name: Cri-o | check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree - name: Cri-o | set is_ostree @@ -56,27 +56,27 @@ file: path: "{{ item }}" state: directory - mode: 0755 + mode: "0755" - name: Cri-o | install cri-o config template: src: crio.conf.j2 dest: /etc/crio/crio.conf - mode: 0644 + mode: "0644" register: config_install - name: Cri-o | install config.json template: src: config.json.j2 dest: /etc/crio/config.json - mode: 0644 + mode: "0644" register: reg_auth_install - name: Cri-o | copy binaries copy: src: "{{ local_release_dir }}/cri-o/bin/{{ item }}" dest: "{{ bin_dir }}/{{ item }}" - mode: 0755 + mode: "0755" remote_src: true with_items: - "{{ crio_bin_files }}" @@ -86,10 +86,24 @@ copy: src: "{{ local_release_dir }}/cri-o/contrib/crio.service" dest: /etc/systemd/system/crio.service - mode: 0755 + mode: "0755" remote_src: true notify: Restart crio +- name: Cri-o | configure crio to use kube reserved cgroups + ansible.builtin.copy: + dest: /etc/systemd/system/crio.service.d/00-slice.conf + owner: root + group: root + mode: '0644' + content: | + [Service] + Slice={{ kube_reserved_cgroups_for_service_slice }} + notify: Restart crio + when: + - kube_reserved is defined and kube_reserved is true + - kube_reserved_cgroups_for_service_slice is defined + - name: Cri-o | update the bin dir for crio.service file replace: dest: /etc/systemd/system/crio.service @@ -101,7 +115,7 @@ copy: src: "{{ local_release_dir }}/cri-o/contrib/policy.json" dest: /etc/containers/policy.json - mode: 0755 + mode: "0755" remote_src: true notify: Restart crio @@ -109,7 +123,7 @@ copy: src: mounts.conf dest: /etc/containers/mounts.conf - mode: 0644 + mode: "0644" when: - ansible_os_family == 'RedHat' notify: Restart crio @@ -119,7 +133,7 @@ path: /etc/containers/oci/hooks.d state: directory owner: root - mode: 0755 + mode: "0755" - name: Cri-o | set overlay driver community.general.ini_file: @@ -127,7 +141,7 @@ section: storage option: "{{ item.option }}" value: "{{ item.value }}" - mode: 0644 + mode: "0644" with_items: - option: driver value: '"overlay"' @@ -143,20 +157,20 @@ section: storage.options.overlay option: mountopt value: '{{ ''"nodev"'' if ansible_kernel is version_compare(("4.18" if ansible_os_family == "RedHat" else "4.19"), "<") else ''"nodev,metacopy=on"'' }}' - mode: 0644 + mode: "0644" - name: Cri-o | create directory registries configs file: path: /etc/containers/registries.conf.d state: directory owner: root - mode: 0755 + mode: "0755" - name: Cri-o | write registries configs template: src: registry.conf.j2 - dest: "/etc/containers/registries.conf.d/10-{{ item.prefix | default(item.location) | regex_replace(':', '_') }}.conf" - mode: 0644 + dest: "/etc/containers/registries.conf.d/10-{{ item.prefix | default(item.location) | regex_replace(':|/', '_') }}.conf" + mode: "0644" loop: "{{ crio_registries }}" notify: Restart crio @@ -164,14 +178,14 @@ template: src: unqualified.conf.j2 dest: "/etc/containers/registries.conf.d/01-unqualified.conf" - mode: 0644 + mode: "0644" notify: Restart crio - name: Cri-o | write cri-o proxy drop-in template: src: http-proxy.conf.j2 dest: /etc/systemd/system/crio.service.d/http-proxy.conf - mode: 0644 + mode: "0644" notify: Restart crio when: http_proxy is defined or https_proxy is defined diff --git a/kubespray/project/roles/container-engine/cri-o/tasks/setup-amazon.yaml b/kubespray/project/roles/container-engine/cri-o/tasks/setup-amazon.yaml index 843bc20..cef0112 100644 --- a/kubespray/project/roles/container-engine/cri-o/tasks/setup-amazon.yaml +++ b/kubespray/project/roles/container-engine/cri-o/tasks/setup-amazon.yaml @@ -8,7 +8,7 @@ lineinfile: dest: /etc/yum.repos.d/amzn2-extras.repo line: "[amzn2extra-docker]" - check_mode: yes + check_mode: true register: amzn2_extras_docker_repo when: - amzn2_extras_file_stat.stat.exists @@ -19,20 +19,8 @@ section: amzn2extra-docker option: enabled value: "0" - backup: yes - mode: 0644 + backup: true + mode: "0644" when: - amzn2_extras_file_stat.stat.exists - not amzn2_extras_docker_repo.changed - -- name: Add container-selinux yum repo - yum_repository: - name: copr:copr.fedorainfracloud.org:lsm5:container-selinux - file: _copr_lsm5-container-selinux.repo - description: Copr repo for container-selinux owned by lsm5 - baseurl: https://download.copr.fedorainfracloud.org/results/lsm5/container-selinux/epel-7-$basearch/ - gpgcheck: yes - gpgkey: https://download.copr.fedorainfracloud.org/results/lsm5/container-selinux/pubkey.gpg - skip_if_unavailable: yes - enabled: yes - repo_gpgcheck: no diff --git a/kubespray/project/roles/container-engine/cri-o/vars/v1.29.yml b/kubespray/project/roles/container-engine/cri-o/vars/v1.29.yml index bc25e2e..ddf34c7 100644 --- a/kubespray/project/roles/container-engine/cri-o/vars/v1.29.yml +++ b/kubespray/project/roles/container-engine/cri-o/vars/v1.29.yml @@ -1,8 +1,12 @@ --- +crio_conmon: "{{ bin_dir }}/crio-conmon" + # cri-o binary files crio_bin_files: - - conmon - - conmonrs + - crio-conmon + - crio-conmonrs + - crio-crun + - crio-runc - crio - pinns diff --git a/kubespray/project/roles/container-engine/crictl/handlers/main.yml b/kubespray/project/roles/container-engine/crictl/handlers/main.yml index 5319586..d6ffe16 100644 --- a/kubespray/project/roles/container-engine/crictl/handlers/main.yml +++ b/kubespray/project/roles/container-engine/crictl/handlers/main.yml @@ -1,7 +1,7 @@ --- - name: Get crictl completion command: "{{ bin_dir }}/crictl completion" - changed_when: False + changed_when: false register: cri_completion check_mode: false @@ -9,4 +9,4 @@ copy: dest: /etc/bash_completion.d/crictl content: "{{ cri_completion.stdout }}" - mode: 0644 + mode: "0644" diff --git a/kubespray/project/roles/container-engine/crictl/tasks/crictl.yml b/kubespray/project/roles/container-engine/crictl/tasks/crictl.yml index cffa050..72bde5d 100644 --- a/kubespray/project/roles/container-engine/crictl/tasks/crictl.yml +++ b/kubespray/project/roles/container-engine/crictl/tasks/crictl.yml @@ -9,13 +9,13 @@ src: crictl.yaml.j2 dest: /etc/crictl.yaml owner: root - mode: 0644 + mode: "0644" - name: Copy crictl binary from download dir copy: src: "{{ local_release_dir }}/crictl" dest: "{{ bin_dir }}/crictl" - mode: 0755 + mode: "0755" remote_src: true notify: - Get crictl completion diff --git a/kubespray/project/roles/container-engine/crun/tasks/main.yml b/kubespray/project/roles/container-engine/crun/tasks/main.yml index c21bb3f..f4ec764 100644 --- a/kubespray/project/roles/container-engine/crun/tasks/main.yml +++ b/kubespray/project/roles/container-engine/crun/tasks/main.yml @@ -8,5 +8,5 @@ copy: src: "{{ downloads.crun.dest }}" dest: "{{ bin_dir }}/crun" - mode: 0755 + mode: "0755" remote_src: true diff --git a/kubespray/project/roles/container-engine/docker-storage/defaults/main.yml b/kubespray/project/roles/container-engine/docker-storage/defaults/main.yml deleted file mode 100644 index 6a69556..0000000 --- a/kubespray/project/roles/container-engine/docker-storage/defaults/main.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -docker_container_storage_setup_repository: https://github.com/projectatomic/container-storage-setup.git -docker_container_storage_setup_version: v0.6.0 -docker_container_storage_setup_profile_name: kubespray -docker_container_storage_setup_storage_driver: devicemapper -docker_container_storage_setup_container_thinpool: docker-pool -# It must be define a disk path for docker_container_storage_setup_devs. -# Otherwise docker-storage-setup will be executed incorrectly. -# docker_container_storage_setup_devs: /dev/vdb -docker_container_storage_setup_data_size: 40%FREE -docker_container_storage_setup_min_data_size: 2G -docker_container_storage_setup_chunk_size: 512K -docker_container_storage_setup_growpart: "false" -docker_container_storage_setup_auto_extend_pool: "yes" -docker_container_storage_setup_pool_autoextend_threshold: 60 -docker_container_storage_setup_pool_autoextend_percent: 20 -docker_container_storage_setup_device_wait_timeout: 60 -docker_container_storage_setup_wipe_signatures: "false" -docker_container_storage_setup_container_root_lv_size: 40%FREE diff --git a/kubespray/project/roles/container-engine/docker-storage/files/install_container_storage_setup.sh b/kubespray/project/roles/container-engine/docker-storage/files/install_container_storage_setup.sh deleted file mode 100644 index 604c843..0000000 --- a/kubespray/project/roles/container-engine/docker-storage/files/install_container_storage_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -e - -repository=${1:-https://github.com/projectatomic/container-storage-setup.git} -version=${2:-master} -profile_name=${3:-kubespray} -dir=`mktemp -d` -export GIT_DIR=$dir/.git -export GIT_WORK_TREE=$dir - -git init -git fetch --depth 1 $repository $version -git merge FETCH_HEAD -make -C $dir install -rm -rf /var/lib/container-storage-setup/$profile_name $dir - -set +e - -/usr/bin/container-storage-setup create $profile_name /etc/sysconfig/docker-storage-setup && /usr/bin/container-storage-setup activate $profile_name -# FIXME: exit status can be 1 for both fatal and non fatal errors in current release, -# could be improved by matching error strings -exit 0 diff --git a/kubespray/project/roles/container-engine/docker-storage/tasks/main.yml b/kubespray/project/roles/container-engine/docker-storage/tasks/main.yml deleted file mode 100644 index ec12975..0000000 --- a/kubespray/project/roles/container-engine/docker-storage/tasks/main.yml +++ /dev/null @@ -1,48 +0,0 @@ ---- - -- name: Docker-storage-setup | install git and make - with_items: [git, make] - package: - pkg: "{{ item }}" - state: present - -- name: Docker-storage-setup | docker-storage-setup sysconfig template - template: - src: docker-storage-setup.j2 - dest: /etc/sysconfig/docker-storage-setup - mode: 0644 - -- name: Docker-storage-override-directory | docker service storage-setup override dir - file: - dest: /etc/systemd/system/docker.service.d - mode: 0755 - owner: root - group: root - state: directory - -- name: Docker-storage-override | docker service storage-setup override file - copy: - dest: /etc/systemd/system/docker.service.d/override.conf - content: |- - ### This file is managed by Ansible - [Service] - EnvironmentFile=-/etc/sysconfig/docker-storage - - owner: root - group: root - mode: 0644 - -# https://docs.docker.com/engine/installation/linux/docker-ce/centos/#install-using-the-repository -- name: Docker-storage-setup | install lvm2 - package: - name: lvm2 - state: present - -- name: Docker-storage-setup | install and run container-storage-setup - become: yes - script: | - install_container_storage_setup.sh \ - {{ docker_container_storage_setup_repository }} \ - {{ docker_container_storage_setup_version }} \ - {{ docker_container_storage_setup_profile_name }} - notify: Docker | reload systemd diff --git a/kubespray/project/roles/container-engine/docker-storage/templates/docker-storage-setup.j2 b/kubespray/project/roles/container-engine/docker-storage/templates/docker-storage-setup.j2 deleted file mode 100644 index 1a502b2..0000000 --- a/kubespray/project/roles/container-engine/docker-storage/templates/docker-storage-setup.j2 +++ /dev/null @@ -1,35 +0,0 @@ -{%if docker_container_storage_setup_storage_driver is defined%}STORAGE_DRIVER={{docker_container_storage_setup_storage_driver}}{%endif%} - -{%if docker_container_storage_setup_extra_storage_options is defined%}EXTRA_STORAGE_OPTIONS={{docker_container_storage_setup_extra_storage_options}}{%endif%} - -{%if docker_container_storage_setup_devs is defined%}DEVS={{docker_container_storage_setup_devs}}{%endif%} - -{%if docker_container_storage_setup_container_thinpool is defined%}CONTAINER_THINPOOL={{docker_container_storage_setup_container_thinpool}}{%endif%} - -{%if docker_container_storage_setup_vg is defined%}VG={{docker_container_storage_setup_vg}}{%endif%} - -{%if docker_container_storage_setup_root_size is defined%}ROOT_SIZE={{docker_container_storage_setup_root_size}}{%endif%} - -{%if docker_container_storage_setup_data_size is defined%}DATA_SIZE={{docker_container_storage_setup_data_size}}{%endif%} - -{%if docker_container_storage_setup_min_data_size is defined%}MIN_DATA_SIZE={{docker_container_storage_setup_min_data_size}}{%endif%} - -{%if docker_container_storage_setup_chunk_size is defined%}CHUNK_SIZE={{docker_container_storage_setup_chunk_size}}{%endif%} - -{%if docker_container_storage_setup_growpart is defined%}GROWPART={{docker_container_storage_setup_growpart}}{%endif%} - -{%if docker_container_storage_setup_auto_extend_pool is defined%}AUTO_EXTEND_POOL={{docker_container_storage_setup_auto_extend_pool}}{%endif%} - -{%if docker_container_storage_setup_pool_autoextend_threshold is defined%}POOL_AUTOEXTEND_THRESHOLD={{docker_container_storage_setup_pool_autoextend_threshold}}{%endif%} - -{%if docker_container_storage_setup_pool_autoextend_percent is defined%}POOL_AUTOEXTEND_PERCENT={{docker_container_storage_setup_pool_autoextend_percent}}{%endif%} - -{%if docker_container_storage_setup_device_wait_timeout is defined%}DEVICE_WAIT_TIMEOUT={{docker_container_storage_setup_device_wait_timeout}}{%endif%} - -{%if docker_container_storage_setup_wipe_signatures is defined%}WIPE_SIGNATURES={{docker_container_storage_setup_wipe_signatures}}{%endif%} - -{%if docker_container_storage_setup_container_root_lv_name is defined%}CONTAINER_ROOT_LV_NAME={{docker_container_storage_setup_container_root_lv_name}}{%endif%} - -{%if docker_container_storage_setup_container_root_lv_size is defined%}CONTAINER_ROOT_LV_SIZE={{docker_container_storage_setup_container_root_lv_size}}{%endif%} - -{%if docker_container_storage_setup_container_root_lv_mount_path is defined%}CONTAINER_ROOT_LV_MOUNT_PATH={{docker_container_storage_setup_container_root_lv_mount_path}}{%endif%} diff --git a/kubespray/project/roles/container-engine/docker/defaults/main.yml b/kubespray/project/roles/container-engine/docker/defaults/main.yml index f756208..4615176 100644 --- a/kubespray/project/roles/container-engine/docker/defaults/main.yml +++ b/kubespray/project/roles/container-engine/docker/defaults/main.yml @@ -1,5 +1,5 @@ --- -docker_version: '24.0' +docker_version: '26.1' docker_cli_version: "{{ docker_version }}" docker_package_info: diff --git a/kubespray/project/roles/container-engine/docker/handlers/main.yml b/kubespray/project/roles/container-engine/docker/handlers/main.yml index 4a8a639..76d16f5 100644 --- a/kubespray/project/roles/container-engine/docker/handlers/main.yml +++ b/kubespray/project/roles/container-engine/docker/handlers/main.yml @@ -1,9 +1,9 @@ --- - name: Docker | reload systemd - systemd: + systemd_service: name: docker daemon_reload: true - masked: no + masked: false listen: Restart docker - name: Docker | reload docker.socket diff --git a/kubespray/project/roles/container-engine/docker/meta/main.yml b/kubespray/project/roles/container-engine/docker/meta/main.yml index d7e4751..1a53ba7 100644 --- a/kubespray/project/roles/container-engine/docker/meta/main.yml +++ b/kubespray/project/roles/container-engine/docker/meta/main.yml @@ -1,5 +1,3 @@ --- dependencies: - role: container-engine/containerd-common - - role: container-engine/docker-storage - when: docker_container_storage_setup and ansible_os_family == "RedHat" diff --git a/kubespray/project/roles/container-engine/docker/tasks/main.yml b/kubespray/project/roles/container-engine/docker/tasks/main.yml index 1fc490b..e56fe4c 100644 --- a/kubespray/project/roles/container-engine/docker/tasks/main.yml +++ b/kubespray/project/roles/container-engine/docker/tasks/main.yml @@ -2,22 +2,15 @@ - name: Check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree - name: Set is_ostree set_fact: is_ostree: "{{ ostree.stat.exists }}" -- name: Set docker_version for openEuler - set_fact: - docker_version: '19.03' - when: ansible_distribution == "openEuler" - tags: - - facts - - name: Gather os specific variables include_vars: "{{ item }}" with_first_found: @@ -67,6 +60,17 @@ environment: "{{ proxy_env }}" when: ansible_pkg_mgr == 'apt' +# ref to https://github.com/kubernetes-sigs/kubespray/issues/11086 +- name: Remove the archived debian apt repository + lineinfile: + path: /etc/apt/sources.list + regexp: 'buster-backports' + state: absent + backup: true + when: + - ansible_os_family == 'Debian' + - ansible_distribution_release == "buster" + - name: Ensure docker-ce repository is enabled apt_repository: repo: "{{ item }}" @@ -78,14 +82,14 @@ template: src: "fedora_docker.repo.j2" dest: "{{ yum_repo_dir }}/docker.repo" - mode: 0644 + mode: "0644" when: ansible_distribution == "Fedora" and not is_ostree - name: Configure docker repository on RedHat/CentOS/OracleLinux/AlmaLinux/KylinLinux template: src: "rh_docker.repo.j2" dest: "{{ yum_repo_dir }}/docker-ce.repo" - mode: 0644 + mode: "0644" when: - ansible_os_family == "RedHat" - ansible_distribution != "Fedora" @@ -96,7 +100,11 @@ name: "{{ item }}" selection: install when: ansible_pkg_mgr == 'apt' + register: ret changed_when: false + failed_when: + - ret is failed + - ret.msg != ( "Failed to find package '" + item + "' to perform selection 'install'." ) with_items: - "{{ containerd_package }}" - docker-ce @@ -175,7 +183,7 @@ - name: Ensure docker service is started and enabled service: name: "{{ item }}" - enabled: yes + enabled: true state: started with_items: - docker diff --git a/kubespray/project/roles/container-engine/docker/tasks/reset.yml b/kubespray/project/roles/container-engine/docker/tasks/reset.yml index 4bca908..725e648 100644 --- a/kubespray/project/roles/container-engine/docker/tasks/reset.yml +++ b/kubespray/project/roles/container-engine/docker/tasks/reset.yml @@ -6,8 +6,8 @@ - name: Docker | Find docker packages set_fact: - docker_packages_list: "{{ ansible_facts.packages.keys() | select('search', '^docker*') }}" - containerd_package: "{{ ansible_facts.packages.keys() | select('search', '^containerd*') }}" + docker_packages_list: "{{ ansible_facts.packages.keys() | select('search', '^docker+') }}" + containerd_package: "{{ ansible_facts.packages.keys() | select('search', '^containerd+') }}" - name: Docker | Stop all running container shell: "set -o pipefail && {{ docker_bin_dir }}/docker ps -q | xargs -r {{ docker_bin_dir }}/docker kill" @@ -102,5 +102,5 @@ ignore_errors: true # noqa ignore-errors - name: Docker | systemctl daemon-reload # noqa no-handler - systemd: + systemd_service: daemon_reload: true diff --git a/kubespray/project/roles/container-engine/docker/tasks/set_facts_dns.yml b/kubespray/project/roles/container-engine/docker/tasks/set_facts_dns.yml index d7c1039..d0ccd74 100644 --- a/kubespray/project/roles/container-engine/docker/tasks/set_facts_dns.yml +++ b/kubespray/project/roles/container-engine/docker/tasks/set_facts_dns.yml @@ -21,9 +21,9 @@ shell: set -o pipefail && grep "^nameserver" /etc/resolv.conf | sed -r 's/^nameserver\s*([^#\s]+)\s*(#.*)?/\1/' args: executable: /bin/bash - changed_when: False + changed_when: false register: system_nameservers - check_mode: no + check_mode: false - name: Check system search domains # noqa risky-shell-pipe - if resolf.conf has no search domain, grep will exit 1 which would force us to add failed_when: false @@ -31,9 +31,9 @@ shell: grep "^search" /etc/resolv.conf | sed -r 's/^search\s*([^#]+)\s*(#.*)?/\1/' args: executable: /bin/bash - changed_when: False + changed_when: false register: system_search_domains - check_mode: no + check_mode: false - name: Add system nameservers to docker options set_fact: diff --git a/kubespray/project/roles/container-engine/docker/tasks/systemd.yml b/kubespray/project/roles/container-engine/docker/tasks/systemd.yml index 57d9b9c..2f16d1f 100644 --- a/kubespray/project/roles/container-engine/docker/tasks/systemd.yml +++ b/kubespray/project/roles/container-engine/docker/tasks/systemd.yml @@ -3,31 +3,21 @@ file: path: /etc/systemd/system/docker.service.d state: directory - mode: 0755 + mode: "0755" - name: Write docker proxy drop-in template: src: http-proxy.conf.j2 dest: /etc/systemd/system/docker.service.d/http-proxy.conf - mode: 0644 + mode: "0644" notify: Restart docker when: http_proxy is defined or https_proxy is defined -- name: Get systemd version - # noqa command-instead-of-module - systemctl is called intentionally here - shell: set -o pipefail && systemctl --version | head -n 1 | cut -d " " -f 2 - args: - executable: /bin/bash - register: systemd_version - when: not is_ostree - changed_when: false - check_mode: false - - name: Write docker.service systemd file template: src: docker.service.j2 dest: /etc/systemd/system/docker.service - mode: 0644 + mode: "0644" register: docker_service_file notify: Restart docker when: @@ -38,14 +28,14 @@ template: src: docker-options.conf.j2 dest: "/etc/systemd/system/docker.service.d/docker-options.conf" - mode: 0644 + mode: "0644" notify: Restart docker - name: Write docker dns systemd drop-in template: src: docker-dns.conf.j2 dest: "/etc/systemd/system/docker.service.d/docker-dns.conf" - mode: 0644 + mode: "0644" notify: Restart docker when: dns_mode != 'none' and resolvconf_mode == 'docker_dns' @@ -53,14 +43,14 @@ copy: src: cleanup-docker-orphans.sh dest: "{{ bin_dir }}/cleanup-docker-orphans.sh" - mode: 0755 + mode: "0755" when: docker_orphan_clean_up | bool - name: Write docker orphan clean up systemd drop-in template: src: docker-orphan-cleanup.conf.j2 dest: "/etc/systemd/system/docker.service.d/docker-orphan-cleanup.conf" - mode: 0644 + mode: "0644" notify: Restart docker when: docker_orphan_clean_up | bool diff --git a/kubespray/project/roles/container-engine/docker/templates/docker.service.j2 b/kubespray/project/roles/container-engine/docker/templates/docker.service.j2 index 539c3a5..bc22019 100644 --- a/kubespray/project/roles/container-engine/docker/templates/docker.service.j2 +++ b/kubespray/project/roles/container-engine/docker/templates/docker.service.j2 @@ -1,19 +1,11 @@ [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com -{% if ansible_os_family == "RedHat" %} -After=network.target {{ ' docker-storage-setup.service' if docker_container_storage_setup else '' }} containerd.service +After=network.target docker.socket containerd.service lvm2-monitor.service SuSEfirewall2.service +{% if ansible_os_family != "Suse" %} BindsTo=containerd.service -{{ 'Wants=docker-storage-setup.service' if docker_container_storage_setup else '' }} -{% elif ansible_os_family == "Debian" %} -After=network.target docker.socket containerd.service -BindsTo=containerd.service -Wants=docker.socket -{% elif ansible_os_family == "Suse" %} -After=network.target lvm2-monitor.service SuSEfirewall2.service -# After=network.target containerd.service -# BindsTo=containerd.service {% endif %} +Wants=docker.socket [Service] Type=notify @@ -31,9 +23,7 @@ ExecStart={{ docker_bin_dir }}/dockerd \ $DOCKER_OPTS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_DNS_OPTIONS -{% if not is_ostree and systemd_version.stdout|int >= 226 %} TasksMax=infinity -{% endif %} LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity diff --git a/kubespray/project/roles/container-engine/docker/vars/amazon.yml b/kubespray/project/roles/container-engine/docker/vars/amazon.yml index 4871f4a..ee4789f 100644 --- a/kubespray/project/roles/container-engine/docker/vars/amazon.yml +++ b/kubespray/project/roles/container-engine/docker/vars/amazon.yml @@ -6,6 +6,8 @@ docker_versioned_pkg: '18.09': docker-18.09.9ce-2.amzn2 '19.03': docker-19.03.13ce-1.amzn2 '20.10': docker-20.10.7-5.amzn2 + '24.0': docker-24.0.5-1.amzn2 + '25.0': docker-25.0.3-1.amzn2 docker_version: "latest" diff --git a/kubespray/project/roles/container-engine/docker/vars/debian.yml b/kubespray/project/roles/container-engine/docker/vars/debian.yml index 02289fa..f6d14d4 100644 --- a/kubespray/project/roles/container-engine/docker/vars/debian.yml +++ b/kubespray/project/roles/container-engine/docker/vars/debian.yml @@ -22,9 +22,11 @@ containerd_versioned_pkg: '1.6.15': "{{ containerd_package }}=1.6.15-1" '1.6.16': "{{ containerd_package }}=1.6.16-1" '1.6.18': "{{ containerd_package }}=1.6.18-1" - '1.6.28': "{{ containerd_package }}=1.6.28-1" - 'stable': "{{ containerd_package }}=1.6.28-1" - 'edge': "{{ containerd_package }}=1.6.28-1" + '1.6.28': "{{ containerd_package }}=1.6.28-2" + '1.6.31': "{{ containerd_package }}=1.6.31-1" + '1.6.32': "{{ containerd_package }}=1.6.32-1" + 'stable': "{{ containerd_package }}=1.6.32-1" + 'edge': "{{ containerd_package }}=1.6.32-1" # https://download.docker.com/linux/debian/ docker_versioned_pkg: @@ -34,6 +36,9 @@ docker_versioned_pkg: '20.10': docker-ce=5:20.10.20~3-0~debian-{{ ansible_distribution_release | lower }} '23.0': docker-ce=5:23.0.6-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} '24.0': docker-ce=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '25.0': docker-ce=5:25.0.5-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '26.0': docker-ce=5:26.0.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '26.1': docker-ce=5:26.1.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} 'stable': docker-ce=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} 'edge': docker-ce=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} @@ -44,8 +49,11 @@ docker_cli_versioned_pkg: '20.10': docker-ce-cli=5:20.10.20~3-0~debian-{{ ansible_distribution_release | lower }} '23.0': docker-ce-cli=5:23.0.6-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} '24.0': docker-ce-cli=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} - 'stable': docker-ce-cli=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} - 'edge': docker-ce-cli=5:24.0.9-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '25.0': docker-ce-cli=5:25.0.5-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '26.0': docker-ce-cli=5:26.0.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + '26.1': docker-ce-cli=5:26.1.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + 'stable': docker-ce-cli=5:26.1.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} + 'edge': docker-ce-cli=5:26.1.2-1~debian.{{ ansible_distribution_major_version }}~{{ ansible_distribution_release | lower }} docker_package_info: pkgs: diff --git a/kubespray/project/roles/container-engine/docker/vars/fedora.yml b/kubespray/project/roles/container-engine/docker/vars/fedora.yml index 39dfbaf..392e553 100644 --- a/kubespray/project/roles/container-engine/docker/vars/fedora.yml +++ b/kubespray/project/roles/container-engine/docker/vars/fedora.yml @@ -22,9 +22,11 @@ containerd_versioned_pkg: '1.6.15': "{{ containerd_package }}-1.6.15-3.1.fc{{ ansible_distribution_major_version }}" '1.6.16': "{{ containerd_package }}-1.6.16-3.1.fc{{ ansible_distribution_major_version }}" '1.6.18': "{{ containerd_package }}-1.6.18-3.1.fc{{ ansible_distribution_major_version }}" - '1.6.28': "{{ containerd_package }}-1.6.28-3.1.fc{{ ansible_distribution_major_version }}" - 'stable': "{{ containerd_package }}-1.6.28-3.1.fc{{ ansible_distribution_major_version }}" - 'edge': "{{ containerd_package }}-1.6.28-3.1.fc{{ ansible_distribution_major_version }}" + '1.6.28': "{{ containerd_package }}-1.6.28-3.2.fc{{ ansible_distribution_major_version }}" + '1.6.31': "{{ containerd_package }}-1.6.31-3.1.fc{{ ansible_distribution_major_version }}" + '1.6.32': "{{ containerd_package }}-1.6.32-3.1.fc{{ ansible_distribution_major_version }}" + 'stable': "{{ containerd_package }}-1.6.32-3.1.fc{{ ansible_distribution_major_version }}" + 'edge': "{{ containerd_package }}-1.6.32-3.1.fc{{ ansible_distribution_major_version }}" # https://docs.docker.com/install/linux/docker-ce/fedora/ # https://download.docker.com/linux/fedora//x86_64/stable/Packages/ @@ -34,8 +36,10 @@ docker_versioned_pkg: '20.10': docker-ce-20.10.20-3.fc{{ ansible_distribution_major_version }} '23.0': docker-ce-3:23.0.6-1.fc{{ ansible_distribution_major_version }} '24.0': docker-ce-3:24.0.9-1.fc{{ ansible_distribution_major_version }} - 'stable': docker-ce-3:24.0.9-1.fc{{ ansible_distribution_major_version }} - 'edge': docker-ce-3:24.0.9-1.fc{{ ansible_distribution_major_version }} + '26.0': docker-ce-3:26.0.2-1.fc{{ ansible_distribution_major_version }} + '26.1': docker-ce-3:26.1.2-1.fc{{ ansible_distribution_major_version }} + 'stable': docker-ce-3:26.1.2-1.fc{{ ansible_distribution_major_version }} + 'edge': docker-ce-3:26.1.2-1.fc{{ ansible_distribution_major_version }} docker_cli_versioned_pkg: 'latest': docker-ce-cli @@ -43,8 +47,10 @@ docker_cli_versioned_pkg: '20.10': docker-ce-cli-20.10.20-3.fc{{ ansible_distribution_major_version }} '23.0': docker-ce-cli-1:23.0.6-1.fc{{ ansible_distribution_major_version }} '24.0': docker-ce-cli-1:24.0.9-1.fc{{ ansible_distribution_major_version }} - 'stable': docker-ce-cli-1:24.0.9-1.fc{{ ansible_distribution_major_version }} - 'edge': docker-ce-cli-1:24.0.9-1.fc{{ ansible_distribution_major_version }} + '26.0': docker-ce-cli-1:26.0.2-1.fc{{ ansible_distribution_major_version }} + '26.1': docker-ce-cli-1:26.0.2-1.fc{{ ansible_distribution_major_version }} + 'stable': docker-ce-cli-1:26.0.2-1.fc{{ ansible_distribution_major_version }} + 'edge': docker-ce-cli-1:26.0.2-1.fc{{ ansible_distribution_major_version }} docker_package_info: enablerepo: "docker-ce" diff --git a/kubespray/project/roles/container-engine/docker/vars/kylin.yml b/kubespray/project/roles/container-engine/docker/vars/kylin.yml index 2b8cdf7..d79cf83 100644 --- a/kubespray/project/roles/container-engine/docker/vars/kylin.yml +++ b/kubespray/project/roles/container-engine/docker/vars/kylin.yml @@ -1,54 +1,62 @@ --- + +docker_version: 26.1 +docker_cli_version: "{{ docker_version }}" +docker_rh_repo_base_url: 'https://download.docker.com/linux/centos/8/$basearch/stable' + # containerd versions are only relevant for docker containerd_versioned_pkg: 'latest': "{{ containerd_package }}" - '1.3.7': "{{ containerd_package }}-1.3.7-3.1.el{{ ansible_distribution_major_version }}" - '1.3.9': "{{ containerd_package }}-1.3.9-3.1.el{{ ansible_distribution_major_version }}" - '1.4.3': "{{ containerd_package }}-1.4.3-3.2.el{{ ansible_distribution_major_version }}" - '1.4.4': "{{ containerd_package }}-1.4.4-3.1.el{{ ansible_distribution_major_version }}" - '1.4.6': "{{ containerd_package }}-1.4.6-3.1.el{{ ansible_distribution_major_version }}" - '1.4.9': "{{ containerd_package }}-1.4.9-3.1.el{{ ansible_distribution_major_version }}" - '1.4.12': "{{ containerd_package }}-1.4.12-3.1.el{{ ansible_distribution_major_version }}" - '1.6.4': "{{ containerd_package }}-1.6.4-3.1.el{{ ansible_distribution_major_version }}" - '1.6.6': "{{ containerd_package }}-1.6.6-3.1.el{{ ansible_distribution_major_version }}" - '1.6.7': "{{ containerd_package }}-1.6.7-3.1.el{{ ansible_distribution_major_version }}" - '1.6.8': "{{ containerd_package }}-1.6.8-3.1.el{{ ansible_distribution_major_version }}" - '1.6.9': "{{ containerd_package }}-1.6.9-3.1.el{{ ansible_distribution_major_version }}" - '1.6.10': "{{ containerd_package }}-1.6.10-3.1.el{{ ansible_distribution_major_version }}" - '1.6.11': "{{ containerd_package }}-1.6.11-3.1.el{{ ansible_distribution_major_version }}" - '1.6.12': "{{ containerd_package }}-1.6.12-3.1.el{{ ansible_distribution_major_version }}" - '1.6.13': "{{ containerd_package }}-1.6.13-3.1.el{{ ansible_distribution_major_version }}" - '1.6.14': "{{ containerd_package }}-1.6.14-3.1.el{{ ansible_distribution_major_version }}" - '1.6.15': "{{ containerd_package }}-1.6.15-3.1.el{{ ansible_distribution_major_version }}" - '1.6.16': "{{ containerd_package }}-1.6.16-3.1.el{{ ansible_distribution_major_version }}" - '1.6.18': "{{ containerd_package }}-1.6.18-3.1.el{{ ansible_distribution_major_version }}" - '1.6.28': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'stable': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'edge': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - -docker_version: 19.03 -docker_cli_version: 19.03 + '1.3.7': "{{ containerd_package }}-1.3.7-3.1.el8" + '1.3.9': "{{ containerd_package }}-1.3.9-3.1.el8" + '1.4.3': "{{ containerd_package }}-1.4.3-3.2.el8" + '1.4.4': "{{ containerd_package }}-1.4.4-3.1.el8" + '1.4.6': "{{ containerd_package }}-1.4.6-3.1.el8" + '1.4.9': "{{ containerd_package }}-1.4.9-3.1.el8" + '1.4.12': "{{ containerd_package }}-1.4.12-3.1.el8" + '1.6.4': "{{ containerd_package }}-1.6.4-3.1.el8" + '1.6.6': "{{ containerd_package }}-1.6.6-3.1.el8" + '1.6.7': "{{ containerd_package }}-1.6.7-3.1.el8" + '1.6.8': "{{ containerd_package }}-1.6.8-3.1.el8" + '1.6.9': "{{ containerd_package }}-1.6.9-3.1.el8" + '1.6.10': "{{ containerd_package }}-1.6.10-3.1.el8" + '1.6.11': "{{ containerd_package }}-1.6.11-3.1.el8" + '1.6.12': "{{ containerd_package }}-1.6.12-3.1.el8" + '1.6.13': "{{ containerd_package }}-1.6.13-3.1.el8" + '1.6.14': "{{ containerd_package }}-1.6.14-3.1.el8" + '1.6.15': "{{ containerd_package }}-1.6.15-3.1.el8" + '1.6.16': "{{ containerd_package }}-1.6.16-3.1.el8" + '1.6.18': "{{ containerd_package }}-1.6.18-3.1.el8" + '1.6.28': "{{ containerd_package }}-1.6.28-3.1.el8" + '1.6.31': "{{ containerd_package }}-1.6.31-3.1.el8" + '1.6.32': "{{ containerd_package }}-1.6.32-3.1.el8" + 'stable': "{{ containerd_package }}-1.6.32-3.1.el8" + 'edge': "{{ containerd_package }}-1.6.32-3.1.el8" # https://docs.docker.com/engine/installation/linux/centos/#install-from-a-package -# https://download.docker.com/linux/centos/>/x86_64/stable/Packages/ +# https://download.docker.com/linux/centos/8/x86_64/stable/Packages/ # or do 'yum --showduplicates list docker-engine' docker_versioned_pkg: 'latest': docker-ce - '18.09': docker-ce-3:18.09.9-3.el{{ ansible_distribution_major_version }} - '19.03': docker-ce-3:19.03.15-3.el{{ ansible_distribution_major_version }} - '23.0': docker-ce-3:23.0.6-1.el{{ ansible_distribution_major_version }} - '24.0': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} - 'stable': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} - 'edge': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} + '18.09': docker-ce-3:18.09.9-3.el8 + '19.03': docker-ce-3:19.03.15-3.el8 + '23.0': docker-ce-3:23.0.6-1.el8 + '24.0': docker-ce-3:24.0.9-1.el8 + '26.0': docker-ce-26.0.2-1.el8 + '26.1': docker-ce-26.1.2-1.el8 + 'stable': docker-ce-26.1.2-1.el8 + 'edge': docker-ce-26.1.2-1.el8 docker_cli_versioned_pkg: 'latest': docker-ce-cli - '18.09': docker-ce-cli-1:18.09.9-3.el{{ ansible_distribution_major_version }} - '19.03': docker-ce-cli-1:19.03.15-3.el{{ ansible_distribution_major_version }} - '23.0': docker-ce-cli-1:23.0.6-1.el{{ ansible_distribution_major_version }} - '24.0': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} - 'stable': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} - 'edge': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} + '18.09': docker-ce-cli-1:18.09.9-3.el8 + '19.03': docker-ce-cli-1:19.03.15-3.el8 + '23.0': docker-ce-cli-1:23.0.6-1.el8 + '24.0': docker-ce-cli-1:24.0.9-1.el8 + '26.0': docker-ce-cli-26.0.2-1.el8 + '26.1': docker-ce-cli-26.1.2-1.el8 + 'stable': docker-ce-cli-26.1.2-1.el8 + 'edge': docker-ce-cli-26.1.2-1.el8 docker_package_info: enablerepo: "docker-ce" diff --git a/kubespray/project/roles/container-engine/docker/vars/openeuler.yml b/kubespray/project/roles/container-engine/docker/vars/openeuler.yml new file mode 120000 index 0000000..1010ef7 --- /dev/null +++ b/kubespray/project/roles/container-engine/docker/vars/openeuler.yml @@ -0,0 +1 @@ +kylin.yml \ No newline at end of file diff --git a/kubespray/project/roles/container-engine/docker/vars/redhat-7.yml b/kubespray/project/roles/container-engine/docker/vars/redhat-7.yml index c10e881..26ec59c 100644 --- a/kubespray/project/roles/container-engine/docker/vars/redhat-7.yml +++ b/kubespray/project/roles/container-engine/docker/vars/redhat-7.yml @@ -23,8 +23,10 @@ containerd_versioned_pkg: '1.6.16': "{{ containerd_package }}-1.6.16-3.1.el7" '1.6.18': "{{ containerd_package }}-1.6.18-3.1.el7" '1.6.28': "{{ containerd_package }}-1.6.28-3.1.el7" - 'stable': "{{ containerd_package }}-1.6.28-3.1.el7" - 'edge': "{{ containerd_package }}-1.6.18-3.1.el7" + '1.6.31': "{{ containerd_package }}-1.6.31-3.1.el7" + '1.6.32': "{{ containerd_package }}-1.6.32-3.1.el7" + 'stable': "{{ containerd_package }}-1.6.32-3.1.el7" + 'edge': "{{ containerd_package }}-1.6.32-3.1.el7" # https://docs.docker.com/engine/installation/linux/centos/#install-from-a-package # https://download.docker.com/linux/centos/>/x86_64/stable/Packages/ @@ -36,8 +38,10 @@ docker_versioned_pkg: '20.10': docker-ce-20.10.20-3.el7 '23.0': docker-ce-23.0.6-1.el7 '24.0': docker-ce-24.0.9-1.el7 - 'stable': docker-ce-24.0.9-1.el7 - 'edge': docker-ce-24.0.9-1.el7 + '26.0': docker-ce-26.0.2-1.el7 + '26.1': docker-ce-26.1.2-1.el7 + 'stable': docker-ce-26.1.2-1.el7 + 'edge': docker-ce-26.1.2-1.el7 docker_cli_versioned_pkg: 'latest': docker-ce-cli @@ -46,8 +50,10 @@ docker_cli_versioned_pkg: '20.10': docker-ce-cli-20.10.20-3.el7 '23.0': docker-ce-cli-23.0.6-1.el7 '24.0': docker-ce-cli-24.0.9-1.el7 - 'stable': docker-ce-cli-24.0.9-1.el7 - 'edge': docker-ce-cli-24.0.9-1.el7 + '26.0': docker-ce-cli-26.0.2-1.el7 + '26.1': docker-ce-cli-26.1.2-1.el7 + 'stable': docker-ce-cli-26.1.2-1.el7 + 'edge': docker-ce-cli-26.1.2-1.el7 docker_package_info: enablerepo: "docker-ce" diff --git a/kubespray/project/roles/container-engine/docker/vars/redhat.yml b/kubespray/project/roles/container-engine/docker/vars/redhat.yml index 453f7f9..deead32 100644 --- a/kubespray/project/roles/container-engine/docker/vars/redhat.yml +++ b/kubespray/project/roles/container-engine/docker/vars/redhat.yml @@ -23,8 +23,10 @@ containerd_versioned_pkg: '1.6.16': "{{ containerd_package }}-1.6.16-3.1.el{{ ansible_distribution_major_version }}" '1.6.18': "{{ containerd_package }}-1.6.18-3.1.el{{ ansible_distribution_major_version }}" '1.6.28': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'stable': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'edge': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" + '1.6.31': "{{ containerd_package }}-1.6.31-3.1.el{{ ansible_distribution_major_version }}" + '1.6.32': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" + 'stable': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" + 'edge': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" # https://docs.docker.com/engine/installation/linux/centos/#install-from-a-package # https://download.docker.com/linux/centos/>/x86_64/stable/Packages/ @@ -36,8 +38,10 @@ docker_versioned_pkg: '20.10': docker-ce-3:20.10.20-3.el{{ ansible_distribution_major_version }} '23.0': docker-ce-3:23.0.6-1.el{{ ansible_distribution_major_version }} '24.0': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} - 'stable': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} - 'edge': docker-ce-3:24.0.9-1.el{{ ansible_distribution_major_version }} + '26.0': docker-ce-3:26.0.2-1.el{{ ansible_distribution_major_version }} + '26.1': docker-ce-3:26.1.2-1.el{{ ansible_distribution_major_version }} + 'stable': docker-ce-3:26.1.2-1.el{{ ansible_distribution_major_version }} + 'edge': docker-ce-3:26.1.2-1.el{{ ansible_distribution_major_version }} docker_cli_versioned_pkg: 'latest': docker-ce-cli @@ -46,8 +50,10 @@ docker_cli_versioned_pkg: '20.10': docker-ce-cli-1:20.10.20-3.el{{ ansible_distribution_major_version }} '23.0': docker-ce-cli-1:23.0.6-1.el{{ ansible_distribution_major_version }} '24.0': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} - 'stable': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} - 'edge': docker-ce-cli-1:24.0.9-1.el{{ ansible_distribution_major_version }} + '26.0': docker-ce-cli-1:26.0.2-1.el{{ ansible_distribution_major_version }} + '26.1': docker-ce-cli-1:26.1.2-1.el{{ ansible_distribution_major_version }} + 'stable': docker-ce-cli-1:26.1.2-1.el{{ ansible_distribution_major_version }} + 'edge': docker-ce-cli-1:26.1.2-1.el{{ ansible_distribution_major_version }} docker_package_info: enablerepo: "docker-ce" diff --git a/kubespray/project/roles/container-engine/docker/vars/ubuntu.yml b/kubespray/project/roles/container-engine/docker/vars/ubuntu.yml index b4c1d28..636e417 100644 --- a/kubespray/project/roles/container-engine/docker/vars/ubuntu.yml +++ b/kubespray/project/roles/container-engine/docker/vars/ubuntu.yml @@ -22,9 +22,11 @@ containerd_versioned_pkg: '1.6.15': "{{ containerd_package }}=1.6.15-1" '1.6.16': "{{ containerd_package }}=1.6.16-1" '1.6.18': "{{ containerd_package }}=1.6.18-1" - '1.6.28': "{{ containerd_package }}=1.6.28-1" - 'stable': "{{ containerd_package }}=1.6.28-1" - 'edge': "{{ containerd_package }}=1.6.28-1" + '1.6.28': "{{ containerd_package }}=1.6.28-2" + '1.6.31': "{{ containerd_package }}=1.6.31-1" + '1.6.32': "{{ containerd_package }}=1.6.32-1" + 'stable': "{{ containerd_package }}=1.6.32-1" + 'edge': "{{ containerd_package }}=1.6.32-1" # https://download.docker.com/linux/ubuntu/ docker_versioned_pkg: @@ -34,8 +36,10 @@ docker_versioned_pkg: '20.10': docker-ce=5:20.10.20~3-0~ubuntu-{{ ansible_distribution_release | lower }} '23.0': docker-ce=5:23.0.6-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} '24.0': docker-ce=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} - 'stable': docker-ce=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} - 'edge': docker-ce=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + '26.0': docker-ce=5:26.0.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + '26.1': docker-ce=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + 'stable': docker-ce=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + 'edge': docker-ce=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} docker_cli_versioned_pkg: 'latest': docker-ce-cli @@ -44,8 +48,10 @@ docker_cli_versioned_pkg: '20.10': docker-ce-cli=5:20.10.20~3-0~ubuntu-{{ ansible_distribution_release | lower }} '23.0': docker-ce-cli=5:23.0.6-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} '24.0': docker-ce-cli=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} - 'stable': docker-ce-cli=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} - 'edge': docker-ce-cli=5:24.0.9-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + '26.0': docker-ce-cli=5:26.0.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + '26.1': docker-ce-cli=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + 'stable': docker-ce-cli=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} + 'edge': docker-ce-cli=5:26.1.2-1~ubuntu.{{ ansible_distribution_version }}~{{ ansible_distribution_release | lower }} docker_package_info: pkgs: diff --git a/kubespray/project/roles/container-engine/docker/vars/uniontech.yml b/kubespray/project/roles/container-engine/docker/vars/uniontech.yml index 0749726..13e1cd6 100644 --- a/kubespray/project/roles/container-engine/docker/vars/uniontech.yml +++ b/kubespray/project/roles/container-engine/docker/vars/uniontech.yml @@ -21,8 +21,9 @@ containerd_versioned_pkg: '1.6.16': "{{ containerd_package }}-1.6.16-3.1.el{{ ansible_distribution_major_version }}" '1.6.18': "{{ containerd_package }}-1.6.18-3.1.el{{ ansible_distribution_major_version }}" '1.6.28': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'stable': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" - 'edge': "{{ containerd_package }}-1.6.28-3.1.el{{ ansible_distribution_major_version }}" + '1.6.32': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" + 'stable': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" + 'edge': "{{ containerd_package }}-1.6.32-3.1.el{{ ansible_distribution_major_version }}" docker_version: 19.03 docker_cli_version: 19.03 diff --git a/kubespray/project/roles/container-engine/gvisor/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/gvisor/molecule/default/prepare.yml index 3ec3602..57c21f2 100644 --- a/kubespray/project/roles/container-engine/gvisor/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/gvisor/molecule/default/prepare.yml @@ -29,7 +29,7 @@ src: "{{ item }}" dest: "/tmp/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - container.json - sandbox.json @@ -38,12 +38,12 @@ path: /etc/cni/net.d state: directory owner: root - mode: 0755 + mode: "0755" - name: Setup CNI copy: src: "{{ item }}" dest: "/etc/cni/net.d/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - 10-mynet.conf diff --git a/kubespray/project/roles/container-engine/gvisor/tasks/main.yml b/kubespray/project/roles/container-engine/gvisor/tasks/main.yml index 1a8277b..4bab9a9 100644 --- a/kubespray/project/roles/container-engine/gvisor/tasks/main.yml +++ b/kubespray/project/roles/container-engine/gvisor/tasks/main.yml @@ -13,8 +13,8 @@ copy: src: "{{ item.src }}" dest: "{{ bin_dir }}/{{ item.dest }}" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true with_items: - { src: "{{ downloads.gvisor_runsc.dest }}", dest: "runsc" } - { src: "{{ downloads.gvisor_containerd_shim.dest }}", dest: "containerd-shim-runsc-v1" } diff --git a/kubespray/project/roles/container-engine/kata-containers/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/kata-containers/molecule/default/prepare.yml index 9d7019a..a5abd27 100644 --- a/kubespray/project/roles/container-engine/kata-containers/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/kata-containers/molecule/default/prepare.yml @@ -29,7 +29,7 @@ src: "{{ item }}" dest: "/tmp/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - container.json - sandbox.json @@ -38,12 +38,12 @@ path: /etc/cni/net.d state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" - name: Setup CNI copy: src: "{{ item }}" dest: "/etc/cni/net.d/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - 10-mynet.conf diff --git a/kubespray/project/roles/container-engine/kata-containers/tasks/main.yml b/kubespray/project/roles/container-engine/kata-containers/tasks/main.yml index e795b1f..5014c21 100644 --- a/kubespray/project/roles/container-engine/kata-containers/tasks/main.yml +++ b/kubespray/project/roles/container-engine/kata-containers/tasks/main.yml @@ -8,22 +8,22 @@ unarchive: src: "{{ downloads.kata_containers.dest }}" dest: "/" - mode: 0755 + mode: "0755" owner: root group: root - remote_src: yes + remote_src: true - name: Kata-containers | Create config directory file: path: "{{ kata_containers_config_dir }}" state: directory - mode: 0755 + mode: "0755" - name: Kata-containers | Set configuration template: src: "{{ item }}.j2" dest: "{{ kata_containers_config_dir }}/{{ item }}" - mode: 0644 + mode: "0644" with_items: - configuration-qemu.toml @@ -33,7 +33,7 @@ template: dest: "{{ kata_containers_containerd_bin_dir }}/containerd-shim-kata-{{ item }}-v2" src: containerd-shim-kata-v2.j2 - mode: 0755 + mode: "0755" with_items: - qemu @@ -48,7 +48,7 @@ - name: Kata-containers | Persist vhost kernel modules copy: dest: /etc/modules-load.d/kubespray-kata-containers.conf - mode: 0644 + mode: "0644" content: | vhost_vsock vhost_net diff --git a/kubespray/project/roles/container-engine/nerdctl/handlers/main.yml b/kubespray/project/roles/container-engine/nerdctl/handlers/main.yml index 27895ff..1744706 100644 --- a/kubespray/project/roles/container-engine/nerdctl/handlers/main.yml +++ b/kubespray/project/roles/container-engine/nerdctl/handlers/main.yml @@ -1,7 +1,7 @@ --- - name: Get nerdctl completion command: "{{ bin_dir }}/nerdctl completion bash" - changed_when: False + changed_when: false register: nerdctl_completion check_mode: false @@ -9,4 +9,4 @@ copy: dest: /etc/bash_completion.d/nerdctl content: "{{ nerdctl_completion.stdout }}" - mode: 0644 + mode: "0644" diff --git a/kubespray/project/roles/container-engine/nerdctl/tasks/main.yml b/kubespray/project/roles/container-engine/nerdctl/tasks/main.yml index e4e4ebd..d3cd007 100644 --- a/kubespray/project/roles/container-engine/nerdctl/tasks/main.yml +++ b/kubespray/project/roles/container-engine/nerdctl/tasks/main.yml @@ -8,7 +8,7 @@ copy: src: "{{ local_release_dir }}/nerdctl" dest: "{{ bin_dir }}/nerdctl" - mode: 0755 + mode: "0755" remote_src: true owner: root group: root @@ -21,7 +21,7 @@ file: path: /etc/nerdctl state: directory - mode: 0755 + mode: "0755" owner: root group: root become: true @@ -30,7 +30,7 @@ template: src: nerdctl.toml.j2 dest: /etc/nerdctl/nerdctl.toml - mode: 0644 + mode: "0644" owner: root group: root become: true diff --git a/kubespray/project/roles/container-engine/runc/tasks/main.yml b/kubespray/project/roles/container-engine/runc/tasks/main.yml index 542a447..1d38876 100644 --- a/kubespray/project/roles/container-engine/runc/tasks/main.yml +++ b/kubespray/project/roles/container-engine/runc/tasks/main.yml @@ -2,9 +2,9 @@ - name: Runc | check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree - name: Runc | set is_ostree @@ -27,7 +27,7 @@ copy: src: "{{ downloads.runc.dest }}" dest: "{{ runc_bin_dir }}/runc" - mode: 0755 + mode: "0755" remote_src: true - name: Runc | Remove orphaned binary diff --git a/kubespray/project/roles/container-engine/skopeo/tasks/main.yml b/kubespray/project/roles/container-engine/skopeo/tasks/main.yml index cef0424..8f21e3f 100644 --- a/kubespray/project/roles/container-engine/skopeo/tasks/main.yml +++ b/kubespray/project/roles/container-engine/skopeo/tasks/main.yml @@ -2,9 +2,9 @@ - name: Skopeo | check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree - name: Skopeo | set is_ostree @@ -28,5 +28,5 @@ copy: src: "{{ downloads.skopeo.dest }}" dest: "{{ bin_dir }}/skopeo" - mode: 0755 + mode: "0755" remote_src: true diff --git a/kubespray/project/roles/container-engine/validate-container-engine/tasks/main.yml b/kubespray/project/roles/container-engine/validate-container-engine/tasks/main.yml index 08ea1e5..ffb541c 100644 --- a/kubespray/project/roles/container-engine/validate-container-engine/tasks/main.yml +++ b/kubespray/project/roles/container-engine/validate-container-engine/tasks/main.yml @@ -2,9 +2,9 @@ - name: Validate-container-engine | check if fedora coreos stat: path: /run/ostree-booted - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: ostree tags: - facts @@ -30,8 +30,8 @@ - name: Check if containerd is installed find: file_type: file - recurse: yes - use_regex: yes + recurse: true + use_regex: true patterns: - containerd.service$ paths: @@ -45,8 +45,8 @@ - name: Check if docker is installed find: file_type: file - recurse: yes - use_regex: yes + recurse: true + use_regex: true patterns: - docker.service$ paths: @@ -60,8 +60,8 @@ - name: Check if crio is installed find: file_type: file - recurse: yes - use_regex: yes + recurse: true + use_regex: true patterns: - crio.service$ paths: diff --git a/kubespray/project/roles/container-engine/youki/molecule/default/prepare.yml b/kubespray/project/roles/container-engine/youki/molecule/default/prepare.yml index 119f58a..a72bdad 100644 --- a/kubespray/project/roles/container-engine/youki/molecule/default/prepare.yml +++ b/kubespray/project/roles/container-engine/youki/molecule/default/prepare.yml @@ -29,7 +29,7 @@ src: "{{ item }}" dest: "/tmp/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - container.json - sandbox.json @@ -38,12 +38,12 @@ path: /etc/cni/net.d state: directory owner: root - mode: 0755 + mode: "0755" - name: Setup CNI copy: src: "{{ item }}" dest: "/etc/cni/net.d/{{ item }}" owner: root - mode: 0644 + mode: "0644" with_items: - 10-mynet.conf diff --git a/kubespray/project/roles/container-engine/youki/tasks/main.yml b/kubespray/project/roles/container-engine/youki/tasks/main.yml index e88f663..86182a3 100644 --- a/kubespray/project/roles/container-engine/youki/tasks/main.yml +++ b/kubespray/project/roles/container-engine/youki/tasks/main.yml @@ -8,5 +8,5 @@ copy: src: "{{ local_release_dir }}/youki_{{ youki_version | regex_replace('\\.', '_') }}_linux/youki-{{ youki_version }}/youki" dest: "{{ youki_bin_dir }}/youki" - mode: 0755 + mode: "0755" remote_src: true diff --git a/kubespray/project/roles/download/tasks/check_pull_required.yml b/kubespray/project/roles/download/tasks/check_pull_required.yml index e5ae1dc..5850131 100644 --- a/kubespray/project/roles/download/tasks/check_pull_required.yml +++ b/kubespray/project/roles/download/tasks/check_pull_required.yml @@ -5,7 +5,7 @@ shell: "{{ image_info_command }}" register: docker_images changed_when: false - check_mode: no + check_mode: false when: not download_always_pull - name: Check_pull_required | Set pull_required if the desired image is not yet loaded diff --git a/kubespray/project/roles/download/tasks/download_container.yml b/kubespray/project/roles/download/tasks/download_container.yml index f98adfa..5e67fe8 100644 --- a/kubespray/project/roles/download/tasks/download_container.yml +++ b/kubespray/project/roles/download/tasks/download_container.yml @@ -26,12 +26,12 @@ - name: Download_container | Determine if image is in cache stat: path: "{{ image_path_cached }}" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false delegate_to: localhost connection: local - delegate_facts: no + delegate_facts: false register: cache_image changed_when: false become: false @@ -57,7 +57,7 @@ - name: Download_container | Download image if required command: "{{ image_pull_command_on_localhost if download_localhost else image_pull_command }} {{ image_reponame }}" delegate_to: "{{ download_delegate if download_run_once else inventory_hostname }}" - delegate_facts: yes + delegate_facts: true run_once: "{{ download_run_once }}" register: pull_task_result until: pull_task_result is succeeded @@ -72,7 +72,7 @@ - name: Download_container | Save and compress image shell: "{{ image_save_command_on_localhost if download_localhost else image_save_command }}" # noqa command-instead-of-shell - image_save_command_on_localhost contains a pipe, therefore requires shell delegate_to: "{{ download_delegate }}" - delegate_facts: no + delegate_facts: false register: container_save_status failed_when: container_save_status.stderr run_once: true @@ -99,7 +99,7 @@ dest: "{{ image_path_final }}" use_ssh_args: true mode: push - delegate_facts: no + delegate_facts: false register: upload_image failed_when: not upload_image until: upload_image is succeeded diff --git a/kubespray/project/roles/download/tasks/download_file.yml b/kubespray/project/roles/download/tasks/download_file.yml index 9773366..53a7a81 100644 --- a/kubespray/project/roles/download/tasks/download_file.yml +++ b/kubespray/project/roles/download/tasks/download_file.yml @@ -22,15 +22,15 @@ file: path: "{{ download.dest | dirname }}" owner: "{{ download.owner | default(omit) }}" - mode: 0755 + mode: "0755" state: directory - recurse: yes + recurse: true - name: Download_file | Create local cache directory file: path: "{{ file_path_cached | dirname }}" state: directory - recurse: yes + recurse: true delegate_to: localhost connection: local delegate_facts: false @@ -45,7 +45,7 @@ file: path: "{{ file_path_cached | dirname }}" state: directory - recurse: yes + recurse: true delegate_to: "{{ download_delegate }}" delegate_facts: false run_once: true diff --git a/kubespray/project/roles/download/tasks/extract_file.yml b/kubespray/project/roles/download/tasks/extract_file.yml index 59d0531..ce7536f 100644 --- a/kubespray/project/roles/download/tasks/extract_file.yml +++ b/kubespray/project/roles/download/tasks/extract_file.yml @@ -5,7 +5,7 @@ dest: "{{ download.dest | dirname }}" owner: "{{ download.owner | default(omit) }}" mode: "{{ download.mode | default(omit) }}" - copy: no + copy: false extra_opts: "{{ download.unarchive_extra_opts | default(omit) }}" when: - download.unarchive | default(false) diff --git a/kubespray/project/roles/download/tasks/prep_download.yml b/kubespray/project/roles/download/tasks/prep_download.yml index 58e5084..15f3a91 100644 --- a/kubespray/project/roles/download/tasks/prep_download.yml +++ b/kubespray/project/roles/download/tasks/prep_download.yml @@ -62,14 +62,14 @@ register: docker_images failed_when: false changed_when: false - check_mode: no + check_mode: false when: download_container - name: Prep_download | Create staging directory on remote node file: path: "{{ local_release_dir }}/images" state: directory - mode: 0755 + mode: "0755" owner: "{{ ansible_ssh_user | default(ansible_user_id) }}" when: - ansible_os_family not in ["Flatcar", "Flatcar Container Linux by Kinvolk"] @@ -78,10 +78,10 @@ file: path: "{{ download_cache_dir }}/images" state: directory - mode: 0755 + mode: "0755" delegate_to: localhost connection: local - delegate_facts: no + delegate_facts: false run_once: true become: false when: diff --git a/kubespray/project/roles/download/tasks/prep_kubeadm_images.yml b/kubespray/project/roles/download/tasks/prep_kubeadm_images.yml index fdfed1d..c1e8c6c 100644 --- a/kubespray/project/roles/download/tasks/prep_kubeadm_images.yml +++ b/kubespray/project/roles/download/tasks/prep_kubeadm_images.yml @@ -1,11 +1,4 @@ --- -- name: Prep_kubeadm_images | Check kubeadm version matches kubernetes version - fail: - msg: "Kubeadm version {{ kubeadm_version }} do not matches kubernetes {{ kube_version }}" - when: - - not skip_downloads | default(false) - - not kubeadm_version == downloads.kubeadm.version - - name: Prep_kubeadm_images | Download kubeadm binary include_tasks: "download_file.yml" vars: @@ -18,7 +11,7 @@ template: src: "kubeadm-images.yaml.j2" dest: "{{ kube_config_dir }}/kubeadm-images.yaml" - mode: 0644 + mode: "0644" when: - not skip_kubeadm_images | default(false) @@ -26,7 +19,7 @@ copy: src: "{{ downloads.kubeadm.dest }}" dest: "{{ bin_dir }}/kubeadm" - mode: 0755 + mode: "0755" remote_src: true - name: Prep_kubeadm_images | Set kubeadm binary permissions diff --git a/kubespray/project/roles/etcd/defaults/main.yml b/kubespray/project/roles/etcd/defaults/main.yml index 814caed..09ee9d6 100644 --- a/kubespray/project/roles/etcd/defaults/main.yml +++ b/kubespray/project/roles/etcd/defaults/main.yml @@ -124,4 +124,7 @@ unsafe_show_logs: false etcd_experimental_enable_distributed_tracing: false etcd_experimental_distributed_tracing_sample_rate: 100 etcd_experimental_distributed_tracing_address: "localhost:4317" -etcd_experimental_distributed_tracing_service_name: etcd \ No newline at end of file +etcd_experimental_distributed_tracing_service_name: etcd + +# The interval for etcd watch progress notify events +etcd_experimental_watch_progress_notify_interval: 5s diff --git a/kubespray/project/roles/etcd/handlers/backup.yml b/kubespray/project/roles/etcd/handlers/backup.yml index b79dd01..84e03ac 100644 --- a/kubespray/project/roles/etcd/handlers/backup.yml +++ b/kubespray/project/roles/etcd/handlers/backup.yml @@ -16,16 +16,16 @@ state: directory owner: root group: root - mode: 0600 + mode: "0600" listen: Restart etcd when: etcd_cluster_is_healthy.rc == 0 - name: Stat etcd v2 data directory stat: path: "{{ etcd_data_dir }}/member" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: etcd_data_dir_member listen: Restart etcd when: etcd_cluster_is_healthy.rc == 0 diff --git a/kubespray/project/roles/etcd/handlers/main.yml b/kubespray/project/roles/etcd/handlers/main.yml index 3389061..9c8b8a8 100644 --- a/kubespray/project/roles/etcd/handlers/main.yml +++ b/kubespray/project/roles/etcd/handlers/main.yml @@ -3,7 +3,7 @@ import_tasks: backup.yml - name: Etcd | reload systemd - systemd: + systemd_service: daemon_reload: true listen: - Restart etcd @@ -26,7 +26,7 @@ - name: Wait for etcd up uri: url: "https://{% if is_etcd_master %}{{ etcd_address }}{% else %}127.0.0.1{% endif %}:2379/health" - validate_certs: no + validate_certs: false client_cert: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}.pem" client_key: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}-key.pem" register: result @@ -41,7 +41,7 @@ - name: Wait for etcd-events up uri: url: "https://{% if is_etcd_master %}{{ etcd_address }}{% else %}127.0.0.1{% endif %}:2383/health" - validate_certs: no + validate_certs: false client_cert: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}.pem" client_key: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}-key.pem" register: result diff --git a/kubespray/project/roles/etcd/tasks/check_certs.yml b/kubespray/project/roles/etcd/tasks/check_certs.yml index 1611f9e..440685a 100644 --- a/kubespray/project/roles/etcd/tasks/check_certs.yml +++ b/kubespray/project/roles/etcd/tasks/check_certs.yml @@ -17,9 +17,9 @@ - name: "Check certs | Register ca and etcd admin/member certs on etcd hosts" stat: path: "{{ etcd_cert_dir }}/{{ item }}" - get_attributes: no - get_checksum: yes - get_mime: no + get_attributes: false + get_checksum: true + get_mime: false register: etcd_member_certs when: inventory_hostname in groups['etcd'] with_items: diff --git a/kubespray/project/roles/etcd/tasks/configure.yml b/kubespray/project/roles/etcd/tasks/configure.yml index 438dbc7..b7b943f 100644 --- a/kubespray/project/roles/etcd/tasks/configure.yml +++ b/kubespray/project/roles/etcd/tasks/configure.yml @@ -6,8 +6,8 @@ register: etcd_cluster_is_healthy failed_when: false changed_when: false - check_mode: no - run_once: yes + check_mode: false + run_once: true when: - is_etcd_master - etcd_cluster_setup @@ -27,8 +27,8 @@ register: etcd_events_cluster_is_healthy failed_when: false changed_when: false - check_mode: no - run_once: yes + check_mode: false + run_once: true when: - is_etcd_master - etcd_events_cluster_setup @@ -49,8 +49,8 @@ template: src: "etcd-{{ etcd_deployment_type }}.service.j2" dest: /etc/systemd/system/etcd.service - backup: yes - mode: 0644 + backup: true + mode: "0644" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:etcd-{{ etcd_deployment_type }}.service'" @@ -60,15 +60,15 @@ template: src: "etcd-events-{{ etcd_deployment_type }}.service.j2" dest: /etc/systemd/system/etcd-events.service - backup: yes - mode: 0644 + backup: true + mode: "0644" validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:etcd-events-{{ etcd_deployment_type }}.service'" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 when: is_etcd_master and etcd_events_cluster_setup - name: Configure | reload systemd - systemd: + systemd_service: daemon_reload: true when: is_etcd_master @@ -77,7 +77,7 @@ service: name: etcd state: started - enabled: yes + enabled: true ignore_errors: "{{ etcd_cluster_is_healthy.rc == 0 }}" # noqa ignore-errors when: is_etcd_master and etcd_cluster_setup @@ -86,7 +86,7 @@ service: name: etcd-events state: started - enabled: yes + enabled: true ignore_errors: "{{ etcd_events_cluster_is_healthy.rc != 0 }}" # noqa ignore-errors when: is_etcd_master and etcd_events_cluster_setup @@ -99,8 +99,8 @@ retries: "{{ etcd_retries }}" delay: "{{ retry_stagger | random + 3 }}" changed_when: false - check_mode: no - run_once: yes + check_mode: false + run_once: true when: - is_etcd_master - etcd_cluster_setup @@ -122,8 +122,8 @@ retries: "{{ etcd_retries }}" delay: "{{ retry_stagger | random + 3 }}" changed_when: false - check_mode: no - run_once: yes + check_mode: false + run_once: true when: - is_etcd_master - etcd_events_cluster_setup @@ -141,7 +141,7 @@ register: etcd_member_in_cluster ignore_errors: true # noqa ignore-errors changed_when: false - check_mode: no + check_mode: false when: is_etcd_master and etcd_cluster_setup tags: - facts @@ -157,7 +157,7 @@ register: etcd_events_member_in_cluster ignore_errors: true # noqa ignore-errors changed_when: false - check_mode: no + check_mode: false when: is_etcd_master and etcd_events_cluster_setup tags: - facts diff --git a/kubespray/project/roles/etcd/tasks/gen_certs_script.yml b/kubespray/project/roles/etcd/tasks/gen_certs_script.yml index 33e9d94..934b5eb 100644 --- a/kubespray/project/roles/etcd/tasks/gen_certs_script.yml +++ b/kubespray/project/roles/etcd/tasks/gen_certs_script.yml @@ -6,23 +6,23 @@ state: directory owner: "{{ etcd_owner }}" mode: "{{ etcd_cert_dir_mode }}" - recurse: yes + recurse: true - name: "Gen_certs | create etcd script dir (on {{ groups['etcd'][0] }})" file: path: "{{ etcd_script_dir }}" state: directory owner: root - mode: 0700 - run_once: yes + mode: "0700" + run_once: true when: inventory_hostname == groups['etcd'][0] - name: Gen_certs | write openssl config template: src: "openssl.conf.j2" dest: "{{ etcd_config_dir }}/openssl.conf" - mode: 0640 - run_once: yes + mode: "0640" + run_once: true delegate_to: "{{ groups['etcd'][0] }}" when: - gen_certs | default(false) @@ -32,8 +32,8 @@ template: src: "make-ssl-etcd.sh.j2" dest: "{{ etcd_script_dir }}/make-ssl-etcd.sh" - mode: 0700 - run_once: yes + mode: "0700" + run_once: true when: - gen_certs | default(false) - inventory_hostname == groups['etcd'][0] @@ -43,7 +43,7 @@ environment: MASTERS: "{{ groups['gen_master_certs_True'] | ansible.builtin.intersect(groups['etcd']) | join(' ') }}" HOSTS: "{{ groups['gen_node_certs_True'] | ansible.builtin.intersect(groups['kube_control_plane']) | join(' ') }}" - run_once: yes + run_once: true delegate_to: "{{ groups['etcd'][0] }}" when: gen_certs | default(false) notify: Set etcd_secret_changed @@ -52,7 +52,7 @@ command: "bash -x {{ etcd_script_dir }}/make-ssl-etcd.sh -f {{ etcd_config_dir }}/openssl.conf -d {{ etcd_cert_dir }}" environment: HOSTS: "{{ groups['gen_node_certs_True'] | ansible.builtin.intersect(groups['k8s_cluster']) | join(' ') }}" - run_once: yes + run_once: true delegate_to: "{{ groups['etcd'][0] }}" when: - kube_network_plugin in ["calico", "flannel", "cilium"] or cilium_deploy_additionally | default(false) | bool @@ -90,7 +90,7 @@ content: "{{ item.content | b64decode }}" group: "{{ etcd_cert_group }}" owner: "{{ etcd_owner }}" - mode: 0640 + mode: "0640" with_items: "{{ etcd_master_certs.results }}" when: - inventory_hostname in groups['etcd'] @@ -122,7 +122,7 @@ content: "{{ item.content | b64decode }}" group: "{{ etcd_cert_group }}" owner: "{{ etcd_owner }}" - mode: 0640 + mode: "0640" with_items: "{{ etcd_master_node_certs.results }}" when: - inventory_hostname in groups['etcd'] @@ -153,4 +153,4 @@ state: directory owner: "{{ etcd_owner }}" mode: "{{ etcd_cert_dir_mode }}" - recurse: yes + recurse: true diff --git a/kubespray/project/roles/etcd/tasks/gen_nodes_certs_script.yml b/kubespray/project/roles/etcd/tasks/gen_nodes_certs_script.yml index 2093bf8..e074d0c 100644 --- a/kubespray/project/roles/etcd/tasks/gen_nodes_certs_script.yml +++ b/kubespray/project/roles/etcd/tasks/gen_nodes_certs_script.yml @@ -21,7 +21,7 @@ executable: /bin/bash no_log: "{{ not (unsafe_show_logs | bool) }}" register: etcd_node_certs - check_mode: no + check_mode: false delegate_to: "{{ groups['etcd'][0] }}" changed_when: false diff --git a/kubespray/project/roles/etcd/tasks/install_docker.yml b/kubespray/project/roles/etcd/tasks/install_docker.yml index cc2fdec..f393bd4 100644 --- a/kubespray/project/roles/etcd/tasks/install_docker.yml +++ b/kubespray/project/roles/etcd/tasks/install_docker.yml @@ -28,8 +28,8 @@ src: etcd.j2 dest: "{{ bin_dir }}/etcd" owner: 'root' - mode: 0750 - backup: yes + mode: "0750" + backup: true when: etcd_cluster_setup - name: Install etcd-events launch script @@ -37,6 +37,6 @@ src: etcd-events.j2 dest: "{{ bin_dir }}/etcd-events" owner: 'root' - mode: 0750 - backup: yes + mode: "0750" + backup: true when: etcd_events_cluster_setup diff --git a/kubespray/project/roles/etcd/tasks/install_host.yml b/kubespray/project/roles/etcd/tasks/install_host.yml index d4baa2a..eb67952 100644 --- a/kubespray/project/roles/etcd/tasks/install_host.yml +++ b/kubespray/project/roles/etcd/tasks/install_host.yml @@ -24,8 +24,8 @@ copy: src: "{{ local_release_dir }}/etcd-{{ etcd_version }}-linux-{{ host_architecture }}/{{ item }}" dest: "{{ bin_dir }}/{{ item }}" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true with_items: - etcd when: etcd_cluster_setup diff --git a/kubespray/project/roles/etcd/tasks/join_etcd-events_member.yml b/kubespray/project/roles/etcd/tasks/join_etcd-events_member.yml index 0fad331..106f06e 100644 --- a/kubespray/project/roles/etcd/tasks/join_etcd-events_member.yml +++ b/kubespray/project/roles/etcd/tasks/join_etcd-events_member.yml @@ -32,7 +32,7 @@ executable: /bin/bash register: etcd_events_member_in_cluster changed_when: false - check_mode: no + check_mode: false tags: - facts environment: @@ -46,4 +46,4 @@ service: name: etcd-events state: started - enabled: yes + enabled: true diff --git a/kubespray/project/roles/etcd/tasks/join_etcd_member.yml b/kubespray/project/roles/etcd/tasks/join_etcd_member.yml index ee77d4b..a2e3771 100644 --- a/kubespray/project/roles/etcd/tasks/join_etcd_member.yml +++ b/kubespray/project/roles/etcd/tasks/join_etcd_member.yml @@ -33,7 +33,7 @@ executable: /bin/bash register: etcd_member_in_cluster changed_when: false - check_mode: no + check_mode: false retries: "{{ etcd_retries }}" delay: "{{ retry_stagger | random + 3 }}" until: etcd_member_in_cluster.rc == 0 @@ -50,4 +50,4 @@ service: name: etcd state: started - enabled: yes + enabled: true diff --git a/kubespray/project/roles/etcd/tasks/main.yml b/kubespray/project/roles/etcd/tasks/main.yml index 40ca3de..74d5f16 100644 --- a/kubespray/project/roles/etcd/tasks/main.yml +++ b/kubespray/project/roles/etcd/tasks/main.yml @@ -33,7 +33,7 @@ command: "openssl x509 -in {{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem -noout -serial" register: "etcd_client_cert_serial_result" changed_when: false - check_mode: no + check_mode: false when: - kube_network_plugin in ["calico", "flannel", "cilium"] or cilium_deploy_additionally | default(false) | bool - kube_network_plugin != "calico" or calico_datastore == "etcd" diff --git a/kubespray/project/roles/etcd/tasks/refresh_config.yml b/kubespray/project/roles/etcd/tasks/refresh_config.yml index d5e0045..effebbd 100644 --- a/kubespray/project/roles/etcd/tasks/refresh_config.yml +++ b/kubespray/project/roles/etcd/tasks/refresh_config.yml @@ -3,7 +3,7 @@ template: src: etcd.env.j2 dest: /etc/etcd.env - mode: 0640 + mode: "0640" notify: Restart etcd when: is_etcd_master and etcd_cluster_setup @@ -11,6 +11,6 @@ template: src: etcd-events.env.j2 dest: /etc/etcd-events.env - mode: 0640 + mode: "0640" notify: Restart etcd-events when: is_etcd_master and etcd_events_cluster_setup diff --git a/kubespray/project/roles/etcd/tasks/upd_ca_trust.yml b/kubespray/project/roles/etcd/tasks/upd_ca_trust.yml index 22c5901..ec81e17 100644 --- a/kubespray/project/roles/etcd/tasks/upd_ca_trust.yml +++ b/kubespray/project/roles/etcd/tasks/upd_ca_trust.yml @@ -21,7 +21,7 @@ src: "{{ etcd_cert_dir }}/ca.pem" dest: "{{ ca_cert_path }}" remote_src: true - mode: 0640 + mode: "0640" register: etcd_ca_cert - name: Gen_certs | update ca-certificates (Debian/Ubuntu/SUSE/Flatcar) # noqa no-handler diff --git a/kubespray/project/roles/etcd/templates/etcd.env.j2 b/kubespray/project/roles/etcd/templates/etcd.env.j2 index 13a2437..ec21795 100644 --- a/kubespray/project/roles/etcd/templates/etcd.env.j2 +++ b/kubespray/project/roles/etcd/templates/etcd.env.j2 @@ -71,8 +71,10 @@ ETCD_EXPERIMENTAL_INITIAL_CORRUPT_CHECK={{ etcd_experimental_initial_corrupt_che {% if etcd_experimental_enable_distributed_tracing %} ETCD_EXPERIMENTAL_ENABLE_DISTRIBUTED_TRACING=true -ETCD_EXPERIMENTAL_DISTRIBUTED_TRACING_SAMPLE_RATE={{ etcd_experimental_distributed_tracing_sample_rate }} +ETCD_EXPERIMENTAL_DISTRIBUTED_TRACING_SAMPLING_RATE={{ etcd_experimental_distributed_tracing_sample_rate }} ETCD_EXPERIMENTAL_DISTRIBUTED_TRACING_ADDRESS={{ etcd_experimental_distributed_tracing_address }} ETCD_EXPERIMENTAL_DISTRIBUTED_TRACING_SERVICE_NAME={{ etcd_experimental_distributed_tracing_service_name }} ETCD_EXPERIMENTAL_DISTRIBUTED_TRACING_INSTANCE_ID={{ etcd_member_name }} -{% endif %} \ No newline at end of file +{% endif %} + +ETCD_EXPERIMENTAL_WATCH_PROGRESS_NOTIFY_INTERVAL={{ etcd_experimental_watch_progress_notify_interval }} diff --git a/kubespray/project/roles/etcd/templates/openssl.conf.j2 b/kubespray/project/roles/etcd/templates/openssl.conf.j2 index f6681a1..b4a2d43 100644 --- a/kubespray/project/roles/etcd/templates/openssl.conf.j2 +++ b/kubespray/project/roles/etcd/templates/openssl.conf.j2 @@ -25,6 +25,11 @@ authorityKeyIdentifier=keyid:always,issuer [alt_names] DNS.1 = localhost {% for host in groups['etcd'] %} +{% if hostvars[host]['etcd_access_address'] is defined and not (hostvars[host]['etcd_access_address'] | ansible.utils.ipaddr) %} +{# If defined, the address which etcd uses to access its members must be included in the SAN, otherwise etcd will fail with a TLS error upon startup. #} +DNS.{{ counter["dns"] }} = {{ hostvars[host]['etcd_access_address'] }}{{ increment(counter, 'dns') }} +{% endif %} +{# This will always expand to inventory_hostname, which can be a completely arbitrary name, that etcd will not know or care about, hence this line is (probably) redundant. #} DNS.{{ counter["dns"] }} = {{ host }}{{ increment(counter, 'dns') }} {% endfor %} {% if apiserver_loadbalancer_domain_name is defined %} diff --git a/kubespray/project/roles/etcdctl_etcdutl/tasks/main.yml b/kubespray/project/roles/etcdctl_etcdutl/tasks/main.yml index be0eea4..053e142 100644 --- a/kubespray/project/roles/etcdctl_etcdutl/tasks/main.yml +++ b/kubespray/project/roles/etcdctl_etcdutl/tasks/main.yml @@ -24,15 +24,15 @@ unarchive: src: "{{ downloads.etcd.dest }}" dest: "{{ local_release_dir }}/" - remote_src: yes + remote_src: true when: container_manager in ['crio', 'containerd'] - name: Copy etcdctl and etcdutl binary from download dir copy: src: "{{ local_release_dir }}/etcd-{{ etcd_version }}-linux-{{ host_architecture }}/{{ item }}" dest: "{{ bin_dir }}/{{ item }}" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true with_items: - etcdctl - etcdutl @@ -42,4 +42,4 @@ template: src: etcdctl.sh.j2 dest: "{{ bin_dir }}/etcdctl.sh" - mode: 0755 + mode: "0755" diff --git a/kubespray/project/roles/helm-apps/meta/argument_specs.yml b/kubespray/project/roles/helm-apps/meta/argument_specs.yml index d8c2b5a..d1be9a8 100644 --- a/kubespray/project/roles/helm-apps/meta/argument_specs.yml +++ b/kubespray/project/roles/helm-apps/meta/argument_specs.yml @@ -46,8 +46,6 @@ argument_specs: default: true wait_timeout: type: str - release_state: - type: str repositories: type: list diff --git a/kubespray/project/roles/helm-apps/vars/main.yml b/kubespray/project/roles/helm-apps/vars/main.yml index acf82c2..bb559e5 100644 --- a/kubespray/project/roles/helm-apps/vars/main.yml +++ b/kubespray/project/roles/helm-apps/vars/main.yml @@ -7,6 +7,4 @@ helm_defaults: helm_repository_defaults: binary_path: "{{ bin_dir }}/helm" - -release_common_opts: - wait_timeout: "5m" + force_update: true diff --git a/kubespray/project/roles/kubernetes-apps/ansible/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/ansible/defaults/main.yml index cb2317b..daebd07 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/defaults/main.yml @@ -16,8 +16,6 @@ coredns_ordinal_suffix: "" coredns_deployment_nodeselector: "kubernetes.io/os: linux" coredns_default_zone_cache_block: | cache 30 -coredns_host_network: false -coredns_port: 53 coredns_pod_disruption_budget: false # value for coredns pdb @@ -96,6 +94,11 @@ netchecker_server_user: 1000 netchecker_agent_group: 1000 netchecker_server_group: 1000 +# Log levels +netchecker_agent_log_level: 5 +netchecker_server_log_level: 5 +netchecker_etcd_log_level: info + # Dashboard dashboard_replicas: 1 diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/coredns.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/coredns.yml index 897c618..46e2006 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/coredns.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/coredns.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" loop: - { name: coredns, file: coredns-clusterrole.yml, type: clusterrole } - { name: coredns, file: coredns-clusterrolebinding.yml, type: clusterrolebinding } @@ -31,7 +31,7 @@ template: src: "{{ item.src }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: coredns, src: coredns-deployment.yml, file: coredns-deployment-secondary.yml, type: deployment } - { name: coredns, src: coredns-svc.yml, file: coredns-svc-secondary.yml, type: svc } diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/dashboard.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/dashboard.yml index 480b3db..5872674 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/dashboard.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/dashboard.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { file: dashboard.yml, type: deploy, name: kubernetes-dashboard } register: manifests diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/etcd_metrics.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/etcd_metrics.yml index 548de89..580ab66 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/etcd_metrics.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/etcd_metrics.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { file: etcd_metrics-endpoints.yml, type: endpoints, name: etcd-metrics } - { file: etcd_metrics-service.yml, type: service, name: etcd-metrics } diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/main.yml index e3d82f1..18deee8 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/main.yml @@ -2,7 +2,7 @@ - name: Kubernetes Apps | Wait for kube-apiserver uri: url: "{{ kube_apiserver_endpoint }}/healthz" - validate_certs: no + validate_certs: false client_cert: "{{ kube_apiserver_client_cert }}" client_key: "{{ kube_apiserver_client_key }}" register: result diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/netchecker.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/netchecker.yml index 0011e7f..2cf4b5d 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/netchecker.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/netchecker.yml @@ -29,7 +29,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ netchecker_templates }}" register: manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/ansible/tasks/nodelocaldns.yml b/kubespray/project/roles/kubernetes-apps/ansible/tasks/nodelocaldns.yml index b438afb..7e522e2 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/tasks/nodelocaldns.yml +++ b/kubespray/project/roles/kubernetes-apps/ansible/tasks/nodelocaldns.yml @@ -20,7 +20,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: nodelocaldns, file: nodelocaldns-config.yml, type: configmap } - { name: nodelocaldns, file: nodelocaldns-sa.yml, type: sa } @@ -51,7 +51,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: nodelocaldns, file: nodelocaldns-second-daemonset.yml, type: daemonset } register: nodelocaldns_second_manifests diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2 index 587a4e6..8a48119 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2 @@ -34,7 +34,7 @@ data: } {% endfor %} {% endif %} - .:{{ coredns_port }} { + .:53 { {% if coredns_additional_configs is defined %} {{ coredns_additional_configs | indent(width=8, first=False) }} {% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2 index cbdca57..e929dba 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2 @@ -24,7 +24,6 @@ spec: annotations: createdby: 'kubespray' spec: - hostNetwork: {{ coredns_host_network | default(false) }} securityContext: seccompProfile: type: RuntimeDefault @@ -76,10 +75,10 @@ spec: - name: config-volume mountPath: /etc/coredns ports: - - containerPort: {{ coredns_port }} + - containerPort: 53 name: dns protocol: UDP - - containerPort: {{ coredns_port }} + - containerPort: 53 name: dns-tcp protocol: TCP - containerPort: 9153 diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2 index 961e02a..0e051c3 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2 @@ -20,11 +20,9 @@ spec: - name: dns port: 53 protocol: UDP - targetPort: "dns" - name: dns-tcp port: 53 protocol: TCP - targetPort: "dns-tcp" - name: metrics port: 9153 protocol: TCP diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2 index 7d28725..e0b60e7 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2 @@ -247,7 +247,7 @@ spec: k8s-app: kubernetes-dashboard --- -# ------------------- Metrics Scrapper Service Account ------------------- # +# ------------------- Metrics Scraper Service Account ------------------- # kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 @@ -263,7 +263,7 @@ rules: --- -# ------------------- Metrics Scrapper Service ------------------- # +# ------------------- Metrics Scraper Service ------------------- # kind: Service apiVersion: v1 metadata: @@ -280,7 +280,7 @@ spec: --- -# ------------------- Metrics Scrapper Deployment ------------------- # +# ------------------- Metrics Scraper Deployment ------------------- # kind: Deployment apiVersion: apps/v1 metadata: diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-ds.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-ds.yml.j2 index 40dd199..b1461b6 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-ds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-ds.yml.j2 @@ -35,7 +35,7 @@ spec: fieldRef: fieldPath: spec.nodeName args: - - "-v=5" + - "-v={{ netchecker_agent_log_level }}" - "-alsologtostderr=true" - "-serverendpoint=netchecker-service:8081" - "-reportinterval={{ agent_report_interval }}" diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-hostnet-ds.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-hostnet-ds.yml.j2 index 50e2793..2dd113c 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-hostnet-ds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-agent-hostnet-ds.yml.j2 @@ -37,7 +37,7 @@ spec: fieldRef: fieldPath: spec.nodeName args: - - "-v=5" + - "-v={{ netchecker_agent_log_level }}" - "-alsologtostderr=true" - "-serverendpoint=netchecker-service:8081" - "-reportinterval={{ agent_report_interval }}" diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-server-deployment.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-server-deployment.yml.j2 index 02fd6b6..2f5c003 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-server-deployment.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/netchecker-server-deployment.yml.j2 @@ -43,7 +43,7 @@ spec: ports: - containerPort: 8081 args: - - -v=5 + - -v={{ netchecker_server_log_level }} - -logtostderr - -kubeproxyinit=false - -endpoint=0.0.0.0:8081 @@ -51,6 +51,9 @@ spec: - name: etcd image: "{{ etcd_image_repo }}:{{ netcheck_etcd_image_tag }}" imagePullPolicy: {{ k8s_image_pull_policy }} + env: + - name: ETCD_LOG_LEVEL + value: "{{ netchecker_etcd_log_level }}" command: - etcd - --listen-client-urls=http://127.0.0.1:2379 diff --git a/kubespray/project/roles/kubernetes-apps/ansible/templates/nodelocaldns-daemonset.yml.j2 b/kubespray/project/roles/kubernetes-apps/ansible/templates/nodelocaldns-daemonset.yml.j2 index 9ca15d7..6e1dda3 100644 --- a/kubespray/project/roles/kubernetes-apps/ansible/templates/nodelocaldns-daemonset.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ansible/templates/nodelocaldns-daemonset.yml.j2 @@ -20,7 +20,7 @@ spec: spec: nodeSelector: {{ nodelocaldns_ds_nodeselector }} - priorityClassName: system-cluster-critical + priorityClassName: system-node-critical serviceAccountName: nodelocaldns hostNetwork: true dnsPolicy: Default # Don't use cluster DNS. diff --git a/kubespray/project/roles/kubernetes-apps/argocd/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/argocd/defaults/main.yml index f98a9d3..b164b62 100644 --- a/kubespray/project/roles/kubernetes-apps/argocd/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/argocd/defaults/main.yml @@ -1,6 +1,6 @@ --- argocd_enabled: false -argocd_version: v2.8.4 +argocd_version: v2.11.0 argocd_namespace: argocd # argocd_admin_password: argocd_install_url: "https://raw.githubusercontent.com/argoproj/argo-cd/{{ argocd_version }}/manifests/install.yaml" diff --git a/kubespray/project/roles/kubernetes-apps/argocd/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/argocd/tasks/main.yml index e11f097..05c6333 100644 --- a/kubespray/project/roles/kubernetes-apps/argocd/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/argocd/tasks/main.yml @@ -8,10 +8,10 @@ ansible.posix.synchronize: src: "{{ downloads.yq.dest }}" dest: "{{ bin_dir }}/yq" - compress: no - perms: yes - owner: no - group: no + compress: false + perms: true + owner: false + group: false delegate_to: "{{ inventory_hostname }}" - name: Kubernetes Apps | Set ArgoCD template list @@ -36,7 +36,7 @@ url: "{{ item.url }}" unarchive: false owner: "root" - mode: 0644 + mode: "0644" sha256: "" download: "{{ download_defaults | combine(download_argocd) }}" with_items: "{{ argocd_templates | selectattr('url', 'defined') | list }}" @@ -49,17 +49,17 @@ ansible.posix.synchronize: src: "{{ local_release_dir }}/{{ item.file }}" dest: "{{ kube_config_dir }}/{{ item.file }}" - compress: no - perms: yes - owner: no - group: no + compress: false + perms: true + owner: false + group: false delegate_to: "{{ inventory_hostname }}" with_items: "{{ argocd_templates | selectattr('url', 'defined') | list }}" when: - "inventory_hostname == groups['kube_control_plane'][0]" - name: Kubernetes Apps | Set ArgoCD namespace for remote manifests - become: yes + become: true command: | {{ bin_dir }}/yq eval-all -i '.metadata.namespace="{{ argocd_namespace }}"' {{ kube_config_dir }}/{{ item.file }} with_items: "{{ argocd_templates | selectattr('url', 'defined') | list }}" @@ -69,11 +69,11 @@ - "inventory_hostname == groups['kube_control_plane'][0]" - name: Kubernetes Apps | Create ArgoCD manifests from templates - become: yes + become: true template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ argocd_templates | selectattr('url', 'undefined') | list }}" loop_control: label: "{{ item.file }}" @@ -81,7 +81,7 @@ - "inventory_hostname == groups['kube_control_plane'][0]" - name: Kubernetes Apps | Install ArgoCD - become: yes + become: true kube: name: ArgoCD kubectl: "{{ bin_dir }}/kubectl" @@ -93,7 +93,7 @@ # https://github.com/argoproj/argo-cd/blob/master/docs/faq.md#i-forgot-the-admin-password-how-do-i-reset-it - name: Kubernetes Apps | Set ArgoCD custom admin password - become: yes + become: true shell: | {{ bin_dir }}/kubectl --kubeconfig /etc/kubernetes/admin.conf -n {{ argocd_namespace }} patch secret argocd-secret -p \ '{ diff --git a/kubespray/project/roles/kubernetes-apps/cloud_controller/oci/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/cloud_controller/oci/tasks/main.yml index 6bfcc25..a5913ec 100644 --- a/kubespray/project/roles/kubernetes-apps/cloud_controller/oci/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/cloud_controller/oci/tasks/main.yml @@ -7,7 +7,7 @@ template: src: controller-manager-config.yml.j2 dest: "{{ kube_config_dir }}/controller-manager-config.yml" - mode: 0644 + mode: "0644" when: inventory_hostname == groups['kube_control_plane'][0] - name: "OCI Cloud Controller | Slurp Configuration" @@ -24,7 +24,7 @@ template: src: oci-cloud-provider.yml.j2 dest: "{{ kube_config_dir }}/oci-cloud-provider.yml" - mode: 0644 + mode: "0644" when: inventory_hostname == groups['kube_control_plane'][0] - name: "OCI Cloud Controller | Apply Manifests" diff --git a/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/main.yml index fdb3205..ef4737e 100644 --- a/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/main.yml @@ -2,7 +2,7 @@ - name: Kubernetes Apps | Wait for kube-apiserver uri: url: "{{ kube_apiserver_endpoint }}/healthz" - validate_certs: no + validate_certs: false client_cert: "{{ kube_apiserver_client_cert }}" client_key: "{{ kube_apiserver_client_key }}" register: result @@ -15,7 +15,7 @@ template: src: "node-crb.yml.j2" dest: "{{ kube_config_dir }}/node-crb.yml" - mode: 0640 + mode: "0640" register: node_crb_manifest when: - rbac_enabled @@ -70,7 +70,7 @@ copy: src: k8s-cluster-critical-pc.yml dest: "{{ kube_config_dir }}/k8s-cluster-critical-pc.yml" - mode: 0640 + mode: "0640" when: inventory_hostname == groups['kube_control_plane'] | last - name: PriorityClass | Create k8s-cluster-critical diff --git a/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/oci.yml b/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/oci.yml index eb07463..e5bef67 100644 --- a/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/oci.yml +++ b/kubespray/project/roles/kubernetes-apps/cluster_roles/tasks/oci.yml @@ -3,7 +3,7 @@ copy: src: "oci-rbac.yml" dest: "{{ kube_config_dir }}/oci-rbac.yml" - mode: 0640 + mode: "0640" when: - cloud_provider is defined - cloud_provider == 'oci' diff --git a/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/tasks/main.yml index 8cba9bf..325fb5f 100644 --- a/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/tasks/main.yml @@ -26,14 +26,14 @@ path: "{{ kube_config_dir }}/addons/container_engine_accelerator" owner: root group: root - mode: 0755 + mode: "0755" recurse: true - name: Container Engine Acceleration Nvidia GPU | Create manifests for nvidia accelerators template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/container_engine_accelerator/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: nvidia-driver-install-daemonset, file: nvidia-driver-install-daemonset.yml, type: daemonset } - { name: k8s-device-plugin-nvidia-daemonset, file: k8s-device-plugin-nvidia-daemonset.yml, type: daemonset } diff --git a/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/vars/centos-7.yml b/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/vars/centos-7.yml deleted file mode 100644 index b1ea65b..0000000 --- a/kubespray/project/roles/kubernetes-apps/container_engine_accelerator/nvidia_gpu/vars/centos-7.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -nvidia_driver_install_container: "{{ nvidia_driver_install_centos_container }}" -nvidia_driver_install_supported: true diff --git a/kubespray/project/roles/kubernetes-apps/container_runtimes/gvisor/tasks/main.yaml b/kubespray/project/roles/kubernetes-apps/container_runtimes/gvisor/tasks/main.yaml index 90562f2..143c8d8 100644 --- a/kubespray/project/roles/kubernetes-apps/container_runtimes/gvisor/tasks/main.yaml +++ b/kubespray/project/roles/kubernetes-apps/container_runtimes/gvisor/tasks/main.yaml @@ -4,7 +4,7 @@ path: "{{ kube_config_dir }}/addons/gvisor" owner: root group: root - mode: 0755 + mode: "0755" recurse: true - name: GVisor | Templates List @@ -16,7 +16,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/gvisor/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ gvisor_templates }}" register: gvisor_manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/container_runtimes/kata_containers/tasks/main.yaml b/kubespray/project/roles/kubernetes-apps/container_runtimes/kata_containers/tasks/main.yaml index a07c7c2..cd85a6d 100644 --- a/kubespray/project/roles/kubernetes-apps/container_runtimes/kata_containers/tasks/main.yaml +++ b/kubespray/project/roles/kubernetes-apps/container_runtimes/kata_containers/tasks/main.yaml @@ -5,7 +5,7 @@ path: "{{ kube_config_dir }}/addons/kata_containers" owner: root group: root - mode: 0755 + mode: "0755" recurse: true - name: Kata Containers | Templates list @@ -17,7 +17,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/kata_containers/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ kata_containers_templates }}" register: kata_containers_manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/aws_ebs/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/aws_ebs/tasks/main.yml index 5570dcc..fc905e4 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/aws_ebs/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/aws_ebs/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: aws-ebs-csi-driver, file: aws-ebs-csi-driver.yml} - {name: aws-ebs-csi-controllerservice, file: aws-ebs-csi-controllerservice-rbac.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/azuredisk/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/azuredisk/tasks/main.yml index a94656f..82d222e 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/azuredisk/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/azuredisk/tasks/main.yml @@ -7,7 +7,7 @@ src: "azure-csi-cloud-config.j2" dest: "{{ kube_config_dir }}/azure_csi_cloud_config" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" when: inventory_hostname == groups['kube_control_plane'][0] - name: Azure CSI Driver | Get base64 cloud-config @@ -20,7 +20,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: azure-csi-azuredisk-driver, file: azure-csi-azuredisk-driver.yml} - {name: azure-csi-cloud-config-secret, file: azure-csi-cloud-config-secret.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/defaults/main.yml index 8776c30..cc8c3b7 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/defaults/main.yml @@ -1,5 +1,4 @@ --- - cinder_csi_attacher_image_tag: "v4.4.2" cinder_csi_provisioner_image_tag: "v3.6.2" cinder_csi_snapshotter_image_tag: "v6.3.2" @@ -35,3 +34,15 @@ cinder_csi_controller_replicas: 1 # cinder_csi_rescan_on_resize: true cinder_tolerations: [] + +## Dictionaries of extra arguments to add to the cinder CSI plugin containers +## Format: +## cinder_csi_attacher_extra_args: +## arg1: "value1" +## arg2: "value2" +cinder_csi_attacher_extra_args: {} +cinder_csi_provisioner_extra_args: {} +cinder_csi_snapshotter_extra_args: {} +cinder_csi_resizer_extra_args: {} +cinder_csi_plugin_extra_args: {} +cinder_liveness_probe_extra_args: {} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/cinder-write-cacert.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/cinder-write-cacert.yml index c6d14a2..dd614fe 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/cinder-write-cacert.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/cinder-write-cacert.yml @@ -7,5 +7,5 @@ src: "{{ cinder_cacert }}" dest: "{{ kube_config_dir }}/cinder-cacert.pem" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" delegate_to: "{{ delegate_host_to_write_cacert }}" diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/main.yml index 47ce6cd..f2d1026 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/tasks/main.yml @@ -18,7 +18,7 @@ src: "cinder-csi-cloud-config.j2" dest: "{{ kube_config_dir }}/cinder_cloud_config" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" when: inventory_hostname == groups['kube_control_plane'][0] - name: Cinder CSI Driver | Get base64 cloud-config @@ -31,7 +31,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: cinder-csi-driver, file: cinder-csi-driver.yml} - {name: cinder-csi-cloud-config-secret, file: cinder-csi-cloud-config-secret.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-controllerplugin.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-controllerplugin.yml.j2 index de27b76..c541c89 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-controllerplugin.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-controllerplugin.yml.j2 @@ -30,6 +30,9 @@ spec: - --leader-election=true {% endif %} - "--default-fstype=ext4" +{% for key, value in cinder_csi_attacher_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock @@ -50,6 +53,9 @@ spec: {% if cinder_csi_controller_replicas is defined and cinder_csi_controller_replicas > 1 %} - "--leader-election=true" {% endif %} +{% for key, value in cinder_csi_provisioner_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock @@ -66,6 +72,9 @@ spec: {% if cinder_csi_controller_replicas is defined and cinder_csi_controller_replicas > 1 %} - --leader-election=true {% endif %} +{% for key, value in cinder_csi_snapshotter_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock @@ -82,6 +91,9 @@ spec: {% if cinder_csi_controller_replicas is defined and cinder_csi_controller_replicas > 1 %} - --leader-election=true {% endif %} +{% for key, value in cinder_csi_resizer_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock @@ -93,6 +105,9 @@ spec: imagePullPolicy: {{ k8s_image_pull_policy }} args: - "--csi-address=$(ADDRESS)" +{% for key, value in cinder_liveness_probe_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock @@ -107,6 +122,9 @@ spec: - "--endpoint=$(CSI_ENDPOINT)" - "--cloud-config=$(CLOUD_CONFIG)" - "--cluster=$(CLUSTER_NAME)" +{% for key, value in cinder_csi_plugin_extra_args.items() %} + - "{{ '--' + key + '=' + value }}" +{% endfor %} env: - name: CSI_ENDPOINT value: unix://csi/csi.sock diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/csi_crd/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/csi_crd/tasks/main.yml index 4790931..75111db 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/csi_crd/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/csi_crd/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: volumesnapshotclasses, file: volumesnapshotclasses.yml} - {name: volumesnapshotcontents, file: volumesnapshotcontents.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/tasks/main.yml index be511ca..6ae54d4 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/tasks/main.yml @@ -9,7 +9,7 @@ src: "{{ gcp_pd_csi_sa_cred_file }}" dest: "{{ kube_config_dir }}/cloud-sa.json" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" when: inventory_hostname == groups['kube_control_plane'][0] - name: GCP PD CSI Driver | Get base64 cloud-sa.json @@ -22,7 +22,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: gcp-pd-csi-cred-secret, file: gcp-pd-csi-cred-secret.yml} - {name: gcp-pd-csi-setup, file: gcp-pd-csi-setup.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-controller.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-controller.yml.j2 index 61157d8..6bdaff6 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-controller.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-controller.yml.j2 @@ -162,4 +162,4 @@ metadata: name: pd.csi.storage.gke.io spec: attachRequired: true - podInfoOnMount: false \ No newline at end of file + podInfoOnMount: false diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-node.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-node.yml.j2 index 9aad620..2992d7f 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-node.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-node.yml.j2 @@ -109,4 +109,4 @@ spec: # See "special case". This will tolerate everything. Node component should # be scheduled on all nodes. tolerations: - - operator: Exists \ No newline at end of file + - operator: Exists diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-regional.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-regional.yml.j2 index 57a8675..fa2e5a8 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-regional.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-regional.yml.j2 @@ -6,4 +6,4 @@ provisioner: pd.csi.storage.gke.io parameters: type: pd-balanced replication-type: regional-pd -volumeBindingMode: WaitForFirstConsumer \ No newline at end of file +volumeBindingMode: WaitForFirstConsumer diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-zonal.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-zonal.yml.j2 index e9bedaf..dc53016 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-zonal.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/gcp_pd/templates/gcp-pd-csi-sc-zonal.yml.j2 @@ -5,4 +5,4 @@ metadata: provisioner: pd.csi.storage.gke.io parameters: type: pd-balanced -volumeBindingMode: WaitForFirstConsumer \ No newline at end of file +volumeBindingMode: WaitForFirstConsumer diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml index ea828f3..cc34086 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml @@ -3,7 +3,7 @@ upcloud_csi_controller_replicas: 1 upcloud_csi_provisioner_image_tag: "v3.1.0" upcloud_csi_attacher_image_tag: "v3.4.0" upcloud_csi_resizer_image_tag: "v1.4.0" -upcloud_csi_plugin_image_tag: "v0.3.3" +upcloud_csi_plugin_image_tag: "v1.1.0" upcloud_csi_node_image_tag: "v2.5.0" upcloud_username: "{{ lookup('env', 'UPCLOUD_USERNAME') }}" upcloud_password: "{{ lookup('env', 'UPCLOUD_PASSWORD') }}" diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml index 8f0b69f..aafb0fd 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml @@ -16,7 +16,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: upcloud-csi-cred-secret, file: upcloud-csi-cred-secret.yml} - {name: upcloud-csi-setup, file: upcloud-csi-setup.yml} diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2 index 1b8519d..9ee2536 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2 @@ -58,13 +58,26 @@ spec: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter + image: k8s.gcr.io/sig-storage/csi-snapshotter:{{ upcloud_csi_snapshotter_image_tag }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--timeout=600s" + - "--leader-election=false" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: "Always" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ - name: csi-upcloud-plugin image: ghcr.io/upcloudltd/upcloud-csi:{{ upcloud_csi_plugin_image_tag }} args: - "--endpoint=$(CSI_ENDPOINT)" - "--nodehost=$(NODE_ID)" - - "--username=$(UPCLOUD_USERNAME)" - - "--password=$(UPCLOUD_PASSWORD)" + - "--mode=monolith" env: - name: CSI_ENDPOINT value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2 index 7ed39be..36fd75f 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2 @@ -42,8 +42,7 @@ spec: args: - "--endpoint=$(CSI_ENDPOINT)" - "--nodehost=$(NODE_ID)" - - "--username=$(UPCLOUD_USERNAME)" - - "--password=$(UPCLOUD_PASSWORD)" + - "--mode=monolith" env: - name: CSI_ENDPOINT value: unix:///csi/csi.sock diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2 index 5af71d2..b43eb24 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2 @@ -62,6 +62,18 @@ rules: - apiGroups: [ "" ] resources: [ "events" ] verbs: [ "list", "watch", "create", "update", "patch" ] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + - apiGroups: [ "snapshot.storage.k8s.io" ] + resources: [ "volumesnapshots" ] + verbs: [ "get", "list" ] - apiGroups: [ "" ] resources: [ "nodes" ] verbs: [ "get", "list", "watch" ] @@ -183,3 +195,54 @@ roleRef: kind: ClusterRole name: csi-upcloud-resizer-role apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-upcloud-snapshotter-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-upcloud-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-upcloud-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-upcloud-snapshotter-role + apiGroup: rbac.authorization.k8s.io diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/defaults/main.yml index 0d41441..325e3cb 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/defaults/main.yml @@ -21,7 +21,7 @@ vsphere_csi_controller_replicas: 1 csi_endpoint: '{% if external_vsphere_version >= "7.0u1" %}/csi{% else %}/var/lib/csi/sockets/pluginproxy{% endif %}' -vsphere_csi_aggressive_node_drain: False +vsphere_csi_aggressive_node_drain: false vsphere_csi_aggressive_node_unreachable_timeout: 300 vsphere_csi_aggressive_node_not_ready_timeout: 300 diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/tasks/main.yml index 102dd8b..6bbb4ff 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/tasks/main.yml @@ -6,7 +6,7 @@ template: src: "{{ item }}.j2" dest: "{{ kube_config_dir }}/{{ item }}" - mode: 0640 + mode: "0640" with_items: - vsphere-csi-cloud-config when: inventory_hostname == groups['kube_control_plane'][0] @@ -15,7 +15,7 @@ template: src: "{{ item }}.j2" dest: "{{ kube_config_dir }}/{{ item }}" - mode: 0644 + mode: "0644" with_items: - vsphere-csi-namespace.yml - vsphere-csi-driver.yml diff --git a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-controller-config.yml.j2 b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-controller-config.yml.j2 index fb52d10..2748896 100644 --- a/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-controller-config.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-controller-config.yml.j2 @@ -18,7 +18,7 @@ data: "max-pvscsi-targets-per-vm": "true" "multi-vcenter-csi-topology": "true" "csi-internal-generated-cluster-id": "true" - "listview-tasks": "true" + "listview-tasks": "true" {% if vsphere_csi_controller is version('v2.7.0', '>=') %} "improved-csi-idempotency": "true" "improved-volume-topology": "true" diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/hcloud/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/hcloud/tasks/main.yml index c626e78..6b482cc 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/hcloud/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/hcloud/tasks/main.yml @@ -4,7 +4,7 @@ src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" with_items: - {name: external-hcloud-cloud-secret, file: external-hcloud-cloud-secret.yml} - {name: external-hcloud-cloud-service-account, file: external-hcloud-cloud-service-account.yml} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/defaults/main.yml index f81bf1e..9cd42ed 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/defaults/main.yml @@ -16,4 +16,4 @@ external_huaweicloud_cloud: "{{ lookup('env','OS_CLOUD') }}" ## arg2: "value2" external_huawei_cloud_controller_extra_args: {} external_huawei_cloud_controller_image_repo: "swr.ap-southeast-1.myhuaweicloud.com" -external_huawei_cloud_controller_image_tag: "v0.26.6" +external_huawei_cloud_controller_image_tag: "v0.26.8" diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/tasks/main.yml index 880be0d..3d82ded 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/tasks/main.yml @@ -24,7 +24,7 @@ src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" with_items: - {name: external-huawei-cloud-config-secret, file: external-huawei-cloud-config-secret.yml} - {name: external-huawei-cloud-controller-manager-roles, file: external-huawei-cloud-controller-manager-roles.yml} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-config.j2 b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-config.j2 index 07f1771..875ea9b 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-config.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-config.j2 @@ -21,3 +21,6 @@ subnet-id={{ external_huaweicloud_lbaas_subnet_id }} {% if external_huaweicloud_lbaas_network_id is defined %} id={{ external_huaweicloud_lbaas_network_id }} {% endif %} +{% if external_huaweicloud_security_group_id is defined %} +security-group-id={{ external_huaweicloud_security_group_id }} +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-ds.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-ds.yml.j2 index b9b2ec3..29f99b2 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-ds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-ds.yml.j2 @@ -47,6 +47,11 @@ spec: - --cloud-config=$(CLOUD_CONFIG) - --cloud-provider=huaweicloud - --use-service-account-credentials=true + - --node-status-update-frequency=5s + - --node-monitor-period=5s + - --leader-elect-lease-duration=30s + - --leader-elect-renew-deadline=20s + - --leader-elect-retry-period=2s {% for key, value in external_huawei_cloud_controller_extra_args.items() %} - "{{ '--' + key + '=' + value }}" {% endfor %} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-role-bindings.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-role-bindings.yml.j2 index bbdf336..65dfefa 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-role-bindings.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-role-bindings.yml.j2 @@ -1,16 +1,12 @@ -apiVersion: v1 -items: -- apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRoleBinding - metadata: - name: system:cloud-controller-manager - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:cloud-controller-manager - subjects: +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:cloud-controller-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:cloud-controller-manager +subjects: - kind: ServiceAccount name: cloud-controller-manager namespace: kube-system -kind: List -metadata: {} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-roles.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-roles.yml.j2 index 2e2d8b6..ccb7c0b 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-roles.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/huaweicloud/templates/external-huawei-cloud-controller-manager-roles.yml.j2 @@ -1,117 +1,113 @@ -apiVersion: v1 -items: -- apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRole - metadata: - name: system:cloud-controller-manager - rules: +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:cloud-controller-manager +rules: - resources: - - tokenreviews + - tokenreviews verbs: - - get - - list - - watch - - create - - update - - patch + - get + - list + - watch + - create + - update + - patch apiGroups: - - authentication.k8s.io + - authentication.k8s.io - resources: - - configmaps - - endpoints - - pods - - services - - secrets - - serviceaccounts - - serviceaccounts/token + - configmaps + - endpoints + - pods + - services + - secrets + - serviceaccounts + - serviceaccounts/token verbs: - - get - - list - - watch - - create - - update - - patch + - get + - list + - watch + - create + - update + - patch apiGroups: - - '' + - '' - resources: - - nodes + - nodes verbs: - - get - - list - - watch - - delete - - patch - - update + - get + - list + - watch + - delete + - patch + - update apiGroups: - - '' + - '' - resources: - - services/status - - pods/status + - services/status + - pods/status verbs: - - update - - patch + - update + - patch apiGroups: - - '' + - '' - resources: - - nodes/status + - nodes/status verbs: - - patch - - update + - patch + - update apiGroups: - - '' + - '' - resources: - - events - - endpoints + - events + - endpoints verbs: - - create - - patch - - update + - create + - patch + - update apiGroups: - - '' + - '' - resources: - - leases + - leases verbs: - - get - - update - - create - - delete + - get + - update + - create + - delete apiGroups: - - coordination.k8s.io + - coordination.k8s.io - resources: - - customresourcedefinitions + - customresourcedefinitions verbs: - - get - - update - - create - - delete + - get + - update + - create + - delete apiGroups: - apiextensions.k8s.io - resources: - - ingresses + - ingresses verbs: - - get - - list - - watch - - update - - create - - patch - - delete + - get + - list + - watch + - update + - create + - patch + - delete apiGroups: - - networking.k8s.io + - networking.k8s.io - resources: - - ingresses/status + - ingresses/status verbs: - - update - - patch + - update + - patch apiGroups: - - networking.k8s.io + - networking.k8s.io - resources: - - endpointslices + - endpointslices verbs: - - get - - list - - watch + - get + - list + - watch apiGroups: - - discovery.k8s.io -kind: List -metadata: {} + - discovery.k8s.io diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/defaults/main.yml index 4bcf135..ab5f152 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/defaults/main.yml @@ -21,5 +21,6 @@ external_openstack_cacert: "{{ lookup('env', 'OS_CACERT') }}" ## arg1: "value1" ## arg2: "value2" external_openstack_cloud_controller_extra_args: {} -external_openstack_cloud_controller_image_tag: "v1.25.3" +external_openstack_cloud_controller_image_tag: "v1.30.0" external_openstack_cloud_controller_bind_address: 127.0.0.1 +external_openstack_cloud_controller_dns_policy: ClusterFirst diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/tasks/main.yml index 787dbb4..8c930f3 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/tasks/main.yml @@ -24,7 +24,7 @@ src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" with_items: - {name: external-openstack-cloud-config-secret, file: external-openstack-cloud-config-secret.yml} - {name: external-openstack-cloud-controller-manager-roles, file: external-openstack-cloud-controller-manager-roles.yml} diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/templates/external-openstack-cloud-controller-manager-ds.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/templates/external-openstack-cloud-controller-manager-ds.yml.j2 index 8bae2aa..85df997 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/templates/external-openstack-cloud-controller-manager-ds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/openstack/templates/external-openstack-cloud-controller-manager-ds.yml.j2 @@ -36,7 +36,7 @@ spec: serviceAccountName: cloud-controller-manager containers: - name: openstack-cloud-controller-manager - image: {{ docker_image_repo }}/k8scloudprovider/openstack-cloud-controller-manager:{{ external_openstack_cloud_controller_image_tag }} + image: {{ external_openstack_cloud_controller_image_repo }}:{{ external_openstack_cloud_controller_image_tag }} args: - /bin/openstack-cloud-controller-manager - --v=1 @@ -81,7 +81,9 @@ spec: - name: CLOUD_CONFIG value: /etc/config/cloud.conf hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet +{% if external_openstack_cloud_controller_dns_policy is defined %} + dnsPolicy: {{ external_openstack_cloud_controller_dns_policy }} +{% endif %} volumes: {% if kubelet_flexvolumes_plugins_dir is defined %} - name: flexvolume-dir diff --git a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/vsphere/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/vsphere/tasks/main.yml index 60b8ec8..585eb98 100644 --- a/kubespray/project/roles/kubernetes-apps/external_cloud_controller/vsphere/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_cloud_controller/vsphere/tasks/main.yml @@ -6,7 +6,7 @@ template: src: "{{ item }}.j2" dest: "{{ kube_config_dir }}/{{ item }}" - mode: 0640 + mode: "0640" with_items: - external-vsphere-cpi-cloud-config when: inventory_hostname == groups['kube_control_plane'][0] @@ -15,7 +15,7 @@ template: src: "{{ item }}.j2" dest: "{{ kube_config_dir }}/{{ item }}" - mode: 0644 + mode: "0644" with_items: - external-vsphere-cpi-cloud-config-secret.yml - external-vsphere-cloud-controller-manager-roles.yml diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/tasks/main.yml index 86cba2d..4993eeb 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/tasks/main.yml @@ -33,7 +33,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -54,7 +54,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/cephfs_provisioner/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ cephfs_provisioner_templates }}" register: cephfs_provisioner_manifests when: inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/tasks/main.yml index 71036ca..f3ae87a 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/tasks/main.yml @@ -5,7 +5,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -13,7 +13,7 @@ file: path: "{{ local_path_provisioner_claim_root }}" state: directory - mode: 0755 + mode: "0755" - name: Local Path Provisioner | Render Template set_fact: @@ -30,7 +30,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/local_path_provisioner/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ local_path_provisioner_templates }}" register: local_path_provisioner_manifests when: inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cm.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cm.yml.j2 index 9cd7fd3..a0b0bc1 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cm.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cm.yml.j2 @@ -32,4 +32,3 @@ data: - name: helper-pod image: "{{ local_path_provisioner_helper_image_repo }}:{{ local_path_provisioner_helper_image_tag }}" imagePullPolicy: IfNotPresent - diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cr.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cr.yml.j2 index 299db6e..2b53ba7 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cr.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_path_provisioner/templates/local-path-storage-cr.yml.j2 @@ -15,4 +15,4 @@ rules: verbs: [ "create", "patch" ] - apiGroups: [ "storage.k8s.io" ] resources: [ "storageclasses" ] - verbs: [ "get", "list", "watch" ] \ No newline at end of file + verbs: [ "get", "list", "watch" ] diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml index 38afefb..e9c5f74 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml @@ -18,3 +18,4 @@ local_volume_provisioner_storage_classes: | "fs_type": "ext4" } } +local_volume_provisioner_log_level: 2 diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/tasks/main.yml index 2308b5c..bc35b47 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/tasks/main.yml @@ -12,7 +12,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" - name: Local Volume Provisioner | Templates list set_fact: @@ -29,7 +29,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/local_volume_provisioner/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ local_volume_provisioner_templates }}" register: local_volume_provisioner_manifests when: inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/templates/local-volume-provisioner-ds.yml.j2 b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/templates/local-volume-provisioner-ds.yml.j2 index 90a4730..87385fc 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/templates/local-volume-provisioner-ds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/templates/local-volume-provisioner-ds.yml.j2 @@ -30,6 +30,8 @@ spec: - name: provisioner image: {{ local_volume_provisioner_image_repo }}:{{ local_volume_provisioner_image_tag }} imagePullPolicy: {{ k8s_image_pull_policy }} + args: + - "-v={{ local_volume_provisioner_log_level }}" securityContext: privileged: true env: diff --git a/kubespray/project/roles/kubernetes-apps/external_provisioner/rbd_provisioner/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/external_provisioner/rbd_provisioner/tasks/main.yml index 76445da..0a1f5b2 100644 --- a/kubespray/project/roles/kubernetes-apps/external_provisioner/rbd_provisioner/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/external_provisioner/rbd_provisioner/tasks/main.yml @@ -33,7 +33,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -54,7 +54,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/rbd_provisioner/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ rbd_provisioner_templates }}" register: rbd_provisioner_manifests when: inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/gateway_api/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/gateway_api/defaults/main.yml new file mode 100644 index 0000000..9896bbf --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/gateway_api/defaults/main.yml @@ -0,0 +1,4 @@ +--- +gateway_api_enabled: false +gateway_api_version: v1.1.0 +gateway_api_experimental_channel: false diff --git a/kubespray/project/roles/kubernetes-apps/gateway_api/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/gateway_api/tasks/main.yml new file mode 100644 index 0000000..107fa70 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/gateway_api/tasks/main.yml @@ -0,0 +1,33 @@ +--- +- name: Gateway API | Create addon dir + file: + path: "{{ kube_config_dir }}/addons/gateway_api" + state: directory + owner: root + group: root + mode: "0755" + when: + - inventory_hostname == groups['kube_control_plane'][0] + +- name: Gateway API | Set channel + set_fact: + gateway_api_channel: "{{ 'experimental' if gateway_api_experimental_channel else 'standard' }}" + when: + - "inventory_hostname == groups['kube_control_plane'][0]" + +- name: Gateway API | Copy Gateway API manifests to remote + template: + src: "{{ gateway_api_channel }}-install.yaml.j2" + dest: "{{ kube_config_dir }}/addons/gateway_api/{{ gateway_api_channel }}-install.yaml" + mode: "0644" + when: + - "inventory_hostname == groups['kube_control_plane'][0]" + +- name: Gateway API | Install Gateway API + kube: + name: Gateway API + kubectl: "{{ bin_dir }}/kubectl" + filename: "{{ kube_config_dir }}/addons/gateway_api/{{ gateway_api_channel }}-install.yaml" + state: latest + when: + - "inventory_hostname == groups['kube_control_plane'][0]" diff --git a/kubespray/project/roles/kubernetes-apps/gateway_api/templates/experimental-install.yaml.j2 b/kubespray/project/roles/kubernetes-apps/gateway_api/templates/experimental-install.yaml.j2 new file mode 100644 index 0000000..8a50a1f --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/gateway_api/templates/experimental-install.yaml.j2 @@ -0,0 +1,18317 @@ +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Gateway API Experimental channel install +# +--- +# +# config/crd/experimental/gateway.networking.k8s.io_backendlbpolicies.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: backendlbpolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies + shortNames: + - blbpolicy + singular: backendlbpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + BackendLBPolicy provides a way to define load balancing rules + for a backend. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 BackendLBPolicy. + properties: + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + + Support: Extended + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookieConfig: + description: |- + CookieConfig provides configuration settings that are specific + to cookie-based session persistence. + + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: 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 + which may be reflected in the cookie or the header. Users + should avoid reusing session names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: 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.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + targetRefs: + description: |- + TargetRef identifies an API object to apply policy to. + Currently, Backends (i.e. Service, ServiceImport, or any + implementation-specific backendRef) are the only valid API + target references. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the 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 + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - group + - kind + - name + x-kubernetes-list-type: map + required: + - targetRefs + type: object + status: + description: Status defines the current state of BackendLBPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies + shortNames: + - btlspolicy + singular: backendtlspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + BackendTLSPolicy provides a way to configure how a Gateway + connects to a Backend via TLS. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 BackendTLSPolicy. + properties: + targetRefs: + description: |- + TargetRefs identifies an API object to apply the policy to. + Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. + Note that this config applies to the entire referenced resource + by default, but this default may change in the future to provide + a more granular application of the policy. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + items: + description: |- + LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a + direct policy to. This should be used as part of Policy resources that can + target single resources. For more information on how this policy attachment + mode works, and a sample Policy resource, refer to the policy attachment + documentation for Gateway API. + + + Note: This should only be used for direct policy attachment when references + to SectionName are actually needed. In all other cases, + LocalPolicyTargetReference should be used. + 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 + sectionName: + description: |- + SectionName is the name of a section within the target resource. When + unspecified, this targetRef targets the entire resource. In the following + resources, SectionName is interpreted as the following: + + + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name + + + If a SectionName is specified, but does not exist on the targeted object, + the Policy must fail to attach, and the policy implementation should record + a `ResolvedRefs` or similar Condition in the Policy's status. + 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: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + validation: + description: Validation contains backend TLS validation configuration. + properties: + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to Kubernetes objects that + contain a PEM-encoded TLS CA certificate bundle, which is used to + validate a TLS handshake between the Gateway and backend Pod. + + + If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be + specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified, + not both. If CACertifcateRefs is empty or unspecified, the configuration for + WellKnownCACertificates MUST be honored instead if supported by the implementation. + + + References to a resource in a different namespace are invalid for the + moment, although we will revisit this in the future. + + + A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a backend, but this behavior is implementation-specific. + + + Support: Core - An optional single reference to a Kubernetes ConfigMap, + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + items: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + maxItems: 8 + type: array + hostname: + description: |- + Hostname is used for two purposes in the connection between Gateways and + backends: + + + 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). + 2. Hostname MUST be used for authentication and MUST match the certificate + served by the matching backend. + + + Support: 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 + wellKnownCACertificates: + description: |- + WellKnownCACertificates specifies whether system CA certificates may be used in + the TLS handshake between the gateway and backend pod. + + + If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs + must be specified with at least one entry for a valid configuration. Only one of + CACertificateRefs or WellKnownCACertificates may be specified, not both. If an + implementation does not support the WellKnownCACertificates field or the value + supplied is not supported, the Status Conditions on the Policy MUST be + updated to include an Accepted: False Condition with Reason: Invalid. + + + Support: Implementation-specific + enum: + - System + type: string + required: + - hostname + 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 specify either CACertificateRefs or WellKnownCACertificates + rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "") + required: + - targetRefs + - validation + type: object + status: + description: Status defines the current state of BackendTLSPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + Support: 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 helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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. + This field is required when referring to a Namespace-scoped resource and + MUST 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 + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + Support: 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 helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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. + This field is required when referring to a Namespace-scoped resource and + MUST 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 + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + labels: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + + An implementation may chose to add additional implementation-specific labels as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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 + required: + - group + - kind + - name + type: object + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: 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 + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: 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 + relates 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. + Valid 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, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + 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 + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + Support: 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + + Support: 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-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 + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + that requests a user to specify the client certificate. + The maximum depth of a certificate chain accepted in verification is Implementation specific. + + + Support: Extended + + + properties: + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to + Kubernetes objects that contain TLS certificates of + the Certificate Authorities that can be used + as a trust anchor to validate the certificates presented by the client. + + + A single CA certificate reference to a Kubernetes ConfigMap + has "Core" support. + Implementations MAY choose to support attaching multiple CA certificates to + a Listener, but this behavior is implementation-specific. + + + Support: Core - A single reference to a Kubernetes ConfigMap + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + + + References to a resource in a different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + description: |- + ObjectReference identifies an API object including its namespace. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 "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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + 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 + type: object + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on 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 + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: 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' + 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: 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))))' + 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 + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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 + 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 Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference 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 + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + labels: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + + An implementation may chose to add additional implementation-specific labels as they see fit. + + + Support: Extended + maxProperties: 8 + type: object + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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 + required: + - group + - kind + - name + type: object + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: 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 + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: 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 + relates 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. + Valid 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, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + 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 + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + Support: 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + + Support: 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-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 + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + that requests a user to specify the client certificate. + The maximum depth of a certificate chain accepted in verification is Implementation specific. + + + Support: Extended + + + properties: + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to + Kubernetes objects that contain TLS certificates of + the Certificate Authorities that can be used + as a trust anchor to validate the certificates presented by the client. + + + A single CA certificate reference to a Kubernetes ConfigMap + has "Core" support. + Implementations MAY choose to support attaching multiple CA certificates to + a Listener, but this behavior is implementation-specific. + + + Support: Core - A single reference to a Kubernetes ConfigMap + with the CA certificate in a key named `ca.crt`. + + + Support: Implementation-specific (More than one reference, or other kinds + of resources). + + + References to a resource in a different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + description: |- + ObjectReference identifies an API object including its namespace. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 "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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + 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 + type: object + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on 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 + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: 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' + 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: 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))))' + 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 + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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 + 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 Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference 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 + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a + Listener and that listener already has another Route (B) of the other + type attached and the intersection of the hostnames of A and B is + non-empty, then the implementation MUST accept exactly one of these two + routes, determined by the following criteria, in order: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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 GRPC matchers, filters and actions. + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression + type: string + type: object + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + Support: Extended + + + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookieConfig: + description: |- + CookieConfig provides configuration settings that are specific + to cookie-based session persistence. + + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: 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 + which may be reflected in the cookie or the header. Users + should avoid reusing session names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: 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.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: true + subresources: + status: {} + - deprecated: true + deprecationWarning: The v1alpha2 version of GRPCRoute has been deprecated and + will be removed in a future release of the API. Please upgrade to v1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a + Listener and that listener already has another Route (B) of the other + type attached and the intersection of the hostnames of A and B is + non-empty, then the implementation MUST accept exactly one of these two + routes, determined by the following criteria, in order: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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 GRPC matchers, filters and actions. + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression + type: string + type: object + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + Support: Extended + + + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookieConfig: + description: |- + CookieConfig provides configuration settings that are specific + to cookie-based session persistence. + + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: 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 + which may be reflected in the cookie or the header. Users + should avoid reusing session names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: 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.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch 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\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + Support: Extended + + + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookieConfig: + description: |- + CookieConfig provides configuration settings that are specific + to cookie-based session persistence. + + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: 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 + which may be reflected in the cookie or the header. Users + should avoid reusing session names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: 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.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + timeouts: + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + + properties: + backendRequest: + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + + Because the Request timeout encompasses the BackendRequest timeout, the value of + BackendRequest must be <= the value of Request timeout. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + request: + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + + When this field is unspecified, request timeout behavior is implementation-specific. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch 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\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + sessionPersistence: + description: |+ + SessionPersistence defines and configures session persistence + for the route rule. + + + Support: Extended + + + properties: + absoluteTimeout: + description: |- + AbsoluteTimeout defines the absolute timeout of the persistent + session. Once the AbsoluteTimeout duration has elapsed, the + session becomes invalid. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + cookieConfig: + description: |- + CookieConfig provides configuration settings that are specific + to cookie-based session persistence. + + + Support: Core + properties: + lifetimeType: + default: Session + description: |- + LifetimeType specifies whether the cookie has a permanent or + session-based lifetime. A permanent cookie persists until its + specified expiry time, defined by the Expires or Max-Age cookie + attributes, while a session cookie is deleted when the current + session ends. + + + When set to "Permanent", AbsoluteTimeout indicates the + cookie's lifetime via the Expires or Max-Age cookie attributes + and is required. + + + When set to "Session", AbsoluteTimeout indicates the + absolute lifetime of the cookie tracked by the gateway and + is optional. + + + Support: Core for "Session" type + + + Support: Extended for "Permanent" type + enum: + - Permanent + - Session + type: string + type: object + idleTimeout: + description: |- + IdleTimeout defines the idle timeout of the persistent session. + Once the session has been idle for more than the specified + IdleTimeout duration, the session becomes invalid. + + + Support: 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 + which may be reflected in the cookie or the header. Users + should avoid reusing session names to prevent unintended + consequences, such as rejection or unpredictable behavior. + + + Support: Implementation-specific + maxLength: 128 + type: string + type: + default: Cookie + description: |- + Type defines the type of session persistence such as through + the use a header or cookie. Defaults to cookie based session + persistence. + + + Support: Core for "Cookie" type + + + Support: 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.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + timeouts: + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + + properties: + backendRequest: + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + + Because the Request timeout encompasses the BackendRequest timeout, the value of + BackendRequest must be <= the value of Request timeout. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + request: + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + + When this field is unspecified, request timeout behavior is implementation-specific. + + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: referencegrants.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferenceGrant + listKind: ReferenceGrantList + plural: referencegrants + shortNames: + - refgrant + singular: referencegrant + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated + and will be removed in a future release of the API. Please upgrade to v1beta1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + A ReferenceGrant is required for all cross-namespace references in Gateway API + (with the exception of cross-namespace Route-Gateway attachment, which is + governed by the AllowedRoutes configuration on the Gateway, and cross-namespace + Service ParentRefs on a "consumer" mesh Route, which defines routing rules + applicable only to workloads in the Route namespace). ReferenceGrants allowing + a reference from a Route to a Service are only applicable to BackendRefs. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core + items: + description: ReferenceGrantFrom describes trusted namespaces and + kinds. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core + items: + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * 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 + refers to all resources of the specified Group and Kind in the local + namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: false + subresources: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + All cross-namespace references in Gateway API (with the exception of cross-namespace + Gateway-route attachment) require a ReferenceGrant. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core + items: + description: ReferenceGrantFrom describes trusted namespaces and + kinds. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core + items: + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * 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 + refers to all resources of the specified Group and Kind in the local + namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: tcproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TCPRoute + listKind: TCPRouteList + plural: tcproutes + singular: tcproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + TCPRoute provides a way to route TCP requests. When combined with a Gateway + listener, it can be used to forward connections on the port specified by the + listener to a set of backends specified by the TCPRoute. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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 + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Connection rejections must + respect weight; if an invalid backend is requested to have 80% of + connections, then 80% of connections must be rejected instead. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended + items: + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where 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". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TCPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: tlsroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TLSRoute + listKind: TLSRouteList + plural: tlsroutes + singular: tlsroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + The TLSRoute resource is similar to TCPRoute, but can be configured + to match against TLS-specific metadata. This allows more flexibility + in matching streams for a given TLS listener. + + + If you need to forward traffic to a single target for a TLS listener, you + could choose to use a TCPRoute with a TLS listener. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + SNI attribute of TLS ClientHello message in TLS handshake. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed in SNI names per RFC 6066. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and TLSRoute, there + must be at least one intersecting hostname for the TLSRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches TLSRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches TLSRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + If both the Listener and TLSRoute have specified hostnames, any + TLSRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + TLSRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and TLSRoute have specified hostnames, and none + match with the criteria above, then the TLSRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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 + sent. If unspecified or invalid (refers to a non-existent resource or + a Service with no endpoints), the rule performs no forwarding; if no + filters are specified that would result in a response being sent, the + underlying implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 500 status code. + Request rejections must respect weight; if an invalid backend is + requested to have 80% of requests, then 80% of requests must be rejected + instead. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended + items: + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where 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". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TLSRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: udproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: UDPRoute + listKind: UDPRouteList + plural: udproutes + singular: udproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + UDPRoute provides a way to route UDP traffic. When combined with a Gateway + listener, it can be used to forward traffic on the port specified by the + listener to a set of backends specified by the UDPRoute. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + 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 + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Packet drops must + respect weight; if an invalid backend is requested to have 80% of + the packets, then 80% of packets must be dropped instead. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Extended + items: + description: |- + BackendRef defines how a Route should forward a request to a Kubernetes + resource. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + + + Note that when the BackendTLSPolicy object is enabled by the implementation, + there are some extra rules about validity to consider here. See the fields + where 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". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of UDPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/kubespray/project/roles/kubernetes-apps/gateway_api/templates/standard-install.yaml.j2 b/kubespray/project/roles/kubernetes-apps/gateway_api/templates/standard-install.yaml.j2 new file mode 100644 index 0000000..fcb65e6 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/gateway_api/templates/standard-install.yaml.j2 @@ -0,0 +1,13478 @@ +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Gateway API Standard channel install +# +--- +# +# config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + Support: 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 helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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. + This field is required when referring to a Namespace-scoped resource and + MUST 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 + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + + Example: "example.net/gateway-controller". + + + This field is not mutable and cannot be empty. + + + Support: 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 helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + + If the referent cannot be found, the GatewayClass's "InvalidParameters" + status condition will be true. + + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + + Support: 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. + This field is required when referring to a Namespace-scoped resource and + MUST 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 + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_gateways.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: 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 + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: 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 + relates 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. + Valid 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, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + 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 + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + Support: 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + + Support: 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-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 + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on 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 + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: 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' + 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: 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))))' + 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 + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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 + 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 Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference 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 + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + + Support: Extended + + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + + HTTP Profile + + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + + TLS Profile + + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + + "Distinct" Listeners have the following property: + + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + + For example, the following Listener scenarios are distinct: + + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + + A Gateway's Listeners are considered "compatible" if: + + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + + Support: 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 + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + + Support: 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 + relates 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. + Valid 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, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + 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 + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + Support: 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 + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + + Support: 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-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 + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on 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 + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + + Support: 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' + 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: 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))))' + 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 + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + + This list may differ from the addresses provided in the spec under some + conditions: + + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + 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: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + 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 + 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 Gateway. + + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + + Known condition types are: + + + * "Accepted" + * "Programmed" + * "Ready" + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + successfully attached to this Listener. + + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + + Uses for this field include troubleshooting Route attachment and + measuring 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.\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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference 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 + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a + Listener and that listener already has another Route (B) of the other + type attached and the intersection of the hostnames of A and B is + non-empty, then the implementation MUST accept exactly one of these two + routes, determined by the following criteria, in order: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName 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))' + - message: sectionName 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)))) + rules: + description: Rules are a list of GRPC matchers, filters and actions. + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression + type: string + type: object + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: true + subresources: + status: {} + - deprecated: true + deprecationWarning: The v1alpha2 version of GRPCRoute has been deprecated and + will be removed in a future release of the API. Please upgrade to v1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a + Listener and that listener already has another Route (B) of the other + type attached and the intersection of the hostnames of A and B is + non-empty, then the implementation MUST accept exactly one of these two + routes, determined by the following criteria, in order: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName 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))' + - message: sectionName 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)))) + rules: + description: Rules are a list of GRPC matchers, filters and actions. + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + Support: Implementation-specific + + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + + If no matches are specified, the implementation MUST match every gRPC request. + + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + + Support: Implementation-specific (Exact with method specified but no service specified) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression + type: string + type: object + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: false + storage: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_httproutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName 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))' + - message: sectionName 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)))) + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch 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\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. 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 + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + ParentRefs must be _distinct_. This means either that: + + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + + Some examples: + + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + This API may be extended in the future to support additional kinds of parent + resources. + + + The API object must be valid in the cluster; the Group and Kind must + be 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. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName 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))' + - message: sectionName 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)))) + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + + Support: Core for Kubernetes Service + + + Support: Extended for Kubernetes ServiceImport + + + Support: Implementation-specific for any other resource + + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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 + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + + Support 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' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + + Conformance-levels at this level are defined based on the type of filter: + + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |- + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + + Support: Extended + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + + Support: Extended for Kubernetes Service + + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When 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 + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: 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 + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: 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. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource 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' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + Support: 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 + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + + If no port is specified, the redirect port MUST be derived using the + following rules: + + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + add: + - name: "my-header" + value: "bar,baz" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + 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 + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + + Config: + remove: ["my-header1", "my-header3"] + + + Output: + GET /foo HTTP/1.1 + 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) + before the action. + + + Input: + GET /foo HTTP/1.1 + my-header: foo + + + Config: + set: + - name: "my-header" + value: "bar" + + + Output: + GET /foo HTTP/1.1 + 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 + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + Support: 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 + path: + description: |- + Path defines a path rewrite. + + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + + Request Path | Prefix Match | Replace Prefix | Modified Path + -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | /xyz/bar + /foo/bar | /foo | /xyz/ | /xyz/bar + /foo/bar | /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | /xyz/bar + /foo | /foo | /xyz | /xyz + /foo/ | /foo | /xyz | /xyz/ + /foo/bar | /foo | | /bar + /foo/ | /foo | | / + /foo | /foo | | / + /foo/ | /foo | / | / + /foo | /foo | / | / + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + + For example, take the following matches configuration: + + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + + Note: The precedence of RegularExpression path matches are implementation-specific. + + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch 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\n\nFor example, + the match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n\n```\nmatch:\n\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + + Support: Core (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + + Support: Extended (Exact) + + + Support: Implementation-specific (RegularExpression) + + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + 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. + This 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. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This 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. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The 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 + 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 + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + + Example: "example.net/gateway-controller". + + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer 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 + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + + Support: 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. + + + There are two kinds of parent resources with "Core" support: + + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + + Support 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. + + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + + + Support: 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 + differently based on the type of parent resource. + + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + + Support: 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 + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: referencegrants.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferenceGrant + listKind: ReferenceGrantList + plural: referencegrants + shortNames: + - refgrant + singular: referencegrant + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated + and will be removed in a future release of the API. Please upgrade to v1beta1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + A ReferenceGrant is required for all cross-namespace references in Gateway API + (with the exception of cross-namespace Route-Gateway attachment, which is + governed by the AllowedRoutes configuration on the Gateway, and cross-namespace + Service ParentRefs on a "consumer" mesh Route, which defines routing rules + applicable only to workloads in the Route namespace). ReferenceGrants allowing + a reference from a Route to a Service are only applicable to BackendRefs. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core + items: + description: ReferenceGrantFrom describes trusted namespaces and + kinds. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core + items: + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * 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 + refers to all resources of the specified Group and Kind in the local + namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: false + storage: false + subresources: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + + All cross-namespace references in Gateway API (with the exception of cross-namespace + Gateway-route attachment) require a ReferenceGrant. + + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + + Support: Core + items: + description: ReferenceGrantFrom describes trusted namespaces and + kinds. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field. + + + When used to permit a SecretObjectReference: + + + * Gateway + + + When used to permit a BackendObjectReference: + + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * 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. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + + Support: Core + items: + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + + Support: 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 + additional resources, the following types are part of the "Core" + support level for this field: + + + * Secret when used to permit a SecretObjectReference + * 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 + refers to all resources of the specified Group and Kind in the local + namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/kubespray/project/roles/kubernetes-apps/helm/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/helm/tasks/main.yml index eae0e21..5951381 100644 --- a/kubespray/project/roles/kubernetes-apps/helm/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/helm/tasks/main.yml @@ -32,18 +32,18 @@ copy: src: "{{ local_release_dir }}/helm-{{ helm_version }}/linux-{{ image_arch }}/helm" dest: "{{ bin_dir }}/helm" - mode: 0755 + mode: "0755" remote_src: true - name: Helm | Get helm completion command: "{{ bin_dir }}/helm completion bash" - changed_when: False + changed_when: false register: helm_completion - check_mode: False + check_mode: false - name: Helm | Install helm completion copy: dest: /etc/bash_completion.d/helm.sh content: "{{ helm_completion.stdout }}" - mode: 0755 - become: True + mode: "0755" + become: true diff --git a/kubespray/project/roles/kubernetes-apps/helm/tasks/pyyaml-flatcar.yml b/kubespray/project/roles/kubernetes-apps/helm/tasks/pyyaml-flatcar.yml index ea0d63a..72f0e21 100644 --- a/kubespray/project/roles/kubernetes-apps/helm/tasks/pyyaml-flatcar.yml +++ b/kubespray/project/roles/kubernetes-apps/helm/tasks/pyyaml-flatcar.yml @@ -2,13 +2,13 @@ - name: Get installed pip version command: "{{ ansible_python_interpreter if ansible_python_interpreter is defined else 'python' }} -m pip --version" register: pip_version_output - ignore_errors: yes + ignore_errors: true changed_when: false - name: Get installed PyYAML version command: "{{ ansible_python_interpreter if ansible_python_interpreter is defined else 'python' }} -m pip show PyYAML" register: pyyaml_version_output - ignore_errors: yes + ignore_errors: true changed_when: false - name: Install pip diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/tasks/main.yml index 8a188a4..4514877 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/tasks/main.yml @@ -6,13 +6,13 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" - name: ALB Ingress Controller | Create manifests template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/alb_ingress/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: alb-ingress-clusterrole, file: alb-ingress-clusterrole.yml, type: clusterrole } - { name: alb-ingress-clusterrolebinding, file: alb-ingress-clusterrolebinding.yml, type: clusterrolebinding } diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml index 4af64ad..8012e77 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml @@ -24,7 +24,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -38,7 +38,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/cert_manager/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ cert_manager_templates }}" register: cert_manager_manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager.crds.yml.j2 b/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager.crds.yml.j2 index ec96dbb..df18a7d 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager.crds.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager.crds.yml.j2 @@ -226,10 +226,10 @@ spec: - subscriptionID properties: clientID: - description: if both this and ClientSecret are left unset MSI will be used + description: 'Auth: Azure Service Principal: The ClientID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientSecret and TenantID must also be set.' type: string clientSecretSecretRef: - description: if both this and ClientID are left unset MSI will be used + description: 'Auth: Azure Service Principal: A reference to a Secret containing the password associated with the Service Principal. If set, ClientID and TenantID must also be set.' type: object required: - name @@ -252,14 +252,14 @@ spec: description: name of the DNS zone that should be used type: string managedIdentity: - description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + description: 'Auth: Azure Workload Identity or Azure Managed Service Identity: Settings to enable Azure Workload Identity or Azure Managed Service Identity If set, ClientID, ClientSecret and TenantID must not be set.' type: object properties: clientID: description: client ID of the managed identity, can not be used at the same time as resourceID type: string resourceID: - description: resource ID of the managed identity, can not be used at the same time as clientID + description: resource ID of the managed identity, can not be used at the same time as clientID Cannot be used for Azure Managed Service Identity type: string resourceGroupName: description: resource group the DNS zone is located in @@ -268,7 +268,7 @@ spec: description: ID of the Azure subscription type: string tenantID: - description: when specifying ClientID and ClientSecret then this field is also needed + description: 'Auth: Azure Service Principal: The TenantID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientID and ClientSecret must also be set.' type: string cloudDNS: description: Use the Google Cloud DNS API to manage DNS01 challenge records. @@ -474,13 +474,13 @@ spec: maxLength: 253 minLength: 1 namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" type: string maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " type: integer format: int32 maximum: 65535 @@ -694,7 +694,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -724,6 +724,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -777,7 +789,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -807,6 +819,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -867,7 +891,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -897,6 +921,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -950,7 +986,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -980,6 +1016,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -1097,6 +1145,11 @@ spec: type: array items: type: string + issuingCertificateURLs: + description: IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details. As an example, such a URL might be "http://ca.domain.com/ca.crt". + type: array + items: + type: string ocspServers: description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". type: array @@ -1507,10 +1560,10 @@ spec: - subscriptionID properties: clientID: - description: if both this and ClientSecret are left unset MSI will be used + description: 'Auth: Azure Service Principal: The ClientID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientSecret and TenantID must also be set.' type: string clientSecretSecretRef: - description: if both this and ClientID are left unset MSI will be used + description: 'Auth: Azure Service Principal: A reference to a Secret containing the password associated with the Service Principal. If set, ClientID and TenantID must also be set.' type: object required: - name @@ -1533,14 +1586,14 @@ spec: description: name of the DNS zone that should be used type: string managedIdentity: - description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + description: 'Auth: Azure Workload Identity or Azure Managed Service Identity: Settings to enable Azure Workload Identity or Azure Managed Service Identity If set, ClientID, ClientSecret and TenantID must not be set.' type: object properties: clientID: description: client ID of the managed identity, can not be used at the same time as resourceID type: string resourceID: - description: resource ID of the managed identity, can not be used at the same time as clientID + description: resource ID of the managed identity, can not be used at the same time as clientID Cannot be used for Azure Managed Service Identity type: string resourceGroupName: description: resource group the DNS zone is located in @@ -1549,7 +1602,7 @@ spec: description: ID of the Azure subscription type: string tenantID: - description: when specifying ClientID and ClientSecret then this field is also needed + description: 'Auth: Azure Service Principal: The TenantID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientID and ClientSecret must also be set.' type: string cloudDNS: description: Use the Google Cloud DNS API to manage DNS01 challenge records. @@ -1755,13 +1808,13 @@ spec: maxLength: 253 minLength: 1 namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" type: string maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " type: integer format: int32 maximum: 65535 @@ -1975,7 +2028,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -2005,6 +2058,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -2058,7 +2123,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -2088,6 +2153,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -2148,7 +2225,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -2178,6 +2255,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -2231,7 +2320,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -2261,6 +2350,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -2822,10 +2923,10 @@ spec: - subscriptionID properties: clientID: - description: if both this and ClientSecret are left unset MSI will be used + description: 'Auth: Azure Service Principal: The ClientID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientSecret and TenantID must also be set.' type: string clientSecretSecretRef: - description: if both this and ClientID are left unset MSI will be used + description: 'Auth: Azure Service Principal: A reference to a Secret containing the password associated with the Service Principal. If set, ClientID and TenantID must also be set.' type: object required: - name @@ -2848,14 +2949,14 @@ spec: description: name of the DNS zone that should be used type: string managedIdentity: - description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + description: 'Auth: Azure Workload Identity or Azure Managed Service Identity: Settings to enable Azure Workload Identity or Azure Managed Service Identity If set, ClientID, ClientSecret and TenantID must not be set.' type: object properties: clientID: description: client ID of the managed identity, can not be used at the same time as resourceID type: string resourceID: - description: resource ID of the managed identity, can not be used at the same time as clientID + description: resource ID of the managed identity, can not be used at the same time as clientID Cannot be used for Azure Managed Service Identity type: string resourceGroupName: description: resource group the DNS zone is located in @@ -2864,7 +2965,7 @@ spec: description: ID of the Azure subscription type: string tenantID: - description: when specifying ClientID and ClientSecret then this field is also needed + description: 'Auth: Azure Service Principal: The TenantID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientID and ClientSecret must also be set.' type: string cloudDNS: description: Use the Google Cloud DNS API to manage DNS01 challenge records. @@ -3070,13 +3171,13 @@ spec: maxLength: 253 minLength: 1 namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" type: string maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " type: integer format: int32 maximum: 65535 @@ -3290,7 +3391,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -3320,6 +3421,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -3373,7 +3486,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -3403,6 +3516,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -3463,7 +3588,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -3493,6 +3618,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -3546,7 +3683,7 @@ spec: - topologyKey properties: labelSelector: - description: A label query over a set of resources, in this case pods. + description: A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods. type: object properties: matchExpressions: @@ -3576,6 +3713,18 @@ spec: additionalProperties: type: string x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + type: array + items: + type: string + x-kubernetes-list-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. type: object @@ -3693,6 +3842,11 @@ spec: type: array items: type: string + issuingCertificateURLs: + description: IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details. As an example, such a URL might be "http://ca.domain.com/ca.crt". + type: array + items: + type: string ocspServers: description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". type: array @@ -4100,9 +4254,83 @@ spec: name: description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string + profile: + description: "Profile specifies the key and certificate encryption algorithms and the HMAC algorithm used to create the PKCS12 keystore. Default value is `LegacyRC2` for backward compatibility. \n If provided, allowed values are: `LegacyRC2`: Deprecated. Not supported by default in OpenSSL 3 or Java 20. `LegacyDES`: Less secure algorithm. Use this option for maximal compatibility. `Modern2023`: Secure algorithm. Use this option in case you have to always use secure algorithms (eg. because of company policy). Please note that the security of the algorithm is not that important in reality, because the unencrypted certificate and private key are also stored in the Secret." + type: string + enum: + - LegacyRC2 + - LegacyDES + - Modern2023 literalSubject: description: "Requested X.509 certificate subject, represented using the LDAP \"String Representation of a Distinguished Name\" [1]. Important: the LDAP string format also specifies the order of the attributes in the subject, this is important when issuing certs for LDAP authentication. Example: `CN=foo,DC=corp,DC=example,DC=com` More info [1]: https://datatracker.ietf.org/doc/html/rfc4514 More info: https://github.com/cert-manager/cert-manager/issues/3203 More info: https://github.com/cert-manager/cert-manager/issues/4424 \n Cannot be set if the `subject` or `commonName` field is set. This is an Alpha Feature and is only enabled with the `--feature-gates=LiteralCertificateSubject=true` option set on both the controller and webhook components." type: string + nameConstraints: + description: "x.509 certificate NameConstraint extension which MUST NOT be used in a non-CA certificate. More Info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10 \n This is an Alpha Feature and is only enabled with the `--feature-gates=NameConstraints=true` option set on both the controller and webhook components." + type: object + properties: + critical: + description: if true then the name constraints are marked critical. + type: boolean + excluded: + description: Excluded contains the constraints which must be disallowed. Any name matching a restriction in the excluded field is invalid regardless of information appearing in the permitted + type: object + properties: + dnsDomains: + description: DNSDomains is a list of DNS domains that are permitted or excluded. + type: array + items: + type: string + emailAddresses: + description: EmailAddresses is a list of Email Addresses that are permitted or excluded. + type: array + items: + type: string + ipRanges: + description: IPRanges is a list of IP Ranges that are permitted or excluded. This should be a valid CIDR notation. + type: array + items: + type: string + uriDomains: + description: URIDomains is a list of URI domains that are permitted or excluded. + type: array + items: + type: string + permitted: + description: Permitted contains the constraints in which the names must be located. + type: object + properties: + dnsDomains: + description: DNSDomains is a list of DNS domains that are permitted or excluded. + type: array + items: + type: string + emailAddresses: + description: EmailAddresses is a list of Email Addresses that are permitted or excluded. + type: array + items: + type: string + ipRanges: + description: IPRanges is a list of IP Ranges that are permitted or excluded. This should be a valid CIDR notation. + type: array + items: + type: string + uriDomains: + description: URIDomains is a list of URI domains that are permitted or excluded. + type: array + items: + type: string + otherNames: + description: '`otherNames` is an escape hatch for SAN that allows any type. We currently restrict the support to string like otherNames, cf RFC 5280 p 37 Any UTF8 String valued otherName can be passed with by setting the keys oid: x.x.x.x and UTF8Value: somevalue for `otherName`. Most commonly this would be UPN set with oid: 1.3.6.1.4.1.311.20.2.3 You should ensure that any OID passed is valid for the UTF8String type as we do not explicitly validate this.' + type: array + items: + type: object + properties: + oid: + description: OID is the object identifier for the otherName SAN. The object identifier must be expressed as a dotted string, for example, "1.2.840.113556.1.4.221". + type: string + utf8Value: + description: utf8Value is the string value of the otherName SAN. The utf8Value accepts any valid UTF8 string to set as value for the otherName SAN. + type: string privateKey: description: Private key options. These include the key algorithm and size, the used encoding and the rotation policy. type: object diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml index c83c8c3..8294302 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml @@ -2,6 +2,8 @@ ingress_nginx_namespace: "ingress-nginx" ingress_nginx_host_network: false ingress_nginx_service_type: LoadBalancer +ingress_nginx_service_nodeport_http: "" +ingress_nginx_service_nodeport_https: "" ingress_publish_status_address: "" ingress_nginx_nodeselector: kubernetes.io/os: "linux" @@ -19,5 +21,6 @@ ingress_nginx_without_class: true ingress_nginx_default: false ingress_nginx_webhook_enabled: false ingress_nginx_webhook_job_ttl: 1800 +ingress_nginx_opentelemetry_enabled: false ingress_nginx_probe_initial_delay_seconds: 10 diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/tasks/main.yml index ac64c82..be26060 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/tasks/main.yml @@ -6,7 +6,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -34,6 +34,7 @@ - { name: role-admission-webhook, file: role-admission-webhook.yml, type: role } - { name: rolebinding-admission-webhook, file: rolebinding-admission-webhook.yml, type: rolebinding } - { name: admission-webhook-job, file: admission-webhook-job.yml, type: job } + - { name: svc-ingress-nginx-controller-admission, file: svc-ingress-nginx-controller-admission.yml, type: svc } - name: NGINX Ingress Controller | Append extra templates to NGINX Ingress Template list for service set_fact: @@ -49,7 +50,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/ingress_nginx/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ ingress_nginx_templates }}" register: ingress_nginx_manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ds-ingress-nginx-controller.yml.j2 b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ds-ingress-nginx-controller.yml.j2 index 7f41935..c7657b6 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ds-ingress-nginx-controller.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ds-ingress-nginx-controller.yml.j2 @@ -23,6 +23,26 @@ spec: spec: serviceAccountName: ingress-nginx terminationGracePeriodSeconds: {{ ingress_nginx_termination_grace_period_seconds }} +{% if ingress_nginx_opentelemetry_enabled %} + initContainers: + - name: opentelemetry + command: + - /init_module + image: {{ ingress_nginx_opentelemetry_image_repo }}:{{ ingress_nginx_opentelemetry_image_tag }} + securityContext: + runAsNonRoot: true + runAsUser: 65532 + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /modules_mount + name: modules +{% endif %} {% if ingress_nginx_host_network %} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet @@ -127,15 +147,27 @@ spec: timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3 -{% if ingress_nginx_webhook_enabled %} +{% if ingress_nginx_webhook_enabled or ingress_nginx_opentelemetry_enabled %} volumeMounts: +{% if ingress_nginx_webhook_enabled %} - mountPath: /usr/local/certificates/ name: webhook-cert readOnly: true {% endif %} -{% if ingress_nginx_webhook_enabled %} +{% if ingress_nginx_opentelemetry_enabled %} + - name: modules + mountPath: /modules_mount +{% endif %} +{% endif %} +{% if ingress_nginx_webhook_enabled or ingress_nginx_opentelemetry_enabled %} volumes: +{% if ingress_nginx_webhook_enabled %} - name: webhook-cert secret: secretName: ingress-nginx-admission {% endif %} +{% if ingress_nginx_opentelemetry_enabled %} + - name: modules + emptyDir: {} +{% endif %} +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx-controller-admission.yml.j2 b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx-controller-admission.yml.j2 new file mode 100644 index 0000000..e22c8e5 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx-controller-admission.yml.j2 @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + name: ingress-nginx-controller-admission + namespace: {{ ingress_nginx_namespace }} +spec: + type: ClusterIP + ports: + - appProtocol: https + name: https-webhook + port: 443 + targetPort: webhook + selector: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx diff --git a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx.yml.j2 b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx.yml.j2 index 115232f..072b989 100644 --- a/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/svc-ingress-nginx.yml.j2 @@ -14,11 +14,17 @@ spec: port: 80 targetPort: 80 protocol: TCP +{% if (ingress_nginx_service_type == 'NodePort' or ingress_nginx_service_type == 'LoadBalancer') and ingress_nginx_service_nodeport_http %} + nodePort: {{ingress_nginx_service_nodeport_http | int}} +{% endif %} - name: https port: 443 targetPort: 443 protocol: TCP +{% if (ingress_nginx_service_type == 'NodePort' or ingress_nginx_service_type == 'LoadBalancer') and ingress_nginx_service_nodeport_https %} + nodePort: {{ingress_nginx_service_nodeport_https | int}} +{% endif %} selector: app.kubernetes.io/name: ingress-nginx - app.kubernetes.io/port-of: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx {% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/krew/tasks/krew.yml b/kubespray/project/roles/kubernetes-apps/krew/tasks/krew.yml index a8b5201..3308aef 100644 --- a/kubespray/project/roles/kubernetes-apps/krew/tasks/krew.yml +++ b/kubespray/project/roles/kubernetes-apps/krew/tasks/krew.yml @@ -8,13 +8,13 @@ template: src: krew.j2 dest: /etc/bash_completion.d/krew - mode: 0644 + mode: "0644" - name: Krew | Copy krew manifest template: src: krew.yml.j2 dest: "{{ local_release_dir }}/krew.yml" - mode: 0644 + mode: "0644" - name: Krew | Install krew # noqa command-instead-of-shell shell: "{{ local_release_dir }}/krew-{{ host_os }}_{{ image_arch }} install --archive={{ local_release_dir }}/krew-{{ host_os }}_{{ image_arch }}.tar.gz --manifest={{ local_release_dir }}/krew.yml" @@ -24,15 +24,15 @@ - name: Krew | Get krew completion command: "{{ local_release_dir }}/krew-{{ host_os }}_{{ image_arch }} completion bash" - changed_when: False + changed_when: false register: krew_completion - check_mode: False - ignore_errors: yes # noqa ignore-errors + check_mode: false + ignore_errors: true # noqa ignore-errors - name: Krew | Install krew completion copy: dest: /etc/bash_completion.d/krew.sh content: "{{ krew_completion.stdout }}" - mode: 0755 - become: True + mode: "0755" + become: true when: krew_completion.rc == 0 diff --git a/kubespray/project/roles/kubernetes-apps/kubelet-csr-approver/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/kubelet-csr-approver/defaults/main.yml index 2edce70..26347cf 100644 --- a/kubespray/project/roles/kubernetes-apps/kubelet-csr-approver/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/kubelet-csr-approver/defaults/main.yml @@ -5,7 +5,7 @@ kubelet_csr_approver_namespace: kube-system kubelet_csr_approver_repository_name: kubelet-csr-approver kubelet_csr_approver_repository_url: https://postfinance.github.io/kubelet-csr-approver kubelet_csr_approver_chart_ref: "{{ kubelet_csr_approver_repository_name }}/kubelet-csr-approver" -kubelet_csr_approver_chart_version: 0.2.8 +kubelet_csr_approver_chart_version: 1.1.0 # Fill values override here # See upstream https://github.com/postfinance/kubelet-csr-approver diff --git a/kubespray/project/roles/kubernetes-apps/meta/main.yml b/kubespray/project/roles/kubernetes-apps/meta/main.yml index 1b9cd6b..37bd109 100644 --- a/kubespray/project/roles/kubernetes-apps/meta/main.yml +++ b/kubespray/project/roles/kubernetes-apps/meta/main.yml @@ -111,6 +111,13 @@ dependencies: tags: - oci + - role: kubernetes-apps/gateway_api + when: + - gateway_api_enabled + - inventory_hostname == groups['kube_control_plane'][0] + tags: + - gateway_api + - role: kubernetes-apps/metallb when: - metallb_enabled @@ -128,7 +135,14 @@ dependencies: - role: kubernetes-apps/scheduler_plugins when: - scheduler_plugins_enabled - - kube_major_version is version('v1.28', '<') + - kube_major_version is version('v1.29', '<') - inventory_hostname == groups['kube_control_plane'][0] tags: - scheduler_plugins + + - role: kubernetes-apps/node_feature_discovery + when: + - node_feature_discovery_enabled + - inventory_hostname == groups['kube_control_plane'][0] + tags: + - node_feature_discovery diff --git a/kubespray/project/roles/kubernetes-apps/metallb/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/metallb/defaults/main.yml index 02f4e3c..c83b293 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/metallb/defaults/main.yml @@ -13,4 +13,4 @@ metallb_speaker_tolerations: key: node-role.kubernetes.io/control-plane operator: Exists metallb_controller_tolerations: [] -metallb_loadbalancer_class: "" \ No newline at end of file +metallb_loadbalancer_class: "" diff --git a/kubespray/project/roles/kubernetes-apps/metallb/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/metallb/tasks/main.yml index 221fe3c..5e6757b 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/metallb/tasks/main.yml @@ -16,7 +16,7 @@ template: src: "metallb.yaml.j2" dest: "{{ kube_config_dir }}/metallb.yaml" - mode: 0644 + mode: "0644" register: metallb_rendering when: - inventory_hostname == groups['kube_control_plane'][0] @@ -33,7 +33,7 @@ - inventory_hostname == groups['kube_control_plane'][0] - name: Kubernetes Apps | Wait for MetalLB controller to be running - command: "{{ bin_dir }}/kubectl rollout status -n metallb-system deployment -l app=metallb,component=controller --timeout=2m" + command: "{{ bin_dir }}/kubectl rollout status -n {{ metallb_namespace }} deployment -l app=metallb,component=controller --timeout=2m" become: true when: - inventory_hostname == groups['kube_control_plane'][0] @@ -47,7 +47,7 @@ ansible.builtin.template: src: pools.yaml.j2 dest: "{{ kube_config_dir }}/pools.yaml" - mode: 0644 + mode: "0644" register: pools_rendering - name: MetalLB | Create address pools configuration @@ -67,7 +67,7 @@ ansible.builtin.template: src: layer2.yaml.j2 dest: "{{ kube_config_dir }}/layer2.yaml" - mode: 0644 + mode: "0644" register: layer2_rendering - name: MetalLB | Create layer2 configuration @@ -87,7 +87,7 @@ ansible.builtin.template: src: layer3.yaml.j2 dest: "{{ kube_config_dir }}/layer3.yaml" - mode: 0644 + mode: "0644" register: layer3_rendering - name: MetalLB | Create layer3 configuration @@ -104,5 +104,5 @@ name: config kubectl: "{{ bin_dir }}/kubectl" resource: ConfigMap - namespace: metallb-system + namespace: "{{ metallb_namespace }}" state: absent diff --git a/kubespray/project/roles/kubernetes-apps/metallb/templates/layer2.yaml.j2 b/kubespray/project/roles/kubernetes-apps/metallb/templates/layer2.yaml.j2 index d249732..e3fdb19 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/templates/layer2.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/metallb/templates/layer2.yaml.j2 @@ -11,7 +11,7 @@ apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: "{{ entry }}" - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: ipAddressPools: - "{{ entry }}" diff --git a/kubespray/project/roles/kubernetes-apps/metallb/templates/layer3.yaml.j2 b/kubespray/project/roles/kubernetes-apps/metallb/templates/layer3.yaml.j2 index 490bae2..b32c194 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/templates/layer3.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/metallb/templates/layer3.yaml.j2 @@ -9,7 +9,7 @@ apiVersion: metallb.io/v1beta1 kind: Community metadata: name: "{{ community_name }}" - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: communities: - name: "{{ community_name }}" @@ -21,7 +21,7 @@ apiVersion: metallb.io/v1beta1 kind: Community metadata: name: well-known - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: communities: - name: no-export @@ -51,7 +51,7 @@ apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: "{{ peer_name }}-local" - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: aggregationLength: 32 aggregationLengthV6: 128 @@ -70,7 +70,7 @@ apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: "{{ peer_name }}-external" - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: {% if peer.aggregation_length is defined and peer.aggregation_length <= 30 %} aggregationLength: {{ peer.aggregation_length }} @@ -93,7 +93,7 @@ apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: "{{ peer_name }}" - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: myASN: {{ peer.my_asn }} peerASN: {{ peer.peer_asn }} diff --git a/kubespray/project/roles/kubernetes-apps/metallb/templates/metallb.yaml.j2 b/kubespray/project/roles/kubernetes-apps/metallb/templates/metallb.yaml.j2 index af18a10..ebdea51 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/templates/metallb.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/metallb/templates/metallb.yaml.j2 @@ -6,7 +6,7 @@ metadata: pod-security.kubernetes.io/audit: privileged pod-security.kubernetes.io/enforce: privileged pod-security.kubernetes.io/warn: privileged - name: metallb-system + name: {{ metallb_namespace }} --- apiVersion: apiextensions.k8s.io/v1 @@ -23,7 +23,7 @@ spec: caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /convert conversionReviewVersions: - v1alpha1 @@ -544,7 +544,7 @@ spec: caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /convert conversionReviewVersions: - v1beta1 @@ -1291,7 +1291,7 @@ metadata: pod-security.kubernetes.io/enforce: privileged pod-security.kubernetes.io/warn: privileged name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" {% if metallb_speaker_enabled %} --- @@ -1301,7 +1301,7 @@ metadata: labels: app: metallb name: speaker - namespace: metallb-system + namespace: "{{ metallb_namespace }}" {% endif %} --- apiVersion: rbac.authorization.k8s.io/v1 @@ -1310,7 +1310,7 @@ metadata: labels: app: metallb name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" rules: - apiGroups: - "" @@ -1402,7 +1402,7 @@ metadata: labels: app: metallb name: pod-lister - namespace: metallb-system + namespace: "{{ metallb_namespace }}" rules: - apiGroups: - "" @@ -1480,7 +1480,7 @@ kind: ClusterRole metadata: labels: app: metallb - name: metallb-system:controller + name: {{ metallb_namespace }}:controller rules: - apiGroups: - "" @@ -1561,7 +1561,7 @@ kind: ClusterRole metadata: labels: app: metallb - name: metallb-system:speaker + name: {{ metallb_namespace }}:speaker rules: - apiGroups: - "" @@ -1598,7 +1598,7 @@ metadata: labels: app: metallb name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" roleRef: apiGroup: rbac.authorization.k8s.io kind: Role @@ -1606,7 +1606,7 @@ roleRef: subjects: - kind: ServiceAccount name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" --- apiVersion: rbac.authorization.k8s.io/v1 @@ -1615,7 +1615,7 @@ metadata: labels: app: metallb name: pod-lister - namespace: metallb-system + namespace: "{{ metallb_namespace }}" roleRef: apiGroup: rbac.authorization.k8s.io kind: Role @@ -1623,7 +1623,7 @@ roleRef: subjects: - kind: ServiceAccount name: speaker - namespace: metallb-system + namespace: "{{ metallb_namespace }}" --- apiVersion: rbac.authorization.k8s.io/v1 @@ -1631,15 +1631,15 @@ kind: ClusterRoleBinding metadata: labels: app: metallb - name: metallb-system:controller + name: {{ metallb_namespace }}:controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: metallb-system:controller + name: {{ metallb_namespace }}:controller subjects: - kind: ServiceAccount name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" {% if metallb_speaker_enabled %} --- @@ -1648,15 +1648,15 @@ kind: ClusterRoleBinding metadata: labels: app: metallb - name: metallb-system:speaker + name: {{ metallb_namespace }}:speaker roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: metallb-system:speaker + name: {{ metallb_namespace }}:speaker subjects: - kind: ServiceAccount name: speaker - namespace: metallb-system + namespace: "{{ metallb_namespace }}" {% endif %} --- @@ -1664,14 +1664,14 @@ apiVersion: v1 kind: Secret metadata: name: webhook-server-cert - namespace: metallb-system + namespace: "{{ metallb_namespace }}" --- apiVersion: v1 kind: Service metadata: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: ports: - port: 443 @@ -1687,7 +1687,7 @@ metadata: app: metallb component: controller name: controller - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: revisionHistoryLimit: 3 selector: @@ -1782,7 +1782,7 @@ metadata: app: metallb component: speaker name: speaker - namespace: metallb-system + namespace: "{{ metallb_namespace }}" spec: selector: matchLabels: @@ -1888,7 +1888,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta2-bgppeer failurePolicy: Fail name: bgppeersvalidationwebhook.metallb.io @@ -1908,7 +1908,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-addresspool failurePolicy: Fail name: addresspoolvalidationwebhook.metallb.io @@ -1928,7 +1928,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-bfdprofile failurePolicy: Fail name: bfdprofilevalidationwebhook.metallb.io @@ -1948,7 +1948,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-bgpadvertisement failurePolicy: Fail name: bgpadvertisementvalidationwebhook.metallb.io @@ -1968,7 +1968,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-community failurePolicy: Fail name: communityvalidationwebhook.metallb.io @@ -1988,7 +1988,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-ipaddresspool failurePolicy: Fail name: ipaddresspoolvalidationwebhook.metallb.io @@ -2008,7 +2008,7 @@ webhooks: clientConfig: service: name: webhook-service - namespace: metallb-system + namespace: "{{ metallb_namespace }}" path: /validate-metallb-io-v1beta1-l2advertisement failurePolicy: Fail name: l2advertisementvalidationwebhook.metallb.io diff --git a/kubespray/project/roles/kubernetes-apps/metallb/templates/pools.yaml.j2 b/kubespray/project/roles/kubernetes-apps/metallb/templates/pools.yaml.j2 index f22a4e3..42cc6ec 100644 --- a/kubespray/project/roles/kubernetes-apps/metallb/templates/pools.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/metallb/templates/pools.yaml.j2 @@ -9,7 +9,7 @@ apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: - namespace: metallb-system + namespace: "{{ metallb_namespace }}" name: "{{ pool_name }}" spec: addresses: diff --git a/kubespray/project/roles/kubernetes-apps/metrics_server/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/metrics_server/tasks/main.yml index 1fe617d..3517686 100644 --- a/kubespray/project/roles/kubernetes-apps/metrics_server/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/metrics_server/tasks/main.yml @@ -19,7 +19,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] @@ -39,7 +39,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/metrics_server/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ metrics_server_templates }}" register: metrics_server_manifests when: diff --git a/kubespray/project/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml index fdbede5..54dd1ed 100644 --- a/kubespray/project/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml @@ -9,7 +9,7 @@ state: "latest" delegate_to: "{{ groups['kube_control_plane'][0] }}" run_once: true - with_items: "{{ multus_manifest_1.results + (multus_nodes_list | map('extract', hostvars, 'multus_manifest_2') | list | json_query('[].results')) }}" + with_items: "{{ (multus_manifest_1.results | default([])) + (multus_nodes_list | map('extract', hostvars, 'multus_manifest_2.results') | default([]) | list) }}" loop_control: label: "{{ item.item.name if item != None else 'skipped' }}" vars: diff --git a/kubespray/project/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml index bc0f932..587b652 100644 --- a/kubespray/project/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml @@ -13,7 +13,7 @@ - name: Weave | Wait for Weave to become available uri: url: http://127.0.0.1:6784/status - return_content: yes + return_content: true register: weave_status retries: 180 delay: 5 diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/defaults/main.yml new file mode 100644 index 0000000..19f09ca --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/defaults/main.yml @@ -0,0 +1,16 @@ +--- +node_feature_discovery_enabled: false +node_feature_discovery_namespace: node-feature-discovery +node_feature_discovery_enable_nodefeature_api: true +node_feature_discovery_gc_replicas: 1 +node_feature_discovery_gc_interval: 1h +node_feature_discovery_gc_sa_name: node-feature-discovery-gc +node_feature_discovery_gc_sa_create: true +node_feature_discovery_master_replicas: 1 +node_feature_discovery_master_crd_controller: null +node_feature_discovery_master_instance: null +node_feature_discovery_master_config: null +node_feature_discovery_worker_sa_name: node-feature-discovery-worker +node_feature_discovery_worker_sa_create: true +node_feature_discovery_worker_config: null +node_feature_discovery_worker_tolerations: null diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/tasks/main.yml new file mode 100644 index 0000000..eb2237a --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/tasks/main.yml @@ -0,0 +1,49 @@ +--- +- name: Node Feature Discovery | Create addon dir + file: + path: "{{ kube_config_dir }}/addons/node_feature_discovery" + state: directory + owner: root + group: root + mode: "0755" + when: + - inventory_hostname == groups['kube_control_plane'][0] + +- name: Node Feature Discovery | Templates list + set_fact: + node_feature_discovery_templates: + - { name: nfd-ns, file: nfd-ns.yaml, type: ns } + - { name: nfd-api-crd, file: nfd-api-crds.yaml, type: crd } + - { name: nfd-serviceaccount, file: nfd-serviceaccount.yaml, type: sa } + - { name: nfd-role, file: nfd-role.yaml, type: role } + - { name: nfd-clusterrole, file: nfd-clusterrole.yaml, type: clusterrole } + - { name: nfd-rolebinding, file: nfd-rolebinding.yaml, type: rolebinding } + - { name: nfd-clusterrolebinding, file: nfd-clusterrolebinding.yaml, type: clusterrolebinding } + - { name: nfd-master-conf, file: nfd-master-conf.yaml, type: cm } + - { name: nfd-worker-conf, file: nfd-worker-conf.yaml, type: cm } + - { name: nfd-topologyupdater-conf, file: nfd-topologyupdater-conf.yaml, type: cm } + - { name: nfd-gc, file: nfd-gc.yaml, type: deploy } + - { name: nfd-master, file: nfd-master.yaml, type: deploy } + - { name: nfd-worker, file: nfd-worker.yaml, type: ds } + - { name: nfd-service, file: nfd-service.yaml, type: srv } + +- name: Node Feature Discovery | Create manifests + template: + src: "{{ item.file }}.j2" + dest: "{{ kube_config_dir }}/addons/node_feature_discovery/{{ item.file }}" + mode: "0644" + with_items: "{{ node_feature_discovery_templates }}" + register: node_feature_discovery_manifests + when: + - inventory_hostname == groups['kube_control_plane'][0] + +- name: Node Feature Discovery | Apply manifests + kube: + name: "{{ item.item.name }}" + kubectl: "{{ bin_dir }}/kubectl" + resource: "{{ item.item.type }}" + filename: "{{ kube_config_dir }}/addons/node_feature_discovery/{{ item.item.file }}" + state: "latest" + with_items: "{{ node_feature_discovery_manifests.results }}" + when: + - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-api-crds.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-api-crds.yaml.j2 new file mode 100644 index 0000000..0a73c5d --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-api-crds.yaml.j2 @@ -0,0 +1,710 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: nodefeatures.nfd.k8s-sigs.io +spec: + group: nfd.k8s-sigs.io + names: + kind: NodeFeature + listKind: NodeFeatureList + plural: nodefeatures + singular: nodefeature + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + NodeFeature resource holds the features discovered for one node in the + cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the NodeFeature, containing features discovered + for a node. + properties: + features: + description: Features is the full "raw" features data that has been + discovered. + properties: + attributes: + additionalProperties: + description: AttributeFeatureSet is a set of features having + string value. + properties: + elements: + additionalProperties: + type: string + description: Individual features of the feature set. + type: object + required: + - elements + type: object + description: Attributes contains all the attribute-type features + of the node. + type: object + flags: + additionalProperties: + description: FlagFeatureSet is a set of simple features only + containing names without values. + properties: + elements: + additionalProperties: + description: Nil is a dummy empty struct for protobuf + compatibility + type: object + description: Individual features of the feature set. + type: object + required: + - elements + type: object + description: Flags contains all the flag-type features of the + node. + type: object + instances: + additionalProperties: + description: InstanceFeatureSet is a set of features each of + which is an instance having multiple attributes. + properties: + elements: + description: Individual features of the feature set. + items: + description: InstanceFeature represents one instance of + a complex features, e.g. a device. + properties: + attributes: + additionalProperties: + type: string + description: Attributes of the instance feature. + type: object + required: + - attributes + type: object + type: array + required: + - elements + type: object + description: Instances contains all the instance-type features + of the node. + type: object + type: object + labels: + additionalProperties: + type: string + description: Labels is the set of node labels that are requested to + be created. + type: object + type: object + required: + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: nodefeaturegroups.nfd.k8s-sigs.io +spec: + group: nfd.k8s-sigs.io + names: + kind: NodeFeatureGroup + listKind: NodeFeatureGroupList + plural: nodefeaturegroups + shortNames: + - nfg + singular: nodefeaturegroup + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeFeatureGroup resource holds Node pools by featureGroup + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 rules to be evaluated. + properties: + featureGroupRules: + description: List of rules to evaluate to determine nodes that belong + in this group. + items: + description: GroupRule defines a rule for nodegroup filtering. + properties: + matchAny: + description: MatchAny specifies a list of matchers one of which + must match. + items: + description: MatchAnyElem specifies one sub-matcher of MatchAny. + properties: + matchFeatures: + description: MatchFeatures specifies a set of matcher + terms all of which must match. + items: + description: |- + FeatureMatcherTerm defines requirements against one feature set. All + requirements (specified as MatchExpressions) are evaluated against each + element in the feature set. + properties: + feature: + description: Feature is the name of the feature + set to match against. + type: string + matchExpressions: + additionalProperties: + description: |- + MatchExpression specifies an expression to evaluate against a set of input + values. It contains an operator that is applied when matching the input and + an array of values that the operator evaluates the input against. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + description: |- + MatchExpressions is the set of per-element expressions evaluated. These + match against the value of the specified elements. + type: object + matchName: + description: |- + MatchName in an expression that is matched against the name of each + element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + required: + - feature + type: object + type: array + required: + - matchFeatures + type: object + type: array + matchFeatures: + description: MatchFeatures specifies a set of matcher terms + all of which must match. + items: + description: |- + FeatureMatcherTerm defines requirements against one feature set. All + requirements (specified as MatchExpressions) are evaluated against each + element in the feature set. + properties: + feature: + description: Feature is the name of the feature set to + match against. + type: string + matchExpressions: + additionalProperties: + description: |- + MatchExpression specifies an expression to evaluate against a set of input + values. It contains an operator that is applied when matching the input and + an array of values that the operator evaluates the input against. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + description: |- + MatchExpressions is the set of per-element expressions evaluated. These + match against the value of the specified elements. + type: object + matchName: + description: |- + MatchName in an expression that is matched against the name of each + element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + required: + - feature + type: object + type: array + name: + description: Name of the rule. + type: string + required: + - name + type: object + type: array + required: + - featureGroupRules + type: object + status: + description: |- + Status of the NodeFeatureGroup after the most recent evaluation of the + specification. + properties: + nodes: + description: Nodes is a list of FeatureGroupNode in the cluster that + match the featureGroupRules + items: + properties: + name: + description: Name of the node. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: nodefeaturerules.nfd.k8s-sigs.io +spec: + group: nfd.k8s-sigs.io + names: + kind: NodeFeatureRule + listKind: NodeFeatureRuleList + plural: nodefeaturerules + shortNames: + - nfr + singular: nodefeaturerule + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + NodeFeatureRule resource specifies a configuration for feature-based + customization of node objects, such as node labeling. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More 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. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More 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 rules to be evaluated. + properties: + rules: + description: Rules is a list of node customization rules. + items: + description: Rule defines a rule for node customization such as + labeling. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to create if the rule matches. + type: object + extendedResources: + additionalProperties: + type: string + description: ExtendedResources to create if the rule matches. + type: object + labels: + additionalProperties: + type: string + description: Labels to create if the rule matches. + type: object + labelsTemplate: + description: |- + LabelsTemplate specifies a template to expand for dynamically generating + multiple labels. Data (after template expansion) must be keys with an + optional value ([=]) separated by newlines. + type: string + matchAny: + description: MatchAny specifies a list of matchers one of which + must match. + items: + description: MatchAnyElem specifies one sub-matcher of MatchAny. + properties: + matchFeatures: + description: MatchFeatures specifies a set of matcher + terms all of which must match. + items: + description: |- + FeatureMatcherTerm defines requirements against one feature set. All + requirements (specified as MatchExpressions) are evaluated against each + element in the feature set. + properties: + feature: + description: Feature is the name of the feature + set to match against. + type: string + matchExpressions: + additionalProperties: + description: |- + MatchExpression specifies an expression to evaluate against a set of input + values. It contains an operator that is applied when matching the input and + an array of values that the operator evaluates the input against. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + description: |- + MatchExpressions is the set of per-element expressions evaluated. These + match against the value of the specified elements. + type: object + matchName: + description: |- + MatchName in an expression that is matched against the name of each + element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + required: + - feature + type: object + type: array + required: + - matchFeatures + type: object + type: array + matchFeatures: + description: MatchFeatures specifies a set of matcher terms + all of which must match. + items: + description: |- + FeatureMatcherTerm defines requirements against one feature set. All + requirements (specified as MatchExpressions) are evaluated against each + element in the feature set. + properties: + feature: + description: Feature is the name of the feature set to + match against. + type: string + matchExpressions: + additionalProperties: + description: |- + MatchExpression specifies an expression to evaluate against a set of input + values. It contains an operator that is applied when matching the input and + an array of values that the operator evaluates the input against. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + description: |- + MatchExpressions is the set of per-element expressions evaluated. These + match against the value of the specified elements. + type: object + matchName: + description: |- + MatchName in an expression that is matched against the name of each + element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: |- + Value is the list of values that the operand evaluates the input + against. Value should be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly one element if the + operator is Gt or Lt and exactly two elements if the operator is GtLt. + In other cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + required: + - feature + type: object + type: array + name: + description: Name of the rule. + type: string + taints: + description: Taints to create if the rule matches. + items: + description: |- + The node this Taint is attached to has the "effect" on + any pod that does not tolerate the Taint. + properties: + effect: + description: |- + Required. The effect of the taint on pods + that do not tolerate the taint. + Valid effects are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied to + a node. + type: string + timeAdded: + description: |- + TimeAdded represents the time at which the taint was added. + It is only written for NoExecute taints. + format: date-time + type: string + value: + description: The taint value corresponding to the taint + key. + type: string + required: + - effect + - key + type: object + type: array + vars: + additionalProperties: + type: string + description: |- + Vars is the variables to store if the rule matches. Variables do not + directly inflict any changes in the node object. However, they can be + referenced from other rules enabling more complex rule hierarchies, + without exposing intermediary output values as labels. + type: object + varsTemplate: + description: |- + VarsTemplate specifies a template to expand for dynamically generating + multiple variables. Data (after template expansion) must be keys with an + optional value ([=]) separated by newlines. + type: string + required: + - name + type: object + type: array + required: + - rules + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrole.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrole.yaml.j2 new file mode 100644 index 0000000..328b3e6 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrole.yaml.j2 @@ -0,0 +1,80 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: node-feature-discovery +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/status + verbs: + - get + - patch + - update + - list +- apiGroups: + - nfd.k8s-sigs.io + resources: + - nodefeatures + - nodefeaturerules + - nodefeaturegroups + verbs: + - get + - list + - watch +- apiGroups: + - nfd.k8s-sigs.io + resources: + - nodefeaturegroup/status + verbs: + - patch + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - "nfd-master.nfd.kubernetes.io" + verbs: + - get + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: node-feature-discovery-gc +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes/proxy + verbs: + - get +- apiGroups: + - topology.node.k8s.io + resources: + - noderesourcetopologies + verbs: + - delete + - list +- apiGroups: + - nfd.k8s-sigs.io + resources: + - nodefeatures + verbs: + - delete + - list diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrolebinding.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrolebinding.yaml.j2 new file mode 100644 index 0000000..c3768c3 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-clusterrolebinding.yaml.j2 @@ -0,0 +1,25 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: node-feature-discovery +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: node-feature-discovery +subjects: +- kind: ServiceAccount + name: node-feature-discovery + namespace: {{ node_feature_discovery_namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: node-feature-discovery-gc +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: node-feature-discovery-gc +subjects: +- kind: ServiceAccount + name: {{ node_feature_discovery_gc_sa_name }} + namespace: {{ node_feature_discovery_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-gc.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-gc.yaml.j2 new file mode 100644 index 0000000..78edbf0 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-gc.yaml.j2 @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: node-feature-discovery-gc + namespace: {{ node_feature_discovery_namespace }} + labels: + app.kubernetes.io/name: node-feature-discovery + role: gc +spec: + replicas: {{ node_feature_discovery_gc_replicas }} + selector: + matchLabels: + app.kubernetes.io/name: node-feature-discovery + role: gc + template: + metadata: + labels: + app.kubernetes.io/name: node-feature-discovery + role: gc + spec: + serviceAccountName: {{ node_feature_discovery_gc_sa_name }} + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: gc + image: {{ node_feature_discovery_image_repo }}:{{ node_feature_discovery_image_tag }} + imagePullPolicy: IfNotPresent + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "nfd-gc" + args: + - "-gc-interval={{ node_feature_discovery_gc_interval }}" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master-conf.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master-conf.yaml.j2 new file mode 100644 index 0000000..92b58e4 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master-conf.yaml.j2 @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: node-feature-discovery-master-conf + namespace: {{ node_feature_discovery_namespace }} +data: +{% if node_feature_discovery_master_config %} + nfd-master.conf: |- + {{ node_feature_discovery_master_config | to_yaml(indent=2, width=1337) | indent(width=4) }} +{% else %} + nfd-master.conf: "null" +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master.yaml.j2 new file mode 100644 index 0000000..c4aacef --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-master.yaml.j2 @@ -0,0 +1,111 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: node-feature-discovery-master + namespace: {{ node_feature_discovery_namespace }} + labels: + app.kubernetes.io/name: node-feature-discovery + role: master +spec: + replicas: {{ node_feature_discovery_master_replicas }} + selector: + matchLabels: + app.kubernetes.io/name: node-feature-discovery + role: master + template: + metadata: + labels: + app.kubernetes.io/name: node-feature-discovery + role: master + spec: + serviceAccountName: node-feature-discovery + enableServiceLinks: false + containers: + - name: master + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + image: {{ node_feature_discovery_image_repo }}:{{ node_feature_discovery_image_tag }} + imagePullPolicy: IfNotPresent + livenessProbe: + grpc: + port: 8082 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + grpc: + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 10 + ports: + - containerPort: 8082 + name: grpc + - containerPort: 8081 + name: metrics + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "nfd-master" + args: + - "-port=8080" +{% if not node_feature_discovery_enable_nodefeature_api %} + - "-enable-nodefeature-api=false" +{% elif node_feature_discovery_master_replicas > 1 %} + - "-enable-leader-election" +{% endif %} +{% if node_feature_discovery_master_crd_controller != none %} + - "-crd-controller={{ node_feature_discovery_master_crd_controller }}" +{% else %} +{% if node_feature_discovery_master_instance %} + ## By default, disable crd controller for other than the default instances + - "-crd-controller=false" +{% else %} + ## By default, disable crd controller for other than the default instances + - "-crd-controller=true" +{% endif %} +{% endif %} + - "-metrics=8081" + volumeMounts: + - name: nfd-master-conf + mountPath: "/etc/kubernetes/node-feature-discovery" + readOnly: true + volumes: + - name: nfd-master-conf + configMap: + name: node-feature-discovery-master-conf + items: + - key: nfd-master.conf + path: nfd-master.conf + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/master + operator: In + values: + - "" + weight: 1 + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: In + values: + - "" + weight: 1 + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Equal + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Equal diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-ns.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-ns.yaml.j2 new file mode 100644 index 0000000..953ae59 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-ns.yaml.j2 @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ node_feature_discovery_namespace }} + labels: + name: {{ node_feature_discovery_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-role.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-role.yaml.j2 new file mode 100644 index 0000000..074e39b --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-role.yaml.j2 @@ -0,0 +1,20 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: node-feature-discovery-worker + namespace: {{ node_feature_discovery_namespace }} +rules: +- apiGroups: + - nfd.k8s-sigs.io + resources: + - nodefeatures + verbs: + - create + - get + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - get diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-rolebinding.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-rolebinding.yaml.j2 new file mode 100644 index 0000000..04a5786 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-rolebinding.yaml.j2 @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: node-feature-discovery-worker + namespace: {{ node_feature_discovery_namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: node-feature-discovery-worker +subjects: +- kind: ServiceAccount + name: {{ node_feature_discovery_worker_sa_name }} + namespace: {{ node_feature_discovery_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-service.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-service.yaml.j2 new file mode 100644 index 0000000..82703b9 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-service.yaml.j2 @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: node-feature-discovery-master + namespace: {{ node_feature_discovery_namespace }} + labels: + app.kubernetes.io/name: node-feature-discovery + role: master +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: grpc + protocol: TCP + name: grpc + selector: + app.kubernetes.io/name: node-feature-discovery + role: master diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-serviceaccount.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-serviceaccount.yaml.j2 new file mode 100644 index 0000000..f79e1b1 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-serviceaccount.yaml.j2 @@ -0,0 +1,22 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: node-feature-discovery + namespace: {{ node_feature_discovery_namespace }} +{% if node_feature_discovery_gc_sa_create %} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ node_feature_discovery_gc_sa_name }} + namespace: {{ node_feature_discovery_namespace }} +{% endif %} +{% if node_feature_discovery_worker_sa_create %} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ node_feature_discovery_worker_sa_name }} + namespace: {{ node_feature_discovery_namespace }} +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-topologyupdater-conf.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-topologyupdater-conf.yaml.j2 new file mode 100644 index 0000000..0f8feca --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-topologyupdater-conf.yaml.j2 @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: node-feature-discovery-topology-updater-conf + namespace: {{ node_feature_discovery_namespace }} +data: + nfd-topology-updater.conf: "null" diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker-conf.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker-conf.yaml.j2 new file mode 100644 index 0000000..280ae56 --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker-conf.yaml.j2 @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: node-feature-discovery-worker-conf + namespace: {{ node_feature_discovery_namespace }} +data: +{% if node_feature_discovery_worker_config %} + nfd-worker.conf: |- + {{ node_feature_discovery_worker_config | to_yaml(indent=2, width=1337) | indent(width=4) }} +{% else %} + nfd-worker.conf: "null" +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker.yaml.j2 b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker.yaml.j2 new file mode 100644 index 0000000..fc6f94c --- /dev/null +++ b/kubespray/project/roles/kubernetes-apps/node_feature_discovery/templates/nfd-worker.yaml.j2 @@ -0,0 +1,105 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: node-feature-discovery-worker + namespace: {{ node_feature_discovery_namespace }} + labels: + app.kubernetes.io/name: node-feature-discovery + role: worker +spec: + selector: + matchLabels: + app.kubernetes.io/name: node-feature-discovery + role: worker + template: + metadata: + labels: + app.kubernetes.io/name: node-feature-discovery + role: worker + spec: + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ node_feature_discovery_worker_sa_name }} + containers: + - name: worker + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + image: {{ node_feature_discovery_image_repo }}:{{ node_feature_discovery_image_tag }} + imagePullPolicy: IfNotPresent + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "nfd-worker" + args: + - "-server=node-feature-discovery-master:8080" +{% if not node_feature_discovery_enable_nodefeature_api %} + - "-enable-nodefeature-api=false" +{% endif %} + - "-metrics=8081" + ports: + - name: metrics + containerPort: 8081 + volumeMounts: + - name: host-boot + mountPath: "/host-boot" + readOnly: true + - name: host-os-release + mountPath: "/host-etc/os-release" + readOnly: true + - name: host-sys + mountPath: "/host-sys" + readOnly: true + - name: host-usr-lib + mountPath: "/host-usr/lib" + readOnly: true + - name: host-lib + mountPath: "/host-lib" + readOnly: true + - name: source-d + mountPath: "/etc/kubernetes/node-feature-discovery/source.d/" + readOnly: true + - name: features-d + mountPath: "/etc/kubernetes/node-feature-discovery/features.d/" + readOnly: true + - name: nfd-worker-conf + mountPath: "/etc/kubernetes/node-feature-discovery" + readOnly: true + volumes: + - name: host-boot + hostPath: + path: "/boot" + - name: host-os-release + hostPath: + path: "/etc/os-release" + - name: host-sys + hostPath: + path: "/sys" + - name: host-usr-lib + hostPath: + path: "/usr/lib" + - name: host-lib + hostPath: + path: "/lib" + - name: source-d + hostPath: + path: "/etc/kubernetes/node-feature-discovery/source.d/" + - name: features-d + hostPath: + path: "/etc/kubernetes/node-feature-discovery/features.d/" + - name: nfd-worker-conf + configMap: + name: node-feature-discovery-worker-conf + items: + - key: nfd-worker.conf + path: nfd-worker.conf +{% if node_feature_discovery_worker_tolerations %} + tolerations: + {{ node_feature_discovery_worker_tolerations | to_yaml(indent=2, width=1337) | indent(width=8) }} +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/aws-ebs-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/aws-ebs-csi/tasks/main.yml index b49acdf..d31f9c6 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/aws-ebs-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/aws-ebs-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "aws-ebs-csi-storage-class.yml.j2" dest: "{{ kube_config_dir }}/aws-ebs-csi-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/azuredisk-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/azuredisk-csi/tasks/main.yml index 9abffbe..4a2bff0 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/azuredisk-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/azuredisk-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "azure-csi-storage-class.yml.j2" dest: "{{ kube_config_dir }}/azure-csi-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/cinder-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/cinder-csi/tasks/main.yml index 52de1c5..78ebe78 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/cinder-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/cinder-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "cinder-csi-storage-class.yml.j2" dest: "{{ kube_config_dir }}/cinder-csi-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/gcp-pd-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/gcp-pd-csi/tasks/main.yml index 29997e7..f58e4cb 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/gcp-pd-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/gcp-pd-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "gcp-pd-csi-storage-class.yml.j2" dest: "{{ kube_config_dir }}/gcp-pd-csi-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/openstack/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/openstack/tasks/main.yml index 3387e7f..90b3ad7 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/openstack/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/openstack/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "openstack-storage-class.yml.j2" dest: "{{ kube_config_dir }}/openstack-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml index 26104a0..aed5679 100644 --- a/kubespray/project/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "upcloud-csi-storage-class.yml.j2" dest: "{{ kube_config_dir }}/upcloud-csi-storage-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/defaults/main.yml b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/defaults/main.yml index d3a780c..8299102 100644 --- a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/defaults/main.yml +++ b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/defaults/main.yml @@ -5,6 +5,7 @@ calico_policy_controller_memory_limit: 256M calico_policy_controller_cpu_requests: 30m calico_policy_controller_memory_requests: 64M calico_policy_controller_deployment_nodeselector: "kubernetes.io/os: linux" +calico_policy_controller_log_level: info # SSL calico_cert_dir: "/etc/calico/certs" diff --git a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml index ba2eebb..fa0c994 100644 --- a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: calico-kube-controllers, file: calico-kube-controllers.yml, type: deployment} - {name: calico-kube-controllers, file: calico-kube-sa.yml, type: sa} diff --git a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2 b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2 index 490111c..0941d29 100644 --- a/kubespray/project/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2 @@ -60,6 +60,8 @@ spec: - -r periodSeconds: 10 env: + - name: LOG_LEVEL + value: {{ calico_policy_controller_log_level }} {% if calico_datastore == "kdd" %} - name: ENABLED_CONTROLLERS value: node diff --git a/kubespray/project/roles/kubernetes-apps/registry/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/registry/tasks/main.yml index a915e07..4e4979d 100644 --- a/kubespray/project/roles/kubernetes-apps/registry/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/registry/tasks/main.yml @@ -31,7 +31,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" - name: Registry | Templates list set_fact: @@ -54,7 +54,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/registry/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: "{{ registry_templates }}" register: registry_manifests when: inventory_hostname == groups['kube_control_plane'][0] @@ -74,7 +74,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/registry/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: registry-pvc, file: registry-pvc.yml, type: pvc } register: registry_manifests diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/tasks/main.yml index d17b191..404a2cb 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/tasks/main.yml @@ -5,7 +5,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: inventory_hostname == groups['kube_control_plane'][0] tags: - scheduler_plugins @@ -14,7 +14,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/scheduler-plugins/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - { name: appgroup, file: appgroup.diktyo.x-k8s.io_appgroups.yaml, type: crd } - { name: networktopology, file: networktopology.diktyo.x-k8s.io_networktopologies.yaml, type: crd } diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/appgroup.diktyo.x-k8s.io_appgroups.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/appgroup.diktyo.x-k8s.io_appgroups.yaml.j2 index 757a3b1..10c30c7 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/appgroup.diktyo.x-k8s.io_appgroups.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/appgroup.diktyo.x-k8s.io_appgroups.yaml.j2 @@ -194,4 +194,4 @@ spec: type: object type: object served: true - storage: true \ No newline at end of file + storage: true diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/cm-scheduler-plugins.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/cm-scheduler-plugins.yaml.j2 index 7e022e8..4b5e024 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/cm-scheduler-plugins.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/cm-scheduler-plugins.yaml.j2 @@ -25,4 +25,4 @@ data: {% if scheduler_plugins_plugin_config is defined and scheduler_plugins_plugin_config | length != 0 %} pluginConfig: {{ scheduler_plugins_plugin_config | to_nice_yaml(indent=2, width=256) | indent(6, true) }} -{% endif %} \ No newline at end of file +{% endif %} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/deploy-scheduler-plugins.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/deploy-scheduler-plugins.yaml.j2 index 114698a..1ded700 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/deploy-scheduler-plugins.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/deploy-scheduler-plugins.yaml.j2 @@ -71,4 +71,4 @@ spec: volumes: - name: scheduler-config configMap: - name: scheduler-config \ No newline at end of file + name: scheduler-config diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/namespace.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/namespace.yaml.j2 index d54ae66..41b0806 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/namespace.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/namespace.yaml.j2 @@ -4,4 +4,4 @@ kind: Namespace metadata: name: {{ scheduler_plugins_namespace }} labels: - name: {{ scheduler_plugins_namespace }} \ No newline at end of file + name: {{ scheduler_plugins_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/networktopology.diktyo.x-k8s.io_networktopologies.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/networktopology.diktyo.x-k8s.io_networktopologies.yaml.j2 index e33157c..7e562f8 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/networktopology.diktyo.x-k8s.io_networktopologies.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/networktopology.diktyo.x-k8s.io_networktopologies.yaml.j2 @@ -145,4 +145,4 @@ spec: type: object type: object served: true - storage: true \ No newline at end of file + storage: true diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/rbac-scheduler-plugins.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/rbac-scheduler-plugins.yaml.j2 index aa6f211..8e86f6b 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/rbac-scheduler-plugins.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/rbac-scheduler-plugins.yaml.j2 @@ -137,4 +137,4 @@ subjects: namespace: {{ scheduler_plugins_namespace }} - kind: ServiceAccount name: scheduler-plugins-controller - namespace: {{ scheduler_plugins_namespace }} \ No newline at end of file + namespace: {{ scheduler_plugins_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/sa-scheduler-plugins.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/sa-scheduler-plugins.yaml.j2 index 6c25e18..7cefdb1 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/sa-scheduler-plugins.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/sa-scheduler-plugins.yaml.j2 @@ -8,4 +8,4 @@ apiVersion: v1 kind: ServiceAccount metadata: name: scheduler-plugins-controller - namespace: {{ scheduler_plugins_namespace }} \ No newline at end of file + namespace: {{ scheduler_plugins_namespace }} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_elasticquotas.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_elasticquotas.yaml.j2 index d63f572..e8f64c3 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_elasticquotas.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_elasticquotas.yaml.j2 @@ -79,4 +79,4 @@ spec: served: true storage: true subresources: - status: {} \ No newline at end of file + status: {} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_podgroups.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_podgroups.yaml.j2 index 3767cf9..a0790dc 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_podgroups.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/scheduling.x-k8s.io_podgroups.yaml.j2 @@ -94,4 +94,4 @@ spec: served: true storage: true subresources: - status: {} \ No newline at end of file + status: {} diff --git a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/topology.node.k8s.io_noderesourcetopologies.yaml.j2 b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/topology.node.k8s.io_noderesourcetopologies.yaml.j2 index d83ef0b..567432f 100644 --- a/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/topology.node.k8s.io_noderesourcetopologies.yaml.j2 +++ b/kubespray/project/roles/kubernetes-apps/scheduler_plugins/templates/topology.node.k8s.io_noderesourcetopologies.yaml.j2 @@ -150,4 +150,4 @@ spec: - zones type: object served: true - storage: true \ No newline at end of file + storage: true diff --git a/kubespray/project/roles/kubernetes-apps/snapshots/cinder-csi/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/snapshots/cinder-csi/tasks/main.yml index 7e9116f..35ec4cd 100644 --- a/kubespray/project/roles/kubernetes-apps/snapshots/cinder-csi/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/snapshots/cinder-csi/tasks/main.yml @@ -3,7 +3,7 @@ template: src: "cinder-csi-snapshot-class.yml.j2" dest: "{{ kube_config_dir }}/cinder-csi-snapshot-class.yml" - mode: 0644 + mode: "0644" register: manifests when: - inventory_hostname == groups['kube_control_plane'][0] diff --git a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/tasks/main.yml b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/tasks/main.yml index e6da292..0c5d3ae 100644 --- a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/tasks/main.yml +++ b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/tasks/main.yml @@ -13,7 +13,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: snapshot-ns, file: snapshot-ns.yml, apply: not snapshot_namespace_exists} - {name: rbac-snapshot-controller, file: rbac-snapshot-controller.yml} diff --git a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/rbac-snapshot-controller.yml.j2 b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/rbac-snapshot-controller.yml.j2 index 9413376..2fa18f4 100644 --- a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/rbac-snapshot-controller.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/rbac-snapshot-controller.yml.j2 @@ -15,7 +15,6 @@ metadata: kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - # rename if there are conflicts name: snapshot-controller-runner rules: - apiGroups: [""] @@ -24,9 +23,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - - apiGroups: ["storage.k8s.io"] - resources: ["storageclasses"] - verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["list", "watch", "create", "update", "patch"] @@ -35,13 +31,37 @@ rules: verbs: ["get", "list", "watch"] - apiGroups: ["snapshot.storage.k8s.io"] resources: ["volumesnapshotcontents"] - verbs: ["create", "get", "list", "watch", "update", "delete"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["patch"] - apiGroups: ["snapshot.storage.k8s.io"] resources: ["volumesnapshots"] - verbs: ["get", "list", "watch", "update"] + verbs: ["get", "list", "watch", "update", "patch", "delete"] - apiGroups: ["snapshot.storage.k8s.io"] resources: ["volumesnapshots/status"] - verbs: ["update"] + verbs: ["update", "patch"] + + - apiGroups: ["groupsnapshot.storage.k8s.io"] + resources: ["volumegroupsnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["groupsnapshot.storage.k8s.io"] + resources: ["volumegroupsnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["groupsnapshot.storage.k8s.io"] + resources: ["volumegroupsnapshotcontents/status"] + verbs: ["patch"] + - apiGroups: ["groupsnapshot.storage.k8s.io"] + resources: ["volumegroupsnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["groupsnapshot.storage.k8s.io"] + resources: ["volumegroupsnapshots/status"] + verbs: ["update", "patch"] + + # Enable this RBAC rule only when using distributed snapshotting, i.e. when the enable-distributed-snapshotting flag is set to true + # - apiGroups: [""] + # resources: ["nodes"] + # verbs: ["get", "list", "watch"] --- kind: ClusterRoleBinding @@ -54,7 +74,6 @@ subjects: namespace: {{ snapshot_controller_namespace }} roleRef: kind: ClusterRole - # change the name also here if the ClusterRole gets renamed name: snapshot-controller-runner apiGroup: rbac.authorization.k8s.io @@ -62,12 +81,12 @@ roleRef: kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - namespace: {{ snapshot_controller_namespace }} name: snapshot-controller-leaderelection + namespace: {{ snapshot_controller_namespace }} rules: -- apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] --- kind: RoleBinding diff --git a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/snapshot-controller.yml.j2 b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/snapshot-controller.yml.j2 index d17ffb3..a27e56f 100644 --- a/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/snapshot-controller.yml.j2 +++ b/kubespray/project/roles/kubernetes-apps/snapshots/snapshot-controller/templates/snapshot-controller.yml.j2 @@ -15,11 +15,12 @@ spec: replicas: {{ snapshot_controller_replicas }} selector: matchLabels: - app: snapshot-controller - # the snapshot controller won't be marked as ready if the v1 CRDs are unavailable - # in #504 the snapshot-controller will exit after around 7.5 seconds if it - # can't find the v1 CRDs so this value should be greater than that - minReadySeconds: 15 + app.kubernetes.io/name: snapshot-controller + # The snapshot controller won't be marked as ready if the v1 CRDs are unavailable. + # The flag --retry-crd-interval-max is used to determine how long the controller + # will wait for the CRDs to become available before exiting. The default is 30 seconds + # so minReadySeconds should be set slightly higher than the flag value. + minReadySeconds: 35 strategy: rollingUpdate: maxSurge: 0 @@ -28,13 +29,13 @@ spec: template: metadata: labels: - app: snapshot-controller + app.kubernetes.io/name: snapshot-controller spec: - serviceAccount: snapshot-controller + serviceAccountName: snapshot-controller containers: - name: snapshot-controller image: {{ snapshot_controller_image_repo }}:{{ snapshot_controller_image_tag }} + imagePullPolicy: {{ k8s_image_pull_policy }} args: - "--v=5" - - "--leader-election=false" - imagePullPolicy: {{ k8s_image_pull_policy }} + - "--leader-election={{ 'true' if snapshot_controller_replicas > 1 else 'false' }}" diff --git a/kubespray/project/roles/kubernetes/client/tasks/main.yml b/kubespray/project/roles/kubernetes/client/tasks/main.yml index e619761..9202051 100644 --- a/kubespray/project/roles/kubernetes/client/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/client/tasks/main.yml @@ -30,9 +30,9 @@ copy: src: "{{ kube_config_dir }}/admin.conf" dest: "{{ ansible_env.HOME | default('/root') }}/.kube/config" - remote_src: yes + remote_src: true mode: "0600" - backup: yes + backup: true - name: Create kube artifacts dir file: @@ -41,8 +41,8 @@ state: directory delegate_to: localhost connection: local - become: no - run_once: yes + become: false + run_once: true when: kubeconfig_localhost - name: Wait for k8s apiserver @@ -54,7 +54,7 @@ - name: Get admin kubeconfig from remote host slurp: src: "{{ kube_config_dir }}/admin.conf" - run_once: yes + run_once: true register: raw_admin_kubeconfig when: kubeconfig_localhost @@ -80,24 +80,24 @@ copy: content: "{{ final_admin_kubeconfig | to_nice_yaml(indent=2) }}" dest: "{{ artifacts_dir }}/admin.conf" - mode: 0600 + mode: "0600" delegate_to: localhost connection: local - become: no - run_once: yes + become: false + run_once: true when: kubeconfig_localhost - name: Copy kubectl binary to ansible host fetch: src: "{{ bin_dir }}/kubectl" dest: "{{ artifacts_dir }}/kubectl" - flat: yes - validate_checksum: no + flat: true + validate_checksum: false register: copy_binary_result until: copy_binary_result is not failed retries: 20 - become: no - run_once: yes + become: false + run_once: true when: kubectl_localhost - name: Create helper script kubectl.sh on ansible host @@ -106,9 +106,9 @@ #!/bin/bash ${BASH_SOURCE%/*}/kubectl --kubeconfig=${BASH_SOURCE%/*}/admin.conf "$@" dest: "{{ artifacts_dir }}/kubectl.sh" - mode: 0755 - become: no - run_once: yes + mode: "0755" + become: false + run_once: true delegate_to: localhost connection: local when: kubectl_localhost and kubeconfig_localhost diff --git a/kubespray/project/roles/kubernetes/control-plane/defaults/main/main.yml b/kubespray/project/roles/kubernetes/control-plane/defaults/main/main.yml index fd70477..df92c41 100644 --- a/kubespray/project/roles/kubernetes/control-plane/defaults/main/main.yml +++ b/kubespray/project/roles/kubernetes/control-plane/defaults/main/main.yml @@ -240,3 +240,6 @@ kubeadm_upgrade_auto_cert_renewal: true kube_apiserver_tracing: false kube_apiserver_tracing_endpoint: 0.0.0.0:4317 kube_apiserver_tracing_sampling_rate_per_million: 100 + +# Enable kubeadm file discovery if anonymous access has been removed +kubeadm_use_file_discovery: "{{ remove_anonymous_access }}" diff --git a/kubespray/project/roles/kubernetes/control-plane/handlers/main.yml b/kubespray/project/roles/kubernetes/control-plane/handlers/main.yml index 1ee64f2..3d7f3e0 100644 --- a/kubespray/project/roles/kubernetes/control-plane/handlers/main.yml +++ b/kubespray/project/roles/kubernetes/control-plane/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: Master | reload systemd - systemd: + systemd_service: daemon_reload: true listen: Master | restart kubelet @@ -81,7 +81,7 @@ endpoint: "{{ kube_scheduler_bind_address if kube_scheduler_bind_address != '0.0.0.0' else 'localhost' }}" uri: url: https://{{ endpoint }}:10259/healthz - validate_certs: no + validate_certs: false register: scheduler_result until: scheduler_result.status == 200 retries: 60 @@ -95,7 +95,7 @@ endpoint: "{{ kube_controller_manager_bind_address if kube_controller_manager_bind_address != '0.0.0.0' else 'localhost' }}" uri: url: https://{{ endpoint }}:10257/healthz - validate_certs: no + validate_certs: false register: controller_manager_result until: controller_manager_result.status == 200 retries: 60 @@ -107,7 +107,7 @@ - name: Master | wait for the apiserver to be running uri: url: "{{ kube_apiserver_endpoint }}/healthz" - validate_certs: no + validate_certs: false register: result until: result.status == 200 retries: 60 diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/define-first-kube-control.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/define-first-kube-control.yml index 36996da..5faa184 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/define-first-kube-control.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/define-first-kube-control.yml @@ -3,16 +3,16 @@ - name: Check which kube-control nodes are already members of the cluster command: "{{ bin_dir }}/kubectl get nodes --selector=node-role.kubernetes.io/control-plane -o json" register: kube_control_planes_raw - ignore_errors: yes + ignore_errors: true changed_when: false - name: Set fact joined_control_planes set_fact: joined_control_planes: "{{ ((kube_control_planes_raw.stdout | from_json)['items']) | default([]) | map(attribute='metadata') | map(attribute='name') | list }}" - delegate_to: item + delegate_to: "{{ item }}" loop: "{{ groups['kube_control_plane'] }}" when: kube_control_planes_raw is succeeded - run_once: yes + run_once: true - name: Set fact first_kube_control_plane set_fact: diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/encrypt-at-rest.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/encrypt-at-rest.yml index 209e4c7..2950c76 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/encrypt-at-rest.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/encrypt-at-rest.yml @@ -2,9 +2,9 @@ - name: Check if secret for encrypting data at rest already exist stat: path: "{{ kube_cert_dir }}/secrets_encryption.yaml" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: secrets_encryption_file - name: Slurp secrets_encryption file if it exists @@ -37,4 +37,4 @@ dest: "{{ kube_cert_dir }}/secrets_encryption.yaml" owner: root group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-backup.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-backup.yml index 36bb627..918f7cf 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-backup.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-backup.yml @@ -4,7 +4,7 @@ src: "{{ kube_cert_dir }}/{{ item }}" dest: "{{ kube_cert_dir }}/{{ item }}.old" mode: preserve - remote_src: yes + remote_src: true with_items: - apiserver.crt - apiserver.key @@ -19,7 +19,7 @@ src: "{{ kube_config_dir }}/{{ item }}" dest: "{{ kube_config_dir }}/{{ item }}.old" mode: preserve - remote_src: yes + remote_src: true with_items: - admin.conf - controller-manager.conf diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-etcd.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-etcd.yml index 9de55c5..788d6b8 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-etcd.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-etcd.yml @@ -25,5 +25,5 @@ path: "{{ etcd_data_dir }}" owner: "{{ etcd_owner }}" group: "{{ etcd_owner }}" - mode: 0700 + mode: "0700" when: etcd_deployment_type == "kubeadm" diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml index 5376aba..e47f571 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml @@ -5,7 +5,7 @@ dest: "{{ kube_config_dir }}/{{ item }}" regexp: '^ server: https' line: ' server: {{ kube_apiserver_endpoint }}' - backup: yes + backup: true with_items: - admin.conf - controller-manager.conf diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml index f3fd207..413d494 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml @@ -25,7 +25,7 @@ - name: Parse certificate key if not set set_fact: kubeadm_certificate_key: "{{ hostvars[groups['kube_control_plane'][0]]['kubeadm_upload_cert'].stdout_lines[-1] | trim }}" - run_once: yes + run_once: true when: - hostvars[groups['kube_control_plane'][0]]['kubeadm_upload_cert'] is defined - hostvars[groups['kube_control_plane'][0]]['kubeadm_upload_cert'] is not skipped @@ -34,8 +34,8 @@ template: src: "kubeadm-controlplane.{{ kubeadmConfig_api_version }}.yaml.j2" dest: "{{ kube_config_dir }}/kubeadm-controlplane.yaml" - mode: 0640 - backup: yes + mode: "0640" + backup: true when: - inventory_hostname != first_kube_control_plane - not kubeadm_already_run.stat.exists @@ -63,6 +63,26 @@ - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists - not kube_external_ca_mode +- name: Get kubeconfig for join discovery process + command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'" + register: kubeconfig_file_discovery + run_once: true + delegate_to: "{{ groups['kube_control_plane'] | first }}" + when: + - kubeadm_use_file_discovery + - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists + +- name: Copy discovery kubeconfig + copy: + dest: "{{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml" + content: "{{ kubeconfig_file_discovery.stdout }}" + owner: "root" + mode: "0644" + when: + - inventory_hostname != first_kube_control_plane + - kubeadm_use_file_discovery + - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists + - name: Joining control plane node to the cluster. command: >- {{ bin_dir }}/kubeadm join diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml index 1f4ff20..52700af 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml @@ -13,9 +13,9 @@ - name: Kubeadm | Check if kubeadm has already run stat: path: "/var/lib/kubelet/config.yaml" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kubeadm_already_run - name: Kubeadm | Backup kubeadm certs / kubeconfig @@ -51,35 +51,35 @@ file: path: "{{ audit_policy_file | dirname }}" state: directory - mode: 0640 + mode: "0640" when: kubernetes_audit | default(false) or kubernetes_audit_webhook | default(false) - name: Write api audit policy yaml template: src: apiserver-audit-policy.yaml.j2 dest: "{{ audit_policy_file }}" - mode: 0640 + mode: "0640" when: kubernetes_audit | default(false) or kubernetes_audit_webhook | default(false) - name: Write api audit webhook config yaml template: src: apiserver-audit-webhook-config.yaml.j2 dest: "{{ audit_webhook_config_file }}" - mode: 0640 + mode: "0640" when: kubernetes_audit_webhook | default(false) - name: Create apiserver tracing config directory file: path: "{{ kube_config_dir }}/tracing" state: directory - mode: 0640 + mode: "0640" when: kube_apiserver_tracing - name: Write apiserver tracing config yaml template: src: apiserver-tracing.yaml.j2 dest: "{{ kube_config_dir }}/tracing/apiserver-tracing.yaml" - mode: 0640 + mode: "0640" when: kube_apiserver_tracing # Nginx LB(default), If kubeadm_config_api_fqdn is defined, use other LB by kubeadm controlPlaneEndpoint. @@ -96,27 +96,27 @@ template: src: "kubeadm-config.{{ kubeadmConfig_api_version }}.yaml.j2" dest: "{{ kube_config_dir }}/kubeadm-config.yaml" - mode: 0640 + mode: "0640" - name: Kubeadm | Create directory to store admission control configurations file: path: "{{ kube_config_dir }}/admission-controls" state: directory - mode: 0640 + mode: "0640" when: kube_apiserver_admission_control_config_file - name: Kubeadm | Push admission control config file template: src: "admission-controls.yaml.j2" dest: "{{ kube_config_dir }}/admission-controls/admission-controls.yaml" - mode: 0640 + mode: "0640" when: kube_apiserver_admission_control_config_file - name: Kubeadm | Push admission control config files template: src: "{{ item | lower }}.yaml.j2" dest: "{{ kube_config_dir }}/admission-controls/{{ item | lower }}.yaml" - mode: 0640 + mode: "0640" when: - kube_apiserver_admission_control_config_file - item in kube_apiserver_admission_plugins_needs_configuration @@ -126,7 +126,7 @@ template: src: "podnodeselector.yaml.j2" dest: "{{ kube_config_dir }}/admission-controls/podnodeselector.yaml" - mode: 0640 + mode: "0640" when: - kube_apiserver_admission_plugins_podnodeselector_default_node_selector is defined - kube_apiserver_admission_plugins_podnodeselector_default_node_selector | length > 0 @@ -178,7 +178,7 @@ file: path: "{{ kubeadm_patches.dest_dir }}" state: directory - mode: 0640 + mode: "0640" when: kubeadm_patches is defined and kubeadm_patches.enabled - name: Kubeadm | Copy kubeadm patches from inventory files @@ -186,7 +186,7 @@ src: "{{ kubeadm_patches.source_dir }}/" dest: "{{ kubeadm_patches.dest_dir }}" owner: "root" - mode: 0644 + mode: "0644" when: kubeadm_patches is defined and kubeadm_patches.enabled - name: Kubeadm | Initialize first master @@ -221,12 +221,16 @@ {{ bin_dir }}/kubeadm --kubeconfig {{ kube_config_dir }}/admin.conf token create {{ kubeadm_token }} changed_when: false when: - - inventory_hostname == first_kube_control_plane + - inventory_hostname == first_kube_control_plane - kubeadm_token is defined - kubeadm_refresh_token tags: - kubeadm_token +- name: Remove binding to anonymous user + command: "{{ kubectl }} -n kube-public delete rolebinding kubeadm:bootstrap-signer-clusterinfo --ignore-not-found" + when: inventory_hostname == first_kube_control_plane and remove_anonymous_access + - name: Create kubeadm token for joining nodes with 24h expiration (default) command: "{{ bin_dir }}/kubeadm --kubeconfig {{ kube_config_dir }}/admin.conf token create" changed_when: false diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-upgrade.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-upgrade.yml index 12ab0b9..f88921e 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-upgrade.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubeadm-upgrade.yml @@ -15,7 +15,6 @@ {{ bin_dir }}/kubeadm upgrade apply -y {{ kube_version }} --certificate-renewal={{ kubeadm_upgrade_auto_cert_renewal }} - --config={{ kube_config_dir }}/kubeadm-config.yaml --ignore-preflight-errors=all --allow-experimental-upgrades --etcd-upgrade={{ (etcd_deployment_type == "kubeadm") | bool | lower }} @@ -37,7 +36,6 @@ {{ bin_dir }}/kubeadm upgrade apply -y {{ kube_version }} --certificate-renewal={{ kubeadm_upgrade_auto_cert_renewal }} - --config={{ kube_config_dir }}/kubeadm-config.yaml --ignore-preflight-errors=all --allow-experimental-upgrades --etcd-upgrade={{ (etcd_deployment_type == "kubeadm") | bool | lower }} @@ -53,6 +51,10 @@ PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}" notify: Master | restart kubelet +- name: Kubeadm | Remove binding to anonymous user + command: "{{ kubectl }} -n kube-public delete rolebinding kubeadm:bootstrap-signer-clusterinfo --ignore-not-found" + when: remove_anonymous_access + - name: Kubeadm | clean kubectl cache to refresh api types file: path: "{{ item }}" diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/kubelet-fix-client-cert-rotation.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/kubelet-fix-client-cert-rotation.yml index 7d0c1a0..409ecb0 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/kubelet-fix-client-cert-rotation.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/kubelet-fix-client-cert-rotation.yml @@ -4,7 +4,7 @@ path: "{{ kube_config_dir }}/kubelet.conf" regexp: '^ client-certificate-data: ' line: ' client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem' - backup: yes + backup: true notify: - "Master | reload kubelet" @@ -13,6 +13,6 @@ path: "{{ kube_config_dir }}/kubelet.conf" regexp: '^ client-key-data: ' line: ' client-key: /var/lib/kubelet/pki/kubelet-client-current.pem' - backup: yes + backup: true notify: - "Master | reload kubelet" diff --git a/kubespray/project/roles/kubernetes/control-plane/tasks/main.yml b/kubespray/project/roles/kubernetes/control-plane/tasks/main.yml index 37f36ab..518bac9 100644 --- a/kubespray/project/roles/kubernetes/control-plane/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/control-plane/tasks/main.yml @@ -8,21 +8,21 @@ template: src: webhook-token-auth-config.yaml.j2 dest: "{{ kube_config_dir }}/webhook-token-auth-config.yaml" - mode: 0640 + mode: "0640" when: kube_webhook_token_auth | default(false) - name: Create webhook authorization config template: src: webhook-authorization-config.yaml.j2 dest: "{{ kube_config_dir }}/webhook-authorization-config.yaml" - mode: 0640 + mode: "0640" when: kube_webhook_authorization | default(false) - name: Create kube-scheduler config template: src: kubescheduler-config.yaml.j2 dest: "{{ kube_config_dir }}/kubescheduler-config.yaml" - mode: 0644 + mode: "0644" - name: Apply Kubernetes encrypt at rest config import_tasks: encrypt-at-rest.yml @@ -35,7 +35,7 @@ copy: src: "{{ downloads.kubectl.dest }}" dest: "{{ bin_dir }}/kubectl" - mode: 0755 + mode: "0755" remote_src: true tags: - kubectl @@ -53,7 +53,7 @@ path: /etc/bash_completion.d/kubectl.sh owner: root group: root - mode: 0755 + mode: "0755" when: ansible_os_family in ["Debian","RedHat"] tags: - kubectl @@ -101,13 +101,13 @@ template: src: k8s-certs-renew.sh.j2 dest: "{{ bin_dir }}/k8s-certs-renew.sh" - mode: 0755 + mode: "0755" - name: Renew K8S control plane certificates monthly 1/2 template: src: "{{ item }}.j2" dest: "/etc/systemd/system/{{ item }}" - mode: 0644 + mode: "0644" validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:{{item}}'" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 @@ -118,9 +118,9 @@ when: auto_renew_certificates - name: Renew K8S control plane certificates monthly 2/2 - systemd: + systemd_service: name: k8s-certs-renew.timer - enabled: yes + enabled: true state: started daemon_reload: "{{ k8s_certs_units is changed }}" when: auto_renew_certificates diff --git a/kubespray/project/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2 b/kubespray/project/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2 index 98decde..7301a35 100644 --- a/kubespray/project/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2 +++ b/kubespray/project/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2 @@ -1,4 +1,4 @@ apiVersion: apiserver.config.k8s.io/v1beta1 kind: TracingConfiguration endpoint: {{ kube_apiserver_tracing_endpoint }} -samplingRatePerMillion: {{ kube_apiserver_tracing_sampling_rate_per_million }} \ No newline at end of file +samplingRatePerMillion: {{ kube_apiserver_tracing_sampling_rate_per_million }} diff --git a/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2 b/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2 index b11fb33..ca48a3a 100644 --- a/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2 +++ b/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2 @@ -14,7 +14,7 @@ certificateKey: {{ kubeadm_certificate_key }} {% endif %} nodeRegistration: {% if kube_override_hostname | default('') %} - name: {{ kube_override_hostname }} + name: "{{ kube_override_hostname }}" {% endif %} {% if inventory_hostname in groups['kube_control_plane'] and inventory_hostname not in groups['kube_node'] %} taints: @@ -76,17 +76,17 @@ etcd: {% endfor %} serverCertSANs: {% for san in etcd_cert_alt_names %} - - {{ san }} + - "{{ san }}" {% endfor %} {% for san in etcd_cert_alt_ips %} - - {{ san }} + - "{{ san }}" {% endfor %} peerCertSANs: {% for san in etcd_cert_alt_names %} - - {{ san }} + - "{{ san }}" {% endfor %} {% for san in etcd_cert_alt_ips %} - - {{ san }} + - "{{ san }}" {% endfor %} {% endif %} dns: @@ -294,7 +294,7 @@ apiServer: {% endif %} certSANs: {% for san in apiserver_sans %} - - {{ san }} + - "{{ san }}" {% endfor %} timeoutForControlPlane: 5m0s controllerManager: @@ -416,7 +416,7 @@ conntrack: tcpEstablishedTimeout: {{ kube_proxy_conntrack_tcp_established_timeout }} enableProfiling: {{ kube_proxy_enable_profiling }} healthzBindAddress: {{ kube_proxy_healthz_bind_address }} -hostnameOverride: {{ kube_override_hostname }} +hostnameOverride: "{{ kube_override_hostname }}" iptables: masqueradeAll: {{ kube_proxy_masquerade_all }} masqueradeBit: {{ kube_proxy_masquerade_bit }} diff --git a/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 b/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 index c950d00..cd19b5c 100644 --- a/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 +++ b/kubespray/project/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 @@ -1,6 +1,10 @@ apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration discovery: +{% if kubeadm_use_file_discovery %} + file: + kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml +{% else %} bootstrapToken: {% if kubeadm_config_api_fqdn is defined %} apiServerEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }} @@ -9,6 +13,7 @@ discovery: {% endif %} token: {{ kubeadm_token }} unsafeSkipCAVerification: true +{% endif %} timeout: {{ discovery_timeout }} tlsBootstrapToken: {{ kubeadm_token }} controlPlane: diff --git a/kubespray/project/roles/kubernetes/kubeadm/defaults/main.yml b/kubespray/project/roles/kubernetes/kubeadm/defaults/main.yml index 61b132e..5047de5 100644 --- a/kubespray/project/roles/kubernetes/kubeadm/defaults/main.yml +++ b/kubespray/project/roles/kubernetes/kubeadm/defaults/main.yml @@ -4,6 +4,9 @@ discovery_timeout: 60s kubeadm_join_timeout: 120s +# Enable kubeadm file discovery if anonymous access has been removed +kubeadm_use_file_discovery: "{{ remove_anonymous_access }}" + # If non-empty, will use this string as identification instead of the actual hostname kube_override_hostname: >- {%- if cloud_provider is defined and cloud_provider in ['aws'] -%} diff --git a/kubespray/project/roles/kubernetes/kubeadm/handlers/main.yml b/kubespray/project/roles/kubernetes/kubeadm/handlers/main.yml index 9f6d431..261e1f2 100644 --- a/kubespray/project/roles/kubernetes/kubeadm/handlers/main.yml +++ b/kubespray/project/roles/kubernetes/kubeadm/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: Kubeadm | reload systemd - systemd: + systemd_service: daemon_reload: true listen: Kubeadm | restart kubelet diff --git a/kubespray/project/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml b/kubespray/project/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml index d39ea2b..13420c0 100644 --- a/kubespray/project/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml +++ b/kubespray/project/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml @@ -8,7 +8,7 @@ template: src: "kubeadm-client.conf.{{ kubeadmConfig_api_version }}.j2" dest: "{{ kube_config_dir }}/kubeadm-cert-controlplane.conf" - mode: 0640 + mode: "0640" vars: kubeadm_cert_controlplane: true diff --git a/kubespray/project/roles/kubernetes/kubeadm/tasks/main.yml b/kubespray/project/roles/kubernetes/kubeadm/tasks/main.yml index 4a65dbb..ad6ac36 100644 --- a/kubespray/project/roles/kubernetes/kubeadm/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/kubeadm/tasks/main.yml @@ -14,17 +14,17 @@ - name: Check if kubelet.conf exists stat: path: "{{ kube_config_dir }}/kubelet.conf" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kubelet_conf - name: Check if kubeadm CA cert is accessible stat: path: "{{ kube_cert_dir }}/ca.crt" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kubeadm_ca_stat delegate_to: "{{ groups['kube_control_plane'][0] }}" run_once: true @@ -57,19 +57,37 @@ set_fact: kubeadmConfig_api_version: v1beta3 +- name: Get kubeconfig for join discovery process + command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'" + register: kubeconfig_file_discovery + run_once: true + delegate_to: "{{ groups['kube_control_plane'] | first }}" + when: kubeadm_use_file_discovery + +- name: Copy discovery kubeconfig + copy: + dest: "{{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml" + content: "{{ kubeconfig_file_discovery.stdout }}" + owner: "root" + mode: "0644" + when: + - not is_kube_master + - not kubelet_conf.stat.exists + - kubeadm_use_file_discovery + - name: Create kubeadm client config template: src: "kubeadm-client.conf.{{ kubeadmConfig_api_version }}.j2" dest: "{{ kube_config_dir }}/kubeadm-client.conf" - backup: yes - mode: 0640 + backup: true + mode: "0640" when: not is_kube_master - name: Kubeadm | Create directory to store kubeadm patches file: path: "{{ kubeadm_patches.dest_dir }}" state: directory - mode: 0640 + mode: "0640" when: kubeadm_patches is defined and kubeadm_patches.enabled - name: Kubeadm | Copy kubeadm patches from inventory files @@ -77,7 +95,7 @@ src: "{{ kubeadm_patches.source_dir }}/" dest: "{{ kubeadm_patches.dest_dir }}" owner: "root" - mode: 0644 + mode: "0644" when: kubeadm_patches is defined and kubeadm_patches.enabled - name: Join to cluster if needed @@ -122,7 +140,7 @@ dest: "{{ kube_config_dir }}/kubelet.conf" regexp: 'server:' line: ' server: {{ kube_apiserver_endpoint }}' - backup: yes + backup: true when: - kubeadm_config_api_fqdn is not defined - not is_kube_master @@ -134,12 +152,23 @@ dest: "{{ kube_config_dir }}/kubelet.conf" regexp: '^ server: https' line: ' server: {{ kube_apiserver_endpoint }}' - backup: yes + backup: true when: - not is_kube_master - loadbalancer_apiserver is defined notify: Kubeadm | restart kubelet +- name: Get current resourceVersion of kube-proxy configmap + command: "{{ kubectl }} get configmap kube-proxy -n kube-system -o jsonpath='{.metadata.resourceVersion}'" + register: original_configmap_resource_version + run_once: true + delegate_to: "{{ groups['kube_control_plane'] | first }}" + delegate_facts: false + when: + - kube_proxy_deployed + tags: + - kube-proxy + # FIXME(mattymo): Need to point to localhost, otherwise masters will all point # incorrectly to first master, creating SPoF. - name: Update server field in kube-proxy kubeconfig @@ -176,6 +205,17 @@ tags: - kube-proxy +- name: Get new resourceVersion of kube-proxy configmap + command: "{{ kubectl }} get configmap kube-proxy -n kube-system -o jsonpath='{.metadata.resourceVersion}'" + register: new_configmap_resource_version + run_once: true + delegate_to: "{{ groups['kube_control_plane'] | first }}" + delegate_facts: false + when: + - kube_proxy_deployed + tags: + - kube-proxy + - name: Set ca.crt file permission file: path: "{{ kube_cert_dir }}/ca.crt" @@ -192,6 +232,7 @@ - kubeadm_config_api_fqdn is not defined or loadbalancer_apiserver is defined - kubeadm_discovery_address != kube_apiserver_endpoint | replace("https://", "") or loadbalancer_apiserver is defined - kube_proxy_deployed + - original_configmap_resource_version.stdout != new_configmap_resource_version.stdout tags: - kube-proxy diff --git a/kubespray/project/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 b/kubespray/project/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 index 5104ecf..3b3bc57 100644 --- a/kubespray/project/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 +++ b/kubespray/project/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.v1beta3.j2 @@ -2,6 +2,10 @@ apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration discovery: +{% if kubeadm_use_file_discovery %} + file: + kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml +{% else %} bootstrapToken: {% if kubeadm_config_api_fqdn is defined %} apiServerEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }} @@ -14,6 +18,7 @@ discovery: - sha256:{{ kubeadm_ca_hash.stdout }} {% else %} unsafeSkipCAVerification: true +{% endif %} {% endif %} timeout: {{ discovery_timeout }} tlsBootstrapToken: {{ kubeadm_token }} diff --git a/kubespray/project/roles/kubernetes/node-label/tasks/main.yml b/kubespray/project/roles/kubernetes/node-label/tasks/main.yml index cda700c..3ebb645 100644 --- a/kubespray/project/roles/kubernetes/node-label/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/node-label/tasks/main.yml @@ -2,7 +2,7 @@ - name: Kubernetes Apps | Wait for kube-apiserver uri: url: "{{ kube_apiserver_endpoint }}/healthz" - validate_certs: no + validate_certs: false client_cert: "{{ kube_apiserver_client_cert }}" client_key: "{{ kube_apiserver_client_key }}" register: result @@ -42,7 +42,7 @@ - name: Set label to node command: >- - {{ kubectl }} label node {{ kube_override_hostname | default(inventory_hostname) }} {{ item }} --overwrite=true + {{ kubectl }} label node {% if kube_override_hostname %}{{ kube_override_hostname }}{% else %}{{ inventory_hostname }}{% endif %} {{ item }} --overwrite=true loop: "{{ role_node_labels + inventory_node_labels }}" delegate_to: "{{ groups['kube_control_plane'][0] }}" changed_when: false diff --git a/kubespray/project/roles/kubernetes/node/defaults/main.yml b/kubespray/project/roles/kubernetes/node/defaults/main.yml index b3f8fbf..7b8438e 100644 --- a/kubespray/project/roles/kubernetes/node/defaults/main.yml +++ b/kubespray/project/roles/kubernetes/node/defaults/main.yml @@ -23,14 +23,18 @@ kubelet_kubelet_cgroups_cgroupfs: "/system.slice/kubelet.service" # Set systemd service hardening features kubelet_systemd_hardening: false +# Kubelet service dependencies other than container runtime +kubelet_systemd_wants_dependencies: [] + # List of secure IPs for kubelet -kubelet_secure_addresses: >- - {%- for host in groups['kube_control_plane'] -%} +kube_node_addresses: >- + {%- for host in (groups['kube_control_plane'] + groups['kube_node'] + groups['etcd']) | unique -%} {{ hostvars[host]['ip'] | default(fallback_ips[host]) }}{{ ' ' if not loop.last else '' }} {%- endfor -%} +kubelet_secure_addresses: "localhost link-local {{ kube_pods_subnet }} {{ kube_node_addresses }}" # Reserve this space for kube resources -# Set to true to reserve resources for kube daemons +# Whether to run kubelet and container-engine daemons in a dedicated cgroup. (Not required for resource reservations). kube_reserved: false kube_reserved_cgroups_for_service_slice: kube.slice kube_reserved_cgroups: "/{{ kube_reserved_cgroups_for_service_slice }}" @@ -66,14 +70,16 @@ eviction_hard_control_plane: {} kubelet_status_update_frequency: 10s # kube-vip -kube_vip_version: v0.5.12 +kube_vip_version: v0.8.0 kube_vip_arp_enabled: false kube_vip_interface: kube_vip_services_interface: kube_vip_cidr: 32 +kube_vip_dns_mode: first kube_vip_controlplane_enabled: false kube_vip_ddns_enabled: false +kube_vip_cp_detect: false kube_vip_services_enabled: false kube_vip_leader_election_enabled: "{{ kube_vip_arp_enabled }}" kube_vip_bgp_enabled: false @@ -87,6 +93,12 @@ kube_vip_address: kube_vip_enableServicesElection: false kube_vip_lb_enable: false kube_vip_lb_fwdmethod: local +kube_vip_leasename: plndr-cp-lock +kube_vip_svc_leasename: plndr-svcs-lock +kube_vip_leaseduration: 5 +kube_vip_renewdeadline: 3 +kube_vip_retryperiod: 1 +kube_vip_enable_node_labeling: false # Requests for load balancer app loadbalancer_apiserver_memory_requests: 32M @@ -258,4 +270,7 @@ conntrack_modules: ## Enable distributed tracing for kubelet kubelet_tracing: false kubelet_tracing_endpoint: 0.0.0.0:4317 -kubelet_tracing_sampling_rate_per_million: 100 \ No newline at end of file +kubelet_tracing_sampling_rate_per_million: 100 + +# The maximum number of image pulls in parallel. Set it to a integer great than 1 to enable image pulling in parallel. +kubelet_max_parallel_image_pulls: 1 diff --git a/kubespray/project/roles/kubernetes/node/handlers/main.yml b/kubespray/project/roles/kubernetes/node/handlers/main.yml index 8195b7d..fa08dba 100644 --- a/kubespray/project/roles/kubernetes/node/handlers/main.yml +++ b/kubespray/project/roles/kubernetes/node/handlers/main.yml @@ -1,6 +1,6 @@ --- - name: Kubelet | reload systemd - systemd: + systemd_service: daemon_reload: true listen: Node | restart kubelet diff --git a/kubespray/project/roles/kubernetes/node/tasks/facts.yml b/kubespray/project/roles/kubernetes/node/tasks/facts.yml index 0aaa11d..6e89952 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/facts.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/facts.yml @@ -8,7 +8,7 @@ executable: /bin/bash register: docker_cgroup_driver_result changed_when: false - check_mode: no + check_mode: false - name: Set kubelet_cgroup_driver_detected fact for docker set_fact: diff --git a/kubespray/project/roles/kubernetes/node/tasks/install.yml b/kubespray/project/roles/kubernetes/node/tasks/install.yml index fb1e8ad..a89ba94 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/install.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/install.yml @@ -3,7 +3,7 @@ copy: src: "{{ downloads.kubeadm.dest }}" dest: "{{ bin_dir }}/kubeadm" - mode: 0755 + mode: "0755" remote_src: true tags: - kubeadm @@ -14,7 +14,7 @@ copy: src: "{{ downloads.kubelet.dest }}" dest: "{{ bin_dir }}/kubelet" - mode: 0755 + mode: "0755" remote_src: true tags: - kubelet diff --git a/kubespray/project/roles/kubernetes/node/tasks/kubelet.yml b/kubespray/project/roles/kubernetes/node/tasks/kubelet.yml index d8ff9e2..1f27bd0 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/kubelet.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/kubelet.yml @@ -11,8 +11,8 @@ src: "kubelet.env.{{ kubeletConfig_api_version }}.j2" dest: "{{ kube_config_dir }}/kubelet.env" setype: "{{ (preinstall_selinux_state != 'disabled') | ternary('etc_t', omit) }}" - backup: yes - mode: 0600 + backup: true + mode: "0600" notify: Node | restart kubelet tags: - kubelet @@ -22,7 +22,7 @@ template: src: "kubelet-config.{{ kubeletConfig_api_version }}.yaml.j2" dest: "{{ kube_config_dir }}/kubelet-config.yaml" - mode: 0600 + mode: "0600" notify: Kubelet | restart kubelet tags: - kubelet @@ -32,8 +32,8 @@ template: src: "kubelet.service.j2" dest: "/etc/systemd/system/kubelet.service" - backup: "yes" - mode: 0600 + backup: true + mode: "0600" validate: "sh -c '[ -f /usr/bin/systemd/system/factory-reset.target ] || exit 0 && systemd-analyze verify %s:kubelet.service'" # FIXME: check that systemd version >= 250 (factory-reset.target was introduced in that release) # Remove once we drop support for systemd < 250 @@ -48,7 +48,7 @@ - name: Enable kubelet service: name: kubelet - enabled: yes + enabled: true state: started tags: - kubelet diff --git a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/haproxy.yml b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/haproxy.yml index 7e5cfce..b4c5812 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/haproxy.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/haproxy.yml @@ -8,7 +8,7 @@ file: path: "{{ haproxy_config_dir }}" state: directory - mode: 0755 + mode: "0755" owner: root - name: Haproxy | Write haproxy configuration @@ -16,19 +16,19 @@ src: "loadbalancer/haproxy.cfg.j2" dest: "{{ haproxy_config_dir }}/haproxy.cfg" owner: root - mode: 0755 - backup: yes + mode: "0755" + backup: true - name: Haproxy | Get checksum from config stat: path: "{{ haproxy_config_dir }}/haproxy.cfg" - get_attributes: no - get_checksum: yes - get_mime: no + get_attributes: false + get_checksum: true + get_mime: false register: haproxy_stat - name: Haproxy | Write static pod template: src: manifests/haproxy.manifest.j2 dest: "{{ kube_manifest_dir }}/haproxy.yml" - mode: 0640 + mode: "0640" diff --git a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/kube-vip.yml b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/kube-vip.yml index f7b04a6..b52261a 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/kube-vip.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/kube-vip.yml @@ -6,8 +6,34 @@ - kube_proxy_mode == 'ipvs' and not kube_proxy_strict_arp - kube_vip_arp_enabled +- name: Kube-vip | Check if super-admin.conf exists + stat: + path: "{{ kube_config_dir }}/super-admin.conf" + failed_when: false + changed_when: false + register: stat_kube_vip_super_admin + +- name: Kube-vip | Check if kubeadm has already run + stat: + path: "/var/lib/kubelet/config.yaml" + get_attributes: false + get_checksum: false + get_mime: false + register: kubeadm_already_run + +- name: Kube-vip | Set admin.conf + set_fact: + kube_vip_admin_conf: admin.conf + +- name: Kube-vip | Set admin.conf for first Control Plane + set_fact: + kube_vip_admin_conf: super-admin.conf + when: + - inventory_hostname == groups['kube_control_plane'] | first + - (stat_kube_vip_super_admin.stat.exists and stat_kube_vip_super_admin.stat.isreg) or (not kubeadm_already_run.stat.exists ) + - name: Kube-vip | Write static pod template: src: manifests/kube-vip.manifest.j2 dest: "{{ kube_manifest_dir }}/kube-vip.yml" - mode: 0640 + mode: "0640" diff --git a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/nginx-proxy.yml b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/nginx-proxy.yml index 5b82ff6..66ebe55 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/nginx-proxy.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/loadbalancer/nginx-proxy.yml @@ -8,7 +8,7 @@ file: path: "{{ nginx_config_dir }}" state: directory - mode: 0700 + mode: "0700" owner: root - name: Nginx-proxy | Write nginx-proxy configuration @@ -16,19 +16,19 @@ src: "loadbalancer/nginx.conf.j2" dest: "{{ nginx_config_dir }}/nginx.conf" owner: root - mode: 0755 - backup: yes + mode: "0755" + backup: true - name: Nginx-proxy | Get checksum from config stat: path: "{{ nginx_config_dir }}/nginx.conf" - get_attributes: no - get_checksum: yes - get_mime: no + get_attributes: false + get_checksum: true + get_mime: false register: nginx_stat - name: Nginx-proxy | Write static pod template: src: manifests/nginx-proxy.manifest.j2 dest: "{{ kube_manifest_dir }}/nginx-proxy.yml" - mode: 0640 + mode: "0640" diff --git a/kubespray/project/roles/kubernetes/node/tasks/main.yml b/kubespray/project/roles/kubernetes/node/tasks/main.yml index 9e15b16..56117bc 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/main.yml @@ -14,7 +14,7 @@ file: path: /var/lib/cni state: directory - mode: 0755 + mode: "0755" - name: Install kubelet binary import_tasks: install.yml @@ -51,10 +51,10 @@ ansible.posix.sysctl: name: net.ipv4.ip_local_reserved_ports value: "{{ kube_apiserver_node_port_range }}" - sysctl_set: yes + sysctl_set: true sysctl_file: "{{ sysctl_file_path }}" state: present - reload: yes + reload: true when: kube_apiserver_node_port_range is defined tags: - kube-proxy @@ -66,7 +66,7 @@ register: modinfo_br_netfilter failed_when: modinfo_br_netfilter.rc not in [0, 1] changed_when: false - check_mode: no + check_mode: false # TODO: Remove once upstream issue is fixed # https://github.com/ansible-collections/community.general/issues/7717 @@ -74,7 +74,7 @@ file: path: "{{ item }}" state: directory - mode: 0755 + mode: "0755" loop: - /etc/modules-load.d - /etc/modprobe.d @@ -89,7 +89,7 @@ copy: dest: /etc/modules-load.d/kubespray-br_netfilter.conf content: br_netfilter - mode: 0644 + mode: "0644" when: modinfo_br_netfilter.rc == 0 # kube-proxy needs net.bridge.bridge-nf-call-iptables enabled when found if br_netfilter is not a module @@ -97,7 +97,7 @@ command: "sysctl net.bridge.bridge-nf-call-iptables" failed_when: false changed_when: false - check_mode: no + check_mode: false register: sysctl_bridge_nf_call_iptables - name: Enable bridge-nf-call tables @@ -106,7 +106,7 @@ state: present sysctl_file: "{{ sysctl_file_path }}" value: "1" - reload: yes + reload: true when: sysctl_bridge_nf_call_iptables.rc == 0 with_items: - net.bridge.bridge-nf-call-iptables @@ -162,7 +162,7 @@ content: "{{ openstack_cacert | b64decode if openstack_cacert_is_base64 else omit }}" dest: "{{ kube_config_dir }}/openstack-cacert.pem" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" when: - cloud_provider is defined - cloud_provider == 'openstack' @@ -176,7 +176,7 @@ src: "cloud-configs/{{ cloud_provider }}-cloud-config.j2" dest: "{{ kube_config_dir }}/cloud_config" group: "{{ kube_cert_group }}" - mode: 0640 + mode: "0640" when: - cloud_provider is defined - cloud_provider in [ 'openstack', 'azure', 'vsphere', 'aws', 'gce' ] diff --git a/kubespray/project/roles/kubernetes/node/tasks/pre_upgrade.yml b/kubespray/project/roles/kubernetes/node/tasks/pre_upgrade.yml index d9c2d07..e4bbf6b 100644 --- a/kubespray/project/roles/kubernetes/node/tasks/pre_upgrade.yml +++ b/kubespray/project/roles/kubernetes/node/tasks/pre_upgrade.yml @@ -11,7 +11,7 @@ executable: /bin/bash failed_when: false changed_when: false - check_mode: no + check_mode: false register: kubelet_container_check - name: "Pre-upgrade | copy /var/lib/cni from kubelet" diff --git a/kubespray/project/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2 b/kubespray/project/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2 index ba90fc9..bc59f03 100644 --- a/kubespray/project/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2 +++ b/kubespray/project/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2 @@ -62,9 +62,10 @@ clusterDNS: {# Node reserved CPU/memory #} {% if kube_reserved | bool %} kubeReservedCgroup: {{ kube_reserved_cgroups }} +{% endif %} kubeReserved: {% if is_kube_master | bool %} - cpu: {{ kube_master_cpu_reserved }} + cpu: "{{ kube_master_cpu_reserved }}" memory: {{ kube_master_memory_reserved }} {% if kube_master_ephemeral_storage_reserved is defined %} ephemeral-storage: {{ kube_master_ephemeral_storage_reserved }} @@ -73,7 +74,7 @@ kubeReserved: pid: "{{ kube_master_pid_reserved }}" {% endif %} {% else %} - cpu: {{ kube_cpu_reserved }} + cpu: "{{ kube_cpu_reserved }}" memory: {{ kube_memory_reserved }} {% if kube_ephemeral_storage_reserved is defined %} ephemeral-storage: {{ kube_ephemeral_storage_reserved }} @@ -82,12 +83,11 @@ kubeReserved: pid: "{{ kube_pid_reserved }}" {% endif %} {% endif %} -{% endif %} {% if system_reserved | bool %} systemReservedCgroup: {{ system_reserved_cgroups }} systemReserved: {% if is_kube_master | bool %} - cpu: {{ system_master_cpu_reserved }} + cpu: "{{ system_master_cpu_reserved }}" memory: {{ system_master_memory_reserved }} {% if system_master_ephemeral_storage_reserved is defined %} ephemeral-storage: {{ system_master_ephemeral_storage_reserved }} @@ -96,7 +96,7 @@ systemReserved: pid: "{{ system_master_pid_reserved }}" {% endif %} {% else %} - cpu: {{ system_cpu_reserved }} + cpu: "{{ system_cpu_reserved }}" memory: {{ system_memory_reserved }} {% if system_ephemeral_storage_reserved is defined %} ephemeral-storage: {{ system_ephemeral_storage_reserved }} @@ -160,6 +160,10 @@ seccompDefault: {{ kubelet_seccomp_default | bool }} {% if kubelet_cpu_manager_policy is defined %} cpuManagerPolicy: {{ kubelet_cpu_manager_policy }} {% endif %} +{% if kubelet_cpu_manager_policy_options is defined %} +cpuManagerPolicyOptions: + {{ kubelet_cpu_manager_policy_options | to_nice_yaml(indent=2) }} +{% endif %} {% if kubelet_topology_manager_policy is defined %} topologyManagerPolicy: {{ kubelet_topology_manager_policy }} {% endif %} @@ -170,4 +174,5 @@ topologyManagerScope: {{ kubelet_topology_manager_scope }} tracing: endpoint: {{ kubelet_tracing_endpoint }} samplingRatePerMillion: {{ kubelet_tracing_sampling_rate_per_million }} -{% endif %} \ No newline at end of file +{% endif %} +maxParallelImagePulls: {{ kubelet_max_parallel_image_pulls }} diff --git a/kubespray/project/roles/kubernetes/node/templates/kubelet.service.j2 b/kubespray/project/roles/kubernetes/node/templates/kubelet.service.j2 index 9df98e0..7b072bb 100644 --- a/kubespray/project/roles/kubernetes/node/templates/kubelet.service.j2 +++ b/kubespray/project/roles/kubernetes/node/templates/kubelet.service.j2 @@ -7,6 +7,11 @@ Wants=docker.socket {% else %} Wants={{ container_manager }}.service {% endif %} +{% for kubelet_dependency in kubelet_systemd_wants_dependencies|default([]) %} +{% if kubelet_dependency|length > 0 %} +Wants={{ kubelet_dependency }} +{% endif %} +{% endfor %} [Service] EnvironmentFile=-{{ kube_config_dir }}/kubelet.env diff --git a/kubespray/project/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2 b/kubespray/project/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2 index 936ad44..35b6f0e 100644 --- a/kubespray/project/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2 +++ b/kubespray/project/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2 @@ -1,4 +1,4 @@ -# Inspired by https://github.com/kube-vip/kube-vip/blob/v0.5.11/pkg/kubevip/config_generator.go#L13 +# Inspired by https://github.com/kube-vip/kube-vip/blob/v0.8.0/pkg/kubevip/config_generator.go#L103 apiVersion: v1 kind: Pod metadata: @@ -16,6 +16,8 @@ spec: value: {{ kube_vip_arp_enabled | string | to_json }} - name: port value: {{ kube_apiserver_port | string | to_json }} + - name: vip_nodename + value: {{ inventory_hostname }} {% if kube_vip_interface %} - name: vip_interface value: {{ kube_vip_interface | string | to_json }} @@ -28,6 +30,10 @@ spec: - name: vip_cidr value: {{ kube_vip_cidr | string | to_json }} {% endif %} +{% if kube_vip_dns_mode %} + - name: dns_mode + value: {{ kube_vip_dns_mode | string | to_json }} +{% endif %} {% if kube_vip_controlplane_enabled %} - name: cp_enable value: "true" @@ -35,11 +41,17 @@ spec: value: kube-system - name: vip_ddns value: {{ kube_vip_ddns_enabled | string | to_json }} + - name: cp_detect + value: {{ kube_vip_cp_detect | string | to_json }} {% endif %} {% if kube_vip_services_enabled %} - name: svc_enable value: "true" {% endif %} +{% if kube_vip_svc_leasename %} + - name: svc_leasename + value: {{ kube_vip_svc_leasename | string | to_json }} +{% endif %} {% if kube_vip_enableServicesElection %} - name: svc_election value: "true" @@ -47,12 +59,18 @@ spec: {% if kube_vip_leader_election_enabled %} - name: vip_leaderelection value: "true" + - name: vip_leasename + value: {{ kube_vip_leasename | string | to_json }} - name: vip_leaseduration - value: "5" + value: {{ kube_vip_leaseduration | string | to_json }} - name: vip_renewdeadline - value: "3" + value: {{ kube_vip_renewdeadline | string | to_json }} - name: vip_retryperiod - value: "1" + value: {{ kube_vip_retryperiod | string | to_json }} +{% endif %} +{% if kube_vip_enable_node_labeling %} + - name: enable_node_labeling + value: {{ kube_vip_enable_node_labeling | string | to_json }} {% endif %} {% if kube_vip_bgp_enabled %} - name: bgp_enable @@ -101,6 +119,6 @@ spec: hostNetwork: true volumes: - hostPath: - path: /etc/kubernetes/admin.conf + path: /etc/kubernetes/{{kube_vip_admin_conf}} name: kubeconfig status: {} diff --git a/kubespray/project/roles/kubernetes/node/vars/ubuntu-24.yml b/kubespray/project/roles/kubernetes/node/vars/ubuntu-24.yml new file mode 100644 index 0000000..59bc55d --- /dev/null +++ b/kubespray/project/roles/kubernetes/node/vars/ubuntu-24.yml @@ -0,0 +1,2 @@ +--- +kube_resolv_conf: "/run/systemd/resolve/resolv.conf" diff --git a/kubespray/project/roles/kubernetes/preinstall/defaults/main.yml b/kubespray/project/roles/kubernetes/preinstall/defaults/main.yml index eb33ed3..bf537f1 100644 --- a/kubespray/project/roles/kubernetes/preinstall/defaults/main.yml +++ b/kubespray/project/roles/kubernetes/preinstall/defaults/main.yml @@ -6,18 +6,6 @@ epel_enabled: false # Kubespray sets this to true after clusterDNS is running to apply changes to the host resolv.conf dns_late: false -common_required_pkgs: - - "{{ (ansible_distribution == 'openSUSE Tumbleweed') | ternary('openssl-1_1', 'openssl') }}" - - curl - - rsync - - socat - - unzip - - e2fsprogs - - xfsprogs - - ebtables - - bash-completion - - tar - # Set to true if your network does not support IPv6 # This may be necessary for pulling Docker images from # GCE docker repository @@ -98,6 +86,13 @@ ntp_servers: ntp_restrict: - "127.0.0.1" - "::1" +# Specify whether to filter interfaces +ntp_filter_interface: false +# Specify the interfaces +# Only takes effect when ntp_filter_interface is true +# ntp_interfaces: +# - ignore wildcard +# - listen xxx # The NTP driftfile path # Only takes effect when ntp_manage_config is true. ntp_driftfile: /var/lib/ntp/ntp.drift @@ -135,21 +130,12 @@ supported_os_distributions: # Extending some distributions into the redhat os family redhat_os_family_extensions: - - "Kylin Linux Advanced Server" - - "openEuler" - "UnionTech" - "UniontechOS" -# Extending some distributions into the debian os family -debian_os_family_extensions: - - "UnionTech OS Server 20" - # Sets DNSStubListener=no, useful if you get "0.0.0.0:53: bind: address already in use" systemd_resolved_disable_stub_listener: "{{ ansible_os_family in ['Flatcar', 'Flatcar Container Linux by Kinvolk'] }}" # Used to disable File Access Policy Daemon service. # If service is enabled, the CNI plugin installation will fail disable_fapolicyd: true - -# Enable 0120-growpart-azure-centos-7 tasks -growpart_azure_enabled: true diff --git a/kubespray/project/roles/kubernetes/preinstall/files/pkgs-schema.json b/kubespray/project/roles/kubernetes/preinstall/files/pkgs-schema.json new file mode 100644 index 0000000..1fb9e28 --- /dev/null +++ b/kubespray/project/roles/kubernetes/preinstall/files/pkgs-schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://kubespray.io/internal/os_packages.schema.json", + "title": "Os packages", + "description": "Criteria for selecting packages to install on Kubernetes nodes during installation by Kubespray", + "type": "object", + "patternProperties": { + ".*": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Escape hatch to filter packages. The value is expected to be pre-resolved to a boolean by Jinja", + "type": "boolean", + "default": true + }, + "groups": { + "description": "Match if the host is in one of these groups. If not specified match any host.", + "type": "array", + "minItems": 1, + "items":{ + "type": "string", + "pattern": "^[0-9A-Za-z_]*$" + } + }, + "os": { + "type": "object", + "description": "If not specified match any OS. Otherwise, must match by 'families' or 'distributions' to be included.", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "families": { + "description": "Match if ansible_os_family is part of the list.", + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "distributions": { + "type": "object", + "description": "Match if ansible_distribution match one of defined keys.", + "minProperties": 1, + "patternProperties": { + ".*": { + "description": "Match if either the value is the empty hash, or one major_versions/versions/releases contains the corresponding variable ('ansible_distrbution_*')", + "type": "object", + "additionalProperties": false, + "properties": { + "major_versions": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "versions": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "releases": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/kubespray/project/roles/kubernetes/preinstall/gen-gitinfos.sh b/kubespray/project/roles/kubernetes/preinstall/gen-gitinfos.sh deleted file mode 100755 index bfab5a4..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/gen-gitinfos.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -set -e - -# Text color variables -txtbld=$(tput bold) # Bold -bldred=${txtbld}$(tput setaf 1) # red -bldgre=${txtbld}$(tput setaf 2) # green -bldylw=${txtbld}$(tput setaf 3) # yellow -txtrst=$(tput sgr0) # Reset -err=${bldred}ERROR${txtrst} -info=${bldgre}INFO${txtrst} -warn=${bldylw}WARNING${txtrst} - -usage() -{ - cat << EOF -Generates a file which contains useful git informations - -Usage : $(basename $0) [global|diff] - ex : - Generate git information - $(basename $0) global - Generate diff from latest tag - $(basename $0) diff -EOF -} - -if [ $# != 1 ]; then - printf "\n$err : Needs 1 argument\n" - usage - exit 2 -fi; - -current_commit=$(git rev-parse HEAD) -latest_tag=$(git describe --abbrev=0 --tags) -latest_tag_commit=$(git show-ref -s ${latest_tag}) -tags_list=$(git tag --points-at "${latest_tag}") - -case ${1} in - "global") -cat< 0 -%} + supersede domain-name-servers {{ dhclient_supersede_nameserver_entries_list | join(', ') }}; + {%- endif -%} - name: Set etcd vars if using kubeadm mode set_fact: @@ -260,9 +218,9 @@ - name: Check /usr readonly stat: path: "/usr" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: usr - name: Set alternate flexvolume path diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0040-verify-settings.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0040-verify-settings.yml index f2d40e9..af9ca06 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0040-verify-settings.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0040-verify-settings.yml @@ -1,10 +1,7 @@ --- -- name: Stop if either kube_control_plane or kube_node group is empty +- name: Stop if kube_control_plane group is empty assert: - that: "groups.get( item )" - with_items: - - kube_control_plane - - kube_node + that: groups.get( 'kube_control_plane' ) run_once: true when: not ignore_assert_errors @@ -47,7 +44,7 @@ assert: that: item.value | type_debug == 'bool' msg: "{{ item.value }} isn't a bool" - run_once: yes + run_once: true with_items: - { name: download_run_once, value: "{{ download_run_once }}" } - { name: deploy_netchecker, value: "{{ deploy_netchecker }}" } @@ -77,6 +74,13 @@ - not ignore_assert_errors - inventory_hostname in groups['kube_node'] +# This command will fail if cgroups are not enabled on the node. +# For reference: https://kubernetes.io/docs/concepts/architecture/cgroups/#check-cgroup-version +- name: Stop if cgroups are not enabled on nodes + command: stat -fc %T /sys/fs/cgroup/ + changed_when: false + when: not ignore_assert_errors + # This assertion will fail on the safe side: One can indeed schedule more pods # on a node than the CIDR-range has space for when additional pods use the host # network namespace. It is impossible to ascertain the number of such pods at @@ -168,21 +172,21 @@ that: - kube_service_addresses | ansible.utils.ipaddr('net') msg: "kube_service_addresses = '{{ kube_service_addresses }}' is not a valid network range" - run_once: yes + run_once: true - name: "Check that kube_pods_subnet is a network range" assert: that: - kube_pods_subnet | ansible.utils.ipaddr('net') msg: "kube_pods_subnet = '{{ kube_pods_subnet }}' is not a valid network range" - run_once: yes + run_once: true - name: "Check that kube_pods_subnet does not collide with kube_service_addresses" assert: that: - kube_pods_subnet | ansible.utils.ipaddr(kube_service_addresses) | string == 'None' msg: "kube_pods_subnet cannot be the same network segment as kube_service_addresses" - run_once: yes + run_once: true - name: "Check that IP range is enough for the nodes" assert: @@ -190,7 +194,7 @@ - 2 ** (kube_network_node_prefix - kube_pods_subnet | ansible.utils.ipaddr('prefix')) >= groups['k8s_cluster'] | length msg: "Not enough IPs are available for the desired node count." when: kube_network_plugin != 'calico' - run_once: yes + run_once: true - name: Stop if unknown dns mode assert: @@ -242,7 +246,7 @@ # TODO: Clean this task up when we drop backward compatibility support for `etcd_kubeadm_enabled` - name: Stop if etcd deployment type is not host or kubeadm when container_manager != docker and etcd_kubeadm_enabled is not defined - run_once: yes + run_once: true when: etcd_kubeadm_enabled is defined block: - name: Warn the user if they are still using `etcd_kubeadm_enabled` @@ -288,7 +292,7 @@ assert: that: containerd_version is version(containerd_min_version_required, '>=') msg: "containerd_version is too low. Minimum version {{ containerd_min_version_required }}" - run_once: yes + run_once: true when: - containerd_version not in ['latest', 'edge', 'stable'] - container_manager == 'containerd' @@ -316,3 +320,15 @@ when: - kube_apiserver_enable_admission_plugins is defined - kube_apiserver_enable_admission_plugins | length > 0 + +- name: Verify that the packages list structure is valid + ansible.utils.validate: + criteria: "{{ lookup('file', 'pkgs-schema.json') }}" + data: "{{ pkgs }}" + +- name: Verify that the packages list is sorted + vars: + pkgs_lists: "{{ pkgs.keys() | list }}" + assert: + that: "pkgs_lists | sort == pkgs_lists" + fail_msg: "pkgs is not sorted: {{ pkgs_lists | ansible.utils.fact_diff(pkgs_lists | sort) }}" diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0050-create_directories.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0050-create_directories.yml index f773989..507a72d 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0050-create_directories.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0050-create_directories.yml @@ -4,7 +4,7 @@ path: "{{ item }}" state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" when: inventory_hostname in groups['k8s_cluster'] become: true tags: @@ -28,7 +28,7 @@ path: "{{ item }}" state: directory owner: root - mode: 0755 + mode: "0755" when: inventory_hostname in groups['k8s_cluster'] become: true tags: @@ -48,9 +48,9 @@ - name: Check if kubernetes kubeadm compat cert dir exists stat: path: "{{ kube_cert_compat_dir }}" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kube_cert_compat_dir_check when: - inventory_hostname in groups['k8s_cluster'] @@ -61,7 +61,7 @@ src: "{{ kube_cert_dir }}" dest: "{{ kube_cert_compat_dir }}" state: link - mode: 0755 + mode: "0755" when: - inventory_hostname in groups['k8s_cluster'] - kube_cert_dir != kube_cert_compat_dir @@ -72,7 +72,7 @@ path: "{{ item }}" state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" with_items: - "/etc/cni/net.d" - "/opt/cni/bin" @@ -93,7 +93,7 @@ path: "{{ item }}" state: directory owner: "{{ kube_owner }}" - mode: 0755 + mode: "0755" with_items: - "/var/lib/calico" when: diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0060-resolvconf.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0060-resolvconf.yml index da5fc85..9aad0db 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0060-resolvconf.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0060-resolvconf.yml @@ -16,10 +16,10 @@ options ndots:{{ ndots }} timeout:{{ dns_timeout | default('2') }} attempts:{{ dns_attempts | default('2') }} state: present insertbefore: BOF - create: yes + create: true backup: "{{ not resolvconf_stat.stat.islnk }}" marker: "# Ansible entries {mark}" - mode: 0644 + mode: "0644" notify: Preinstall | propagate resolvconf to k8s components - name: Remove search/domain/nameserver options before block @@ -53,6 +53,6 @@ dest: "{{ resolveconf_cloud_init_conf }}" src: resolvconf.j2 owner: root - mode: 0644 + mode: "0644" notify: Preinstall | update resolvconf for Flatcar Container Linux by Kinvolk when: ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk"] diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0061-systemd-resolved.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0061-systemd-resolved.yml index 9edec2e..f1aa8f5 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0061-systemd-resolved.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0061-systemd-resolved.yml @@ -3,7 +3,7 @@ file: state: directory name: /etc/systemd/resolved.conf.d/ - mode: 0755 + mode: "0755" - name: Write Kubespray DNS settings to systemd-resolved template: @@ -11,5 +11,5 @@ dest: /etc/systemd/resolved.conf.d/kubespray.conf owner: root group: root - mode: 0644 + mode: "0644" notify: Preinstall | Restart systemd-resolved diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0062-networkmanager-unmanaged-devices.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0062-networkmanager-unmanaged-devices.yml index 44d6191..6ebed25 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0062-networkmanager-unmanaged-devices.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0062-networkmanager-unmanaged-devices.yml @@ -3,7 +3,7 @@ file: path: "/etc/NetworkManager/conf.d" state: directory - recurse: yes + recurse: true - name: NetworkManager | Prevent NetworkManager from managing Calico interfaces (cali*/tunl*/vxlan.calico) copy: @@ -11,7 +11,7 @@ [keyfile] unmanaged-devices+=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico dest: /etc/NetworkManager/conf.d/calico.conf - mode: 0644 + mode: "0644" when: - kube_network_plugin == "calico" notify: Preinstall | reload NetworkManager @@ -24,5 +24,5 @@ [keyfile] unmanaged-devices+=interface-name:kube-ipvs0;interface-name:nodelocaldns dest: /etc/NetworkManager/conf.d/k8s.conf - mode: 0644 + mode: "0644" notify: Preinstall | reload NetworkManager diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0063-networkmanager-dns.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0063-networkmanager-dns.yml index e155f0a..6dfa724 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0063-networkmanager-dns.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0063-networkmanager-dns.yml @@ -6,7 +6,7 @@ option: servers value: "{{ nameserverentries }}" mode: '0600' - backup: yes + backup: true when: - nameserverentries != "127.0.0.53" or systemd_resolved_enabled.rc != 0 notify: Preinstall | update resolvconf for networkmanager @@ -23,7 +23,7 @@ option: searches value: "{{ (default_searchdomains | default([]) + searchdomains | default([])) | join(',') }}" mode: '0600' - backup: yes + backup: true notify: Preinstall | update resolvconf for networkmanager - name: NetworkManager | Add DNS options to NM configuration @@ -33,5 +33,5 @@ option: options value: "ndots:{{ ndots }},timeout:{{ dns_timeout | default('2') }},attempts:{{ dns_attempts | default('2') }}" mode: '0600' - backup: yes + backup: true notify: Preinstall | update resolvconf for networkmanager diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0070-system-packages.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0070-system-packages.yml index ccfb490..c8b480c 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0070-system-packages.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0070-system-packages.yml @@ -30,11 +30,11 @@ Pin-Priority: 1001 dest: "/etc/apt/preferences.d/libseccomp2" owner: "root" - mode: 0644 + mode: "0644" - name: Update package management cache (APT) apt: - update_cache: yes + update_cache: true cache_valid_time: 3600 when: ansible_os_family == "Debian" tags: @@ -48,20 +48,6 @@ - ansible_os_family == "RedHat" - not is_fedora_coreos -- name: Install python3-dnf for latest RedHat versions - command: dnf install -y python3-dnf - register: dnf_task_result - until: dnf_task_result is succeeded - retries: 4 - delay: "{{ retry_stagger | random + 3 }}" - when: - - ansible_distribution == "Fedora" - - ansible_distribution_major_version | int >= 30 - - not is_fedora_coreos - changed_when: False - tags: - - bootstrap-os - - name: Install epel-release on RHEL derivatives package: name: epel-release @@ -73,27 +59,29 @@ tags: - bootstrap-os -- name: Update common_required_pkgs with ipvsadm when kube_proxy_mode is ipvs - set_fact: - common_required_pkgs: "{{ common_required_pkgs | default([]) + ['ipvsadm', 'ipset'] }}" - when: kube_proxy_mode == 'ipvs' - - name: Install packages requirements + vars: + # The json_query for selecting packages name is split for readability + # see files/pkgs-schema.json for the structure of `pkgs` + # and the matching semantics + full_query: "[? value | (enabled == null || enabled) && ( {{ filters_os }} ) && ( {{ filters_groups }} ) ].key" + filters_groups: "groups | @ == null || [? contains(`{{ group_names }}`, @)]" + filters_os: "os == null || (os | ( {{ filters_family }} ) || ( {{ filters_distro }} ))" + dquote: !unsafe '"' + # necessary to workaround Ansible escaping + filters_distro: "distributions.{{ dquote }}{{ ansible_distribution }}{{ dquote }} | + @ == `{}` || + contains(not_null(major_versions, `[]`), '{{ ansible_distribution_major_version }}') || + contains(not_null(versions, `[]`), '{{ ansible_distribution_version }}') || + contains(not_null(releases, `[]`), '{{ ansible_distribution_release }}')" + filters_family: "families && contains(families, '{{ ansible_os_family }}')" package: - name: "{{ required_pkgs | default([]) | union(common_required_pkgs | default([])) }}" + name: "{{ pkgs | dict2items | to_json|from_json | community.general.json_query(full_query) }}" state: present register: pkgs_task_result until: pkgs_task_result is succeeded retries: "{{ pkg_install_retries }}" delay: "{{ retry_stagger | random + 3 }}" - when: not (ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk", "ClearLinux"] or is_fedora_coreos) + when: not (ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk"] or is_fedora_coreos) tags: - bootstrap-os - -- name: Install ipvsadm for ClearLinux - package: - name: ipvsadm - state: present - when: - - ansible_os_family in ["ClearLinux"] - - kube_proxy_mode == 'ipvs' diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0080-system-configurations.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0080-system-configurations.yml index 8159dcc..8941a64 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0080-system-configurations.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0080-system-configurations.yml @@ -3,9 +3,9 @@ - name: Confirm selinux deployed stat: path: /etc/selinux/config - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false when: - ansible_os_family == "RedHat" - "'Amazon' not in ansible_distribution" @@ -27,9 +27,9 @@ dest: /etc/gai.conf line: "precedence ::ffff:0:0/96 100" state: present - create: yes - backup: yes - mode: 0644 + create: true + backup: true + mode: "0644" when: - disable_ipv6_dns - not ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk"] @@ -47,9 +47,9 @@ - name: Stat sysctl file configuration stat: path: "{{ sysctl_file_path }}" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: sysctl_file_stat tags: - bootstrap-os @@ -67,7 +67,7 @@ file: name: "{{ sysctl_file_path | dirname }}" state: directory - mode: 0755 + mode: "0755" - name: Enable ip forwarding ansible.posix.sysctl: @@ -75,7 +75,7 @@ name: net.ipv4.ip_forward value: "1" state: present - reload: yes + reload: true - name: Enable ipv6 forwarding ansible.posix.sysctl: @@ -83,15 +83,15 @@ name: net.ipv6.conf.all.forwarding value: "1" state: present - reload: yes + reload: true when: enable_dual_stack_networks | bool - name: Check if we need to set fs.may_detach_mounts stat: path: /proc/sys/fs/may_detach_mounts - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: fs_may_detach_mounts ignore_errors: true # noqa ignore-errors @@ -101,16 +101,16 @@ name: fs.may_detach_mounts value: 1 state: present - reload: yes + reload: true when: fs_may_detach_mounts.stat.exists | d(false) -- name: Ensure kube-bench parameters are set +- name: Ensure kubelet expected parameters are set ansible.posix.sysctl: sysctl_file: "{{ sysctl_file_path }}" name: "{{ item.name }}" value: "{{ item.value }}" state: present - reload: yes + reload: true with_items: - { name: kernel.keys.root_maxbytes, value: 25000000 } - { name: kernel.keys.root_maxkeys, value: 1000000 } @@ -133,12 +133,12 @@ name: "{{ item.name }}" value: "{{ item.value }}" state: present - reload: yes + reload: true with_items: "{{ additional_sysctl }}" - name: Disable fapolicyd service failed_when: false - systemd: + systemd_service: name: fapolicyd state: stopped enabled: false diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0081-ntp-configurations.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0081-ntp-configurations.yml index da4b312..b1e2fee 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0081-ntp-configurations.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0081-ntp-configurations.yml @@ -40,7 +40,7 @@ template: src: "{{ ntp_config_file | basename }}.j2" dest: "{{ ntp_config_file }}" - mode: 0644 + mode: "0644" notify: Preinstall | restart ntp when: - ntp_manage_config diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0090-etchosts.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0090-etchosts.yml index 6bec169..0b44d26 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0090-etchosts.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0090-etchosts.yml @@ -11,19 +11,19 @@ {% endfor %} delegate_to: localhost connection: local - delegate_facts: yes - run_once: yes + delegate_facts: true + run_once: true - name: Hosts | populate inventory into hosts file blockinfile: path: /etc/hosts block: "{{ hostvars.localhost.etc_hosts_inventory_block }}" state: "{{ 'present' if populate_inventory_to_hosts_file else 'absent' }}" - create: yes - backup: yes - unsafe_writes: yes + create: true + backup: true + unsafe_writes: true marker: "# Ansible inventory hosts {mark}" - mode: 0644 + mode: "0644" - name: Hosts | populate kubernetes loadbalancer address into hosts file lineinfile: @@ -31,8 +31,8 @@ regexp: ".*{{ apiserver_loadbalancer_domain_name }}$" line: "{{ loadbalancer_apiserver.address }} {{ apiserver_loadbalancer_domain_name }}" state: present - backup: yes - unsafe_writes: yes + backup: true + unsafe_writes: true when: - populate_loadbalancer_apiserver_to_hosts_file - loadbalancer_apiserver is defined @@ -69,8 +69,8 @@ line: "{{ item.key }} {{ item.value | join(' ') }}" regexp: "^{{ item.key }}.*$" state: present - backup: yes - unsafe_writes: yes + backup: true + unsafe_writes: true loop: "{{ etc_hosts_localhosts_dict_target | default({}) | dict2items }}" # gather facts to update ansible_fqdn diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0100-dhclient-hooks.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0100-dhclient-hooks.yml index da38147..9745ab2 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0100-dhclient-hooks.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0100-dhclient-hooks.yml @@ -2,16 +2,16 @@ - name: Configure dhclient to supersede search/domain/nameservers blockinfile: block: |- - {% for item in [supersede_domain, supersede_search, supersede_nameserver] -%} + {% for item in [supersede_domain, supersede_search, supersede_nameserver] | reject('equalto', '') -%} {{ item }} {% endfor %} path: "{{ dhclientconffile }}" - create: yes + create: true state: present insertbefore: BOF - backup: yes + backup: true marker: "# Ansible entries {mark}" - mode: 0644 + mode: "0644" notify: Preinstall | propagate resolvconf to k8s components - name: Configure dhclient hooks for resolv.conf (non-RH) @@ -19,7 +19,7 @@ src: dhclient_dnsupdate.sh.j2 dest: "{{ dhclienthookfile }}" owner: root - mode: 0755 + mode: "0755" notify: Preinstall | propagate resolvconf to k8s components when: ansible_os_family not in [ "RedHat", "Suse" ] @@ -28,6 +28,6 @@ src: dhclient_dnsupdate_rh.sh.j2 dest: "{{ dhclienthookfile }}" owner: root - mode: 0755 + mode: "0755" notify: Preinstall | propagate resolvconf to k8s components when: ansible_os_family == "RedHat" diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0110-dhclient-hooks-undo.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0110-dhclient-hooks-undo.yml index 024e39f..dd320d5 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0110-dhclient-hooks-undo.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/0110-dhclient-hooks-undo.yml @@ -7,7 +7,7 @@ blockinfile: path: "{{ dhclientconffile }}" state: absent - backup: yes + backup: true marker: "# Ansible entries {mark}" notify: Preinstall | propagate resolvconf to k8s components diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/0120-growpart-azure-centos-7.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/0120-growpart-azure-centos-7.yml deleted file mode 100644 index 621629f..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/0120-growpart-azure-centos-7.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -# Running growpart seems to be only required on Azure, as other Cloud Providers do this at boot time - -- name: Install growpart - package: - name: cloud-utils-growpart - state: present - -- name: Gather mounts facts - setup: - gather_subset: 'mounts' - -- name: Search root filesystem device - vars: - query: "[?mount=='/'].device" - _root_device: "{{ ansible_mounts | json_query(query) }}" - set_fact: - device: "{{ _root_device | first | regex_replace('([^0-9]+)[0-9]+', '\\1') }}" - partition: "{{ _root_device | first | regex_replace('[^0-9]+([0-9]+)', '\\1') }}" - root_device: "{{ _root_device }}" - -- name: Check if growpart needs to be run - command: growpart -N {{ device }} {{ partition }} - failed_when: False - changed_when: "'NOCHANGE:' not in growpart_needed.stdout" - register: growpart_needed - environment: - LC_ALL: C - -- name: Check fs type - command: file -Ls {{ root_device }} - changed_when: False - register: fs_type - -- name: Run growpart # noqa no-handler - command: growpart {{ device }} {{ partition }} - when: growpart_needed.changed - environment: - LC_ALL: C - -- name: Run xfs_growfs # noqa no-handler - command: xfs_growfs {{ root_device }} - when: growpart_needed.changed and 'XFS' in fs_type.stdout diff --git a/kubespray/project/roles/kubernetes/preinstall/tasks/main.yml b/kubespray/project/roles/kubernetes/preinstall/tasks/main.yml index ee4de5d..a645080 100644 --- a/kubespray/project/roles/kubernetes/preinstall/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/preinstall/tasks/main.yml @@ -68,6 +68,7 @@ - not dns_late tags: - bootstrap-os + - system-packages - name: Apply system configurations import_tasks: 0080-system-configurations.yml @@ -120,25 +121,15 @@ - name: Check if we are running inside a Azure VM stat: path: /var/lib/waagent/ - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: azure_check when: - not dns_late tags: - bootstrap-os -- name: Grow partition on azure CentOS - import_tasks: 0120-growpart-azure-centos-7.yml - when: - - not dns_late - - azure_check.stat.exists - - ansible_os_family == "RedHat" - - growpart_azure_enabled - tags: - - bootstrap-os - - name: Run calico checks include_role: name: network_plugin/calico diff --git a/kubespray/project/roles/kubernetes/preinstall/templates/ntp.conf.j2 b/kubespray/project/roles/kubernetes/preinstall/templates/ntp.conf.j2 index abeb899..1a5c69c 100644 --- a/kubespray/project/roles/kubernetes/preinstall/templates/ntp.conf.j2 +++ b/kubespray/project/roles/kubernetes/preinstall/templates/ntp.conf.j2 @@ -35,6 +35,13 @@ restrict -6 default kod notrap nomodify nopeer noquery limited restrict {{ item }} {% endfor %} +# Needed for filtering interfaces +{% if ntp_filter_interface %} +{% for item in ntp_interfaces %} +interface {{ item }} +{% endfor %} +{% endif %} + # Needed for adding pool entries restrict source notrap nomodify noquery diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/amazon.yml b/kubespray/project/roles/kubernetes/preinstall/vars/amazon.yml deleted file mode 100644 index 09c645f..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/amazon.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -required_pkgs: - - libselinux-python - - device-mapper-libs - - nss - - conntrack-tools - - libseccomp diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/centos.yml b/kubespray/project/roles/kubernetes/preinstall/vars/centos.yml deleted file mode 100644 index 9b1a874..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/centos.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -required_pkgs: - - "{{ ((ansible_distribution_major_version | int) < 8) | ternary('libselinux-python', 'python3-libselinux') }}" - - device-mapper-libs - - nss - - conntrack - - container-selinux - - libseccomp diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/debian-11.yml b/kubespray/project/roles/kubernetes/preinstall/vars/debian-11.yml deleted file mode 100644 index 59cbc5a..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/debian-11.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -required_pkgs: - - python3-apt - - gnupg - - apt-transport-https - - software-properties-common - - conntrack - - iptables - - apparmor - - libseccomp2 diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/debian-12.yml b/kubespray/project/roles/kubernetes/preinstall/vars/debian-12.yml deleted file mode 100644 index e0dca4d..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/debian-12.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -required_pkgs: - - python3-apt - - gnupg - - apt-transport-https - - software-properties-common - - conntrack - - iptables - - apparmor - - libseccomp2 - - mergerfs diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/debian.yml b/kubespray/project/roles/kubernetes/preinstall/vars/debian.yml deleted file mode 100644 index 51a2802..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/debian.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -required_pkgs: - - python-apt - - aufs-tools - - apt-transport-https - - software-properties-common - - conntrack - - apparmor - - libseccomp2 diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/fedora.yml b/kubespray/project/roles/kubernetes/preinstall/vars/fedora.yml deleted file mode 100644 index d69b111..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/fedora.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -required_pkgs: - - iptables - - libselinux-python3 - - device-mapper-libs - - conntrack - - container-selinux - - libseccomp diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/main.yml b/kubespray/project/roles/kubernetes/preinstall/vars/main.yml new file mode 100644 index 0000000..e788b5d --- /dev/null +++ b/kubespray/project/roles/kubernetes/preinstall/vars/main.yml @@ -0,0 +1,103 @@ +--- +pkgs: + apparmor: &debian_family_base + os: + families: + - Debian + apt-transport-https: *debian_family_base + aufs-tools: &deb_10 + groups: + - k8s_cluster + os: + distributions: + Debian: + major_versions: + - "10" + bash-completion: {} + conntrack: &deb_redhat + groups: + - k8s_cluster + os: + families: + - Debian + - RedHat + conntrack-tools: + groups: + - k8s_cluster + os: + families: + - Suse + distributions: + Amazon: {} + container-selinux: &redhat_family + groups: + - k8s_cluster + os: + families: + - RedHat + curl: {} + device-mapper: + groups: + - k8s_cluster + os: + families: + - Suse + device-mapper-libs: *redhat_family + e2fsprogs: {} + ebtables: {} + gnupg: &debian + groups: + - k8s_cluster + os: + distributions: + Debian: + major_versions: + - "11" + - "12" + ipset: + enabled: "{{ kube_proxy_mode != 'ipvs' }}" + groups: + - k8s_cluster + iptables: *deb_redhat + ipvsadm: + enabled: "{{ kube_proxy_mode == 'ipvs' }}" + groups: + - k8s_cluster + libseccomp: *redhat_family + libseccomp2: + groups: + - k8s_cluster + os: + families: + - Suse + - Debian + libselinux-python: # TODO: Handle rehat_family + major < 8 + os: + distributions: + Amazon: {} + libselinux-python3: + os: + distributions: + Fedora: {} + mergerfs: + os: + distributions: + Debian: + major_versions: + - "12" + nss: *redhat_family + openssl: {} + python-apt: *deb_10 + # TODO: not for debian 10 + python3-apt: *debian_family_base + python3-libselinux: + os: + distributions: + RedHat: {} + CentOS: {} + rsync: {} + socat: {} + software-properties-common: *debian_family_base + tar: {} + unzip: {} + xfsprogs: {} diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/redhat.yml b/kubespray/project/roles/kubernetes/preinstall/vars/redhat.yml deleted file mode 100644 index 9b1a874..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/redhat.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -required_pkgs: - - "{{ ((ansible_distribution_major_version | int) < 8) | ternary('libselinux-python', 'python3-libselinux') }}" - - device-mapper-libs - - nss - - conntrack - - container-selinux - - libseccomp diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/suse.yml b/kubespray/project/roles/kubernetes/preinstall/vars/suse.yml deleted file mode 100644 index d089ac1..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/suse.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -required_pkgs: - - device-mapper - - conntrack-tools - - libseccomp2 diff --git a/kubespray/project/roles/kubernetes/preinstall/vars/ubuntu.yml b/kubespray/project/roles/kubernetes/preinstall/vars/ubuntu.yml deleted file mode 100644 index 85b3f25..0000000 --- a/kubespray/project/roles/kubernetes/preinstall/vars/ubuntu.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -required_pkgs: - - python3-apt - - apt-transport-https - - software-properties-common - - conntrack - - apparmor - - libseccomp2 diff --git a/kubespray/project/roles/kubernetes/tokens/tasks/check-tokens.yml b/kubespray/project/roles/kubernetes/tokens/tasks/check-tokens.yml index a157a05..d8bb203 100644 --- a/kubespray/project/roles/kubernetes/tokens/tasks/check-tokens.yml +++ b/kubespray/project/roles/kubernetes/tokens/tasks/check-tokens.yml @@ -2,9 +2,9 @@ - name: "Check_tokens | check if the tokens have already been generated on first master" stat: path: "{{ kube_token_dir }}/known_tokens.csv" - get_attributes: no - get_checksum: yes - get_mime: no + get_attributes: false + get_checksum: true + get_mime: false delegate_to: "{{ groups['kube_control_plane'][0] }}" register: known_tokens_master run_once: true @@ -23,9 +23,9 @@ - name: "Check tokens | check if a cert already exists" stat: path: "{{ kube_token_dir }}/known_tokens.csv" - get_attributes: no - get_checksum: yes - get_mime: no + get_attributes: false + get_checksum: true + get_mime: false register: known_tokens - name: "Check_tokens | Set 'sync_tokens' to true" diff --git a/kubespray/project/roles/kubernetes/tokens/tasks/gen_tokens.yml b/kubespray/project/roles/kubernetes/tokens/tasks/gen_tokens.yml index 6ac6b49..a64aea9 100644 --- a/kubespray/project/roles/kubernetes/tokens/tasks/gen_tokens.yml +++ b/kubespray/project/roles/kubernetes/tokens/tasks/gen_tokens.yml @@ -3,8 +3,8 @@ copy: src: "kube-gen-token.sh" dest: "{{ kube_script_dir }}/kube-gen-token.sh" - mode: 0700 - run_once: yes + mode: "0700" + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" when: gen_tokens | default(false) @@ -17,7 +17,7 @@ - "{{ groups['kube_control_plane'] }}" register: gentoken_master changed_when: "'Added' in gentoken_master.stdout" - run_once: yes + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" when: gen_tokens | default(false) @@ -30,14 +30,14 @@ - "{{ groups['kube_node'] }}" register: gentoken_node changed_when: "'Added' in gentoken_node.stdout" - run_once: yes + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" when: gen_tokens | default(false) - name: Gen_tokens | Get list of tokens from first master command: "find {{ kube_token_dir }} -maxdepth 1 -type f" register: tokens_list - check_mode: no + check_mode: false delegate_to: "{{ groups['kube_control_plane'][0] }}" run_once: true when: sync_tokens | default(false) @@ -47,7 +47,7 @@ args: executable: /bin/bash register: tokens_data - check_mode: no + check_mode: false delegate_to: "{{ groups['kube_control_plane'][0] }}" run_once: true when: sync_tokens | default(false) diff --git a/kubespray/project/roles/kubernetes/tokens/tasks/main.yml b/kubespray/project/roles/kubernetes/tokens/tasks/main.yml index c9dfd07..cab5a06 100644 --- a/kubespray/project/roles/kubernetes/tokens/tasks/main.yml +++ b/kubespray/project/roles/kubernetes/tokens/tasks/main.yml @@ -11,7 +11,7 @@ file: path: "{{ kube_token_dir }}" state: directory - mode: 0644 + mode: "0644" group: "{{ kube_cert_group }}" - name: Generate tokens diff --git a/kubespray/project/roles/kubespray-defaults/defaults/main/checksums.yml b/kubespray/project/roles/kubespray-defaults/defaults/main/checksums.yml index 963ec23..d1096cd 100644 --- a/kubespray/project/roles/kubespray-defaults/defaults/main/checksums.yml +++ b/kubespray/project/roles/kubespray-defaults/defaults/main/checksums.yml @@ -1,67 +1,96 @@ --- crictl_checksums: arm: - v1.29.0: 0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5 + v1.30.0: 0 + v1.29.0: 0 v1.28.0: 1ea267f3872f4b7f311963ab43ce6653ceeaf8727206c889b56587c95497e9dd - v1.27.1: ec24fb7e4d45b7f3f3df254b22333839f9bdbde585187a51c93d695abefbf147 - v1.27.0: 0b6983195cc62bfc98de1f3fc2ee297a7274fb79ccabf413b8a20765f12d522a arm64: + v1.30.0: 3769043fc6018a9e1697fcb768bb89ecd429176bd71e849058916f79a46a07a8 v1.29.0: 0b615cfa00c331fb9c4524f3d4058a61cc487b33a3436d1269e7832cf283f925 v1.28.0: 06e9224e42bc5e23085751e93cccdac89f7930ba6f7a45b8f8fc70ef663c37c4 - v1.27.1: 322bf64d12f9e5cd9540987d47446bf9b0545ceb1900ef93376418083ad88241 - v1.27.0: 9317560069ded8e7bf8b9488fdb110d9e62f0fbc0e33ed09fe972768b47752bd amd64: + v1.30.0: 3dd03954565808eaeb3a7ffc0e8cb7886a64a9aa94b2bfdfbdc6e2ed94842e49 v1.29.0: d16a1ffb3938f5a19d5c8f45d363bd091ef89c0bc4d44ad16b933eede32fdcbb v1.28.0: 8dc78774f7cbeaf787994d386eec663f0a3cf24de1ea4893598096cb39ef2508 - v1.27.1: b70e8d7bde8ec6ab77c737b6c69be8cb518ce446365734c6db95f15c74a93ce8 - v1.27.0: d335d6e16c309fbc3ff1a29a7e49bb253b5c9b4b030990bf7c6b48687f985cee ppc64le: + v1.30.0: ada550cecb5647014f16dd3ff6c59d7ef7d942ca8cb6c51c15ed019622f39ee9 v1.29.0: 2803a1865045077f29f798b9c569e1db7d44b5c329a546a0fd183e906925b99f v1.28.0: b70fb7bee5982aa1318ba25088319f1d0d1415567f1f76cd69011b8a14da4daf - v1.27.1: c408bb5e797bf02215acf9604c43007bd09cf69353cefa8f20f2c16ab1728a85 - v1.27.0: 3e4301c2d4b561d861970004002fe15d49af907963de06c70d326f2af1f145e0 crio_archive_checksums: arm: + v1.30.3: 0 + v1.30.2: 0 + v1.30.1: 0 + v1.30.0: 0 v1.29.2: 0 v1.29.1: 0 v1.29.0: 0 + v1.28.4: 0 + v1.28.3: 0 v1.28.2: 0 v1.28.1: 0 v1.28.0: 0 - v1.27.1: 0 - v1.27.0: 0 arm64: - v1.29.2: 9b4aa572d4cd51a41b1067161d961423d0d12b120fb636ea887a12a975d4b19a - v1.29.1: b6d3b502ba1474da370519bcdb9eefa07bb04a5a8e7073fbb7071d6e96f49411 + v1.30.3: 2e47b4b307788b15263256e0e423574c60eec80e17576704df736a7ccc13d7bd + v1.30.2: 6c0ed1a8a38c65fda45d8b725b8742d247e9f658d8cd6c56baa05bd749b9ccbe + v1.30.1: 371a6da24dfc7c9e01f29191b36a0629474a37cd8300fa8a36483647a7859b72 + v1.30.0: 7e7c934cebff6433594e4cdc440e1ceb5602741a35d74b2342dac6fb585c3549 + v1.29.2: e2ddaeb9d46b6a39057e67f77f5840e79d2226839014d77eb6ef243b88761f7a + v1.29.1: f7d7ca187b44ec490f4511e32f5a6bdf2d5ff14fb3dd1b452e330d7369e69c29 v1.29.0: 2bf11aeb85362ce4b25a7d9fc17bbe80659013425430e5efb922b4388031a027 - v1.28.2: 739923cb744a862039557f23823f4cc12feba121bd26ca3cc01d80cc8aaa1efb + v1.28.4: de110f71160202a1183bd3282a0a480363e6851ee101bbcaa34ba2e38c3b924d + v1.28.3: 05c98df0a3cc1fe9eec37b4fbf7c74c63f72fdbb4e9df56cf86db42a7b9fd879 + v1.28.2: 178bd67abae247d077168d9ff29c7abeae9b8427a6f9c33793b0ddb98ced2859 v1.28.1: 98a96c6b6bdf20c60e1a7948847c28b57d9e6e47e396b2e405811ea2c24ab9dc v1.28.0: c8ea800244d9e4ce74af85126afadea2939cd6f7ddd152d0f09fafbf294ef1cc - v1.27.1: ddf601e28dc22d878cdd34549402a236afaa47e0a08f39b09e65bab7034b1b97 - v1.27.0: c6615360311bff7fdfe1933e8d5030a2e9926b7196c4e7a07fcb10e51a676272 amd64: - v1.29.2: f71a85039b71fe08f1c063a93d61a1c952dc8f9a8c6be9b13fbdac8f0d9ff960 - v1.29.1: 6ff5af9962bfc079275ecec2b6caf5dbd25bf037fff53e87d67f27c2617432c5 + v1.30.3: 622809ec7e21350a3ff7897c7d2cabdf4367b1a5904d346514adc485de3c7172 + v1.30.2: 10be07d2626a093b58a29110e84256029d4c46aeb06a6b41e8bddc30bcfcaa4b + v1.30.1: 7293f51295d89106e59fe0f83af9599e71fe4f446e1b13c40687ef63ecc1b194 + v1.30.0: c2b189febc9f9cb51f84eecad0da955182e31b98a9f456314546bb83ee2a901a + v1.29.2: 55e71ef1bceb1cd9490ec85fdbfc889d3f3a9dd2ef3b8954dcbcf33cb6609167 + v1.29.1: 127ca9f57c2a3ad44dde2e64e0ec94169886245dffb74c12e68eedc80756c260 v1.29.0: 79c161d8db8ee7f0f4807d6232283d481ef0c20c514b61289238258f66734ac6 - v1.28.2: c8002a622e268b73f8d45b0adbdff9422b832106a23be137fabdc8a233b3f787 + v1.28.4: 4bf81791f6d5f65df797f4e25dee0c8fcc157c2800c0159c68c943fd78d63e30 + v1.28.3: 76c25d00f14f2297b68f5b71be6b80766b5235c4ba8972aff8d841a355e4d10c + v1.28.2: f3b82e7330bca2a8b833502c59f21ad26b9bdef7a5d98358293cea1ae62a796b v1.28.1: 63cee2e67e283e29d790caa52531bcca7bc59473fb73bde75f4fd8daa169d4bf v1.28.0: fa87497c12815766d18f332b38a4d823fa6ad6bb3d159e383a5557e6c912eb3b - v1.27.1: 23c0b26f9df65671f20c042466c0e6c543e16ba769bbf63aa26abef170f393ba - v1.27.0: 8f99db9aeea00299cb3f28ee61646472014cac91930e4c7551c9153f8f720093 ppc64le: - v1.29.1: c79cc835b66fbf2d2dc8e43908475f0603714f688a1450d4736d1f9f86579b52 + v1.30.3: 44ed039a1c0c492b14212bbe59c63fe804e3cc525102f47475a5bc0ffd08f4e8 + v1.30.2: 19169b1ef3324c749a0b0105b47288c0ef4949964b340c85229d00234e6148a1 + v1.30.1: e6fb05de749a06316d046e46f8ff4345a413264e63f63dc9e3f1db2cb8a7c962 + v1.30.0: e6fe5c39fa7b7cf8167bb59b94dc9028f8def0c4fec4c1c9028ec4b84da6c53a + v1.29.2: 6577d1476124bcd6bcfd25419bb0d1dc01585dc6e8246a986a7769ad2af407fa + v1.29.1: e26613e038d48271ad83877e5db5ad6f2116181d202495de849d378ab4a76062 v1.29.0: 8adddaf6cf0ed2905820dc162ca5ef541baa7b251368ee00c75435a872a886fb - v1.28.2: 0 - v1.28.1: 0 - v1.28.0: 0 - v1.27.1: 0 - v1.27.0: 0 + v1.28.4: 98ddbe8469ebaccab91f286c06b97024c31277e4b6664d162fa6c62f6d7f6366 + v1.28.3: c952aafe98dd55038525e3abc461152c0fcd758a50b0cbd8a0adc0eba2632dea + v1.28.2: 319e413d513bcb649244333881830d2eaccfb2bb77553baf9be3fa6118a70209 + v1.28.1: 7d22ba73a04e6b64088f82b37c03f1c5891e7c0847eeabeaeb83597a87b85292 + v1.28.0: ffcb7cb90c0a616bf642ea02361d18007a227393f7348c4dfdcbc370d6fff98e # Checksum # Kubernetes versions above Kubespray's current target version are untested and should be used with caution. kubelet_checksums: arm: + v1.30.4: 0 + v1.30.3: 0 + v1.30.2: 0 + v1.30.1: 0 + v1.30.0: 0 + v1.29.7: 0 + v1.29.6: 0 + v1.29.5: 0 + v1.29.4: 0 + v1.29.3: 0 + v1.29.2: 0 v1.29.1: 0 v1.29.0: 0 + v1.28.12: 0 + v1.28.11: 0 + v1.28.10: 0 + v1.28.9: 0 + v1.28.8: 0 v1.28.7: 0 v1.28.6: 0 v1.28.5: 0 @@ -70,22 +99,25 @@ kubelet_checksums: v1.28.2: 0 v1.28.1: 0 v1.28.0: 0 - v1.27.11: 0 - v1.27.10: 0 - v1.27.9: 0 - v1.27.8: 0 - v1.27.7: 0 - v1.27.6: 0 - v1.27.5: 0 - v1.27.4: 0 - v1.27.3: 0 - v1.27.2: 0 - v1.27.1: 0 - v1.27.0: 0 arm64: + v1.30.4: d3df7a4acff9aba5518930b9c417e8e0ca8cf5e105b7fee6504891fa8f3e962a + v1.30.3: 41d1926cd7b9c7c250c45f11c8fa9d1946cae98aec2eefc61a2cb4933612bcce + v1.30.2: 72ceb082311b42032827a936f80cd2437b8eee03053d05dbe36ba48585febfb8 + v1.30.1: c45049b829af876588ec1a30def3884ce77c2c175cd77485d49c78d2064a38fb + v1.30.0: fa887647422d34f3c7cc5b30fefcf97084d2c3277eff237c5808685ba8e4b15a + v1.29.7: f088079f26fb3bffc8a1c467e1caa5ad807023b63e70013e874163df87be6829 + v1.29.6: 0f0fa9429d0bcf04f271dcf4f666582dd4a4b15d6f116a45f17b5fcda90c2d2c + v1.29.5: 0d4328a3c67e4f0dbf270fa49343f3eab9316adde1a1bd2a857fa56876a9aff1 + v1.29.4: dc4bb6ea6cd35b024d63cc20d1c1800a9c695bd6f70411c57358d7c407513b00 + v1.29.3: 891dce19ed0eae34050c2eca0454204892e97bfe1a926f988cd044a987a9c7c9 v1.29.2: 9b4aa572d4cd51a41b1067161d961423d0d12b120fb636ea887a12a975d4b19a v1.29.1: e46417ab1ceae995f0e00d4177959a36ed34b807829422bc9dda70b263fe5c5d v1.29.0: 0e0e4544c2a0a3475529154b7534d0d58683466efa04a2bb2e763b476db0bb16 + v1.28.12: 8e28fda6ab1bd506ca4090a0a617aa29d9988c7e23711e70819497089ba67388 + v1.28.11: 0e01c1393f8746965994431b70a20c32b8547dfb1dcf2770cb692990fc65ba5f + v1.28.10: feae161e374ee0155b5263cda339f30f16b525631535a003be7aa437661e1580 + v1.28.9: 312471ad255acfcdeea2c5849b171467af4518e96d69d727a3197ff334e9299d + v1.28.8: 90d61f40b7bb061b0fc6d08b8b9ddae51f90863c899b098e19eaa89dc855f2c0 v1.28.7: e2c98b39b0b0745ef3e30febaeb8eaaf31ec721012405bd0dcf25e84026c221e v1.28.6: ee2c060deff330d3338e24aec9734c9e5d5aea4fea1905c0795bccff6997a65e v1.28.5: 28ddb696eb6e076f2a2f59ccaa2e409785a63346e5bda819717c6e0f58297702 @@ -94,22 +126,25 @@ kubelet_checksums: v1.28.2: 32269e9ec38c561d028b65c3048ea6a100e1292cbe9e505565222455c8096577 v1.28.1: 9b7fa64b2785da4a38768377961e227f8da629c56a5df43ca1b665dd07b56f3c v1.28.0: 05dd12e35783cab4960e885ec0e7d0e461989b94297e7bea9018ccbd15c4dce9 - v1.27.11: e81987a864fb47afe14f65fa4e93760bc19c424335e0f0540c6c725b727ce22a - v1.27.10: 0edadc44ef36be8d8106cad9972360c0477540e2d8c0bbeb38fd97fd1d7801d5 - v1.27.9: 8a14bc3739f5ca3b23d08301c2e769ee58c8d1cecb7243b46b1c098ae77effd7 - v1.27.8: 71849182ceb018dc084f499ad28b7b1afb7f23e35ccaf8421941dd5dafef0d4c - v1.27.7: ed5bfa48ee64d5e6cf23ed9fc03ea0593021839429fdc1ea7cc2ebf3f11b6491 - v1.27.6: be579ef4e8fa3e1de9d40a77e4d35d99e535a293f66bf3038cbea9cf803d11e5 - v1.27.5: 4e78fafdeb5d61ab6ebcd6e75e968c47001c321bec169bb9bd9f001132de5321 - v1.27.4: c75ad8e7c7ef05c0c021b21a9fe86e92f64db1e4c1bc84e1baf45d8dbb8ba8d1 - v1.27.3: 2838fd55340d59f777d7bd7e5989fc72b7a0ca198cf4f3f723cd9956859ce942 - v1.27.2: 810cd9a611e9f084e57c9ee466e33c324b2228d4249ff38c2588a0cc3224f10d - v1.27.1: dbb09d297d924575654db38ed2fc627e35913c2d4000c34613ac6de4995457d0 - v1.27.0: 37aa2edc7c0c4b3e488518c6a4b44c8aade75a55010534ee2be291220c73d157 amd64: + v1.30.4: 0c02c0f997b3e9769eae7ca051856054411fca947b3d5409d991ce1964dd0e69 + v1.30.3: 9a37ddd5ea026639b7d85e98fa742e392df7aa5ec917bed0711a451613de3c1c + v1.30.2: 6923abe67ef069afca61c71c585023840426e802b198298055af3a82e11a4e52 + v1.30.1: 87bd6e5de9c0769c605da5fedb77a35c8b764e3bda1632447883c935dcf219d3 + v1.30.0: 32a32ec3d7e7f8b2648c9dd503ce9ef63b4af1d1677f5b5aed7846fb02d66f18 + v1.29.7: f16329e64f5b2204c1cb906f694abebb7f6869d56e6e8b60b54afa0057006b84 + v1.29.6: a946789d4fef64e6f5905dbd7dca01d4c3abd302d0da7958fdaa924fe2729c0b + v1.29.5: 261dc3f3c384d138835fe91a02071c642af94abb0cca56ebc04719240440944c + v1.29.4: 58571f0ed62543a9bbac541e52c15d8385083113a463e23aec1341d0b5043939 + v1.29.3: d8b55a2f8a87c8cd2cbf867d76d1d7f98b7198a740db19bad6ed7b8b813de771 v1.29.2: f71a85039b71fe08f1c063a93d61a1c952dc8f9a8c6be9b13fbdac8f0d9ff960 v1.29.1: 1b1975c58d38be1a99a8bcba4564ac489afd223b0abe9f2ab08bbde89d2412a3 v1.29.0: e1c38137db8d8777eed8813646b59bf4d22d19b9011ab11dc28e2e34f6b80a05 + v1.28.12: 4648ae155b1ab05ab8dbef417bde4d5acfcd5ad32e8d1e3209006b40c440a56c + v1.28.11: 230f0634ea42a54a6c96771f12eecd6cadfe0b76ab41c3bc39aa7cbbe4dfb12e + v1.28.10: a361e744aaeef4539f0636ecd1827c85207a5f2b0c2b0a98dbbce1498061f509 + v1.28.9: f3af46cff11c675a80d91ebb38ebc4e85a9f813ce93e56ee131e7fea1491b786 + v1.28.8: 049b412a5861255cd3922f612acb79ab51135e166c5d80acf12fba9179eebf0c v1.28.7: 120b1495babc4364f7e16a9d0f8b8e6b6f78316d047e4f6de77b5569b05813c7 v1.28.6: 8506df1f20a5f8bba0592f5a4cf5d0cc541047708e664cb88580735400d0b26f v1.28.5: bf37335da58182783a8c63866ec1f895b4c436e3ed96bdd87fe3f8ae8004ba1d @@ -118,22 +153,25 @@ kubelet_checksums: v1.28.2: 17edb866636f14eceaad58c56eab12af7ab3be3c78400aff9680635d927f1185 v1.28.1: 2bc22332f44f8fcd3fce57879fd873f977949ebd261571fbae31fbb2713a5dd3 v1.28.0: bfb6b977100963f2879a33e5fbaa59a5276ba829a957a6819c936e9c1465f981 - v1.27.11: 2ce92a5d8985b93bd8ffc4f5519cd79bf2f844590aa38228a3d809c5bf5986e0 - v1.27.10: 25a34bf98bb8a296ea07f1ebbcb496b1e6b6c6da3247695288a7c99fc8c1be2c - v1.27.9: ede60eea3acbac3f35dbb23d7b148f45cf169ebbb20af102d3ce141fc0bac60c - v1.27.8: 2e0557b38c5b9a1263eed25a0b84d741453ed9c0c7bd916f80eadaf7edfb7784 - v1.27.7: 236bc8bc22c52e914d3364c23e273628c63e193365b6a43b8cb013716c1cd2f5 - v1.27.6: daa42f9b6f5e2176bbce0d24d89a05613000630bcddec1fafd2a8d42a523ce9d - v1.27.5: 66df07ab4f9d72028c97ec7e5eea23adc0ab62a209ba2285431456d7d75a5bb3 - v1.27.4: 385f65878dc8b48df0f2bd369535ff273390518b5ac2cc1a1684d65619324704 - v1.27.3: c0e18da6a55830cf4910ecd7261597c66ea3f8f58cf44d4adb6bdcb6e2e6f0bf - v1.27.2: a0d12afcab3b2836de4a427558d067bebdff040e9b306b0512c93d9d2a066579 - v1.27.1: cb2845fff0ce41c400489393da73925d28fbee54cfeb7834cd4d11e622cbd3a7 - v1.27.0: 0b4ed4fcd75d33f5dff3ba17776e6089847fc83064d3f7a3ad59a34e94e60a29 ppc64le: + v1.30.4: 50ea965747f3f8c69288aa9268e5c2cc1eb6c3f0b3efa7eba862258bd225d98d + v1.30.3: c48df46a72ff9764fd1bc54e99b6154772031b1e66c36b0ac5764a5801eadfc0 + v1.30.2: 268dfbb7ee3abcb8ff9fd0a88f81204e40dd33d177f7878941c9ff6b7cca0474 + v1.30.1: 1ac58eae0aa02fefad47d2318bfa5846ae0d7d11a5b691850cd86b2b614ceffe + v1.30.0: 8d4aa6b10bcddae9a7c754492743cfea88c1c6a4628cab98cdd29bb18d505d03 + v1.29.7: 52a70e6c9cab9f123cc0f2677b65ac6426cfc549d375c64008b43bcb8fae1d76 + v1.29.6: 77c2256d6863ac0e33a0e8e8c4cc798618ae73aac91b4f18b9e87d8e62973c61 + v1.29.5: b0caa52184a3e89a7f529c776ebabd7d34aecad560614f787fe08cff777a43cb + v1.29.4: 1ecc89b6f17df357835e3e56f553ec27f2aea69a5865dfb39cff77e6e70e6adb + v1.29.3: 811f2b17f443cd694b8650f5ec2c7e3a59394f8bf3e25d16182549aaab16a420 v1.29.2: b0eb5e0362a4e153ed1239c65b0abb02b2d9fbbca6846d0bab8b285de8c84fca v1.29.1: 467d2b457205363f53f72081295ea390fc25215b0ccc29dc04c4f82925266067 v1.29.0: 67f09f866d3e4aee8211ce9887ec8bc427b188474a882a7af999fc0fee939028 + v1.28.12: d22af902a74d8d257ea508e9e6f91574e6e0e50006868a1943c47144dd3f9615 + v1.28.11: 35daf1aacafd035420d85052b037bc0aa1eec9193100c40f626aa3b140d4d48d + v1.28.10: 0ba43fda35f588eaf65955481a7c6f633e4e787a45322bf55a7558ece4944e39 + v1.28.9: cf33fbff3fb852ce9f8afda8818381af343fb5e7d30dde72999cc0d273631815 + v1.28.8: f3e4551e5234d296344a481196e607d88581705fedd561e8c807db1de8a9cc4b v1.28.7: c67277445af9a97a375da3caa6a7dae7bb52fa454deb811c5bc89c2838b3322f v1.28.6: 8f79f40bef88aaedfdf7256de48a972295b0069ae0ddefa90dff3f8690c825ce v1.28.5: ae9fe81804ba67ee81e8a5fe1dc18fe285267764c61f831886a25245a11d8528 @@ -142,23 +180,26 @@ kubelet_checksums: v1.28.2: 79f568ac700d29f88d669c6b6a09adb3b726bdd13c10aa0839cbc70b414372e5 v1.28.1: 547fc76f0c1d78352fad841ebeacd387fe48750b2648565dfd49197621622fbb v1.28.0: 22de59965f2d220afa24bf04f4c6d6b65a4bb1cd80756c13381973b1ac3b4578 - v1.27.11: ce4dc48a61399038eff680b952386ed9be471c5af1e43dc461e0fb5339de9356 - v1.27.10: c5014bed224347245fadec3d763846ec33ccd7a580d0c4ee19a45a948392f20c - v1.27.9: f270051c9b0f36da10a5d27011783be042edd396e8c729709c2396f29b72b6d2 - v1.27.8: 2354fdb19b5018cabe43fde1979965686afd3c95b75531e678a0064c4a30b4e9 - v1.27.7: 9154a7b5d5793fb8a05cba0d309ddfd975409d0e0686be19cf2feca172f06162 - v1.27.6: 1001da3586a3f868c371aefde991af94ca780ec1599c8a969390ba105aaf9dcb - v1.27.5: 3c643564bf07753c1388096aef9125811800fd28aa6a5faf3bfb1cef0e1637eb - v1.27.4: 16c69a941f2b67fef35d84062626622d205f9e2375a8daf3410fb1a42fc6e9e7 - v1.27.3: a8ea8f9e857d1140b569fff88d8d750dccaea0aa33d624befbb67f725b5340a0 - v1.27.2: 3af92edd687f7932e7fce877944dfe5efa437bf5f171fc8331725c631a1a86ef - v1.27.1: 7a800b9539beaba0b5d6357070a40fb3c4d216c2ad6693b15f9b1307b1c99e1f - v1.27.0: 17c061a9f7919697ac71c151c19337f65b86f59f59441687ac92e977d851c75b kubectl_checksums: arm: + v1.30.4: a31676f522cc745f241b1fd5755b9965558e4f1f5db5149319439a15f49806d1 + v1.30.3: f9147ca81cbcb7b1cf41b75d95a0fd3597defb7c0e6db8c54e6ca7f493929c71 + v1.30.2: 2dab982920d87bc9a17c539bfa4f94b758afc454bb044029dee06144e8dbee08 + v1.30.1: b05c4c4b1c440e8797445b8b15e9f4a00010f1365533a2420b9e68428da19d89 + v1.30.0: ff54e96c73f4b87d740768f77edada7df8f2003f278d3c79bbbaa047b1fc708d + v1.29.7: cf875cbbdca7ea0e190075c7a4b3f2fa59864079c1fe9da482f8806b1ad64364 + v1.29.6: 7762244b8da5564d2ee6a65403dd3aa3f94e8e9b16887c51936a4e941de8fd95 + v1.29.5: f3c83a9674098c5a4f27defed001934719f487897dd61db1992057e5ed103b3e + v1.29.4: ff4a1f437dc902b73505841a7705a6405694856a798e962ec2fdf7793f0aeadb + v1.29.3: 12f72bd88eaa04cd8f09827c64195a695fdd5fb64e11c98524c83d21bcb0e37a v1.29.2: f1bab202f0ce0c4209af0a977fc3dd4076397b1983544e09942ca4f586dff900 v1.29.1: a4b478cc0e9adaab0c5bb3627c20c5228ea0fe2aeff9e805d611eb3edb761972 v1.29.0: a2388eb458d07ec734e4fa02fd0147456a1922a7d6b8e67a32db9d64a4d7621c + v1.28.12: 54d5c9c302a93daec427ff4f20f50124bb0eaa99c1c477b49e78893d7c9ff1d3 + v1.28.11: 2710129489d782a35c5273202a7148aac42e316c5117aa89c64a8cc62f9ce140 + v1.28.10: e7b977779169f394383696afe872f6f0a4274789adbce1b70f5b28a20ee2cbd0 + v1.28.9: 2da7aead4f58aefee6892b2cc8184de26ef7808bf2d599553267d5cdbc1ce83a + v1.28.8: 98c44038dd978a58aa01849c25c2bd522fab7494a39bb3fd56c90944ba6e872f v1.28.7: d0c2e9228aff23bdcc62072ef9cebf5ebb0b14fb8638b6df8f7f6d5220c36bd9 v1.28.6: 2358d98d4970c177a3af0ae1c2398f69922074a961a61cdff6ae4a7f13106dc1 v1.28.5: 0819c9d0ea66a1e20d74d9a455090e1f67fe07d671866be342ab55532203f4bc @@ -167,22 +208,25 @@ kubectl_checksums: v1.28.2: 6576aa70413ff00c593a07b549b8b9d9e5ef73c42bb39ab4af475e0fdb540613 v1.28.1: eaa05dab1bffb8593d8e5caa612530ee5c914ee2be73429b7ce36c3becad893f v1.28.0: 372c4e7bbe98c7067c4b7820c4a440c931ad77f7cb83d3237b439ca3c14d3d37 - v1.27.11: 11586f333abaf2776e0d2f9e02c71ae5eeff3ad8e629815aa8bb7d7e9a406301 - v1.27.10: 4d81649935ec127f9aa21954697f82e0796f61e8e6406fd058b3a8b80e858c8e - v1.27.9: 89b76aa415018377f2c5fc33fc4d45f4997cc63677336f1768ee8a11593515ce - v1.27.8: 2f2936f950beb3f08ee0e45fbf80d020163829b95aa11c99ec726ee1a922329c - v1.27.7: 2a387ade64cd4cf90f002ae8c0e6f60250d26d1ee2cce6051f559430a44352ea - v1.27.6: 3a34a38908a9d0f85dc531cc1c49061ceeaa2ab742382d891d9fc7bf8dc53b8c - v1.27.5: c5e8a02102a93c84413ce8a029f194049429d27ad559061de267d84020a4594b - v1.27.4: 4269133eca9abd29c0a31e15ede2837713635893f1763eccba4b27e66a45abfb - v1.27.3: 1d51a48a0497e47f4f4036687cd337c53d297ea5322e8395432879570379d82e - v1.27.2: 7792f5630543c0af84f444521ee6113da5ae00f2b50872d57324aa725a5341c5 - v1.27.1: fe704e355bf2c5f69964cd12772687535a11a5e9ec0baf4f27e0a8fb156bc615 - v1.27.0: 288470e3eb89a2f55273d753ce6674dfb00e732f2971428acb964810aa726188 arm64: + v1.30.4: 1d8b4e6443c7df8e92a065d88d146142a202fea5ec694135b83d9668529ea3b1 + v1.30.3: c6f9568f930b16101089f1036677bb15a3185e9ed9b8dbce2f518fb5a52b6787 + v1.30.2: 56becf07105fbacd2b70f87f3f696cfbed226cb48d6d89ed7f65ba4acae3f2f8 + v1.30.1: d90446719b815e3abfe7b2c46ddf8b3fda17599f03ab370d6e47b1580c0e869e + v1.30.0: 669af0cf520757298ea60a8b6eb6b719ba443a9c7d35f36d3fb2fd7513e8c7d2 + v1.29.7: 7b6649aaa298be728c5fb7ccb65f98738a4e8bda0741afbd5a9ed9e488c0e725 + v1.29.6: 21816488cf3af4cf2b956ee58f7afc5b4964c29488f63756f5ddcf09b0df5be9 + v1.29.5: 9ee9168def12ac6a6c0c6430e0f73175e756ed262db6040f8aa2121ad2c1f62e + v1.29.4: 61537408eedcad064d7334384aed508a8aa1ea786311b87b505456a2e0535d36 + v1.29.3: 191a96b27e3c6ae28b330da4c9bfefc9592762670727df4fcf124c9f1d5a466a v1.29.2: 3507ecb4224cf05ae2151a98d4932253624e7762159936d5347b19fe037655ca v1.29.1: 96d6dc7b2bdcd344ce58d17631c452225de5bbf59b83fd3c89c33c6298fb5d8b v1.29.0: 8f7a4bd6bae900a4ddab12bd1399aa652c0d59ea508f39b910e111d248893ff7 + v1.28.12: f7e01dfffebb1d5811c37d558f28eefd80cbfadc0b9783b0b0ebf37c40c5c891 + v1.28.11: 7984a98d52365d190b6f56caa962339a7228b6f432e58ba5f1b1e60dbedac275 + v1.28.10: e659d23d442c2706debe5b96742326c0a1e1d7b5c695a9fe7dfe8ea7402caee8 + v1.28.9: e0341d3973213f8099e7fcbbf6d1d506967bc2b7a4faac3fb3b4340f226e9b2f + v1.28.8: 93d60dd36093b4c719f1f1bafcf59437c17cb2209341c7c94771e7dd9acdab33 v1.28.7: 13d547495bdea49b223fe06bffb6d2bef96436634847f759107655aa80fc990e v1.28.6: 0de705659a80c3fef01df43cc0926610fe31482f728b0f992818abd9bdcd2cb9 v1.28.5: f87fe017ae3ccfd93df03bf17edd4089672528107f230563b8c9966909661ef2 @@ -191,22 +235,25 @@ kubectl_checksums: v1.28.2: ea6d89b677a8d9df331a82139bb90d9968131530b94eab26cee561531eff4c53 v1.28.1: 46954a604b784a8b0dc16754cfc3fa26aabca9fd4ffd109cd028bfba99d492f6 v1.28.0: f5484bd9cac66b183c653abed30226b561f537d15346c605cc81d98095f1717c - v1.27.11: d30e1aa873e78eb376ddee3c785aa78c44eddc56ce2ef901dac1ce0c2c4f50b0 - v1.27.10: 2e1996379d5a8b132e0606fcd3df3c8689e11882630b75cca3b7135126847871 - v1.27.9: bda475539fdeda9d8a85a84b967af361af264d0826c121b23b0b62ee9b00cd2d - v1.27.8: 97ed6739e2803e63fd2d9de78be22d5ba6205bb63179a16ec773063526525a8e - v1.27.7: 61fc334f2c0290270e43fb8a1d4ff07e8cec5642d5a123eb7ab66a134b04ae83 - v1.27.6: 7322a6f600de6d0d06cf333bdc24cd2a340bba12920b0c2385c97884c808c810 - v1.27.5: 0158955c59c775165937918f910380ed7b52fca4a26fb41a369734e83aa44874 - v1.27.4: 5178cbb51dcfff286c20bc847d64dd35cd5993b81a2e3609581377a520a6425d - v1.27.3: 7bb7fec4e28e0b50b603d64e47629e812408751bd1e0ce059b2fee83b0e3ff6f - v1.27.2: 1b0966692e398efe71fe59f913eaec44ffd4468cc1acd00bf91c29fa8ff8f578 - v1.27.1: fd3cb8f16e6ed8aee9955b76e3027ac423b6d1cc7356867310d128082e2db916 - v1.27.0: f8e09630211f2b7c6a8cc38835e7dea94708d401f5c84b23a37c70c604602ddc amd64: + v1.30.4: 2ffd023712bbc1a9390dbd8c0c15201c165a69d394787ef03eda3eccb4b9ac06 + v1.30.3: abd83816bd236b266c3643e6c852b446f068fe260f3296af1a25b550854ec7e5 + v1.30.2: c6e9c45ce3f82c90663e3c30db3b27c167e8b19d83ed4048b61c1013f6a7c66e + v1.30.1: 5b86f0b06e1a5ba6f8f00e2b01e8ed39407729c4990aeda961f83a586f975e8a + v1.30.0: 7c3807c0f5c1b30110a2ff1e55da1d112a6d0096201f1beb81b269f582b5d1c5 + v1.29.7: e3df008ef60ea50286ea93c3c40a020e178a338cea64a185b4e21792d88c75d6 + v1.29.6: 339553c919874ebe3b719e9e1fcd68b55bc8875f9b5a005cf4c028738d54d309 + v1.29.5: 603c8681fc0d8609c851f9cc58bcf55eeb97e2934896e858d0232aa8d1138366 + v1.29.4: 10e343861c3cb0010161e703307ba907add2aeeeaffc6444779ad915f9889c88 + v1.29.3: 89c0435cec75278f84b62b848b8c0d3e15897d6947b6c59a49ddccd93d7312bf v1.29.2: 7816d067740f47f949be826ac76943167b7b3a38c4f0c18b902fffa8779a5afa v1.29.1: 69ab3a931e826bf7ac14d38ba7ca637d66a6fcb1ca0e3333a2cafdf15482af9f v1.29.0: 0e03ab096163f61ab610b33f37f55709d3af8e16e4dcc1eb682882ef80f96fd5 + v1.28.12: e8aee7c9206c00062ced394418a17994b58f279a93a1be1143b08afe1758a3a2 + v1.28.11: 1dba63e1a5c9520fc516c6e817924d927b9b83b8e08254c8fe2a2edb65da7a9c + v1.28.10: 389c17a9700a4b01ebb055e39b8bc0886330497440dde004b5ed90f2a3a028db + v1.28.9: b4693d0b22f509250694b10c7727c42b427d570af04f2065fe23a55d6c0051f1 + v1.28.8: e02aad5c0bac52c970700b814645b62c4f18b634144398ac344875dbaf1072f8 v1.28.7: aff42d3167685e4d8e86fda0ad9c6ce6ec6c047bc24d608041d54717a18192ba v1.28.6: c8351fe0611119fd36634dd3f53eb94ec1a2d43ef9e78b92b4846df5cc7aa7e3 v1.28.5: 2a44c0841b794d85b7819b505da2ff3acd5950bd1bcd956863714acc80653574 @@ -215,22 +262,25 @@ kubectl_checksums: v1.28.2: c922440b043e5de1afa3c1382f8c663a25f055978cbc6e8423493ec157579ec5 v1.28.1: e7a7d6f9d06fab38b4128785aa80f65c54f6675a0d2abef655259ddd852274e1 v1.28.0: 4717660fd1466ec72d59000bb1d9f5cdc91fac31d491043ca62b34398e0799ce - v1.27.11: 7ae327978a1edb43700070c86f5fd77215792c6b58a7ea70192647e0da848e29 - v1.27.10: bfb219643c28d9842fceae51590776f06987835d93fc3cb9b0149c9111c741ac - v1.27.9: d0caae91072297b2915dd65f6ef3055d27646dce821ec67d18da35ba9a8dc85b - v1.27.8: 027b3161e99fa0a7fa529e8f17f73ee2c0807c81c721ca7cf307f6b41c17bc57 - v1.27.7: e5fe510ba6f421958358d3d43b3f0b04c2957d4bc3bb24cf541719af61a06d79 - v1.27.6: 2b7adb71c8630904da1b94e262c8c3c477e9609b3c0ed8ae1213a1e156ae38dd - v1.27.5: 9a091fb65e4cf4e8be3ce9a21c79210177dd7ce31a2998ec638c92f37f058bcd - v1.27.4: 4685bfcf732260f72fce58379e812e091557ef1dfc1bc8084226c7891dd6028f - v1.27.3: fba6c062e754a120bc8105cde1344de200452fe014a8759e06e4eec7ed258a09 - v1.27.2: 4f38ee903f35b300d3b005a9c6bfb9a46a57f92e89ae602ef9c129b91dc6c5a5 - v1.27.1: 7fe3a762d926fb068bae32c399880e946e8caf3d903078bea9b169dcd5c17f6d - v1.27.0: 71a78259d70da9c5540c4cf4cff121f443e863376f68f89a759d90cef3f51e87 ppc64le: + v1.30.4: a913b4b8573d356483d5c7f14d2cecb290b41ab3b58812567b54ce09e763aad9 + v1.30.3: 3f2ba2216e43b833251a570b1218cba61d43ef2734c0a7751d281656066ab30b + v1.30.2: 738bc1bad45df79fc4313d167a68ed5a1cf747f1f94e4434f0733e3126989f2e + v1.30.1: ef01ae21e91600469db3df01172144fac6c61083e7d3282bef72ce732d76d0d8 + v1.30.0: f8a9eac6e12bc8ab7debe6c197d6536f5b3a9f199e8837afd8e4405291351811 + v1.29.7: fd2bb7de3d46a375c63499f8235dc22901b563a9554f315f7606e0bac78fff94 + v1.29.6: cc145dc1f27f56c81aa2c96c97370e1341b41fbb4fc64cfde4ef4956230fc0e9 + v1.29.5: 1d2635f6bd0218c53037c113171479e15e51b60823f7f1b93afb48ae1d9e5b09 + v1.29.4: 10a1a7e4423483a386ab1ab9237cda1e9d24423c2cf23b7fa514f533aa23ce87 + v1.29.3: 84292286ed2941e52a9df9ccaaf30c3bfebe02a096b67e553d8b643295f231f0 v1.29.2: 382552d15a1aa7ec5a316b2a912e7fbdaaff2f3c714cd38b2b0c6a48b670fed8 v1.29.1: b7780124ccfe9640f3a37d242d31e8dbb252bcd379bd0d7bf3776d15baf15ca3 v1.29.0: ea926d8cf25e2ce982ff5c375da32b51ccbd122b721b1bc4a32f52a9a0d073ab + v1.28.12: ed8255ef27836a88982651bff592e98c623677c926b2a9bc08443319c6678257 + v1.28.11: 63fa54ab9b4fc7b61415a8093bd48db9ce609b78f75c09b03b3b82a3a0c3105f + v1.28.10: aea8f54280e56dd58822fa4ae835ce6c6586727b32fb7bc915c2bee5038ccba9 + v1.28.9: 6c5f40b6467b67fe2cc1540c7e7cb15ba6ad092361395aa7989c2c26e3de0697 + v1.28.8: c9c21c1db306ec34bdc0f8179d1a1e20f8bcdd6d42fccf84267a5686e3218ad1 v1.28.7: 1394cc047551bbecffee7f1c28cccd0f3c9839a72344854362a08e98d6513c18 v1.28.6: 60fdb4386b5499dd6a6e3a369f35eef63c99647f7a0436fdbeb4db8c052d14f6 v1.28.5: 4448a9f95421cbe69726aa4d2967d706bc43466b9c656c7425b55431b1c20dd4 @@ -239,23 +289,26 @@ kubectl_checksums: v1.28.2: 87cca30846fec99a4fbea122b21e938717b309631bd2220de52049fce30d2e81 v1.28.1: 81b45c27abbdf2be6c5203dfccfd76ded1ac273f9f7672e6dcdf3440aa191324 v1.28.0: 7a9dcb4c75b33b9dac497c1a756b1f12c7c63f86fc0f321452360fbe1a79ce0f - v1.27.11: af736cbdb7ae42e696fa3543e483726c1728c95039b9520797511965caca56b6 - v1.27.10: 445928336932248cb104d99919e659696afa60f8dd8513821f92775e893d0dcb - v1.27.9: 2464d947370b8902e1245b0a75a4ecf55fe2aeee5bc87f2add7da00b73535a59 - v1.27.8: e25a09dea99192ff43ee13af61bfadd7c79eb538dc8e85376b6c590b4d471204 - v1.27.7: a60da56f856bc5b224f0be71b03443d5a0fb69424f31cd86f069cc79c13b2870 - v1.27.6: f3ed7752a20dbae271eeff9e9d109381e3ed6772853b5c84dc8a7476bbad847c - v1.27.5: 7ab5fe6eb51bd267b3156ef6e18f9e264e6c7c26ec0dafc2f55edcf3164bac99 - v1.27.4: dee25e38897b16ed9009ddcfd96b6635ab3097a051573c6c444209dc27e8ada5 - v1.27.3: b2da3d262e61ffc3e70511977a933b344b18efa5c238bfa388438bc321bc5e11 - v1.27.2: efee037a276f72c77cc230194d7dadf943a5778be46b7985edeb414d27894266 - v1.27.1: 440bcfd9611319f3d9e5d4fa4cdee2421cdf80c01fad223934d9a9b640673d75 - v1.27.0: daa9f1d4fe3f217de2546bca4ac14601f34b34a25c1f571f1e44eb313aee1385 kubeadm_checksums: arm: + v1.30.4: 0 + v1.30.3: 0 + v1.30.2: 0 + v1.30.1: 0 + v1.30.0: 0 + v1.29.6: 0 + v1.29.7: 0 + v1.29.5: 0 + v1.29.4: 0 + v1.29.3: 0 v1.29.2: 0 v1.29.1: 0 v1.29.0: 0 + v1.28.12: 0 + v1.28.11: 0 + v1.28.10: 0 + v1.28.9: 0 + v1.28.8: 0 v1.28.7: 0 v1.28.6: 0 v1.28.5: 0 @@ -264,22 +317,25 @@ kubeadm_checksums: v1.28.2: 0 v1.28.1: 0 v1.28.0: 0 - v1.27.11: 0 - v1.27.10: 0 - v1.27.9: 0 - v1.27.8: 0 - v1.27.7: 0 - v1.27.6: 0 - v1.27.5: 0 - v1.27.4: 0 - v1.27.3: 0 - v1.27.2: 0 - v1.27.1: 0 - v1.27.0: 0 arm64: + v1.30.4: 609afad8590afb39b500cc5175c64b17690f7bf0b0eebcf1d347656d262e5c8c + v1.30.3: 6590f2447c87346aac29e2ab42fe4f29873f9bf154ee878f00da4c81bfdb8ea2 + v1.30.2: 7268762b7afd44bf07619985dd52c376b63e47d73b8f9a3b08cc49624a8fbd55 + v1.30.1: bda423cb4b9d056f99a2ef116bdf227fadbc1c3309fa3d76da571427a7f41478 + v1.30.0: c36afd28921303e6db8e58274de16c60a80a1e75030fc3c4e9c4ed6249b6b696 + v1.29.7: d0ad904dc3823821c3920499fc151fc83fb6cb9e1c920e39173f96720ad0e053 + v1.29.6: 3ba6879ef491cdd8433647020d345d86c0ea8e77f726375bc4b5495888bbf778 + v1.29.5: d4db8c514f2764edc039462c218dbcd316577f76f21b209b76e9a4b1f08e3100 + v1.29.4: 438287a91e08cbefecab79be8ac893a935c3dbf6e87bea895fb99f2bc38cf06e + v1.29.3: ce2e4c230f954e59ae77e34c4ff2ae08cad3970505ae1e21b6337e6d83b21682 v1.29.2: e05720feb9d2d67eff25b0156a5c22e2de37be2ffab4e1f4d31e8c526fafd0e1 v1.29.1: 3bff8c50c104c45e416cce9991706c6ac46365f0defbcd54f8cf4ace0fa68dcf v1.29.0: bbddee2d46d2e1643ae3623698b45b13aa2e858616d61c642f2f49e5bb14c980 + v1.28.12: e0d94607a036323e45a6866127bc7a374543e27f45f8fc0bf948a2452eab667f + v1.28.11: 15a021fdecf08989d6b64af873d89c61750d3a0564bee58c248eafe5cc4df433 + v1.28.10: f6809d72ed1bf6fde460e48e5c714c3bc92f680e328defa9bd592a796347b644 + v1.28.9: cd6aefad8144a9771fd470529ff14be2675df7b561f7c56dee3fed4f81332dc4 + v1.28.8: e0f47adc69ef84e2f6c42cc341b8a790904a929ad10ed1c23c2e822ec804e247 v1.28.7: f556e49494737f97a15bf15bb4b27d45f8747b477302cdfd22dd61816bc02203 v1.28.6: 4298cad464e92eec19cdf3e6a607a82a1d626ae70fedba7956175152ab983457 v1.28.5: 22bb6b3377204e93d008f33ac4924d77adca1478f1ae3b515c03476ba54f1adc @@ -288,22 +344,25 @@ kubeadm_checksums: v1.28.2: 010789a94cf512d918ec4a3ef8ec734dea0061d89a8293059ef9101ca1bf6bff v1.28.1: 7d2f68917470a5d66bd2a7d62897f59cb4afaeffb2f26c028afa119acd8c3fc8 v1.28.0: b9b473d2d9136559b19eb465006af77df45c09862cd7ce6673a33aae517ff5ab - v1.27.11: b8452d6c3f1331beb3d5fa42466a9bc96638a76c40980dba9822300f230c0858 - v1.27.10: ed0447155a7e967ae23480b06b31b2c0aaa871e7c59dfd82ae25b03a1eccf6e6 - v1.27.9: d3d022842b0b8e4661222e8873249f5acafdbef52fd1bfb98152a582352b3c40 - v1.27.8: 0d0f5b2781d663d314e785d14361aa5a09cfaf6e1694aa3cc731f4f06342ec13 - v1.27.7: 46d7c43532233906919a53ee0e03ab04ab9e08514392d17a86f058e0364cda4b - v1.27.6: faec35315203913b835e9b789d89001a05e072943c960bcf4de1e331d08e10c8 - v1.27.5: 3023ef1d2eff885af860e13c8b9fcdb857d259728f16bf992d59c2be522cec82 - v1.27.4: b4ede8a18ef3d1cfa61e6fbca8fcab02f8eee3d0770d2329490fa7be90a4cae4 - v1.27.3: 495e2193ed779d25584b4b532796c2270df0f7139ef15fb89dc7980603615ef4 - v1.27.2: 8f01f363f7c7f92de2f2276124a895503cdc5a60ff549440170880f296b087eb - v1.27.1: 024a59cd6fc76784b597c0c1cf300526e856e8c9fefa5fa7948158929b739551 - v1.27.0: acd805c6783b678ee0068b9dd8165bbfd879c345fd9c25d6a978dbc965f48544 amd64: + v1.30.4: 6c6053fb8b31030ef7fffe146eb29489f7bf53d7a5ca10e0b10c907bf4b7e281 + v1.30.3: bb78c2a27027278ee644d523f583ed7fdba48b4fbf31e3cfb0e309b6457dda69 + v1.30.2: 672b0cae2accce5eac10a1fe4ea6b166e5b518c79ccf71a2fbe7b53c2ca74062 + v1.30.1: 651faa3bbbfb368ed00460e4d11732614310b690b767c51810a7b638cc0961a2 + v1.30.0: 29f4232c50e6524abba3443ff3b9948d386964d79eb8dfefb409e1f8a8434c14 + v1.29.7: 7699c6f06fbc8e813766b8237de69a095ad820fe484856ffd921a7894b5af605 + v1.29.6: 8f1e04079e614dd549e36be8114ee7022517d646ea715b5778e7c6ab353eb354 + v1.29.5: e424dcdbe661314b6ca1fcc94726eb554bc3f4392b060b9626f9df8d7d44d42c + v1.29.4: ea20ab064f716ab7f69a36d72df340257b31c9721ea86e1cf9d70b35999ddeea + v1.29.3: 6abaa1208bf40b6d1f49e518bd68c8ae4a1be0c5b7d3e45d87979999ab070d8b v1.29.2: 2d4e4fa8685bcbfb661cb41050cd4756f50a7aa147f68492d51a99f9cdfd69ac v1.29.1: d4d81d9020b550c896376fb9e0586a9f15a332175890d061619b52b3e9bc6cbd v1.29.0: 629d4630657caace9c819fd3797f4a70c397fbd41a2a7e464a0507dad675d52c + v1.28.12: 3ffcf5100c6bca3dd0a6c317c744dd97fe497c7c4aefe468321171f940d34971 + v1.28.11: 1f2c7c69736698aa13a59c6705ac26b7b6752d9651330605369357c1ac99c7c6 + v1.28.10: 1a344d34755c5f005120308f09a730e7564c8f857de6606b6bc5f18a69606e5a + v1.28.9: a4d8acf0a74cb1d07d96a1a34148f54c6420874221af16d8ec902d9bffc7ef89 + v1.28.8: c11946cbfd962e1197062534514226cfd70230349e6343ff3ecebfca5476ee64 v1.28.7: 8aa005bdf6af43e47fc818b26f4cb9f361aae8ec4390519e8d4033be65fbef2b v1.28.6: bda3eda8d51e8746a42b535b7eab7df52b091a796227c3212dc30909a8f1b431 v1.28.5: 2b54078c5ea9e85b27f162f508e0bf834a2753e52a57e896812ec3dca92fe9cd @@ -312,22 +371,25 @@ kubeadm_checksums: v1.28.2: 6a4808230661c69431143db2e200ea2d021c7f1b1085e6353583075471310d00 v1.28.1: 6134dbc92dcb83c3bae1a8030f7bb391419b5d13ea94badd3a79b7ece75b2736 v1.28.0: 12ea68bfef0377ccedc1a7c98a05ea76907decbcf1e1ec858a60a7b9b73211bb - v1.27.11: 31bf446a712fb08190838c35d1f4c93b0f975708c59634a5dc3d8915a241c83e - v1.27.10: 23985e958443ac1aabdbeeedc675358abc0638eb580707829fd42b0996a0aae5 - v1.27.9: 78dddac376fa2f04116022cb44ed39ccb9cb0104e05c5b21b220d5151e5c0f86 - v1.27.8: f8864769b8b2d7a14f53eb983f23317ff14d68ab76aba71e9de17ce84c38d4eb - v1.27.7: bc589219a003b3b94c114e4bcf20549a02657a0c6e5c73f588b37817148892d2 - v1.27.6: 2bcdd68957ec25d0689bb56f32b4ec86e38463d2691d5ea21cd109c7afa3aa7c - v1.27.5: 35df8efa6e1bc864ed3c48a665caed634a5c46cfd7f41cda5ad66defdfddb2aa - v1.27.4: 7be21d6fb3707fbbe8f0db0403db6234c8af773b941f931bf8248759ee988bcd - v1.27.3: 2cd663f25c2490bd614a6c0ad9089a47ef315caf0dbdf78efd787d5653b1c6e3 - v1.27.2: 95c4bfb7929900506a42de4d92280f06efe6b47e0a32cbc1f5a1ed737592977a - v1.27.1: c7d32d698e99b90f877025104cb4a9f3f8c707e99e6817940f260135b6d1ad0a - v1.27.0: 78d0e04705a7bdb76a514d60f60c073b16334b15f57ee87f064354ca8a233e80 ppc64le: + v1.30.4: df0a42a57e69f3080871736d0953f1f287f63def0ed514324aca2469463efd7a + v1.30.3: 76a58a7389365295fb4ea1163c2644c3700f066a8e8cb1b7897ad83576e43ce2 + v1.30.2: 8aee71554003411470a5933cdff7896736ae1182055c0de6bb3782d0a7581c71 + v1.30.1: dc529fae8227422a23a8d4f70e28161fa207a4da7cb24d340aae0592dd729ea5 + v1.30.0: a77badcaff292862df8324e17f74ab7ce3c6ea9f390647878f1838a3a832f413 + v1.29.7: 8570e534f3712511284b2e0122d8fe46e36050a0c009df852b69b2de931c53b7 + v1.29.6: 577cdd37fc929be0ffcdc2aa5337bba36a409e00f538da0dcca611a4161be461 + v1.29.5: 05c92f52d75268f0aaff5056e0d6b3e03002b2d17432360750100ada9b2c381b + v1.29.4: ec47a2dbe1969b9513b0313b5b07b72a870e5da54864d9c8391ec5e857404659 + v1.29.3: c0e1f6e9451f28c7b8abf7d3a081fe97578ada69908135e3390f5783511ff7f8 v1.29.2: a0f8ffa8cbfa4bb061ff028df2f6dbb31a9527c561d8c0186d679559f9f347b4 v1.29.1: 3ec6d90c05dd8e4c6bb1f42fd2fe0f091d85317efaf47d9baebd9af506b3878b v1.29.0: 4c414a463ed4277e9062c797d1c0435aa7aec2fd1688c5d34e3161c898113cb5 + v1.28.12: 36f6419cacb46b44d762c12a9580f1e16c6af266e4269e8cedb4d8e5fe355da1 + v1.28.11: 23d8f0c63acea7c9ae4082930f4fa82fc9659ea112f408a439a09a40c5d59223 + v1.28.10: 39a5a27b70ea9eb7e86a37c8862691d875f462a6d52a02355873ffca4595e045 + v1.28.9: 616d06ae90a8e3eb79d99a06b1a7dd304da02e7a2d8c58c1c0e501bdd3982a00 + v1.28.8: 5a42d2c06f553c4284ce6f3f48432389cd63f768f2a032b78ca6ee4c925e9b11 v1.28.7: 60aec330562326fe1ac4a26fe16053c976467fdbc5811c37a5b4a5c13379cac8 v1.28.6: 71fc8af0f80599a991ece0c31b21ca85f3ce49322941a305048d9287c249446c v1.28.5: a9bf8b18711639d9d002f63cebc22c8df1627737891c640f2229461d19b8c321 @@ -336,90 +398,80 @@ kubeadm_checksums: v1.28.2: fdc28482a4316c84d61b0997c29c4d4c7b11459af9c654fdee3b4a3031f0fcb7 v1.28.1: 73e06f2b614ed5665951f7c059e225a7b0b31319c64a3f57e146fbe7a77fe54e v1.28.0: 146fe9194486e46accd5054fa93939f9608fdbeefefc4bc68e4c40fb4a84ccc9 - v1.27.11: b7da90f29cae799d96e47aadb1f20b567fbded09d3d5ddcb88d3378098c6a1f3 - v1.27.10: c928ad330bae724b1ef9775e07285408727513a024e3d86e3d72e05768859db8 - v1.27.9: 92da9084fa9f8b8b55436b61ec3c697ef951b0b0416a3b3a7f0dd0e5e4d8cd88 - v1.27.8: d65b972cd661cb28972f0df731f9e5b65d959920275bad5ef44ff94d3bb8331d - v1.27.7: 6a95a8fb5560a6698d895b2a809485ace0cf5b8c6fb89c843ab20cf89d8b11ad - v1.27.6: f2b53fdcd0a71390e84d16facbcd7a581f1309cb8bd0501f9508ebefe5a3498c - v1.27.5: 3df86ca5de57a6c6b4043be3c050ed9ed39a50720364b399e12e9e52e87e377b - v1.27.4: 1635ba4269daf422be112ae8c3954332e69c2b1e50ecd285343f1f2d65955de8 - v1.27.3: 3f174f096a5aaa62fe0298e9a16b3af9031cb1d2a29fc3823f80f9a2144d5fd4 - v1.27.2: 412bccd310f4976201d359f0637745944944c0fb2ace315e5e07b180445530c7 - v1.27.1: d4c46dcc3d210b6eae0b8c34b3ece9f24b1bb2697175615c451db717a99430fb - v1.27.0: cf2860aef800496fee0d9fd8722bd7d17c6609e32d87ca380127151f2ce02bb0 etcd_binary_checksums: arm: + v3.5.12: 0 + v3.5.11: 0 v3.5.10: 0 v3.5.9: 0 v3.5.8: 0 v3.5.7: 0 v3.5.6: 0 - v3.5.5: 0 - v3.5.4: 0 - v3.5.3: 0 arm64: + v3.5.12: 31f30c01918771ece28d6e553e0f33be9483ced989896ecf6bbe1edb07786141 + v3.5.11: 6edf0cddc8fa2d7674129abe2e44d5a37cc3a6e3b500c13c6cbc2ed2ecf08bf4 v3.5.10: ff74a6018d9b2a1320bff30e5a11b4f2f5c2a3d147df8a8bad53c01b9f800ee1 v3.5.9: bb201c106a61bbab59e2d9f37f4bdff99d50201f513c66b4578741eab581fb28 v3.5.8: 3f4441b293a2d0d4d2f8b2cd9504376e15818f7b865ef4b436e8e6f865f895ff v3.5.7: 1a35314900da7db006b198dd917e923459b462128101736c63a3cda57ecdbf51 v3.5.6: 888e25c9c94702ac1254c7655709b44bb3711ebaabd3cb05439f3dd1f2b51a87 - v3.5.5: a8d177ae8ecfd1ef025c35ac8c444041d14e67028c1a7b4eda3a69a8dee5f9c3 - v3.5.4: 8e9c2c28ed6b35f36fd94300541da10e1385f335d677afd8efccdcba026f1fa7 - v3.5.3: 8b00f2f51568303799368ee4a3c9b9ff8a3dd9f8b7772c4f6589e46bc62f7115 amd64: + v3.5.12: f2ff0cb43ce119f55a85012255609b61c64263baea83aa7c8e6846c0938adca5 + v3.5.11: e256885e753dc99001335e099d3c2eb8cf21a865a087ee4d7e3665752ae5929a v3.5.10: 26e90d024fa2310bc52bb40e7f2132e81640b55f8fc446c00ae07e30af2a44fd v3.5.9: d59017044eb776597eca480432081c5bb26f318ad292967029af1f62b588b042 v3.5.8: d4c1b8d90ad53658f12ffc293afc5694b7bc6cb093af609188649a799e1cc8dc v3.5.7: a43119af79c592a874e8f59c4f23832297849d0c479338f9df36e196b86bc396 v3.5.6: 4db32e3bc06dd0999e2171f76a87c1cffed8369475ec7aa7abee9023635670fb - v3.5.5: 7910a2fdb1863c80b885d06f6729043bff0540f2006bf6af34674df2636cb906 - v3.5.4: b1091166153df1ee0bb29b47fb1943ef0ddf0cd5d07a8fe69827580a08134def - v3.5.3: e13e119ff9b28234561738cd261c2a031eb1c8688079dcf96d8035b3ad19ca58 ppc64le: + v3.5.12: ebd8060508d572678d8d1e4f90f87863e3a6cfcba856ceca32379b03251c0597 + v3.5.11: a2e70b291811fa8ccc34cc7d297bf7d31e3af790bc31e54cad034a49e9db2eb7 v3.5.10: 10cd8e4ecf6718b9712bf2edfac2e4924d7f21dbe58d368e6e10578c85bd8c01 v3.5.9: 551539ebb344ebdc77f170ea51512a6cda35877ffdcbd8b3316b2495a8b2bd87 v3.5.8: 20e28302c1424b1a3daf7d817f2662e4c64e395a82765d1696cb53cb6bc37a4e v3.5.7: e861aa6acd4d326ec01bfa06fffb80d33f3f8c26e0eb8b73e4424578d149bd04 v3.5.6: e235cb885996b8aac133975e0077eaf0a2f8dc7062ad052fa7395668a365906b - v3.5.5: 08422dffd5749f0a5f18bd820241d751e539a666af94251c3715cba8f4702c42 - v3.5.4: 2f0389caed87c2504ffc5a07592ca2a688dee45d599073e5f977d9ce75b5f941 - v3.5.3: f14154897ca5ad4698383b4c197001340fbe467525f6fab3b89ee8116246480f cni_binary_checksums: arm: + v1.4.0: 6cddc5804fff93b914f3314d62fa03f24d69f59c03940e0bbe85a370371b5bb8 v1.3.0: 86c4c866a01a8073ad14f6feec74de1fd63669786850c7be47521433f9570902 v1.2.0: fde5bf2da73995196d248177ee8deeafa8005f33cbe1ab33bd2d75c17ca5a99a v1.1.1: 84f97baf80f9670a8cd0308dedcc8405d2bbc65166d670b48795e0d1262b4248 v1.1.0: 91e03a9287dcf8d0249159c90357b0f871ecf7ef0ca5014b2e143f2b30ae9c6d v1.0.1: d35e3e9fd71687fc7e165f7dc7b1e35654b8012995bbfd937946b0681926d62d v1.0.0: 910c2ba8b6f50b1081b219d6db04459b555940973249fcf39a792932a91f6d39 - v0.9.1: 909e800d01cc61ffa26f2629e4a202a58d727e6ccaabd0310ef18d2b1e00943c arm64: + v1.4.0: 304d4389d5b732b7a73513d002c4895f731d030682d40653f411e10e39114194 v1.3.0: de7a666fd6ad83a228086bd55756db62ef335a193d1b143d910b69f079e30598 v1.2.0: 525e2b62ba92a1b6f3dc9612449a84aa61652e680f7ebf4eff579795fe464b57 v1.1.1: 16484966a46b4692028ba32d16afd994e079dc2cc63fbc2191d7bfaf5e11f3dd v1.1.0: 33fc7b8d9d5be2d7f95e69e6a9e2af206879942f1e6b7615c04017dce5067f1a v1.0.1: 2d4528c45bdd0a8875f849a75082bc4eafe95cb61f9bcc10a6db38a031f67226 v1.0.0: 736335bc5923a37cfb6cc2305489ce6206bcc565004f525b5f7c3604f092aa3a - v0.9.1: ef17764ffd6cdcb16d76401bac1db6acc050c9b088f1be5efa0e094ea3b01df0 amd64: + v1.4.0: c2485ddb3ffc176578ae30ae58137f0b88e50f7c7f2af7d53a569276b2949a33 v1.3.0: 754a71ed60a4bd08726c3af705a7d55ee3df03122b12e389fdba4bea35d7dd7e v1.2.0: f3a841324845ca6bf0d4091b4fc7f97e18a623172158b72fc3fdcdb9d42d2d37 v1.1.1: b275772da4026d2161bf8a8b41ed4786754c8a93ebfb6564006d5da7f23831e5 v1.1.0: 05d46ac19d01669d424ee57401c0deba101763ac494858064b4ea4ffdcc37c5d v1.0.1: 5238fbb2767cbf6aae736ad97a7aa29167525dcd405196dfbc064672a730d3cf v1.0.0: 5894883eebe3e38f4474810d334b00dc5ec59bd01332d1f92ca4eb142a67d2e8 - v0.9.1: 962100bbc4baeaaa5748cdbfce941f756b1531c2eadb290129401498bfac21e7 ppc64le: + v1.4.0: c87a36a75ad1692933e3218cae734ba809ae2190c725a050ac9033fc96d2ed26 v1.3.0: 8ceff026f4eccf33c261b4153af6911e10784ac169d08c1d86cf6887b9f4e99b v1.2.0: 4960283b88d53b8c45ff7a938a6b398724005313e0388e0a36bd6d0b2bb5acdc v1.1.1: 1551259fbfe861d942846bee028d5a85f492393e04bcd6609ac8aaa7a3d71431 v1.1.0: 98239a57452e93c0a27ba9f87bcbb80c7f982f225246f3fe4f3f5ac9b6b1becb v1.0.1: f078e33067e6daaef3a3a5010d6440f2464b7973dec3ca0b5d5be22fdcb1fd96 v1.0.0: 1a055924b1b859c54a97dc14894ecaa9b81d6d949530b9544f0af4173f5a8f2a - v0.9.1: 5bd3c82ef248e5c6cc388f25545aa5a7d318778e5f9bc0a31475361bb27acefe calicoctl_binary_checksums: arm: + v3.28.1: 0 + v3.28.0: 0 + v3.27.3: 0 + v3.27.2: 0 + v3.27.1: 0 + v3.27.0: 0 v3.26.4: 0 v3.26.3: 0 v3.26.2: 0 @@ -437,14 +489,13 @@ calicoctl_binary_checksums: v3.24.0: 0 v3.23.5: 0 v3.23.4: 0 - v3.23.3: 0 - v3.23.2: 0 - v3.23.1: 0 - v3.23.0: 0 - v3.22.5: 0 - v3.22.4: 0 - v3.22.3: 0 arm64: + v3.28.1: c062d13534498a427c793a4a9190be4df3cf796a3feb29e4a501e1d6f48daa7c + v3.28.0: c4ca8563d2a920729116a3a30171c481580c8c447938ce974ce14d7ce25a31bf + v3.27.3: 1fc5f58a18d8b1c487b4663fc5cbe23b45bd9d31617debd309f6dfac7c11a8ef + v3.27.2: 0fd1f65a511338cf9940835987d420c94ab95b5386288ba9673b736a4d347463 + v3.27.1: 0 + v3.27.0: b4b8c71f9658165e45336b9b5e4fad865529feeffe4294247eb5b4c4310dcaf9 v3.26.4: d647d9443ce89df62da6619643375a4f577f5a7fa4e1162416403df521826c2d v3.26.3: c50272a39658a3b358b33c03fe10d1dde894764413279fecc72d40b95535b398 v3.26.2: 44de9118f481a1125e2d50cdfbb55073e744dd8e71d2be45eeb2757302910c67 @@ -462,14 +513,13 @@ calicoctl_binary_checksums: v3.24.0: db306755fc9c6a746516eec33337bc102b0d546f6b9fc671795b47d1a878f05d v3.23.5: 0941ad0deeb03d8fda96340948cdbc15d14062086438150cf3ec5ee2767b22c3 v3.23.4: c54b7d122d9315bbab1a88707b7168a0934a80c4f2a94c9e871bcc8a8cf11c11 - v3.23.3: 741b222f9bb10b7b5e268e5362796061c8862d4f785bb6b9c4f623ea143f4682 - v3.23.2: 232b992e6767c68c8c832cc7027a0d9aacb29901a9b5e8871e25baedbbb9c64c - v3.23.1: 30f7e118c21ecba445b4fbb27f7ac8bc0d1525ab3c776641433e3b1a3388c65b - v3.23.0: 2afa5795c426faae1fdfd966249f8191929e43d2b94bea268fa9c7ab5a36f6b6 - v3.22.5: f0f6ba82d55c7faa5afb361eb76a78c8e2cf38cd06e0287e03821f77af0c7837 - v3.22.4: e84ba529091818282012fd460e7509995156e50854781c031c81e4f6c715a39a - v3.22.3: 3a3e70828c020efd911181102d21cb4390b7b68669898bd40c0c69b64d11bb63 amd64: + v3.28.1: 22ec5727c38dbe19001792b4ca64ac760a6e2985d5c1a231d919dbebe5bca171 + v3.28.0: 4ea270699e67ca29e5533ddb0a68d370cb0005475796c7e841f83047da6297b6 + v3.27.3: e22b8bb41684f8ffb5143b50bf3b2ab76985604d774d397cfb6fb11d8a19f326 + v3.27.2: 692f69dc656e41cd35e23e24f56c98c4aeeb723fed129985b46f71e6eb5e1594 + v3.27.1: 0 + v3.27.0: 46e79ae146b3dd90998f56511cf5d6db64deb97cb784235caf1f99e0672d66e4 v3.26.4: 9960357ef6d61eda7abf80bd397544c1952f89d61e5eaf9f6540dae379a3ef61 v3.26.3: 82bd7d12b0f6973f9593fb62f5410ad6a81ff6b79e92f1afd3e664202e8387cf v3.26.2: eba9bc34f44801a513c48f730a409dc1ece0ebfd9c1acc21fd3adf0eff93ecdc @@ -487,14 +537,13 @@ calicoctl_binary_checksums: v3.24.0: 0da282a6a7870fe25742799a921730343c57a1609c5e255e1bb06b5e85011ee2 v3.23.5: 4c777881709ddaabcf4b56dcbe683125d7ed5743c036fee9273c5295e522082f v3.23.4: 1ea0d3b6543645612e8239978878b6adefdb7619a16ecbdb8e6dc2687538f689 - v3.23.3: d9c04ab15bad9d8037192abd2aa4733a01b0b64a461c7b788118a0d6747c1737 - v3.23.2: 3784200cdfc0106c9987df2048d219bb91147f0cc3fa365b36279ac82ea37c7a - v3.23.1: e8fd04d776df5571917512560800bf77f3cdf36ca864c9cae966cb74d62ba4fe - v3.23.0: 38106fdd581ab30dc835efeaf83a88b49b21484f8ad33afbefdaf3c49e007550 - v3.22.5: ba75fa65be0e97555b37282e1ab469ad933866eed164b40513e835279bea7348 - v3.22.4: cc412783992abeba6dc01d7bc67bdb2e3a0cf2f27fc3334bdfc02d326c3c9e15 - v3.22.3: a9e5f6bad4ad8c543f6bdcd21d3665cdd23edc780860d8e52a87881a7b3e203c ppc64le: + v3.28.1: 985caad36fed7b883a2cd4cf91e556974bcca95fe4e6b7ff4cb64d8d8fbe9223 + v3.28.0: 0789cb0d1478ec3f0a44db265b19042be9dfc18bc1776343c7ea8d246561d12b + v3.27.3: 5f2ac510c0ec31ec4c02ff2660f2502b68b655616d5b766a51bd99d2e3604fbc + v3.27.2: f918bb88de1d01de3d143e1e75d0ee1256f247c5cbabec7d665aaf8d1fd3cc6c + v3.27.1: 0 + v3.27.0: 3de46d8bc30c6f9d9387d484ed62a5655c1f204b1b831b5a90f0a0d1c1ffd752 v3.26.4: 41cfa77cc27cfe89a046ddb033cf71a46512f4b81251e28c69fca2cee13617ff v3.26.3: 30a32acbe71894a9783e350ed44294e739b3322f157b2c224ad3c058473e5701 v3.26.2: c4d42a85afb67020e9cf9dcafe184af6ad60c5609d60001b9505b1a83959b246 @@ -512,59 +561,58 @@ calicoctl_binary_checksums: v3.24.0: cf63f4820e792c101940af3ed6422e1b8769ffcbafd0c3672f2e86675733b053 v3.23.5: 1b352e73515cbe5746f9b9d7633d8317bd48f713b9b731837f7d79089463321c v3.23.4: cdd6eace3dc2676b7eed79c665cb0b3dbdd9dcb3bf5b09d7ae20f4f015f75f9b - v3.23.3: f83efcd8d3d7c96dfe8e596dc9739eb5d9616626a6afba29b0af97e5c222575a - v3.23.2: d9ded02381a0fc1311561d0cc9eed9ea827462f3b823593d6ac8bd0591d2020f - v3.23.1: ef5e9b413fbe32da09023cdafc2c3977627dd64a0abcfc68398d3b3923cdd8a6 - v3.23.0: 8b4d40a4613cbc94540b1c7f3252b5924cb549085e73f49e4f84e7814bac7c06 - v3.22.5: 1b3ea734a474d4504c019a8b2213385c8c18cd334edcaefb877e59f8381d2b45 - v3.22.4: f8672ac27ab72c1b05b0f9ae5694881ef8e061bfbcf551f964e7f0a37090a243 - v3.22.3: 7c2fe391f2a18eccff65c64bf93133dc5c58c7322cbd31ea207bbfef5b563947 ciliumcli_binary_checksums: arm: - v0.15.0: c8c2d7e2564b1cb6bc82266132f584cb42a430930967ef1fced0b01c8384fedc - v0.14.8: d93dc926c795696f43e7f979ca3a1ed3e912d2c8fd5af305f78c8b08521ef939 - v0.14.7: f9ecd2c029f69d89cb418f461a6098039824ae841aaf9d213df698ccb6a1bfc6 - v0.14.6: 2481dd4edeb01de08c193a421e1b12068b215ee03ff77c3c8ed4514fb810a9d7 - v0.14.5: 08ba6fed412d8e0d1d8f2d9c402aea6c69ac69630f6bf0fd985ad1909b298aae - v0.14.4: 08decd0cca8e1dfcda4322e76c1dbb7eb2c32a2ee6fb8b78d4d6d5bf9cf06373 - v0.14.3: 172e8320ac42750b3a2f41cc6407e4a63c59b30c32ab6e0ff8d5c0695026a5f3 - v0.14.2: 294f27672ad32d065f8899899c68f2561293b68714a65229394769a209254bbd - v0.14.1: 78eae78564624b1346998da9b7da200e5f8489575da09af042bcde0532674264 - v0.14.0: f1873e41a14c380971ee418d60cf37bd8dd2ceefd7eeff6befbbe0768283a65b + v0.16.0: 0 + v0.15.23: 0 + v0.15.22: 0 + v0.15.21: 0 + v0.15.20: 0 + v0.15.19: 0 + v0.15.18: 0 + v0.15.17: 0 + v0.15.16: 0 + v0.15.15: 0 arm64: - v0.15.0: 57daf587073147402421f5d8bf069018f73cb66a2da5b4393b742ef59ee15139 - v0.14.8: 25e568d7f26c2a0e83e125a98255ae2faa8ea9e0b0e6d34cd8c690238911e97b - v0.14.7: ad12a491a71185e9cf37665734bf529c5b992025f00c5f3cebfca9524af36472 - v0.14.6: c8218c246fe4c2c2fabfdaaa6f779ab3d8a20bdad9d7113289e9cf9aa0fe75ff - v0.14.5: 7cf13e10162f4ff6114e17c85377b96ed91f187e3131e0c6c35d8f6a181de07d - v0.14.4: 6b6326c178df30085da0f584ac380b1c81bdfbbb7c2a8df0862184444b8bd9eb - v0.14.3: 36df943449dde3eecf1e45cc42a244ef5163ac89f614791a0657cf03ff92273f - v0.14.2: bf94d6aaaf02a6bf728e4ea022e7e37b2dfdc49d5931245be298b2ff4d6af008 - v0.14.1: a73afb03a9815297e6f891aa8420ea04434b479e2777b04b49084d7a8d9cf062 - v0.14.0: e59bd6a38a9bc42f61e34907698ae5cb53a43d93bdec6e7327613f911cb8f205 + v0.16.0: fe16bcd447fc6fe764ca75712f5832d7504845e9f782684ff09c9f52548237fe + v0.15.23: 9aa37d99a15e72bbcb555d7ed5b88c2ae3a7e6fbc478f9ee402a835ba6b41175 + v0.15.22: 23caf44dade82b5a986e9799db333724845750bebe32e571a356ab9116406f6d + v0.15.21: 346bf2d0d60e11e02c676bcd7cb379cbedd88830188dbf811ad7099f5907da9d + v0.15.20: 4b05fb1661b699edd89f37124d5cd0aa4f5dcfc197cef6a0bc7a6faa3dc119d4 + v0.15.19: a32521b2add0203c1945f71c6d8a50739946b4f7e35c2636529a5063959072d4 + v0.15.18: fa1aecaf1c69663bdece17608c6e85f0a5a2c8ee8fe2cbbadf25cbe887b7ae15 + v0.15.17: 4df6f634512a0e426258fbb83d43c0defabe9d91c81480c040af08fa05b4a989 + v0.15.16: 86ed6a2e796c39dd00072e7c141fc35b68d63392d1ac5e183a7ce9d7263e23a0 + v0.15.15: 5c1693ea163b094a92ebc6997b6e678cc8c24a52040c22433b58b419de74b28f amd64: - v0.15.0: 504bbb94b55d4605157b78bf7747cca778888910f8c65729fe69cb94c3d37f5b - v0.14.8: b36014107cea29bdd1df34aa1f292eca9f966d0cc9255232891c0ac6956d421c - v0.14.7: 687b913840f6d54c80e540fac31dd22edbce8962fe8875810e7ed4abc874a45a - v0.14.6: 83fa27d0318f85df78ae6ca06f33c71b900e309cf7488c0db9b9ad5753f6560f - v0.14.5: e6d3b2d297129b10f5690558a85e97d2af407ac30d85758ff77dea686b9c1303 - v0.14.4: 6b3950f8c3b1e8cf7e2123bb4cb1fae4217d720b3353bf924c78d87824c9f1b0 - v0.14.3: 613ffc1cc62ce35b519feb6fc39d1cb2b46635511d365db0da5df498fc6bc001 - v0.14.2: 7ff65f0e85af5daa755c63851f85dea656a59ae4a306e1e9ae02abdf0014f564 - v0.14.1: 86c27fff43f99719271f54a330374ee23f4308aeb6decf7747b354e885a0fcfd - v0.14.0: 73bcbce6fac15c3a62d2a68629f292fa2787440a15998d8c868dae20a6e0e6ed + v0.16.0: da98675f961833d4ffd68b1046d907b228a7d394ded2abd70a50b20eaca171c4 + v0.15.23: cda3f1c40ae2191a250a7cea9e2c3987eaa81cb657dda54cd8ce25f856c384da + v0.15.22: c9bdf99362c16bb63ea44a214e39319d8ac1d196345792caae9665f36fe274a3 + v0.15.21: 89190bb3fdcde892d7a8d3a9718e5ffacd312d2535eee54d93ccc81c2d430cb7 + v0.15.20: a1a09f3f0176e118b1b00be4fcd7f9f32f27c9587c64b5579d2747d751e72e23 + v0.15.19: 9632fa506d7d0e0298dc5b80b9e05239ceb01d60b124dde2132417a96ba4d07b + v0.15.18: b10359784d4c194d43bbd1de5d7000f9697e451049008ade5a0754e3c4f7958e + v0.15.17: ed8edbce96ac7921ee75b2fbe42409fbe381e2f8f896c10d13f864cc52e07a43 + v0.15.16: f30095e1a0b926d2114b7a419141bea76e950b643182e97e666950ca05a205d9 + v0.15.15: 492279c1f960c79747290a5d1e1b21084a04a93f9e13ab4ae7df4c76fe808aff ppc64le: - v0.15.0: 0 - v0.14.8: 0 - v0.14.7: 0 - v0.14.6: 0 - v0.14.5: 0 - v0.14.4: 0 - v0.14.3: 0 - v0.14.2: 0 - v0.14.1: 0 - v0.14.0: 0 + v0.16.0: 0 + v0.15.23: 0 + v0.15.22: 0 + v0.15.21: 0 + v0.15.20: 0 + v0.15.19: 0 + v0.15.18: 0 + v0.15.17: 0 + v0.15.16: 0 + v0.15.15: 0 calico_crds_archive_checksums: + v3.28.1: c56f1530e7ded9d5b4afb9d83a7a24da6d2959ef7ad38521813f1c2bf138182d + v3.28.0: ee721337db0cd847e91aae1cdfd420596896ebcb865575fd913c2f12ac2cdb76 + v3.27.3: d11a32919bff389f642af5df8180ad3cec586030decd35adb2a7d4a8aa3b298e + v3.27.2: 8154bb4aad887f2a5500b505fe203a918f72c4e602b04c688c4b94f76a26e925 + v3.27.1: 76abb0db222af279e3514cfae02be9259097b565bbb2ffcb776ca00566480edb + v3.27.0: 2a4b5132035dfd6ac4abc8d545f33de139350eca523e0c5cfe4ac32e43fcb2f1 v3.26.4: 481e52de684c049f3f7f7bac78f0f6f4ae424d643451adc9e3d3fa9d03fb6d57 v3.26.3: b51817e7ae5189b0737ccc901b7b5950a4f84b6029eebfdcc3e3b851bd410d03 v3.26.2: 8c15b29db525c4cab7bea304357c942a0d55483c03d9c2a0ed3303f66b8f9ff8 @@ -582,310 +630,219 @@ calico_crds_archive_checksums: v3.24.0: 3c6694779b916fa364592a8e19d45f509c67e7dec64fb4cf09c379e170de7720 v3.23.5: aca591282d9e10a180a2afb05da6ca8db4dd02b886b4788f4962cf5b37ba1bda v3.23.4: c8b6b033755416756b2b5ef248332b7c5b660618327cb7f83a80fb949fdc601a - v3.23.3: d25f5c9a3adeba63219f3c8425a8475ebfbca485376a78193ec1e4c74e7a6115 - v3.23.2: 37c429650723c5f12ffc20dd390ead1e10d2b8a955a199666d155115a49b4dcc - v3.23.1: a1754ae4bb158e3b46ba3fb326d8038d54cd0dc2c5c8527eadf2b0a6cf8ef2e3 - v3.23.0: 27dd12ff792eb8f680506566e8d99467673f859298fe93d4f23c2139cc3f0c96 - v3.22.5: f3b6a6861b7beae549b4cf0be5c4b954c0cc19e95adb89dd9d78e983f9f2a5d7 - v3.22.4: e72e7b8b26256950c1ce0042ac85fa83700154dae9723c8d007de88343f6a7e5 - v3.22.3: 55ece01da00f82c62619b82b6bfd6442a021acc6fd915a753735e6ebceabaa21 krew_archive_checksums: darwin: arm: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 arm64: v0.4.4: e6ac776140b228d6bdfda11247baf4e9b11068f42005d0975fc260c629954464 v0.4.3: 22f29ce3c3c9c030e2eaf3939d2b00f0187dfdbbfaee37fba8ffaadc46e51372 - v0.4.2: a69d48f8cad7d87b379071129cde3ee4abcaaa1c3f3692bc80887178b2cc7d33 amd64: v0.4.4: 5f4d2f34868a87cf1188212cf7cb598e76a32f389054089aad1fa46e6daf1e1b v0.4.3: 6f6a774f03ad4190a709d7d4dcbb4af956ca0eb308cb0d0a44abc90777b0b21a - v0.4.2: 47c6b5b647c5de679a2302444f75a36a70530fa4751cb655e0edd5da56a5f110 ppc64le: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 linux: arm: v0.4.4: 4f3d550227e014f3ba7c72031108ffda0654cb755f70eb96be413a5102d23333 v0.4.3: 68eb9e9f5bba29c7c19fb52bfc43a31300f92282a4e81f0c51ad26ed2c73eb03 - v0.4.2: 115f503e35ef7f63f00a9b01236d80a9f94862ec684010a81c3a3b51bdca1351 arm64: v0.4.4: f8f0cdbf698ed3e8cb46e7bd213754701341a10e11ccb69c90d4863e0cf5a16a v0.4.3: 0994923848882ad0d4825d5af1dc227687a10a02688f785709b03549dd34d71d - v0.4.2: 7581be80d803536acc63cceb20065023b96f07fd7eb9f4ee495dce0294a866eb amd64: v0.4.4: e471396b0ed4f2be092b4854cc030dfcbb12b86197972e7bef0cb89ad9c72477 v0.4.3: 5df32eaa0e888a2566439c4ccb2ef3a3e6e89522f2f2126030171e2585585e4f - v0.4.2: 203bfd8006b304c1e58d9e96f9afdc5f4a055e0fbd7ee397fac9f36bf202e721 ppc64le: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 windows: arm: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 arm64: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 amd64: v0.4.4: da0dfeb2a598f11fb9ce871ee7f3b1a69beb371a45f531ee65a71b2201511d28 v0.4.3: d1343a366a867e9de60b23cc3d8ee935ee185af25ff8f717a5e696ba3cae7c85 - v0.4.2: 3150ff0291ac876ebe4fe0e813ee90a18aa2bc0510c3adcfae6117dec44ef269 ppc64le: v0.4.4: 0 v0.4.3: 0 - v0.4.2: 0 helm_archive_checksums: arm: - v3.13.2: 06e8436bde78d53ddb5095ba146fe6c7001297c7dceb9ef6b68992c3ecfde770 - v3.13.1: a9c188c1a79d2eb1721aece7c4e7cfcd56fa76d1e37bd7c9c05d3969bb0499b4 - v3.13.0: bb2cdde0d12c55f65e88e7c398e67463e74bc236f68b7f307a73174b35628c2e - v3.12.3: 6b67cf5fc441c1fcb4a860629b2ec613d0e6c8ac536600445f52a033671e985e - v3.12.2: 39cc63757901eaea5f0c30b464d3253a5d034ffefcb9b9d3c9e284887b9bb381 - v3.12.1: 6ae6d1cb3b9f7faf68d5cd327eaa53c432f01e8fd67edba4e4c744dcbd8a0883 - v3.12.0: 1d1d3b0b6397825c3f91ec5f5e66eb415a4199ccfaf063ca399d64854897f3f0 - v3.11.3: 0816db0efd033c78c3cc1c37506967947b01965b9c0739fe13ec2b1eea08f601 - v3.11.2: 444b65100e224beee0a3a3a54cb19dad37388fa9217ab2782ba63551c4a2e128 - v3.11.1: 77b797134ea9a121f2ede9d159a43a8b3895a9ff92cc24b71b77fb726d9eba6d - v3.11.0: cddbef72886c82a123038883f32b04e739cc4bd7b9e5f869740d51e50a38be01 - v3.10.3: dca718eb68c72c51fc7157c4c2ebc8ce7ac79b95fc9355c5427ded99e913ec4c + v3.15.4: aa3fb3014d147e5dcf8bfe4f6d5fe8677029ed720d4a4bcc64e54cb745a72206 + v3.15.3: 77a9c9699c836dd34fca3d9e783f9e70e0ddbe1a4b44aa13fac82f6193da452f + v3.15.2: 2b28fda1d8c6f087011bc7ec820051a13409dadce8385529f306476632e24e85 + v3.15.1: fa7a8b472c8f311ac618a231218511efeafad306781d11ad68976e0461074b0e + v3.15.0: 614d53ab1192667facce7e8d4e884ff067e5684199a7e5223e8808abc43e927f + v3.14.4: 962297c944c06e1f275111a6e3d80e37c9e9e8fed967d4abec8efcf7fc9fb260 + v3.14.3: d4ff88f02d6731ec5dbde86a67bf391e673d0d9e87901727fbf62372aff106ec + v3.14.2: b70fb6fa2cdf0a5c782320c9d7e7b155fcaec260169218c98316bb3cf0d431d9 + v3.14.1: f50c00c262b74435530e677bcec07637aaeda1ed92ef809b49581a4e6182cbbe + v3.14.0: cf38dfdead7266ae56662743bda0c78655814f0adeca382d1b07a812bb1a599a arm64: - v3.13.2: f5654aaed63a0da72852776e1d3f851b2ea9529cb5696337202703c2e1ed2321 - v3.13.1: 8c4a0777218b266a7b977394aaf0e9cef30ed2df6e742d683e523d75508d6efe - v3.13.0: d12a0e73a7dbff7d89d13e0c6eb73f5095f72d70faea30531941d320678904d2 - v3.12.3: 79ef06935fb47e432c0c91bdefd140e5b543ec46376007ca14a52e5ed3023088 - v3.12.2: cfafbae85c31afde88c69f0e5053610c8c455826081c1b2d665d9b44c31b3759 - v3.12.1: 50548d4fedef9d8d01d1ed5a2dd5c849271d1017127417dc4c7ef6777ae68f7e - v3.12.0: 658839fed8f9be2169f5df68e55cb2f0aa731a50df454caf183186766800bbd0 - v3.11.3: 9f58e707dcbe9a3b7885c4e24ef57edfb9794490d72705b33a93fa1f3572cce4 - v3.11.2: 0a60baac83c3106017666864e664f52a4e16fbd578ac009f9a85456a9241c5db - v3.11.1: 919173e8fb7a3b54d76af9feb92e49e86d5a80c5185020bae8c393fa0f0de1e8 - v3.11.0: 57d36ff801ce8c0201ce9917c5a2d3b4da33e5d4ea154320962c7d6fb13e1f2c - v3.10.3: 260cda5ff2ed5d01dd0fd6e7e09bc80126e00d8bdc55f3269d05129e32f6f99d + v3.15.4: fa419ecb139442e8a594c242343fafb7a46af3af34041c4eac1efcc49d74e626 + v3.15.3: bd57697305ba46fef3299b50168a34faa777dd2cf5b43b50df92cca7ed118cce + v3.15.2: adcf07b08484b52508e5cbc8b5f4b0b0db50342f7bc487ecd88b8948b680e6a7 + v3.15.1: b4c5519b18f01dd2441f5e09497913dc1da1a1eec209033ae792a8d45b9e0e86 + v3.15.0: c3b0281fca4c030548211dd6e9b032ee0a9fc53eab614f6acbaff631682ce808 + v3.14.4: 113ccc53b7c57c2aba0cd0aa560b5500841b18b5210d78641acfddc53dac8ab2 + v3.14.3: 85e1573e76fa60af14ba7e9ec75db2129b6884203be866893fa0b3f7e41ccd5e + v3.14.2: c65d6a9557bb359abc2c0d26670de850b52327dc3976ad6f9e14c298ea3e1b61 + v3.14.1: f865b8ad4228fd0990bbc5b50615eb6cb9eb31c9a9ca7238401ed897bbbe9033 + v3.14.0: b29e61674731b15f6ad3d1a3118a99d3cc2ab25a911aad1b8ac8c72d5a9d2952 amd64: - v3.13.2: 55a8e6dce87a1e52c61e0ce7a89bf85b38725ba3e8deb51d4a08ade8a2c70b2d - v3.13.1: 98c363564d00afd0cc3088e8f830f2a0eeb5f28755b3d8c48df89866374a1ed0 - v3.13.0: 138676351483e61d12dfade70da6c03d471bbdcac84eaadeb5e1d06fa114a24f - v3.12.3: 1b2313cd198d45eab00cc37c38f6b1ca0a948ba279c29e322bdf426d406129b5 - v3.12.2: 2b6efaa009891d3703869f4be80ab86faa33fa83d9d5ff2f6492a8aebe97b219 - v3.12.1: 1a7074f58ef7190f74ce6db5db0b70e355a655e2013c4d5db2317e63fa9e3dea - v3.12.0: da36e117d6dbc57c8ec5bab2283222fbd108db86c83389eebe045ad1ef3e2c3b - v3.11.3: ca2d5d40d4cdfb9a3a6205dd803b5bc8def00bd2f13e5526c127e9b667974a89 - v3.11.2: 781d826daec584f9d50a01f0f7dadfd25a3312217a14aa2fbb85107b014ac8ca - v3.11.1: 0b1be96b66fab4770526f136f5f1a385a47c41923d33aab0dcb500e0f6c1bf7c - v3.11.0: 6c3440d829a56071a4386dd3ce6254eab113bc9b1fe924a6ee99f7ff869b9e0b - v3.10.3: 950439759ece902157cf915b209b8d694e6f675eaab5099fb7894f30eeaee9a2 + v3.15.4: 11400fecfc07fd6f034863e4e0c4c4445594673fd2a129e701fe41f31170cfa9 + v3.15.3: ad871aecb0c9fd96aa6702f6b79e87556c8998c2e714a4959bf71ee31282ac9c + v3.15.2: 2694b91c3e501cff57caf650e639604a274645f61af2ea4d601677b746b44fe2 + v3.15.1: 7b20e7791c04ea71e7fe0cbe11f1a8be4a55a692898b57d9db28f3b0c1d52f11 + v3.15.0: a74747ac40777b86d3ff6f1be201504bba65ca46cd68b5fe25d3c394d0dcf745 + v3.14.4: a5844ef2c38ef6ddf3b5a8f7d91e7e0e8ebc39a38bb3fc8013d629c1ef29c259 + v3.14.3: 3c90f24e180f8c207b8a18e5ec82cb0fa49858a7a0a86e4ed52a98398681e00b + v3.14.2: 0885a501d586c1e949e9b113bf3fb3290b0bbf74db9444a1d8c2723a143006a5 + v3.14.1: 75496ea824f92305ff7d28af37f4af57536bf5138399c824dff997b9d239dd42 + v3.14.0: f43e1c3387de24547506ab05d24e5309c0ce0b228c23bd8aa64e9ec4b8206651 ppc64le: - v3.13.2: 11d96134cc4ec106c23cd8c163072e9aed6cd73e36a3da120e5876d426203f37 - v3.13.1: f0d4ae95b4db25d03ced987e30d424564bd4727af6a4a0b7fca41f14203306fb - v3.13.0: d9be0057c21ce5994885630340b4f2725a68510deca6e3c455030d83336e4797 - v3.12.3: 8f2182ae53dd129a176ee15a09754fa942e9e7e9adab41fd60a39833686fe5e6 - v3.12.2: fb0313bfd6ec5a08d8755efb7e603f76633726160040434fd885e74b6c10e387 - v3.12.1: 32b25dba14549a4097bf3dd62221cf6df06279ded391f7479144e3a215982aaf - v3.12.0: 252d952b0e1b4ed2013710ddedf687ed5545d9f95a4fd72de0ff9617ff69155c - v3.11.3: 9f0a8299152ec714cee7bdf61066ba83d34d614c63e97843d30815b55c942612 - v3.11.2: 04cbb8d053f2d8023e5cc6b771e9fa384fdd341eb7193a0fb592b7e2a036bf3d - v3.11.1: 6ab8f2e253c115b17eda1e10e96d1637047efd315e9807bcb1d0d0bcad278ab7 - v3.11.0: 6481a51095f408773212ab53edc2ead8a70e39eba67c2491e11c4229a251f9b5 - v3.10.3: 93cdf398abc68e388d1b46d49d8e1197544930ecd3e81cc58d0a87a4579d60ed + v3.15.4: e4efce93723f52dd858e9046ea836c9c75f346facce1b87b8cf78c817b97e6ac + v3.15.3: fac86a8a0515e1f4593d6288426c99f2b3edac946b7f118fcfe03e4a09523f25 + v3.15.2: 9d95528fb797f6429f7f9b6dee0cf87bf8c71f6470e1db4a51e844c169c285a3 + v3.15.1: 0bfe2ff8b29c1f26b0484261c0fe0d041188b2e1aa5da8e461e44083bbf655a3 + v3.15.0: bcec19cdad95cae99edce046ccd8090f275e63381ccb6accb4304819fc26e004 + v3.14.4: d0d625b43f6650ad376428520b2238baa2400bfedb43b2e0f24ad7247f0f59b5 + v3.14.3: aab121ca470e2a502cda849a9b3e92eeb9a32e213b0f0a79a95a04e375d26ce7 + v3.14.2: f3bc8582ff151e619cd285d9cdf9fef1c5733ee5522d8bed2ef680ef07f87223 + v3.14.1: 4d853ab8fe3462287c7272fbadd5f73531ecdd6fa0db37d31630e41ae1ae21de + v3.14.0: f1f9d3561724863edd4c06d89acb2e2fd8ae0f1b72058ceb891fa1c346ce5dbc cri_dockerd_archive_checksums: arm: + 0.3.11: 0 + 0.3.10: 0 0.3.9: 0 0.3.8: 0 0.3.7: 0 0.3.6: 0 0.3.5: 0 - 0.3.4: 0 - 0.3.3: 0 - 0.3.2: 0 - 0.3.1: 0 - 0.3.0: 0 - 0.2.6: 0 - 0.2.5: 0 arm64: + 0.3.11: 877f635a7005b393f7aab24ca4b1cd7bdfb3b967d055e858408240c86e3cab9a + 0.3.10: 24d2d9cdbb4ed4bda4b0838edb52104ac7a4e2212a0ee05b177de0ae5b6a4a9a 0.3.9: f5051002b4f95b0e8fe7fbd5f8de4493350e010834d2a8b647f2b26c45c6c203 0.3.8: 64286af171785f0facb72cf364867600b4db19f43a01db49b8b364f5d04aadae 0.3.7: 8da54563ee7ddee36b1adf1f96b3b7b97ec2bc0ec23559b89d9af8eae5e62d9e 0.3.6: 793b8f57cecf734c47bface10387a8e90994c570b516cb755900f21ebd0a663b 0.3.5: c20014dc5a71e6991a3bd7e1667c744e3807b5675b1724b26bb7c70093582cfe - 0.3.4: 598709c96585936729140d31a76be778e86f9e31180ff3622a44b63806f37779 - 0.3.3: fa0aa587fc7615248f814930c2e0c9a252afb18dc37c8f4d6d0263faed45d5a7 - 0.3.2: b24ae82808bb5ee531348c952152746241ab9b1b7477466ba6c47a7698ef16ae - 0.3.1: dcaa2794ac23348c6d370717a68e70d1da1723a11a892d63459cd88fb5d82226 - 0.3.0: 2a7e5bb156b80f737ef07ae2e8050394ea3e47fb0b7055afac47a365eaa321fb - 0.2.6: 90122641e45e8ff81dbdd4d84c06fd9744b807b87bff5d0db7f826ded326a9fd - 0.2.5: 067242bf5e4b39fece10500a239612c7b0723ce9766ba309dbd22acaf1a2def2 amd64: + 0.3.11: b2475988f3b86d85c7835269121171e35c92454ad5f4cd6252183b0fccd74d63 + 0.3.10: 3e19ef525e02d2d1dfd42e8d661ee45b4bc8a49a6dcafd8baa578bdb3a23aeb6 0.3.9: a6d9b4b796e9eff830311a2349d259507302cb3955dd07b78296b91e40e8b433 0.3.8: e12ea6df8228b7d0794c930d32117c4e5a3dcf25a56c3facdf7006289ec6383c 0.3.7: 518c5d5345085f36d311f274208705d7fdb79337a80c256871ce941d5a7d47a1 0.3.6: cf271d65abee88c0c0a6d9dacb151913bf37d25d45913a7e04b09efe408eae18 0.3.5: 30d47bd89998526d51a8518f9e8ef10baed408ab273879ee0e30350702092938 - 0.3.4: b77a1fbd70d12e5b1dacfa24e5824619ec54184dbc655e721b8523572651adeb - 0.3.3: 169dce95e7252165c719e066a90b4a64af64119f9ee74fdca73bf9386bcf96c8 - 0.3.2: 93acc0b8c73c68720c9e40b89c2a220a2df315eb2cd3d162b294337c4dcb2193 - 0.3.1: 126431e7b207e013004311f5a21803cad44511616e7440157381476bdc6c5219 - 0.3.0: 8e6a445591e77b9570299d0afadeee26cb7aa23e4bfd7518baa6a3260b9ee889 - 0.2.6: 5d57b160d5a1f75333149823bec3e291a1a0960383ddc9ddd6e4ff177382c755 - 0.2.5: 1660052586390fd2668421d16265dfcc2bbdba79d923c7ede268cf91935657c1 ppc64le: + 0.3.11: 0 + 0.3.10: 0 0.3.9: 0 0.3.8: 0 0.3.7: 0 0.3.6: 0 0.3.5: 0 - 0.3.4: 0 - 0.3.3: 0 - 0.3.2: 0 - 0.3.1: 0 - 0.3.0: 0 - 0.2.6: 0 - 0.2.5: 0 runc_checksums: arm: + v1.1.13: 0 v1.1.12: 0 v1.1.11: 0 v1.1.10: 0 v1.1.9: 0 v1.1.8: 0 - v1.1.7: 0 - v1.1.6: 0 - v1.1.5: 0 - v1.1.4: 0 - v1.1.3: 0 arm64: + v1.1.13: 4b93701752f5338ed51592b38e039aef8c1a59856d1225df21eba84c2830743c v1.1.12: 879f910a05c95c10c64ad8eb7d5e3aa8e4b30e65587b3d68e009a3565aed5bb8 v1.1.11: 9f1ee53f06b78cc4a115ca6ae4eec10567999539ce828a22c5351edba043ed12 v1.1.10: 4830afd426bdeacbdf9cb8729524aa2ed51790b8c4b28786995925593708f1c8 v1.1.9: b43e9f561e85906f469eef5a7b7992fc586f750f44a0e011da4467e7008c33a0 v1.1.8: 7c22cb618116d1d5216d79e076349f93a672253d564b19928a099c20e4acd658 - v1.1.7: 1b309c4d5aa4cc7b888b2f79c385ecee26ca3d55dae0852e7c4a692196d5faab - v1.1.6: da5b2ed26a173a69ea66eae7c369feebf59c1031e14985f512a0a293bb5f76fb - v1.1.5: 54e79e4d48b9e191767e4abc08be1a8476a1c757e9a9f8c45c6ded001226867f - v1.1.4: dbb71e737eaef454a406ce21fd021bd8f1b35afb7635016745992bbd7c17a223 - v1.1.3: 00c9ad161a77a01d9dcbd25b1d76fa9822e57d8e4abf26ba8907c98f6bcfcd0f amd64: + v1.1.13: bcfc299c1ab255e9d045ffaf2e324c0abaf58f599831a7c2c4a80b33f795de94 v1.1.12: aadeef400b8f05645768c1476d1023f7875b78f52c7ff1967a6dbce236b8cbd8 v1.1.11: 77ae134de014613c44d25e6310a57a219a7a91155cd47d069a0f22a2cad5caea v1.1.10: 81f73a59be3d122ab484d7dfe9ddc81030f595cc59968f61c113a9a38a2c113a v1.1.9: b9bfdd4cb27cddbb6172a442df165a80bfc0538a676fbca1a6a6c8f4c6933b43 v1.1.8: 1d05ed79854efc707841dfc7afbf3b86546fc1d0b3a204435ca921c14af8385b - v1.1.7: c3aadb419e5872af49504b6de894055251d2e685fddddb981a79703e7f895cbd - v1.1.6: 868bee5b8dc2a01df0ca41d0accfad6a3372dc1165ebfb76143d2c6672e86115 - v1.1.5: f00b144e86f8c1db347a2e8f22caade07d55382c5f76dd5c0a5b1ab64eaec8bb - v1.1.4: db772be63147a4e747b4fe286c7c16a2edc4a8458bd3092ea46aaee77750e8ce - v1.1.3: 6e8b24be90fffce6b025d254846da9d2ca6d65125f9139b6354bab0272253d01 ppc64le: + v1.1.13: 4675d51dc0b08ad8e17d3065f2e4ce47760728945f33d3092385e792357e6519 v1.1.12: 4069d1d57724126e116ad6dbd84409082d1b0afee1ee960b17558f146a742bb6 v1.1.11: e3d1da41f97db1bb7e9a8d96c9092747c14ee53bc9f160048828e63f3a2d0896 v1.1.10: 94a091c06c363e4af7be398dc31fa6e02576d5ecda6de1cbf3a08fe8662bf678 v1.1.9: 065cf4f84b5acc0acdb017af2955743dfb5f5e1f49a493eea3e8206f33bf6fe6 v1.1.8: a816cd654e804249c4f757cc6bf2aa2c128e4b8e6a993067d44c63c891c081ab - v1.1.7: eb0e76876d09fa8119dc6e6b037107e5d265d1cfa51f1fbed5418e5745ecf153 - v1.1.6: f98d585dd88d45a296a3f3adde39eaec84e0cfc75f75c50e5470d871e3538460 - v1.1.5: 4f06d25b46e11e6670bf38e638c9183bb6676787801f1226f0aa8e74e40169ea - v1.1.4: 0f7fb3d2426b6012d9b33c354c778c0ffbce02c329c4c16c1189433a958fd60d - v1.1.3: 3b1b7f953fc8402dec53dcf2de05b6b72d86850737efa9766f8ffefc7cae3c0a crun_checksums: arm: + 1.14.4: 0 + 1.14.3: 0 + 1.14.2: 0 + 1.14.1: 0 1.11.2: 0 1.11.1: 0 1.9.2: 0 - 1.9.1: 0 - 1.8.7: 0 - 1.8.6: 0 - 1.8.5: 0 - 1.8.4: 0 - 1.8.3: 0 - 1.8.2: 0 - 1.8.1: 0 - 1.7.2: 0 - 1.7.1: 0 arm64: + 1.14.4: 308f8719055de178897f66cbb72d6a02567050ac645dd5eca52f48de347dda6c + 1.14.3: 0486629e1599c3bccded279f6555ff22691958cde56203ceca099af6f2407263 + 1.14.2: 409ebdcb4935b004ce0efa8ada4aaf8d4dd63b77cde1d0acdf55664c168acbd9 + 1.14.1: 25f85c85b9ae15de589ac02d2b766178967d29122325f9479ab068534b7a9658 1.11.2: 9e1aeb86bce609eccff46a8b976ed06994bca27d639e564fd45756786c4d0123 1.11.1: c8b0d243f6ac4fb02665c157b5404e5184bdc9240dbdcdde0ccef2db352ce97a 1.9.2: 1ad8bd3c1aa693f59133c480aa13bbdf6d81e4528e72ce955612c6bae8cb1720 - 1.9.1: fab460328d425a72cfd1a70f8fc25c888b6f17cfd95abdace61035a80c3dfe4a - 1.8.7: 004f40b48ec28e963eee79929002b9dfb88496be5699e6052358c67e47fdc88a - 1.8.6: 1f86d20292284f29593594df8d8556d5363a9e087e169626604cc212c77d1727 - 1.8.5: 77032341af7c201db03a53e46707ba8b1af11cdd788530426f2da6ccb9535202 - 1.8.4: 29bbb848881868c58908933bab252e73ee055672d00b7f40cea751441ca74fa4 - 1.8.3: 5394336630618c724274bf3e5e0c8a64c2e67e4723f671029c4f57f459359f73 - 1.8.2: d17970486fab69058e182c3322b7f9fe51561cc3ce28339a0d65b0c81acda933 - 1.8.1: c8382b91a52ac09797ff44990daf014803dde9487d1a41243bc9d8eaf07484e4 - 1.7.2: 576a39ca227a911e0e758db8381d2786f782bfbd40b54684be4af5e1fe67b018 - 1.7.1: 8d458c975f6bf754e86ebedda9927abc3942cbebe4c4cb34a2f1df5acd399690 amd64: + 1.14.4: 4f170aaa10d2ef02560cfb60b67ddfa1a83b1b4f7018227e9cb23a6af3955ec1 + 1.14.3: 80c5ab9422d4672f650f2bad3da933568349b64117d055486abc3534517be2af + 1.14.2: 4d3a64961ea9e6a1313ab807f86a17bc6ebcecad2df84a120322fddebff00bcf + 1.14.1: a30afd16bbf7eed9d9ce662062f64ef9fbb5d7c76963668c33e90a5693941fbd 1.11.2: acb62839ab8615f0e2485e8d71272b5659cbe35182eb24c5e96bd213240567fe 1.11.1: ca8c9cef23f4a3f7a635ee58a3d9fa35e768581fda89dc3b6baed219cc407a02 1.9.2: 2bb60bcd5652cb17e44f66f0b8ae48195434bd1d66593db97fba85c7778eac53 - 1.9.1: a2bc565c8bbcb1074b70cdec0c39ca93e4aa84f1188641d160531f4a8aae80f0 - 1.8.7: f26e90ab197df8b1cb81d70bcb2cd36a80299d6445470b3c1a84ceda59a34199 - 1.8.6: 23cd9901106ad7a8ebf33725a16b99a14b95368a085d6ffc2ede0b0c9b002bde - 1.8.5: 75062fa96a7cabd70e6f6baf1e11da00131584cc74a2ef682a172769178d8731 - 1.8.4: 99be7d3c9ba3196c35d64b63fa14e9f5c37d1e91b194cfdbfa92dbcbebd651bc - 1.8.3: f82ccdc575a72fe2d91ea8d68161746a0e28898bc86a2a6f55eed00aa1d79afa - 1.8.2: 9febf1dd7600d15db2ee9a6b8836a76db563bf715e009d0c5f662353e7fa6c29 - 1.8.1: b7f2150da473ed2d052df371244176aa96c9ad908fed06b81ebcb51a8a0f6b06 - 1.7.2: 2bd2640d43bc78be598e0e09dd5bb11631973fc79829c1b738b9a1d73fdc7997 - 1.7.1: 8e095f258eee554bb94b42af07aa5c54e0672a403d56b2cfecd49153a11d6760 ppc64le: + 1.14.4: 0 + 1.14.3: 0 + 1.14.2: 0 + 1.14.1: 0 1.11.2: 0 1.11.1: 0 1.9.2: 0 - 1.9.1: 0 - 1.8.7: 0 - 1.8.6: 0 - 1.8.5: 0 - 1.8.4: 0 - 1.8.3: 0 - 1.8.2: 0 - 1.8.1: 0 - 1.7.2: 0 - 1.7.1: 0 youki_checksums: arm: + 0.3.2: 0 + 0.3.1: 0 0.3.0: 0 0.2.0: 0 0.1.0: 0 0.0.5: 0 0.0.4: 0 - 0.0.3: 0 - 0.0.2: 0 - 0.0.1: 0 arm64: + 0.3.2: 0 + 0.3.1: 0 0.3.0: 0 0.2.0: 0 0.1.0: 0 0.0.5: 0 0.0.4: 0 - 0.0.3: 0 - 0.0.2: 0 - 0.0.1: 0 amd64: + 0.3.2: 0 + 0.3.1: 0 0.3.0: 741ba3cd85d768bebba02598cedcf3b15a2160e4d6ce33a3d5c4e1b3080f9c1c 0.2.0: b268689a91db07feebfd41d5806b10c7d051fbcbf7efb15076e2228763ac0762 0.1.0: f00677e9674215b44f140f0c0f4b79b0001c72c073d2c5bb514b7a9dcb13bdbc 0.0.5: 8504f4c35a24b96782b9e0feb7813aba4e7262c55a39b8368e94c80c9a4ec564 0.0.4: c213376393cb16462ef56586e68fef9ec5b5dd80787e7152f911d7cfd72d952e - 0.0.3: 15df10c78f6a35e45a1dce92c827d91b9aef22dc926c619ff5befafc8543f1bb - 0.0.2: dd61f1c3af204ec8a29a52792897ca0d0f21dca0b0ec44a16d84511a19e4a569 - 0.0.1: 8bd712fe95c8a81194bfbc54c70516350f95153d67044579af95788fbafd943b ppc64le: + 0.3.2: 0 + 0.3.1: 0 0.3.0: 0 0.2.0: 0 0.1.0: 0 0.0.5: 0 0.0.4: 0 - 0.0.3: 0 - 0.0.2: 0 - 0.0.1: 0 kata_containers_binary_checksums: arm: 3.2.0: 0 @@ -895,10 +852,6 @@ kata_containers_binary_checksums: 3.1.0: 0 3.0.2: 0 3.0.1: 0 - 3.0.0: 0 - 2.5.2: 0 - 2.5.1: 0 - 2.5.0: 0 arm64: 3.2.0: 0 3.1.3: 0 @@ -907,10 +860,6 @@ kata_containers_binary_checksums: 3.1.0: 0 3.0.2: 0 3.0.1: 0 - 3.0.0: 0 - 2.5.2: 0 - 2.5.1: 0 - 2.5.0: 0 amd64: 3.2.0: 21bb8484a060450d6522f29bed7d88d773c28520774eaa2c522b6f47fd12c4a1 3.1.3: 266c906222c85b67867dea3c9bdb58c6da0b656be3a29f9e0bed227c939f3f26 @@ -919,10 +868,6 @@ kata_containers_binary_checksums: 3.1.0: 452cc850e021539c14359d016aba18ddba128f59aa9ab637738296d9b5cd78a0 3.0.2: a32dc555ffae23f3caab3bc57b03d5ed7792f651221f6cb95cdfe906e18c4bd1 3.0.1: e2505482f68cc1b1417b8011f2755bf87171a8dd6daaace28531746118fbddaa - 3.0.0: ff475932f65936504f63ff087c81f89103df2a99e0ceb6571246f63f7a4f948e - 2.5.2: 2c7ce463b32d52b613c1b1ea3d89e83a59ca0fd0ee7fdd24eb854ab2de05ec10 - 2.5.1: 4e4fe5204ae9aea43aa9d9bee467a780d4ae9d52cd716edd7e28393a881377ad - 2.5.0: 044e257c16b8dfa1df92663bd8e4b7f62dbef3e431bc427cdd498ff1b2163515 ppc64le: 3.2.0: 0 3.1.3: 0 @@ -931,271 +876,123 @@ kata_containers_binary_checksums: 3.1.0: 0 3.0.2: 0 3.0.1: 0 - 3.0.0: 0 - 2.5.2: 0 - 2.5.1: 0 - 2.5.0: 0 gvisor_runsc_binary_checksums: arm: - 20230807: 0 - 20230801: 0 - 20230731: 0 - 20230724: 0 - 20230717: 0 - 20230710: 0 - 20230627: 0 - 20230621: 0 - 20230605: 0 - 20230529: 0 - 20230522: 0 - 20230517: 0 - 20230508: 0 - 20230501: 0 - 20230417: 0 - 20231030: 0 - 20231023: 0 - 20231016: 0 - 20231009: 0 - 20231003: 0 - 20230925: 0 - 20230920: 0 - 20230911: 0 - 20230904: 0 + 20240305: 0 + 20240212: 0 + 20240206: 0 + 20240129: 0 + 20240122: 0 + 20240115: 0 + 20240109: 0 + 20231218: 0 arm64: - 20230807: 562c629abb6576d02a4b5a5c32cb4706e29122f72737c55a2bf87d012682117f - 20230801: 69f4b7fd068fcc9a30181657ae5dcdd259e5fe71111d86e7cb0065e190b82fc3 - 20230731: 228ad19507ed23f97d99a2ea19be355f57fa4fddc70d0c425879952bd2d2cd7d - 20230724: bbc929ade0211f1d4759db4d3b1e12942dbd198ec91e3e40a272a787856be6e9 - 20230717: 94e36ee1581b951ab328b097d8aff994e96c035462bd2ea5d67f0bc225996c7a - 20230710: 1af3f8640f517339e2b1d522c6ec7066bc32329d0d96d265af6fe7e6d966d4b3 - 20230627: b791646f8129542f110f5ed9d88c3c1fbe6a242207202a8fba2873fad4c6eca6 - 20230621: 7e57e36c146e4aeae736b777c13bcd077a60110e5f1db9e60b87199aed1b533f - 20230605: ef3a965ff6e585c5604f72172a03e6bf3c7511a04f86925eaad6b78b7b9cb4f1 - 20230529: d31e781026a0afa4e2864839993ab17cf4f581ec92419e7c263f4ed34958a2cd - 20230522: 873163cb0e850685efa2f8c98a3b57502e4af72e5a14edf15c81d8830afa3dc3 - 20230517: 9a107bed8a1184a6f1040e6893c0975e572966a3ecd7009e8b2be70482e4ab1d - 20230508: b1cffc3c3071fe92f2d6c14aa946d50f01b0650ce8a8ed51b240cebc2ae2d1f0 - 20230501: b0e0e74ca92efbb65cfa2de1fbb00f767056c2797ca1b1b091ecee9ae0be8122 - 20230417: 21d01bb86f31812d5bca09fa89129ceee6561e5dd2722afcc52e28649383f311 - 20231030: c4a11ed7066bff777db048167b01a8662d0e1a48672a8c78ab7c3d5e5a5297c7 - 20231023: 90572e057cc05360c052aa2a161038e65328b9860d85d1f5db6c24c4c6a2433e - 20231016: 2bd8aee1ca3563e08afdd7019783d02c8c701c63e67fac3be6ee1243c5b0ee21 - 20231009: c6730e8ba356dd763b451b00e0206d0c69ff9857fd0a7ad456546db192b3ca4b - 20231003: 5b18676dab77d2725da02489de61445336e590018678898b7d8ff0afcda4d9f8 - 20230925: 64b6f59a7ec247fa01db5b9ee0a66c5a2e4c5ddf891dda8c8db65cbf8a4f0ae2 - 20230920: 8db0d62d750c510e7c0458e7644926be5d8d11d099dde3ed97591f6ecc10e278 - 20230911: 34aa27e693666335c69d233747be2fccfa8665ef88381d451c0b1a33a2050ae1 - 20230904: 990734ea106aaac65bd97ed496f7f87115fc743896ee4ef897e12c10204aea9d + 20240305: b8b54b45fed2dd1fa14decefecc68c8da605b8abaaee97a0550deeee4afc427f + 20240212: a03fb515df9cabf1c618193e9ed7400543c0410ab7107d1ce291ebc9212521cf + 20240206: 50b637dcb7c1b2fb1c1ce189a48ca6732d4b5a5c17ac08d5dd22d33b06fd31c8 + 20240129: d2ecc989f27d40a0e7cd53f0712fa91405b1eef2cb466deccffa41a7f607bacd + 20240122: ae9507f4ff950dc315e7dea2c4b0086dce66b88b8c8bac2008d8e754bac7af7a + 20240115: 7b2ce18408212542477c31cc1bd0ddddf6fbf7439d57e56f6884091f62c81cd8 + 20240109: 51a1b299997834b902192806def688b1e23ff6b14f28a9ed3397f3f6572a189a + 20231218: 86262a78946deacc309c0f08883659ee3298c288048dc30955945e71993c81a8 amd64: - 20230807: bb5055d820a3698181b593e3f6d2b44e8e957a6df91bea7776fee030c007814f - 20230801: 9df74be6ed44f4b35d5aa5ba1956bb3959680c6909748009a2f9476e04b0921e - 20230731: 50e586ce482bce290d893277644ca950a3ab09b53719170578b324666c6e0eec - 20230724: 859476ba858012724d845b3d417070dfb577b68640f0c0840712485710c975fd - 20230717: 4ab67b11728ab1f8d5a897c3346bfb2d725c73c358a588eab0ad3b3ddaa094c8 - 20230710: cd5648f0e32862a4a733840c565c112fe7b505970a10d3b2e882805158bd82b2 - 20230627: d2db10692a56c73cf2fb78776cb41a911db26f65d122922455786db63e25e22c - 20230621: d4e03fee422c87c8f533493de04286277def528e768b3fc90d22c15d8cc1ff7e - 20230605: 85c8feb5d71f45abe29f97548c5432966cd1e57feab560a923f2ea64395b63c1 - 20230529: 41eb6a5fc545e27c253a21b2d6881c7bfed25932cc34e042023600d17a5b3cd9 - 20230522: 5587bcd68e32432d596492c78e935463a530980c35c34abd215d84e93efd1e8f - 20230517: 20ec2fc2e5bc90840ae6540fcd83879e84c7495b0400bc377f9d502b9fdff591 - 20230508: 2a1385d3ef6e31058671e2d2a1ce83130e934081fa2c5c93589eebf7856f5681 - 20230501: b60dccad63a07553809065d1c4d094dfc5e862353cc61a933b05100ffd1f831c - 20230417: 7c0ccb6144861e45bd14e2ccd02f3fdb935219447256d16c71f6c8e42f90a73d - 20231030: 61467bc39f58109dd7a2115e7bcecff460565fc681b0e89436a88d5c316300c8 - 20231023: 99363d5d432bf466f2de2f9de6be140fa1eee0ffc3fceceec87ef0fad907015e - 20231016: dc06735fd3bb333a08294931c55c6867e679dc484713e9262ec5dc258e8a08d6 - 20231009: 9532413b235dace99911192ae82414fd20be4af7f1d3479624412e49be707500 - 20231003: e925c65f51c879ee29ceb9d346a400b2efd8e36deb68028845f3fea1ccb57710 - 20230925: 72a0ef23ae6d487e164aa9749c2e1f81fb0512a18a1f776d9adc7b0c156ed194 - 20230920: 1fe85e4a6963fea744cb70044d38063e4b884dccf7ed7308c1e75cb802fbc276 - 20230911: 2048af00625f45d7134a651cd836f0be29c2edfc8f061162ea3fde2b212c443b - 20230904: 5c107f15c5be5cfacd1be0e3745fb680bee516ee613a0c6d1e9314795c911458 + 20240305: 3b949f7fab2c7d3d75df09fe5f170b46951e62b8833dcc4abad0a4d6c12f41f3 + 20240212: da5390680d18c3f98f1e88cd7363f97de42ed63a767e61d476b1740b0918b93c + 20240206: 996a8e855c1d54a7dcf688d52ee698fd714f0fd143c42ee793707e7f4f18124d + 20240129: b7765ea92c0100fcd1d03c7b23073c9be9486350cf38ffcbb72eb7915fe26605 + 20240122: d184712583d543b8f56a28e8583a1fa55c7256e77934123fe21c621e0d9b975c + 20240115: 9ae176da972b288880e69b1a438052eea2c502b6292aea8a1a33fbcf65e135dd + 20240109: f32810820c81a4dfe570080c06c5dabfc1be74ec0d5da659f93ae5cc1fc5c098 + 20231218: c353d36a134dfc2fab8509f72a34abf6a761603975eb00a39e4077c41aeaf31b ppc64le: - 20230807: 0 - 20230801: 0 - 20230731: 0 - 20230724: 0 - 20230717: 0 - 20230710: 0 - 20230627: 0 - 20230621: 0 - 20230605: 0 - 20230529: 0 - 20230522: 0 - 20230517: 0 - 20230508: 0 - 20230501: 0 - 20230417: 0 - 20231030: 0 - 20231023: 0 - 20231016: 0 - 20231009: 0 - 20231003: 0 - 20230925: 0 - 20230920: 0 - 20230911: 0 - 20230904: 0 + 20240305: 0 + 20240212: 0 + 20240206: 0 + 20240129: 0 + 20240122: 0 + 20240115: 0 + 20240109: 0 + 20231218: 0 gvisor_containerd_shim_binary_checksums: arm: - 20230807: 0 - 20230801: 0 - 20230731: 0 - 20230724: 0 - 20230717: 0 - 20230710: 0 - 20230627: 0 - 20230621: 0 - 20230605: 0 - 20230529: 0 - 20230522: 0 - 20230517: 0 - 20230508: 0 - 20230501: 0 - 20230417: 0 - 20231030: 0 - 20231023: 0 - 20231016: 0 - 20231009: 0 - 20231003: 0 - 20230925: 0 - 20230920: 0 - 20230911: 0 - 20230904: 0 + 20240305: 0 + 20240212: 0 + 20240206: 0 + 20240129: 0 + 20240122: 0 + 20240115: 0 + 20240109: 0 + 20231218: 0 arm64: - 20230807: 0b80fba82a7c492dc8c7d8585d172d399116970155c2d35f3a29d37aa5eeb80d - 20230801: 08323b1db170fe611f39306922bf56c8c4ee354d6881385fae0a27d84d6f5a62 - 20230731: 74e72b4c7f0f818f8f1a983072beca3c27f72536be808597fb1f9878f736c6ef - 20230724: 78d106ae19da764065e3e16573f347609206ebc72b48a678e14c2cf5ad04c901 - 20230717: 6425bc2285d8a6322bd9e18864da601b9ba56d7d1759a9a93805e270621036da - 20230710: 3ea3487f5d9ba87fc557c43d8f3b830780696048805883255757c940b669664c - 20230627: 5b0db73bcd6b051e7398fd7bb894bb9969ba7a1291d036aac3d47448e59c5aca - 20230621: bf5fb12a0aba6f3c1520f1b7b18d5bbdc05a5ceeb7143feb46063434c70253de - 20230605: 5ccd58ba24c1b44e6d0add79fd728d124e40b0ccfa40e9731f357719cc020bfc - 20230529: 3b1dd2904e31ab8da3aa518cdee2540caed67eecbe4fc87e143dbe90f294e31d - 20230522: 850bab454c134adefc20bc0f24015beb562ec289537b67c42e6ea3781e1fb763 - 20230517: e3ccb7aea2708d664e2b278b7c40dbf0156e2d2f773e2b13ba5766beb67b7ad2 - 20230508: d16d59d076b0856242d67eda95ee1b2301b04f14abd95ef4fe6c08509f304617 - 20230501: a5f4361897a634ac5832b269e1cc5bc1993825c06e4b0080770a948b36584754 - 20230417: 575163e65e1fda019cb34ee56120d5ecf63b0a3a00dda28c0fc138ce58a5bbff - 20231030: 6b2a6ff15d37e3cffe09cacf8dc22255759dc87f6c2290253c9bc82b4ba15909 - 20231023: ac80cb6a9be9697eefdbe0b1f60e00657f8b97552b9f7d3105b03fa30fb9e99b - 20231016: 3f513a2c042096f7636e6c2e1313ed43d2fae43b2428dcc3135f6f844e559f8d - 20231009: 638167817a34b73b3c737f4755a7564abc51ab42327334e652d7a70116e8fada - 20231003: ed8a6df203dcb80f44d239452c88ef4b86123e85443c3d7f019512d37611bab5 - 20230925: ed8a6df203dcb80f44d239452c88ef4b86123e85443c3d7f019512d37611bab5 - 20230920: a397cdf0f3a08d5f9b54ce40e01cc07373b270649caf065e2a21400f98c99687 - 20230911: f62538996f4680ace4c38dccb7fe433ad7c95622a65b1afad0f9cb35d249e1ab - 20230904: 24480f319a51d8d66a4617d80b113069ca56e1157c731fb39a0f412a1d3e4176 + 20240305: 466c51e4f4bf592da0edf8c70c70ba74f026bb48f980bb28ffb582a93c88c049 + 20240212: 4b122fd5684c068d5d73189a30a8130cc5280aefadda0b8532321446c9c79c90 + 20240206: 34ded13729aeea0bee6c6d4cbc57ac19a9f4a532631b307ae975cbeb2a09a4ff + 20240129: 41c033549c24c13c776db42d212a416a2df20a6cff57cc26f70df8cdff738441 + 20240122: e5f3dbcd7f1b1fb9f46e1432656a8b07dda63a5c65fdbe639062761439df23c0 + 20240115: eae0a657656c4153db44dd51ca285b423b44c4eaad872ea56c18b6a430cdfda5 + 20240109: 40eb0a4f5f0013afb221e228fd6e71887127c4b09c7f2eb36705a0cd5c746d57 + 20231218: 5f66938de981221359a64f05a5c770b228090db3a2697d91ad622c18dd19f4b2 amd64: - 20230807: fa16b92b3a36665783951fa6abb541bca52983322d135eb1d91ae03b93f4b477 - 20230801: 372a7c60054ab3351f5d32c925fb19bb0467b7eb9cd6032f846ba3f5b23451f8 - 20230731: 8d3f2a3c5634d56a2c2cf6017ccb2ef2764c1bceb3814a1276efe043b440d0b6 - 20230724: ff9c5e51f210c06a3e07a71f6214a0420651cd4c30fddd04d01b6d09ce24eb61 - 20230717: cf342881148b80ed95a8946f9f44781bb9323211e3c7cdc0254d27af5c5b215f - 20230710: db008c53e5a2a868d8b44df0faa051eae7fc5241f1488b53c6040a3665ac04b8 - 20230627: e55b22970b81ccee9b9d0837b11d2a20ad670fc4c028c7e87d03721257e928a9 - 20230621: 180a7320466b997114a903b034fe71aa3a65b9374b3565f7461df587b167e5de - 20230605: 4be04c512c72415b3456b0e94ca9d0c850ffd2c5fd06211f2515da70ac7f74b7 - 20230529: a8fcba918f06d984f4626acef700ab359350d631431564ca37a9ce8b4869eab1 - 20230522: 72587a1f458f20eb029f01a578fe018219688b2c4461453fdb15e97efc987e55 - 20230517: 8de99272600cfdc8b3319dc77f63c57ae592f1319b3c1b50245bc67a0740f2ae - 20230508: 7e4c74b8fc05738a7cdf7c8d99d8030007894cbc7dda774533482c5c459a8ba9 - 20230501: f951c2b8d017005787437d9f849c3edfff54c79d39eb172f92abe745652ef94d - 20230417: 61c3d75a46c8d2652306b5b3ab33e4fb519b03a3852bea738c2700ec650afe4e - 20231030: ea485191cd95d57d7e7fd1a59f7e42a624432a5634bd9b6e4f3d37e86ab0e935 - 20231023: 5045ac4983701aea469ec9934b9fd37c292259682c35e2e25f664633d183db93 - 20231016: a9f85a10b914526f78465142958c82c058484cbab1f6af5bf4cf1d95a0322ea3 - 20231009: 274eeb298a538d899ca19a659120b8249dd3169f3128a1e5794308a241ce3fcc - 20231003: c96d0f062d979249e03355421659363a353310169df86511861505f329ab1614 - 20230925: c96d0f062d979249e03355421659363a353310169df86511861505f329ab1614 - 20230920: 09eafdf9d37e51fa9719a3752c11564124a5ba509fa50c651f81967a0051781d - 20230911: 6f1f1fc33f0dc1255642ece98b909ebccf3a54a1a2c950d1d84928b78a7c3e22 - 20230904: 73b2e9c4761622ef82eefe74a3346196834728ad8b980101e2d87c6e3c48015c + 20240305: 11a1b482e0ed6c72ea6ca72692e1cb2d0794214d142be5389e30517a96b157dc + 20240212: 48333e9b6158f8d4192a35e1d1f74319b6a083d6cbc3779c847548de6a5faf5f + 20240206: 9c88e82b71dc07f689c74f61143ea00fa8621a6d5c31c5fadb9714ad3be8465a + 20240129: 840b4b9d47bd04f3dfed6cf8fbee7c2c4a697e17461c22afb873d67499d4d9b9 + 20240122: cd7d9e4bb4cb0ac8242d15fc03580880f53eb36ebd9fb8d686e2811e86ad698e + 20240115: b95d05f667f1040cb07f262f27396d1deb23573ce4c4a31ea3568e6ca3b70c24 + 20240109: d677683326cfd42c7913636651f74ffd1a6866066877903d8a58c644422c2e18 + 20231218: a0578a357feb9320298730bf5ba683880ba35c476dc74dc82c79f0b5acc42656 ppc64le: - 20230807: 0 - 20230801: 0 - 20230731: 0 - 20230724: 0 - 20230717: 0 - 20230710: 0 - 20230627: 0 - 20230621: 0 - 20230605: 0 - 20230529: 0 - 20230522: 0 - 20230517: 0 - 20230508: 0 - 20230501: 0 - 20230417: 0 - 20231030: 0 - 20231023: 0 - 20231016: 0 - 20231009: 0 - 20231003: 0 - 20230925: 0 - 20230920: 0 - 20230911: 0 - 20230904: 0 + 20240305: 0 + 20240212: 0 + 20240206: 0 + 20240129: 0 + 20240122: 0 + 20240115: 0 + 20240109: 0 + 20231218: 0 nerdctl_archive_checksums: arm: + 1.7.6: 4c48463659b09636aa23b50825f85cdc38901b6c42e321f69a589d89f6e1d0d5 + 1.7.5: 2d258a7d67e9fa808424ad42f9299a0feb318cafd2758f0287748acedeee4c0d + 1.7.4: 91d3a8bcc2247dd80f8f5769419e6f344dea412937de4c318f65d8e9bf01355b + 1.7.3: 44369f34a98e5955eb02e41779b1a470332194e4c2bef136fe471943eaf8057a + 1.7.2: d952c1cbe3d25478bbed5f4ee7af4bb52fa4ed47e43802dc5eb2888a4c8da704 1.7.1: 799d35de7a182da35d850308c7f1787cd7321404348ff2d5ba64ad43b06b395a 1.7.0: 8b9e7cccbcc0a472685d1bc285f591f41005f8699e7265ea5438a3e06aefdcfd - 1.6.2: 69363f4dbf2616d5238647bfbff60525b7b59417a26de8eb255b6d6a09171175 - 1.6.1: 89187ff46c5a515a5635a4017a476d82cdc1fc3de906135273c64329189b906e - 1.6.0: 20dc5f6912de321d4b6aa8647ce77c261cd6d5726d0b5dfae56bd9cdbd7c28fb - 1.5.0: 36c44498b08a08b652d01812e5f857009373fba64ce9c8ff22e101b205bbc5fb - 1.4.0: b81bece6e8a10762a132f04f54df60d043df4856b5c5ce35d8e6c6936db0b6a0 - 1.3.1: ed24086dbea22612dbcc3d14ee6f1d152b0eb6905bd8c84d3413c1f4c8d45d10 - 1.3.0: 2fa1b0cdb95cafb9ea6293c86a164b2a00b342e02d7a9444794f48f002e187c3 - 1.2.1: 750e4788515779cb8e3ea18678c3125b5724e521214bb18a799903821c17d32c - 1.2.0: d42b3329c3c99d6243a4efa0f33e9324a26597e175dd7fdae574270bf3e26f28 - 1.1.0: cc3bc31b4df015806717149f13b3b329f8fb62e3631aa2abdbae71664ce5c40d - 1.0.0: 8fd283a2f2272b15f3df43cd79642c25f19f62c3c56ad58bb68afb7ed92904c2 arm64: + 1.7.6: 4fa0a6e936c7a9cb9bb81e784fddaa593cb00afb48b08842e3f0503748c21348 + 1.7.5: a53d87fc7d1f4ffeec55e5e08d2397b02ada0d334874c3cece306ad36f828a6c + 1.7.4: d8df47708ca57b9cd7f498055126ba7dcfc811d9ba43aae1830c93a09e70e22d + 1.7.3: e4f16b78d884768f6997558130146ba9bd7846828b19fa2ca8e8eda988953fd7 + 1.7.2: de68d5380d65604cd26c164988547cf46b698f7819a5d51d98e3a0f031f5594d 1.7.1: 46affa0564bb74f595a817e7d5060140099d9cfd9e00e1272b4dbe8b0b85c655 1.7.0: 1255eea5bc2dbac9339d0a9acfb0651dda117504d52cd52b38cf3c2251db4f39 - 1.6.2: ece848045290dd61f542942248587e91125563af46c0ea972a7c908d0d39c96c - 1.6.1: b91ec17a6f7bcb148ed7ad086da6c470ee33f7218c769d5d490e0a1d6a45fdb4 - 1.6.0: d5f1ed3cda151385d313f9007afc708cae0018c9da581088b092328db154d0c6 - 1.5.0: 1bb613049a91871614d407273e883057040e8393ef7be9508598a92b2efda4b7 - 1.4.0: 0edb064a7d68d0425152ed59472ce7566700b4e547afb300481498d4c7fc6cf1 - 1.3.1: 9e82a6a34c89d3e6a65dc8d77a3723d796d71e0784f54a0c762a2a1940294e3b - 1.3.0: e3405bbaadbee716e50ce4535d03f854129773152aab4876b14f117e1ed3b5ee - 1.2.1: 8dc3d918b44b3ea863a4bc8f121277389d3bdb952d549e44916502a0774ab1bb - 1.2.0: 79d71bbdd0b433838d64ef96d26eb9648911f8d5e5ab494359d32d0ff09abb34 - 1.1.0: a0b57b39341b9d67a3f0ae74e19985c72e930bad14291cbbd8479ed6a6a64e83 - 1.0.0: 27622c9d95efe6d807d5f3770d24ddd71719c6ae18f76b5fc89663a51bcd6208 amd64: + 1.7.6: 0326d6a42dbec5c104ed9d7aa8cbc62727433dbe000cf21cc29d06b22507e0f0 + 1.7.5: 775f8bddd5e93acc4162c568dd6b84d5925549180991b83cfd4b7e33d4844921 + 1.7.4: 71aee9d987b7fad0ff2ade50b038ad7e2356324edc02c54045960a3521b3e6a7 + 1.7.3: ee93ffe6f90e50bde153a9a0dd779594e0bc13a26949053965958b91b6dffdd0 + 1.7.2: aed7d33d645bfb97c8df978d952a1e1f7e02b0b3ed2c0089ee4285af7f8f971b 1.7.1: 5fc0a6e8c3a71cbba95fbdb6833fb8a7cd8e78f53de10988362d4029c14b905a 1.7.0: 844c47b175a3d6bc8eaad0c51f23624a5ef10c09e55607803ec2bc846fb04df9 - 1.6.2: 67991fc144b03596f15be6c20ca112d10bd92ad467414e95b0f1d60d332ae34e - 1.6.1: 992e4ffd3d88cf197f78b78333ac345faf5f184a119d43ad8a106f560781fd89 - 1.6.0: fc3e7eef775eff85eb6c16b2761a574e83de444831312bc92e755a1f5577872d - 1.5.0: 6dc945e3dfdc38e77ceafd2ec491af753366a3cf83fefccb1debaed3459829f1 - 1.4.0: d8dcd4e270ae76ab294be3a451a2d8299010e69dce6ae559bc3193535610e4cc - 1.3.1: 3ab552877100b336ebe3167aa57f66f99db763742f2bce9e6233644ef77fb7c9 - 1.3.0: 28299050ed28ed78db4fed95daef1ce326ce0101569dc73cc49f8f7e0c17de25 - 1.2.1: 67aa5cf2a32a3dc0c335b96133daee4d2764d9c1a4d86a38398c4995d2df2176 - 1.2.0: 9d6f3427a1c0af0c38a0a707751b424d04cca13b82c62ad03ec3f4799c2de48c - 1.1.0: fcfd36b0b9441541aab0793c0f586599e6d774781c74f16468a3300026120c0e - 1.0.0: 3e993d714e6b88d1803a58d9ff5a00d121f0544c35efed3a3789e19d6ab36964 ppc64le: + 1.7.6: 89906f9bcdf8d5bd866646c43e14c0ae15a83ba3ebed44b06c3629a11517e242 + 1.7.5: 8e0891f608144d8d751070edea5cd98d2a76a053ad7fa6b9d4aae94a700aaea2 + 1.7.4: 97c99ab6030ffac1fb780fe012de06a36512b17b13de5c99445468b5a5fe5a62 + 1.7.3: e63ae0a8f5ccd12877ff944b609d0a4c55c97ba79808ab16c7dc7e99fd8f3dd6 + 1.7.2: e5c01702d3cec0763d28bd3cf6ea9c3efc58662a93cb4e15669a839782af10d7 1.7.1: 09fd0cbef25c98e08c5cc2d1e39da279cbf66c430fdf6c8738e56ce8f949dad9 1.7.0: e421ae655ff68461bad04b4a1a0ffe40c6f0fcfb0847d5730d66cd95a7fd10cd - 1.6.2: 3b0d6e4c42b99e2dd8059ded81cde69f42b065d9f486142f3c9b0861ba7effef - 1.6.1: 3924467d9430df991ebdf4e78211bac2b29e9a066d5000d98f8d4ebde2bb7b4c - 1.6.0: c47717ed176f55b291d2068ed6e2445481c391936bd322614e0ff9effe06eb4d - 1.5.0: 169d546d35ba3e6ef088cc81e101f58d5ecb08e71c5ed776c99482854ea3ef8a - 1.4.0: 306d5915b387637407db67ceb96cd89ff7069f0024fb1bbc948a6602638eceaa - 1.3.1: 21700f5fe8786ed7749b61b3dbd49e3f2345461e88fe2014b418a1bdeffbfb99 - 1.3.0: 8eda05b803da56772e38dd0970279e081ba797f6d36ad28a535ba8a98993074c - 1.2.1: d5c60700709e8c3908e9863df57303e43d343e38aadf96f2d06eaaac3bc2b06b - 1.2.0: 64fb56543ee69dafa57691a9dc3b756f9cd6fec021ba1c591680d16ebb8d109d - 1.1.0: 7e97d0a856439d07e82cc26a16dfe243c21da14b7099e330e4da11e825004478 - 1.0.0: 2fb02e629a4be16b194bbfc64819132a72ede1f52596bd8e1ec2beaf7c28c117 containerd_archive_checksums: arm: + 1.7.21: 0 + 1.7.20: 0 + 1.7.19: 0 + 1.7.18: 0 + 1.7.17: 0 + 1.7.16: 0 + 1.7.15: 0 + 1.7.14: 0 1.7.13: 0 1.7.12: 0 1.7.11: 0 @@ -1210,7 +1007,15 @@ containerd_archive_checksums: 1.7.2: 0 1.7.1: 0 1.7.0: 0 + 1.6.34: 0 + 1.6.33: 0 + 1.6.32: 0 + 1.6.31: 0 + 1.6.30: 0 + 1.6.29: 0 1.6.28: 0 + 1.6.27: 0 + 1.6.26: 0 1.6.25: 0 1.6.24: 0 1.6.23: 0 @@ -1223,26 +1028,15 @@ containerd_archive_checksums: 1.6.16: 0 1.6.15: 0 1.6.14: 0 - 1.6.13: 0 - 1.6.12: 0 - 1.6.11: 0 - 1.6.10: 0 - 1.6.9: 0 - 1.6.8: 0 - 1.6.7: 0 - 1.6.6: 0 - 1.6.5: 0 - 1.6.4: 0 - 1.6.3: 0 - 1.6.2: 0 - 1.6.1: 0 - 1.6.0: 0 - 1.5.18: 0 - 1.5.17: 0 - 1.5.16: 0 - 1.5.15: 0 - 1.5.14: 0 arm64: + 1.7.21: 7b6b67d998eb86856d23df5d57269c054539072bbb27677975cf78269b2c5c10 + 1.7.20: cf80cd305f7d1c23aaf0c57bc1c1e37089cad9130d533db6fe968cdebd16c759 + 1.7.19: 1839e6f7cd7c62d9df3ef3deac3f404cdd5cd47bbdf8acfeb0b0f3776eb20002 + 1.7.18: e80ce87b469af03b3bdcf68b95f0f4a303787ae247581bcd42f04acf1ad4c24d + 1.7.17: 8d9749985796a208e860afe331ec77cb485566104e5cc7c0b5e9e82ec7681969 + 1.7.16: 2d4373de40a6f58cd0f29377c0257b35697a987248e6268520586996771d7a75 + 1.7.15: 5cc8bd8f3d9803ef0ef701596e89d62ad6850a2544e722842f4533642df36d87 + 1.7.14: 44df66d0a0332465e7d15e90b974cd4f08d059dfa26652218ed9485390f47f9e 1.7.13: 118759e398f35337109592b4d237538872dc12a207d38832b9d04515d0acbc4d 1.7.12: 8a1b35a521d071a8828f63fe007a51e5b7ac863a1195f5dee32543b1a9d5f2b6 1.7.11: 5eae27cce38a14be5390d4035127aa11416bc5ae592a9ff25b11870872ce1159 @@ -1257,7 +1051,14 @@ containerd_archive_checksums: 1.7.2: d75a4ca53d9addd0b2c50172d168b12957e18b2d8b802db2658f2767f15889a6 1.7.1: 1f828dc063e3c24b0840b284c5635b5a11b1197d564c97f9e873b220bab2b41b 1.7.0: e7e5be2d9c92e076f1e2e15c9f0a6e0609ddb75f7616999b843cba92d01e4da2 + 1.6.34: 9e898686ff003cec2d80c30cf5ad342c1ac88373568dae792f93cd088e66d038 + 1.6.33: 432cf17fbc01ba4fc59b949210baa96865185b8eb3b3292eb7a00e2f6bde9fe9 + 1.6.32: a9cb16bafbf1eb8cea11b4803d76f78cf7bef311b951dd1ae49c238bb41ec649 + 1.6.31: 91a74cc602c7724668537f754006692114af70cfb6ef840b288f922fa68f7ed7 + 1.6.30: 0bbf1eed508d6ebc240b900648c76f12a07c0c6125aa8c22d46c9ce24252f9e3 + 1.6.29: 0 1.6.28: 96a231f875ddf9cc7682b881d408ae993f2bd5d0a40402a74ec4fda672047427 + 1.6.27: 433b0e8113adfd726374e04fc2f61dafad65c53db5665569f2715a7a916a1813 1.6.26: 177bed65b6425255bacbe48d99ea7aa5209d381576962c0962dc8615ef16c5c5 1.6.25: 4948677cfc5f98a1d5d46cec90d6d6f84f6b27cd6d28fd87f7f5936d61580ceb 1.6.24: 1d741e9e2d907f02a8b2a46034a28ff9aacdba88c485cef2f4bad18be9ea23ba @@ -1271,26 +1072,15 @@ containerd_archive_checksums: 1.6.16: c2bf51fde02ec9cf8b9c18721bc4f53bd1f19fb2bb3251f41ece61af7347e082 1.6.15: d63e4d27c51e33cd10f8b5621c559f09ece8a65fec66d80551b36cac9e61a07d 1.6.14: 3ccb61218e60cbba0e1bbe1e5e2bf809ac1ead8eafbbff36c3195d3edd0e4809 - 1.6.13: 8c7892ae7c2e96a4a9358b1064fb5519a5c0528b715beee67b72e74d7a644064 - 1.6.12: 0a0133336596b2d1dcafe3587eb91ab302afc28f273614e0e02300694b5457a0 - 1.6.11: 1b34d8ff067da482af021dac325dc4e993d7356c0bd9dc8e5a3bb8271c1532de - 1.6.10: 6d655e80a843f480e1c1cead18479185251581ff2d4a2e2e5eb88ad5b5e3d937 - 1.6.9: 140197aee930a8bd8a69ff8e0161e56305751be66e899dccd833c27d139f4f47 - 1.6.8: b114e36ecce78cef9d611416c01b784a420928c82766d6df7dc02b10d9da94cd - 1.6.7: 4167bf688a0ed08b76b3ac264b90aad7d9dd1424ad9c3911e9416b45e37b0be5 - 1.6.6: 807bf333df331d713708ead66919189d7b142a0cc21ec32debbc988f9069d5eb - 1.6.5: 2833e2f0e8f3cb5044566d64121fdd92bbdfe523e9fe912259e936af280da62a - 1.6.4: 0205bd1907154388dc85b1afeeb550cbb44c470ef4a290cb1daf91501c85cae6 - 1.6.3: 354e30d52ff94bd6cd7ceb8259bdf28419296b46cf5585e9492a87fdefcfe8b2 - 1.6.2: a4b24b3c38a67852daa80f03ec2bc94e31a0f4393477cd7dc1c1a7c2d3eb2a95 - 1.6.1: fbeec71f2d37e0e4ceaaac2bdf081295add940a7a5c7a6bcc125e5bbae067791 - 1.6.0: 6eff3e16d44c89e1e8480a9ca078f79bab82af602818455cc162be344f64686a - 1.5.18: 0 - 1.5.17: 0 - 1.5.16: 0 - 1.5.15: 0 - 1.5.14: 0 amd64: + 1.7.21: 3d1fcdfd0b141f4dc4916b7aee7f9a7773dc344baffc8954e1ca66b1adc5c120 + 1.7.20: e09410787b6f392748959177a84e024424f75d7aff33ea1c5b783f2260edce67 + 1.7.19: 97f75e60f0ad19d335b1d23385835df721cad4492740d50576997f2717dc3f94 + 1.7.18: a24b05b341c155a0ec367d3d0fd1d437c09a0261dffdecc0e44e9abbf2d02aca + 1.7.17: 04cf937349f82d29fe98553ff45a7e9ea2ed6b81fe6514e3679cf263b50409ff + 1.7.16: 4f4f2c3c7d14fd59a404961a3a3341303c2fdeeba0e78808c209f606e828f99c + 1.7.15: ea27e6454954bd9cb62a70b0a40eb085ae9c96cb8c075a74910102b33586e07d + 1.7.14: 48e0d9747cd51cb90e0b278d100397653d9f2e765effca194427e4796395b240 1.7.13: c2371c009dd8b7738663333d91e5ab50d204f8bcae24201f45d59060d12c3a23 1.7.12: 6a24d8b996533fa1b0d7348fe9813a78cd01fa16cff865a961ad0d556f5cd665 1.7.11: d66161d54546fad502fd50a13fcb79efff033fcd895adc9c44762680dcde4e69 @@ -1305,7 +1095,14 @@ containerd_archive_checksums: 1.7.2: 2755c70152ab40856510b4549c2dd530e15f5355eb7bf82868e813c9380e22a7 1.7.1: 9504771bcb816d3b27fab37a6cf76928ee5e95a31eb41510a7d10ae726e01e85 1.7.0: b068b05d58025dc9f2fc336674cac0e377a478930f29b48e068f97c783a423f0 + 1.6.34: 18969d667cd6b9993d168f6d30f9ad978f0aca72cf984c1f522fc5277780885b + 1.6.33: a0c7daa50386dc3ca19cbeb83d6987d43bdd92c0bb0429d08be7f9be4f9c307a + 1.6.32: 7acab4dda6edb7e8e0a6cfc3abd9f323db05a3d92a8a1842de8f6c9e28af501d + 1.6.31: 52080601f414b7e63a5b8e0cb8c1d641c9e070447ac96da9b1aeb00480744ba5 + 1.6.30: 1f1b65190b626883394e6f2ecbe5141afc6c45fc1ca035ef052e66bb2c479a5f + 1.6.29: 0 1.6.28: b2f15c722d1cc8b74ed643068e043b92bd031fc23d53488d1e837cf4b2777391 + 1.6.27: 8c0b04a8b39127c084d490cca905d565c94929dd15e168b0f8663076fdcf5539 1.6.26: fa806d3e945a8ad25aa1f8123a98524768ead83af2ed1ab3d922d2dd5fe6b14c 1.6.25: 878b331b5fa65df3d33c68ee355724de0044c25071486086409b374a9c62d145 1.6.24: a56fac5ba03c3d6f74ceae14abdc9fafabcba900105e9890c0ac895cc00164ad @@ -1319,26 +1116,15 @@ containerd_archive_checksums: 1.6.16: 2415b431a900275c14942f87f751e1e13d513c1c2f062322b5ca5a9a2190f22a 1.6.15: 191bb4f6e4afc237efc5c85b5866b6fdfed731bde12cceaa6017a9c7f8aeda02 1.6.14: 7da626d46c4edcae1eefe6d48dc6521db3e594a402715afcddc6ac9e67e1bfcd - 1.6.13: 97f00411587512e62ec762828e581047b23199f8744754706d09976ec24a2736 - 1.6.12: a56c39795fd0d0ee356b4099a4dfa34689779f61afc858ef84c765c63e983a7d - 1.6.11: 21870d7022c52f5f74336d440deffb208ba747b332a88e6369e2aecb69382e48 - 1.6.10: dd1f4730daf728822aea3ba35a440e14b1dfa8f1db97288a59a8666676a13637 - 1.6.9: 9ee2644bfb95b23123f96b564df2035ec94a46f64060ae12322e09a8ec3c2b53 - 1.6.8: 3a1322c18ee5ff4b9bd5af6b7b30c923a3eab8af1df05554f530ef8e2b24ac5e - 1.6.7: 52e817b712d521b193773529ff33626f47507973040c02474a2db95a37da1c37 - 1.6.6: 0212869675742081d70600a1afc6cea4388435cc52bf5dc21f4efdcb9a92d2ef - 1.6.5: cf02a2da998bfcf61727c65ede6f53e89052a68190563a1799a7298b0cea86b4 - 1.6.4: f23c8ac914d748f85df94d3e82d11ca89ca9fe19a220ce61b99a05b070044de0 - 1.6.3: 306b3c77f0b5e28ed10d527edf3d73f56bf0a1fb296075af4483d8516b6975ed - 1.6.2: 3d94f887de5f284b0d6ee61fa17ba413a7d60b4bb27d756a402b713a53685c6a - 1.6.1: c1df0a12af2be019ca2d6c157f94e8ce7430484ab29948c9805882df40ec458b - 1.6.0: f77725e4f757523bf1472ec3b9e02b09303a5d99529173be0f11a6d39f5676e9 - 1.5.18: d132525d375bbafd3aee8e9aa5517203cef2bbf77197db7522c8730cc526b3db - 1.5.17: b676f56f43bf02782179320b5070fb210cbc1784a9b0875086bc15c3bcc546f3 - 1.5.16: f5326865c2b86aba794f590fd2ca479f817fa1f88c084d97a45816aec9d0ce32 - 1.5.15: 0d09043be08dcf6bf136aa78bfd719e836cf9f9679afa4db0b6e4d478e396528 - 1.5.14: 8513ead11aca164b7e70bcea0429b4e51dad836b6383b806322e128821aaebbd ppc64le: + 1.7.21: 5ce0c1125e8d9ca04e2b524a2bac8b1eb97876c073023d5e083f7da64fcd8207 + 1.7.20: dc611df0baa90509dda35e0be993da52f42b067514329fcf538d000b110364e8 + 1.7.19: f41c2f28ee933a9ca24ff02cca159099fbcf798850e56cf0b7a6047ebe21fa86 + 1.7.18: d6cfb3bc8fbdead7d435d5f3f6b1913b5896f7f97102c1bbad206f9123c2a5d3 + 1.7.17: 873b76a507d362eec73887f61fa1400f3a892c7dbed1759f5dad2b654095b534 + 1.7.16: d0add7a55a5d4411cafb276469d2b78bc3ada11cb4b444b9e35f9ef60c00960d + 1.7.15: b38641d9bd18139495cf9839999039b19941f53d36a6d72efe4577c489dfda0c + 1.7.14: b84b523909b9dd0c0b2bc40bd2b9af543ec9f1186df69c220ae3749e34623dbb 1.7.13: 89605ed2365d5eb779477d11947101236eb44e5244f1e58bb162a9e68d242798 1.7.12: 80f16891b387d86712026234de7d4d0365a38106dbe5e51b65b1200b24822721 1.7.11: 6f91c5dabdccd1fc75aae8687381bb185b9eb4200beb29d0993dea8175f5fa61 @@ -1353,7 +1139,14 @@ containerd_archive_checksums: 1.7.2: cbe7ec913cb603ca218bd8867efdce4bee3b0e0115e467e51c910467daf8184e 1.7.1: 17d97ef55c6ce7af9778dbafb5e73f577d1b34220043a91cccde49dbcc610342 1.7.0: 051e897d3ee5b8c8097f65be447fea2d29226b583ca5d9ed78e9aebcf4e69889 + 1.6.34: 14a4392ba4e533e313fe6d3ed1a68cfdce038b87ad4693be6e71ff31568e2173 + 1.6.33: 0a77fba37290a40a7853dbd7e5a297288d3657f7e92cd7864bc7187189a0a370 + 1.6.32: d733e4b66ca2bc8191ae5e8770e4806ebd4094fdc657258045b925930ad9bfc5 + 1.6.31: 4458a2398f27241b6e674ea9ba1f56dc4d9ab9dacc5a07469602776c3e428110 + 1.6.30: ba3d790f504a845b060e2faae3cc0603afd125ebdddb3bdb513b8d70a4337d87 + 1.6.29: 0 1.6.28: 35411f9d1bafc9cae91c2e30d46a59d01bffc7e18ac7f0942dca9d1d5907ab38 + 1.6.27: 8106915bc62c51383baa77925748505e79229fded7efcd7e74cb352ad10d0ce9 1.6.26: 75fb01a4bd3bcd16263c2f833b8e7081356e2e390dd7eb0710232cb04dac5a01 1.6.25: 3ddcc1739ffeb3e1df786d45518a01d93a5cef243eb6dee61cbdd4cd110bc723 1.6.24: abff9e7ec4cc21d19150d2bc55fc89cf53dc03c002cdaf5016ee82aedead9b03 @@ -1367,120 +1160,69 @@ containerd_archive_checksums: 1.6.16: 9cfd5dade6a1c2671f5c76496395afe0aa0ce902c13672b306d8d09fdbb99492 1.6.15: 502f3e4c8ea2018aaa285fe4f704bfd560fdf93193bb829dd9302d013bc38370 1.6.14: 73025da0666079fc3bbd48cf185da320955d323c7dc42d8a4ade0e7926d62bb0 - 1.6.13: f2508ada0c8bd7d3cb09b0e7f10416aba3d643c0da7adc27efe4e76d444322ae - 1.6.12: 088e4d1fe1787fc4a173de24a58da01880d1ead5a13f1ab55e1ade972d3907d4 - 1.6.11: e600a5714ffb29937b3710f9ae81bb7aa15b7b6661192f5e8d0b9b58ac6d5e66 - 1.6.10: 704b1affd306b807fe6b4701d778129283635c576ecedc6d0a9da5370a07d56a - 1.6.9: fe0046437cfe971ef0b3101ee69fcef5cf52e8868de708d35f8b82f998044f6e - 1.6.8: f18769721f614828f6b778030c72dc6969ce2108f2363ddc85f6c7a147df0fb8 - 1.6.7: 0db5cb6d5dd4f3b7369c6945d2ec29a9c10b106643948e3224e53885f56863a9 - 1.6.6: 0 - 1.6.5: 0 - 1.6.4: 0 - 1.6.3: 0 - 1.6.2: 0 - 1.6.1: 0 - 1.6.0: 0 - 1.5.18: 0 - 1.5.17: 0 - 1.5.16: 0 - 1.5.15: 0 - 1.5.14: 0 skopeo_binary_checksums: arm: + v1.15.0: 0 + v1.14.2: 0 + v1.14.1: 0 v1.13.3: 0 v1.13.2: 0 v1.13.1: 0 v1.13.0: 0 - v1.12.0: 0 - v1.11.2: 0 - v1.11.1: 0 - v1.11.0: 0 - v1.10.0: 0 - v1.9.3: 0 - v1.9.2: 0 arm64: + v1.15.0: bde8cc7e764d246281430d5da07ca906ee0838803199e3a6136a58802b2e0207 + v1.14.2: 364c46085de31edf4b312f13587442f4eade1f181bc5a9ea2ab2ffab5b575916 + v1.14.1: fd4fc0adae14f27788fd52cf0d23be2cfd1963e184c4af689de30185455e29a6 v1.13.3: 1f7726b020ff9bc931ce16caa13c29999738a231f1414028282cd8f8661eb747 v1.13.2: 520cc31c15796405b82d01c78629d5b581eced3512ca0b6b184ed82f5e18dc86 v1.13.1: 3b7db2b827fea432aa8a861b5caa250271c05da70bd240aa4045f692eba52e24 v1.13.0: d23e43323c0a441d1825f9da483b07c7f265f2bd0a4728f7daac4239460600a3 - v1.12.0: f34476bd33d2ab3784675611b405cc0855ce5decedfa22287e261d23d17e7688 - v1.11.2: cd90552f7d4eb78ba032c885b47cd97ef015a958279d2a2b828b109d75d6c7e0 - v1.11.1: 693f7d2791e0549b173b2c16f1c3326328aa5e95bc2b4d71f5ecd35b6524b09d - v1.11.0: 3e510999ffb6544b11d339812df75d14a46261518b5c73f530242ebed679fb1b - v1.10.0: 3bfc344d4940df29358f8056de7b8dd488b88a5d777b3106748ba66851fa2c58 - v1.9.3: 27c88183de036ebd4ffa5bc5211329666e3c40ac69c5d938bcdab9b9ec248fd4 - v1.9.2: 1b7b4411c9723dbbdda4ae9dde23a33d8ab093b54c97d3323784b117d3e9413f amd64: + v1.15.0: 3cdbcde0163abb4c942f62d0302479d5aa4d31c5970d712841cf5d5f76edc594 + v1.14.2: 51218f93a2b079e36a36f7fbe2d2d86778be0a6947653031b4f9e254e2469224 + v1.14.1: 6b7776bcdf0c92af5d3f3c91a959d091011b42d839025b90f12b7201a083f308 v1.13.3: 65707992885b1a4a446af6342874749478a1af7e17ab3f4df8fb89509e8b1966 v1.13.2: 2f00be6ee1c4cbfa7f2452be90a1a2ce88fd92a6d0f6a2e9d901bd2087bd9092 v1.13.1: 8c15c56a6caffeb863c17d73a6361218c04c7763e020fffc8d5d6745cacfa901 v1.13.0: 8cb477ee25010497fc9df53a6205dbd9fe264dd8a5ea4e934b9ec24d5bdc126c - v1.12.0: 38143238e945959e6b24dba1447ba49e0b79f10a3aef2634391d0205ab950003 - v1.11.2: c8641decb185f43bb49f3f2a68abbc22e051a497440beba28b10d25d0a856574 - v1.11.1: 9aad99e41533800ce08526a602de2f87b8ce123ea9547358e2cccfa2f9c3a9e0 - v1.11.0: 0a6c0a1b349d2efd2895d2ec9a1d9c5c4bbd59f10c3993acb0c92d31914fbd62 - v1.10.0: 20fbd1bac1d33768c3671e4fe9d90c5233d7e13a40e4935b4b24ebc083390604 - v1.9.3: 6e00cf4661c081fb1d010ce60904dccb880788a52bf10de16a40f32082415a87 - v1.9.2: 5c82f8fc2bcb2502cf7cdf9239f54468d52f5a2a8072893c75408b78173c4ba6 ppc64le: + v1.15.0: fb7f390f52f4b81f85d9bdce8715af5e27ee3969eff236b5f3c0f3a0b5a182e1 + v1.14.2: 0 + v1.14.1: 0 v1.13.3: 0 v1.13.2: 0 v1.13.1: 0 v1.13.0: 0 - v1.12.0: 0 - v1.11.2: 0 - v1.11.1: 0 - v1.11.0: 0 - v1.10.0: 0 - v1.9.3: 0 - v1.9.2: 0 yq_checksums: arm: - v4.40.1: 5a005b89cb63994f999785716ab196160042516cad53a0535244f76aad468966 - v4.35.2: 000e1a8e82be5e99341c507a2abe93e104f0d4619dc7df742e88043206544c7e - v4.35.1: b2349bc220394329bc95865375feb5d777f5a5177bcdede272788b218f057a05 - v4.34.2: 161f2b64e7bf277614983014b2b842e9ae9c1f234a9ea12593b0e5ebe5a89681 - v4.34.1: dfda7fc51bdf44d3551c4bca78ecd52c13d7137d99ec3f7b466c50333e0a0b7c - v4.33.3: 77c239e17cb50a330da3c48af7dbd3b667af02c950a9ecae49b171cc0bf66c48 - v4.33.2: ee8d61975ebdfabf9b79ed2947ebfe39d62f290ab71d6eb53af183f06cfa1af2 - v4.33.1: 80ec1487b9497e0c5f182c8e44d73b5e9c437719230e114b9fce2fa25c23f95a - v4.32.2: 776b8dcfaf796255e60c0e9893d24ce9eb61cc7e787a1cc8b4a5dc37a84f02d5 - v4.32.1: 0fc6c3e41af7613dcd0e2af5c3c448e7d0a46eab8b38a22f682d71e35720daed - v4.31.2: 4873c86de5571487cb2dcfd68138fc9e0aa9a1382db958527fa8bc02349b5b26 + v4.42.1: 4e3fe0c37793d28e96d465d9958fbf679d8c616e1857d0faf7980ad087f32aee + v4.41.1: ccd50344652c02574ca7dd123c7d66a06b391838e8ca6088b688e6edf2e25d0c + v4.40.7: fb922bb1e3974fbd15957feafb5e9bbabe43f4192999cf9b3e0e470815f2e0da + v4.40.6: 0 + v4.40.5: c587b2411e43d3fbcdd24c233fb558a362b5111a8446b23f9ce9a4a5665a7041 + v4.40.4: 2ff3f17483f2172a20130b16328114bfe6abd7d3068d66d8194a5093079e8529 + v4.40.3: 6a97856e8b4ef992ce08dcfdf97fec517cf612b1a89078406f401673f126c21c arm64: - v4.40.1: 11491c62fa0af9995f26a64e9cce97c8404018bb6b0acd7d7ac1be0f437ecf28 - v4.35.2: 6ea822bc966e7dc23bb7d675a1ff36bc2e7a9a9f88c402129eafbd6b19d8ff8a - v4.35.1: 1d830254fe5cc2fb046479e6c781032976f5cf88f9d01a6385898c29182f9bed - v4.34.2: 6ea70418755aa805b6d03e78a1c8a1bf236220f187ba3fb4f30663a35c43b4c1 - v4.34.1: c1410df7b1266d34a89a91dcfeaf8eb27cb1c3f69822d72040d167ec61917ba0 - v4.33.3: 15925a972d268bcb0a7aa2236c7e5925b7a3ba4b5569bb57e943db7e8c6f834f - v4.33.2: aa86e5f36850f9350a7393c7cf654ee726df99ae985b663eb3605ca2bdd24692 - v4.33.1: e3a47e60765322995f11422108829881d2166dcf9b13a3ae8ad2c002ee61f8a1 - v4.32.2: 2f855a9e616eb9c635269630666e7594931ab7524326ff02a8351d5762a28940 - v4.32.1: db4eba6ced2656e1c40e4d0f406ee189773bdda1054cbd097c1dba471e04dd4d - v4.31.2: 590f19f0a696103376e383c719fe0df28c62515627bf44e5e69403073ba83cbf + v4.42.1: 16a57531a594b66c3e0981cd93f9e9cd4b684a347b86eaf5e3f409074ad67eb8 + v4.41.1: 066aa930d74e39a25447b1900d8cbb3e1c7df72cd75bc203bc6ae5ee577a5b4a + v4.40.7: a84f2c8f105b70cd348c3bf14048aeb1665c2e7314cbe9aaff15479f268b8412 + v4.40.6: 0 + v4.40.5: 9431f0fa39a0af03a152d7fe19a86e42e9ff28d503ed4a70598f9261ec944a97 + v4.40.4: 79c61a1ebfedb165ec8c4678777775b52e2c581801f5d4cd80f97300852fe0f0 + v4.40.3: 44a5cca10d33019b8a46212882197be4f961dfe7deddde0af497065aa980a6a4 amd64: - v4.40.1: 97e931eb40791b7f0cf02363065684d807bdbc0c5973b97a37d60a7a71e8cf73 - v4.35.2: 8afd786b3b8ba8053409c5e7d154403e2d4ed4cf3e93c237462dc9ef75f38c8d - v4.35.1: bd695a6513f1196aeda17b174a15e9c351843fb1cef5f9be0af170f2dd744f08 - v4.34.2: 1952f93323e871700325a70610d2b33bafae5fe68e6eb4aec0621214f39a4c1e - v4.34.1: c5a92a572b3bd0024c7b1fe8072be3251156874c05f017c23f9db7b3254ae71a - v4.33.3: 4ee662847c588c3ef2fec8bfb304e8739e3dbaba87ccb9a608d691c88f5b64dc - v4.33.2: fbcc9551afd66622ffd68ad417837139741b2ad0eef9af1bb4b64e3596679ffa - v4.33.1: 5b9d60aa55e53fc06c9114aa5b9d5f1de9bdb231c91aed62b35d10d991831cda - v4.32.2: 0e5c6b5a74d4ccd6eed43180f60dd48a6e1d0e778f834dca33a312301674b628 - v4.32.1: e53b82caa86477bd96cf447138c72c9a0a857142a5bcdd34440b2644693ed18f - v4.31.2: 71ef4141dbd9aec3f7fb45963b92460568d044245c945a7390831a5a470623f7 + v4.42.1: 1a95960dddd426321354d58d2beac457717f7c49a9ec0806749a5a9e400eb45e + v4.41.1: ce0d5a61c256a463fd32f67f133e0c2948bc2cf77d44c42ff335a40e6bef34bf + v4.40.7: 4f13ee9303a49f7e8f61e7d9c87402e07cc920ae8dfaaa8c10d7ea1b8f9f48ed + v4.40.6: 0 + v4.40.5: 0d6aaf1cf44a8d18fbc7ed0ef14f735a8df8d2e314c4cc0f0242d35c0a440c95 + v4.40.4: f9163412d9aa2aa55e888fdcaf2b4053ada20074be35f701424caa7163100704 + v4.40.3: 6e9a5ed9591dbf1d13aaec4efaaf0ecdaf4945ea393b9ce01f4c3dea22311470 ppc64le: - v4.40.1: 7434cac727b3bc544e2e91abffb52bafa7180cc344cd84b5019ccbd2eebf9f0c - v4.35.2: 33242c57d1cab1b880b37ea7235c09966a8525319edc41ced2c70290c6a7c924 - v4.35.1: 713e2c40c5d659cbed7bf093f4c718674a75f9fe5b10ac96fd422372af198684 - v4.34.2: e149b36f93a1318414c0af971755a1488df4844356b6e9e052adf099a72e3a3a - v4.34.1: 3e629c51a07302920110893796f54f056a6ef232f791b9c67fdbe95362921a03 - v4.33.3: b5b7a59e72a5f603b819f50f2dc3e42e53127398c6f0d77da7a06d2f4d0952ea - v4.33.2: 682db3754da9f91ea447e9811e582c3f395e8d566b5afc43d1a67f6be56fa1e2 - v4.33.1: 22311b8726022963e50494d5510ffe5bb63bd0aa3f47feff445e35c4483ac68a - v4.32.2: a3650f6838a8a7a9b8914a8c27c16fb3a172ac3430836565c3927bf1a641d714 - v4.32.1: 43f1f5078a2fa7748cb5dab693538a9e634557ef2c8aad390f147beb727278cf - v4.31.2: 14e79e8eb6d36858adb3355d77ccd1d128ce74257d1358f53e1a46b2f252e28c + v4.42.1: d0d1cdbd2c4a7e6995433baf879cadaa47f6f12290e1661ea11933ed90baccb6 + v4.41.1: eed2af79d0ad787878b2d5c7c592e43ac152208d9ed432b42a43663167e276e8 + v4.40.7: ac0e8d06a7ed9afc108b4e2e9d6900312b01757f61b75fcecb809f15c39b10e7 + v4.40.6: 0 + v4.40.5: a1df9d2b872fbb30583526bf4f37f737dc1913b28606dfc1dafeaf56a8862b3d + v4.40.4: c67379085a44558825a60a8af3b59b400852b168356070829bc0f45c70553f45 + v4.40.3: 2fe818a0b141913a41548e0e727267479d0f755221c73f9e304788c8e9139a45 diff --git a/kubespray/project/roles/kubespray-defaults/defaults/main/download.yml b/kubespray/project/roles/kubespray-defaults/defaults/main/download.yml index 273d4dd..687dc1d 100644 --- a/kubespray/project/roles/kubespray-defaults/defaults/main/download.yml +++ b/kubespray/project/roles/kubespray-defaults/defaults/main/download.yml @@ -74,17 +74,16 @@ image_info_command_on_localhost: "{{ lookup('vars', image_command_tool_on_localh image_arch: "{{ host_architecture | default('amd64') }}" # Versions -kubeadm_version: "{{ kube_version }}" -crun_version: 1.8.5 -runc_version: v1.1.12 +crun_version: 1.14.4 +runc_version: v1.1.13 kata_containers_version: 3.1.3 youki_version: 0.1.0 -gvisor_version: 20230807 -containerd_version: 1.7.13 -cri_dockerd_version: 0.3.9 +gvisor_version: 20240305 +containerd_version: 1.7.21 +cri_dockerd_version: 0.3.11 # this is relevant when container_manager == 'docker' -docker_containerd_version: 1.6.28 +docker_containerd_version: 1.6.32 # gcr and kubernetes image repo define gcr_image_repo: "gcr.io" @@ -101,7 +100,7 @@ github_image_repo: "ghcr.io" # TODO(mattymo): Move calico versions to roles/network_plugins/calico/defaults # after migration to container download -calico_version: "v3.26.4" +calico_version: "v3.28.1" calico_ctl_version: "{{ calico_version }}" calico_cni_version: "{{ calico_version }}" calico_flexvol_version: "{{ calico_version }}" @@ -113,89 +112,94 @@ calico_apiserver_enabled: false flannel_version: "v0.22.0" flannel_cni_version: "v1.1.2" -cni_version: "v1.3.0" -weave_version: 2.8.1 +weave_version: 2.8.7 +cni_version: "v1.4.0" -cilium_version: "v1.13.4" -cilium_cli_version: "v0.15.0" +cilium_version: "v1.15.4" +cilium_cli_version: "v0.16.0" cilium_enable_hubble: false -kube_ovn_version: "v1.11.5" +kube_ovn_version: "v1.12.21" kube_ovn_dpdk_version: "19.11-{{ kube_ovn_version }}" kube_router_version: "v2.0.0" multus_version: "v3.8" -helm_version: "v3.13.1" -nerdctl_version: "1.7.1" +helm_version: "v3.15.4" +nerdctl_version: "1.7.6" krew_version: "v0.4.4" -skopeo_version: "v1.13.2" +skopeo_version: "v1.15.0" # Get kubernetes major version (i.e. 1.17.4 => 1.17) kube_major_version: "{{ kube_version | regex_replace('^v([0-9])+\\.([0-9]+)\\.[0-9]+', 'v\\1.\\2') }}" pod_infra_supported_versions: + v1.30: "3.9" v1.29: "3.9" v1.28: "3.9" - v1.27: "3.9" pod_infra_version: "{{ pod_infra_supported_versions[kube_major_version] }}" etcd_supported_versions: - v1.29: "v3.5.10" - v1.28: "v3.5.10" - v1.27: "v3.5.10" + v1.30: "v3.5.12" + v1.29: "v3.5.12" + v1.28: "v3.5.12" etcd_version: "{{ etcd_supported_versions[kube_major_version] }}" crictl_supported_versions: + v1.30: "v1.30.0" v1.29: "v1.29.0" v1.28: "v1.28.0" - v1.27: "v1.27.1" crictl_version: "{{ crictl_supported_versions[kube_major_version] }}" crio_supported_versions: + v1.30: v1.30.3 v1.29: v1.29.1 - v1.28: v1.28.1 - v1.27: v1.27.1 + v1.28: v1.28.4 crio_version: "{{ crio_supported_versions[kube_major_version] }}" -# Scheduler plugins doesn't build for K8s 1.28 yet +# Scheduler plugins doesn't build for K8s 1.29 yet scheduler_plugins_supported_versions: + v1.30: 0 v1.29: 0 - v1.28: 0 - v1.27: v0.27.8 + v1.28: v0.28.9 scheduler_plugins_version: "{{ scheduler_plugins_supported_versions[kube_major_version] }}" -yq_version: "v4.35.2" +yq_version: "v4.42.1" + +github_url: https://github.com +dl_k8s_io_url: https://dl.k8s.io +storage_googleapis_url: https://storage.googleapis.com +get_helm_url: https://get.helm.sh # Download URLs -kubelet_download_url: "https://dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet" -kubectl_download_url: "https://dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl" -kubeadm_download_url: "https://dl.k8s.io/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm" -etcd_download_url: "https://github.com/etcd-io/etcd/releases/download/{{ etcd_version }}/etcd-{{ etcd_version }}-linux-{{ image_arch }}.tar.gz" -cni_download_url: "https://github.com/containernetworking/plugins/releases/download/{{ cni_version }}/cni-plugins-linux-{{ image_arch }}-{{ cni_version }}.tgz" -calicoctl_download_url: "https://github.com/projectcalico/calico/releases/download/{{ calico_ctl_version }}/calicoctl-linux-{{ image_arch }}" -calico_crds_download_url: "https://github.com/projectcalico/calico/archive/{{ calico_version }}.tar.gz" -ciliumcli_download_url: "https://github.com/cilium/cilium-cli/releases/download/{{ cilium_cli_version }}/cilium-linux-{{ image_arch }}.tar.gz" -crictl_download_url: "https://github.com/kubernetes-sigs/cri-tools/releases/download/{{ crictl_version }}/crictl-{{ crictl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz" -crio_download_url: "https://storage.googleapis.com/cri-o/artifacts/cri-o.{{ image_arch }}.{{ crio_version }}.tar.gz" -helm_download_url: "https://get.helm.sh/helm-{{ helm_version }}-linux-{{ image_arch }}.tar.gz" -runc_download_url: "https://github.com/opencontainers/runc/releases/download/{{ runc_version }}/runc.{{ image_arch }}" -crun_download_url: "https://github.com/containers/crun/releases/download/{{ crun_version }}/crun-{{ crun_version }}-linux-{{ image_arch }}" -youki_download_url: "https://github.com/containers/youki/releases/download/v{{ youki_version }}/youki_{{ youki_version | regex_replace('\\.', '_') }}_linux.tar.gz" -kata_containers_download_url: "https://github.com/kata-containers/kata-containers/releases/download/{{ kata_containers_version }}/kata-static-{{ kata_containers_version }}-{{ ansible_architecture }}.tar.xz" +kubelet_download_url: "{{ dl_k8s_io_url }}/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet" +kubectl_download_url: "{{ dl_k8s_io_url }}/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl" +kubeadm_download_url: "{{ dl_k8s_io_url }}/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubeadm" +etcd_download_url: "{{ github_url }}/etcd-io/etcd/releases/download/{{ etcd_version }}/etcd-{{ etcd_version }}-linux-{{ image_arch }}.tar.gz" +cni_download_url: "{{ github_url }}/containernetworking/plugins/releases/download/{{ cni_version }}/cni-plugins-linux-{{ image_arch }}-{{ cni_version }}.tgz" +calicoctl_download_url: "{{ github_url }}/projectcalico/calico/releases/download/{{ calico_ctl_version }}/calicoctl-linux-{{ image_arch }}" +calico_crds_download_url: "{{ github_url }}/projectcalico/calico/archive/{{ calico_version }}.tar.gz" +ciliumcli_download_url: "{{ github_url }}/cilium/cilium-cli/releases/download/{{ cilium_cli_version }}/cilium-linux-{{ image_arch }}.tar.gz" +crictl_download_url: "{{ github_url }}/kubernetes-sigs/cri-tools/releases/download/{{ crictl_version }}/crictl-{{ crictl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz" +crio_download_url: "{{ storage_googleapis_url }}/cri-o/artifacts/cri-o.{{ image_arch }}.{{ crio_version }}.tar.gz" +helm_download_url: "{{ get_helm_url }}/helm-{{ helm_version }}-linux-{{ image_arch }}.tar.gz" +runc_download_url: "{{ github_url }}/opencontainers/runc/releases/download/{{ runc_version }}/runc.{{ image_arch }}" +crun_download_url: "{{ github_url }}/containers/crun/releases/download/{{ crun_version }}/crun-{{ crun_version }}-linux-{{ image_arch }}" +youki_download_url: "{{ github_url }}/containers/youki/releases/download/v{{ youki_version }}/youki_{{ youki_version | regex_replace('\\.', '_') }}_linux.tar.gz" +kata_containers_download_url: "{{ github_url }}/kata-containers/kata-containers/releases/download/{{ kata_containers_version }}/kata-static-{{ kata_containers_version }}-{{ ansible_architecture }}.tar.xz" # gVisor only supports amd64 and uses x86_64 to in the download link -gvisor_runsc_download_url: "https://storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/runsc" -gvisor_containerd_shim_runsc_download_url: "https://storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/containerd-shim-runsc-v1" -nerdctl_download_url: "https://github.com/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz" -krew_download_url: "https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew-{{ host_os }}_{{ image_arch }}.tar.gz" -containerd_download_url: "https://github.com/containerd/containerd/releases/download/v{{ containerd_version }}/containerd-{{ containerd_version }}-linux-{{ image_arch }}.tar.gz" -cri_dockerd_download_url: "https://github.com/Mirantis/cri-dockerd/releases/download/v{{ cri_dockerd_version }}/cri-dockerd-{{ cri_dockerd_version }}.{{ image_arch }}.tgz" -skopeo_download_url: "https://github.com/lework/skopeo-binary/releases/download/{{ skopeo_version }}/skopeo-linux-{{ image_arch }}" -yq_download_url: "https://github.com/mikefarah/yq/releases/download/{{ yq_version }}/yq_linux_{{ image_arch }}" +gvisor_runsc_download_url: "{{ storage_googleapis_url }}/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/runsc" +gvisor_containerd_shim_runsc_download_url: "{{ storage_googleapis_url }}/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/containerd-shim-runsc-v1" +nerdctl_download_url: "{{ github_url }}/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz" +krew_download_url: "{{ github_url }}/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew-{{ host_os }}_{{ image_arch }}.tar.gz" +containerd_download_url: "{{ github_url }}/containerd/containerd/releases/download/v{{ containerd_version }}/containerd-{{ containerd_version }}-linux-{{ image_arch }}.tar.gz" +cri_dockerd_download_url: "{{ github_url }}/Mirantis/cri-dockerd/releases/download/v{{ cri_dockerd_version }}/cri-dockerd-{{ cri_dockerd_version }}.{{ image_arch }}.tgz" +skopeo_download_url: "{{ github_url }}/lework/skopeo-binary/releases/download/{{ skopeo_version }}/skopeo-linux-{{ image_arch }}" +yq_download_url: "{{ github_url }}/mikefarah/yq/releases/download/{{ yq_version }}/yq_linux_{{ image_arch }}" etcd_binary_checksum: "{{ etcd_binary_checksums[image_arch][etcd_version] }}" cni_binary_checksum: "{{ cni_binary_checksums[image_arch][cni_version] }}" kubelet_binary_checksum: "{{ kubelet_checksums[image_arch][kube_version] }}" kubectl_binary_checksum: "{{ kubectl_checksums[image_arch][kube_version] }}" -kubeadm_binary_checksum: "{{ kubeadm_checksums[image_arch][kubeadm_version] }}" +kubeadm_binary_checksum: "{{ kubeadm_checksums[image_arch][kube_version] }}" yq_binary_checksum: "{{ yq_checksums[image_arch][yq_version] }}" calicoctl_binary_checksum: "{{ calicoctl_binary_checksums[image_arch][calico_ctl_version] }}" calico_crds_archive_checksum: "{{ calico_crds_archive_checksums[calico_version] }}" @@ -250,9 +254,9 @@ netcheck_agent_image_tag: "{{ netcheck_version }}" netcheck_server_image_repo: "{{ docker_image_repo }}/mirantis/k8s-netchecker-server" netcheck_server_image_tag: "{{ netcheck_version }}" netcheck_etcd_image_tag: "v3.4.17" -weave_kube_image_repo: "{{ docker_image_repo }}/weaveworks/weave-kube" +weave_kube_image_repo: "{{ docker_image_repo }}/rajchaudhuri/weave-kube" weave_kube_image_tag: "{{ weave_version }}" -weave_npc_image_repo: "{{ docker_image_repo }}/weaveworks/weave-npc" +weave_npc_image_repo: "{{ docker_image_repo }}/rajchaudhuri/weave-npc" weave_npc_image_tag: "{{ weave_version }}" cilium_image_repo: "{{ quay_image_repo }}/cilium/cilium" cilium_image_tag: "{{ cilium_version }}" @@ -270,15 +274,19 @@ cilium_hubble_envoy_image_repo: "{{ docker_image_repo }}/envoyproxy/envoy" cilium_hubble_envoy_image_tag: "v1.22.5" kube_ovn_container_image_repo: "{{ docker_image_repo }}/kubeovn/kube-ovn" kube_ovn_container_image_tag: "{{ kube_ovn_version }}" +kube_ovn_vpc_container_image_repo: "{{ docker_image_repo }}/kubeovn/vpc-nat-gateway" +kube_ovn_vpc_container_image_tag: "{{ kube_ovn_version }}" kube_ovn_dpdk_container_image_repo: "{{ docker_image_repo }}/kubeovn/kube-ovn-dpdk" kube_ovn_dpdk_container_image_tag: "{{ kube_ovn_dpdk_version }}" kube_router_image_repo: "{{ docker_image_repo }}/cloudnativelabs/kube-router" kube_router_image_tag: "{{ kube_router_version }}" multus_image_repo: "{{ github_image_repo }}/k8snetworkplumbingwg/multus-cni" multus_image_tag: "{{ multus_version }}" +external_openstack_cloud_controller_image_repo: "registry.k8s.io/provider-os/openstack-cloud-controller-manager" +external_openstack_cloud_controller_image_tag: "v1.30.0" kube_vip_image_repo: "{{ github_image_repo }}/kube-vip/kube-vip" -kube_vip_image_tag: v0.5.12 +kube_vip_image_tag: v0.8.0 nginx_image_repo: "{{ docker_image_repo }}/library/nginx" nginx_image_tag: 1.25.2-alpine haproxy_image_repo: "{{ docker_image_repo }}/library/haproxy" @@ -324,14 +332,16 @@ rbd_provisioner_image_tag: "{{ rbd_provisioner_version }}" local_path_provisioner_version: "v0.0.24" local_path_provisioner_image_repo: "{{ docker_image_repo }}/rancher/local-path-provisioner" local_path_provisioner_image_tag: "{{ local_path_provisioner_version }}" -ingress_nginx_version: "v1.9.6" +ingress_nginx_version: "v1.11.2" ingress_nginx_controller_image_repo: "{{ kube_image_repo }}/ingress-nginx/controller" +ingress_nginx_opentelemetry_image_repo: "{{ kube_image_repo }}/ingress-nginx/opentelemetry" ingress_nginx_controller_image_tag: "{{ ingress_nginx_version }}" +ingress_nginx_opentelemetry_image_tag: "v20230721-3e2062ee5" ingress_nginx_kube_webhook_certgen_image_repo: "{{ kube_image_repo }}/ingress-nginx/kube-webhook-certgen" -ingress_nginx_kube_webhook_certgen_image_tag: "v20231011-8b53cabe0" +ingress_nginx_kube_webhook_certgen_image_tag: "v1.4.3" alb_ingress_image_repo: "{{ docker_image_repo }}/amazon/aws-alb-ingress-controller" alb_ingress_image_tag: "v1.1.9" -cert_manager_version: "v1.13.2" +cert_manager_version: "v1.14.7" cert_manager_controller_image_repo: "{{ quay_image_repo }}/jetstack/cert-manager-controller" cert_manager_controller_image_tag: "{{ cert_manager_version }}" cert_manager_cainjector_image_repo: "{{ quay_image_repo }}/jetstack/cert-manager-cainjector" @@ -353,13 +363,13 @@ csi_livenessprobe_image_repo: "{{ kube_image_repo }}/sig-storage/livenessprobe" csi_livenessprobe_image_tag: "v2.5.0" snapshot_controller_supported_versions: - v1.29: "v6.3.3" - v1.28: "v4.2.1" - v1.27: "v4.2.1" + v1.30: "v7.0.2" + v1.29: "v7.0.2" + v1.28: "v7.0.2" snapshot_controller_image_repo: "{{ kube_image_repo }}/sig-storage/snapshot-controller" snapshot_controller_image_tag: "{{ snapshot_controller_supported_versions[kube_major_version] }}" -cinder_csi_plugin_version: "v1.29.0" +cinder_csi_plugin_version: "v1.30.0" cinder_csi_plugin_image_repo: "{{ kube_image_repo }}/provider-os/cinder-csi-plugin" cinder_csi_plugin_image_tag: "{{ cinder_csi_plugin_version }}" @@ -398,6 +408,10 @@ metallb_speaker_image_repo: "{{ quay_image_repo }}/metallb/speaker" metallb_controller_image_repo: "{{ quay_image_repo }}/metallb/controller" metallb_version: v0.13.9 +node_feature_discovery_version: v0.16.4 +node_feature_discovery_image_repo: "{{ kube_image_repo }}/nfd/node-feature-discovery" +node_feature_discovery_image_tag: "{{ node_feature_discovery_version }}" + downloads: netcheck_server: enabled: "{{ deploy_netchecker }}" @@ -406,7 +420,7 @@ downloads: tag: "{{ netcheck_server_image_tag }}" sha256: "{{ netcheck_server_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster netcheck_agent: enabled: "{{ deploy_netchecker }}" @@ -415,7 +429,7 @@ downloads: tag: "{{ netcheck_agent_image_tag }}" sha256: "{{ netcheck_agent_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster etcd: container: "{{ etcd_deployment_type != 'host' }}" @@ -433,7 +447,7 @@ downloads: owner: "root" mode: "0755" groups: - - etcd + - etcd cni: enabled: true @@ -446,20 +460,20 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster kubeadm: enabled: true file: true - version: "{{ kubeadm_version }}" - dest: "{{ local_release_dir }}/kubeadm-{{ kubeadm_version }}-{{ image_arch }}" + version: "{{ kube_version }}" + dest: "{{ local_release_dir }}/kubeadm-{{ kube_version }}-{{ image_arch }}" sha256: "{{ kubeadm_binary_checksum }}" url: "{{ kubeadm_download_url }}" unarchive: false owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster kubelet: enabled: true @@ -472,7 +486,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster kubectl: enabled: true @@ -485,7 +499,7 @@ downloads: owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane crictl: file: true @@ -498,7 +512,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster crio: file: true @@ -511,7 +525,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster cri_dockerd: file: true @@ -522,11 +536,11 @@ downloads: url: "{{ cri_dockerd_download_url }}" unarchive: true unarchive_extra_opts: - - --strip=1 + - --strip=1 owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster crun: file: true @@ -539,7 +553,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster youki: file: true @@ -552,7 +566,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster runc: file: true @@ -565,7 +579,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster kata_containers: enabled: "{{ kata_containers_enabled }}" @@ -578,7 +592,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster containerd: enabled: "{{ container_manager == 'containerd' }}" @@ -591,7 +605,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster gvisor_runsc: enabled: "{{ gvisor_enabled }}" @@ -604,7 +618,7 @@ downloads: owner: "root" mode: 755 groups: - - k8s_cluster + - k8s_cluster gvisor_containerd_shim: enabled: "{{ gvisor_enabled }}" @@ -617,7 +631,7 @@ downloads: owner: "root" mode: 755 groups: - - k8s_cluster + - k8s_cluster nerdctl: file: true @@ -630,7 +644,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster skopeo: file: true @@ -643,7 +657,7 @@ downloads: owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane cilium: enabled: "{{ kube_network_plugin == 'cilium' or cilium_deploy_additionally | default(false) | bool }}" @@ -652,7 +666,7 @@ downloads: tag: "{{ cilium_image_tag }}" sha256: "{{ cilium_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_operator: enabled: "{{ kube_network_plugin == 'cilium' or cilium_deploy_additionally | default(false) | bool }}" @@ -661,7 +675,7 @@ downloads: tag: "{{ cilium_operator_image_tag }}" sha256: "{{ cilium_operator_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_hubble_relay: enabled: "{{ cilium_enable_hubble }}" @@ -670,7 +684,7 @@ downloads: tag: "{{ cilium_hubble_relay_image_tag }}" sha256: "{{ cilium_hubble_relay_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_hubble_certgen: enabled: "{{ cilium_enable_hubble }}" @@ -679,7 +693,7 @@ downloads: tag: "{{ cilium_hubble_certgen_image_tag }}" sha256: "{{ cilium_hubble_certgen_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_hubble_ui: enabled: "{{ cilium_enable_hubble }}" @@ -688,7 +702,7 @@ downloads: tag: "{{ cilium_hubble_ui_image_tag }}" sha256: "{{ cilium_hubble_ui_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_hubble_ui_backend: enabled: "{{ cilium_enable_hubble }}" @@ -697,7 +711,7 @@ downloads: tag: "{{ cilium_hubble_ui_backend_image_tag }}" sha256: "{{ cilium_hubble_ui_backend_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster cilium_hubble_envoy: enabled: "{{ cilium_enable_hubble }}" @@ -706,7 +720,7 @@ downloads: tag: "{{ cilium_hubble_envoy_image_tag }}" sha256: "{{ cilium_hubble_envoy_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster ciliumcli: enabled: "{{ kube_network_plugin == 'cilium' or cilium_deploy_additionally | default(false) | bool }}" @@ -719,7 +733,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster multus: enabled: "{{ kube_network_plugin_multus }}" @@ -728,7 +742,7 @@ downloads: tag: "{{ multus_image_tag }}" sha256: "{{ multus_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster flannel: enabled: "{{ kube_network_plugin == 'flannel' }}" @@ -737,7 +751,7 @@ downloads: tag: "{{ flannel_image_tag }}" sha256: "{{ flannel_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster flannel_init: enabled: "{{ kube_network_plugin == 'flannel' }}" @@ -746,7 +760,7 @@ downloads: tag: "{{ flannel_init_image_tag }}" sha256: "{{ flannel_init_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calicoctl: enabled: "{{ kube_network_plugin == 'calico' }}" @@ -759,7 +773,7 @@ downloads: owner: "root" mode: "0755" groups: - - k8s_cluster + - k8s_cluster calico_node: enabled: "{{ kube_network_plugin == 'calico' }}" @@ -768,7 +782,7 @@ downloads: tag: "{{ calico_node_image_tag }}" sha256: "{{ calico_node_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_cni: enabled: "{{ kube_network_plugin == 'calico' }}" @@ -777,7 +791,7 @@ downloads: tag: "{{ calico_cni_image_tag }}" sha256: "{{ calico_cni_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_flexvol: enabled: "{{ kube_network_plugin == 'calico' }}" @@ -786,7 +800,7 @@ downloads: tag: "{{ calico_flexvol_image_tag }}" sha256: "{{ calico_flexvol_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_policy: enabled: "{{ enable_network_policy and kube_network_plugin in ['calico'] }}" @@ -795,7 +809,7 @@ downloads: tag: "{{ calico_policy_image_tag }}" sha256: "{{ calico_policy_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_typha: enabled: "{{ typha_enabled }}" @@ -804,7 +818,7 @@ downloads: tag: "{{ calico_typha_image_tag }}" sha256: "{{ calico_typha_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_apiserver: enabled: "{{ calico_apiserver_enabled }}" @@ -813,7 +827,7 @@ downloads: tag: "{{ calico_apiserver_image_tag }}" sha256: "{{ calico_apiserver_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster calico_crds: file: true @@ -824,13 +838,13 @@ downloads: url: "{{ calico_crds_download_url }}" unarchive: true unarchive_extra_opts: - - "{{ '--strip=6' if (calico_version is version('v3.22.3', '<')) else '--strip=3' }}" - - "--wildcards" - - "{{ '*/_includes/charts/calico/crds/kdd/' if (calico_version is version('v3.22.3', '<')) else '*/libcalico-go/config/crd/' }}" + - "{{ '--strip=6' if (calico_version is version('v3.22.3', '<')) else '--strip=3' }}" + - "--wildcards" + - "{{ '*/_includes/charts/calico/crds/kdd/' if (calico_version is version('v3.22.3', '<')) else '*/libcalico-go/config/crd/' }}" owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane weave_kube: enabled: "{{ kube_network_plugin == 'weave' }}" @@ -839,7 +853,7 @@ downloads: tag: "{{ weave_kube_image_tag }}" sha256: "{{ weave_kube_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster weave_npc: enabled: "{{ kube_network_plugin == 'weave' }}" @@ -848,7 +862,7 @@ downloads: tag: "{{ weave_npc_image_tag }}" sha256: "{{ weave_npc_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster kube_ovn: enabled: "{{ kube_network_plugin == 'kube-ovn' }}" @@ -857,7 +871,7 @@ downloads: tag: "{{ kube_ovn_container_image_tag }}" sha256: "{{ kube_ovn_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster kube_router: enabled: "{{ kube_network_plugin == 'kube-router' }}" @@ -866,7 +880,7 @@ downloads: tag: "{{ kube_router_image_tag }}" sha256: "{{ kube_router_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster pod_infra: enabled: true @@ -875,7 +889,7 @@ downloads: tag: "{{ pod_infra_image_tag }}" sha256: "{{ pod_infra_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster kube-vip: enabled: "{{ kube_vip_enabled }}" @@ -884,7 +898,7 @@ downloads: tag: "{{ kube_vip_image_tag }}" sha256: "{{ kube_vip_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane nginx: enabled: "{{ loadbalancer_apiserver_localhost and loadbalancer_apiserver_type == 'nginx' }}" @@ -893,7 +907,7 @@ downloads: tag: "{{ nginx_image_tag }}" sha256: "{{ nginx_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node haproxy: enabled: "{{ loadbalancer_apiserver_localhost and loadbalancer_apiserver_type == 'haproxy' }}" @@ -902,7 +916,7 @@ downloads: tag: "{{ haproxy_image_tag }}" sha256: "{{ haproxy_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node coredns: enabled: "{{ dns_mode in ['coredns', 'coredns_dual'] }}" @@ -911,7 +925,7 @@ downloads: tag: "{{ coredns_image_tag }}" sha256: "{{ coredns_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster nodelocaldns: enabled: "{{ enable_nodelocaldns }}" @@ -920,7 +934,7 @@ downloads: tag: "{{ nodelocaldns_image_tag }}" sha256: "{{ nodelocaldns_digest_checksum | default(None) }}" groups: - - k8s_cluster + - k8s_cluster dnsautoscaler: enabled: "{{ dns_mode in ['coredns', 'coredns_dual'] }}" @@ -929,7 +943,7 @@ downloads: tag: "{{ dnsautoscaler_image_tag }}" sha256: "{{ dnsautoscaler_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane helm: enabled: "{{ helm_enabled }}" @@ -942,7 +956,7 @@ downloads: owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane krew: enabled: "{{ krew_enabled }}" @@ -955,7 +969,7 @@ downloads: owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane registry: enabled: "{{ registry_enabled }}" @@ -964,7 +978,7 @@ downloads: tag: "{{ registry_image_tag }}" sha256: "{{ registry_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node metrics_server: enabled: "{{ metrics_server_enabled }}" @@ -973,7 +987,7 @@ downloads: tag: "{{ metrics_server_image_tag }}" sha256: "{{ metrics_server_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane local_volume_provisioner: enabled: "{{ local_volume_provisioner_enabled }}" @@ -982,7 +996,7 @@ downloads: tag: "{{ local_volume_provisioner_image_tag }}" sha256: "{{ local_volume_provisioner_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node cephfs_provisioner: enabled: "{{ cephfs_provisioner_enabled }}" @@ -991,7 +1005,7 @@ downloads: tag: "{{ cephfs_provisioner_image_tag }}" sha256: "{{ cephfs_provisioner_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node rbd_provisioner: enabled: "{{ rbd_provisioner_enabled }}" @@ -1000,7 +1014,7 @@ downloads: tag: "{{ rbd_provisioner_image_tag }}" sha256: "{{ rbd_provisioner_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node local_path_provisioner: enabled: "{{ local_path_provisioner_enabled }}" @@ -1009,7 +1023,7 @@ downloads: tag: "{{ local_path_provisioner_image_tag }}" sha256: "{{ local_path_provisioner_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node ingress_nginx_controller: enabled: "{{ ingress_nginx_enabled }}" @@ -1018,7 +1032,7 @@ downloads: tag: "{{ ingress_nginx_controller_image_tag }}" sha256: "{{ ingress_nginx_controller_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node ingress_alb_controller: enabled: "{{ ingress_alb_enabled }}" @@ -1027,7 +1041,7 @@ downloads: tag: "{{ alb_ingress_image_tag }}" sha256: "{{ ingress_alb_controller_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node cert_manager_controller: enabled: "{{ cert_manager_enabled }}" @@ -1036,7 +1050,7 @@ downloads: tag: "{{ cert_manager_controller_image_tag }}" sha256: "{{ cert_manager_controller_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node cert_manager_cainjector: enabled: "{{ cert_manager_enabled }}" @@ -1045,7 +1059,7 @@ downloads: tag: "{{ cert_manager_cainjector_image_tag }}" sha256: "{{ cert_manager_cainjector_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node cert_manager_webhook: enabled: "{{ cert_manager_enabled }}" @@ -1054,7 +1068,7 @@ downloads: tag: "{{ cert_manager_webhook_image_tag }}" sha256: "{{ cert_manager_webhook_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node csi_attacher: enabled: "{{ cinder_csi_enabled or aws_ebs_csi_enabled }}" @@ -1063,7 +1077,7 @@ downloads: tag: "{{ csi_attacher_image_tag }}" sha256: "{{ csi_attacher_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node csi_provisioner: enabled: "{{ cinder_csi_enabled or aws_ebs_csi_enabled }}" @@ -1072,7 +1086,7 @@ downloads: tag: "{{ csi_provisioner_image_tag }}" sha256: "{{ csi_provisioner_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node csi_snapshotter: enabled: "{{ cinder_csi_enabled or aws_ebs_csi_enabled }}" @@ -1081,7 +1095,7 @@ downloads: tag: "{{ csi_snapshotter_image_tag }}" sha256: "{{ csi_snapshotter_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node snapshot_controller: enabled: "{{ csi_snapshot_controller_enabled }}" @@ -1090,7 +1104,7 @@ downloads: tag: "{{ snapshot_controller_image_tag }}" sha256: "{{ snapshot_controller_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node csi_resizer: enabled: "{{ cinder_csi_enabled or aws_ebs_csi_enabled }}" @@ -1099,7 +1113,7 @@ downloads: tag: "{{ csi_resizer_image_tag }}" sha256: "{{ csi_resizer_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node csi_node_driver_registrar: enabled: "{{ cinder_csi_enabled or aws_ebs_csi_enabled }}" @@ -1108,7 +1122,7 @@ downloads: tag: "{{ csi_node_driver_registrar_image_tag }}" sha256: "{{ csi_node_driver_registrar_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node cinder_csi_plugin: enabled: "{{ cinder_csi_enabled }}" @@ -1117,7 +1131,7 @@ downloads: tag: "{{ cinder_csi_plugin_image_tag }}" sha256: "{{ cinder_csi_plugin_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node aws_ebs_csi_plugin: enabled: "{{ aws_ebs_csi_enabled }}" @@ -1126,7 +1140,7 @@ downloads: tag: "{{ aws_ebs_csi_plugin_image_tag }}" sha256: "{{ aws_ebs_csi_plugin_digest_checksum | default(None) }}" groups: - - kube_node + - kube_node dashboard: enabled: "{{ dashboard_enabled }}" @@ -1135,7 +1149,7 @@ downloads: tag: "{{ dashboard_image_tag }}" sha256: "{{ dashboard_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane dashboard_metrics_scrapper: enabled: "{{ dashboard_enabled }}" @@ -1144,7 +1158,7 @@ downloads: tag: "{{ dashboard_metrics_scraper_tag }}" sha256: "{{ dashboard_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane metallb_speaker: enabled: "{{ metallb_speaker_enabled }}" @@ -1153,7 +1167,7 @@ downloads: tag: "{{ metallb_version }}" sha256: "{{ metallb_speaker_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane metallb_controller: enabled: "{{ metallb_enabled }}" @@ -1162,7 +1176,7 @@ downloads: tag: "{{ metallb_version }}" sha256: "{{ metallb_controller_digest_checksum | default(None) }}" groups: - - kube_control_plane + - kube_control_plane yq: enabled: "{{ argocd_enabled }}" @@ -1175,7 +1189,7 @@ downloads: owner: "root" mode: "0755" groups: - - kube_control_plane + - kube_control_plane download_defaults: container: false diff --git a/kubespray/project/roles/kubespray-defaults/defaults/main/main.yml b/kubespray/project/roles/kubespray-defaults/defaults/main/main.yml index 8966431..4f1dfd2 100644 --- a/kubespray/project/roles/kubespray-defaults/defaults/main/main.yml +++ b/kubespray/project/roles/kubespray-defaults/defaults/main/main.yml @@ -6,6 +6,8 @@ ansible_ssh_common_args: "{% if 'bastion' in groups['all'] %} -o ProxyCommand='s # selinux state preinstall_selinux_state: permissive +# Setting this value to false will fail +# For details, read this comment https://github.com/kubernetes-sigs/kubespray/pull/11016#issuecomment-2004985001 kube_api_anonymous_auth: true # Default value, but will be set to true automatically if detected @@ -16,10 +18,10 @@ kubelet_fail_swap_on: true kubelet_swap_behavior: LimitedSwap ## Change this to use another Kubernetes version, e.g. a current beta release -kube_version: v1.29.2 +kube_version: v1.30.4 ## The minimum version working -kube_version_min_required: v1.27.0 +kube_version_min_required: v1.28.0 ## Kube Proxy mode One of ['iptables', 'ipvs'] kube_proxy_mode: ipvs @@ -50,6 +52,9 @@ kubeadm_join_phases_skip_default: [] kubeadm_join_phases_skip: >- {{ kubeadm_join_phases_skip_default }} +# Set to true to remove the role binding to anonymous users created by kubeadm +remove_anonymous_access: false + # A string slice of values which specify the addresses to use for NodePorts. # Values may be valid IP blocks (e.g. 1.2.3.0/24, 1.2.3.4/32). # The default empty string slice ([]) means to use all local addresses. @@ -312,13 +317,6 @@ crio_insecure_registries: [] ## Please note that overlay2 is only supported on newer kernels # docker_storage_options: -s overlay2 -## Enable docker_container_storage_setup, it will configure devicemapper driver on Centos7 or RedHat7. -docker_container_storage_setup: false - -## It must be define a disk path for docker_container_storage_setup_devs. -## Otherwise docker-storage-setup will be executed incorrectly. -# docker_container_storage_setup_devs: /dev/vdb - ## Only set this if you have more than 3 nameservers: ## If true Kubespray will only use the first 3, otherwise it will fail docker_dns_servers_strict: false @@ -397,7 +395,7 @@ metrics_server_enabled: false enable_network_policy: true local_path_provisioner_enabled: false local_volume_provisioner_enabled: false -local_volume_provisioner_directory_mode: 0700 +local_volume_provisioner_directory_mode: "0700" cinder_csi_enabled: false aws_ebs_csi_enabled: false azure_csi_enabled: false diff --git a/kubespray/project/roles/kubespray-defaults/tasks/fallback_ips.yml b/kubespray/project/roles/kubespray-defaults/tasks/fallback_ips.yml index 26b9447..ae3b151 100644 --- a/kubespray/project/roles/kubespray-defaults/tasks/fallback_ips.yml +++ b/kubespray/project/roles/kubespray-defaults/tasks/fallback_ips.yml @@ -3,15 +3,15 @@ # ansible_default_ipv4 isn't what you think. # Thanks https://medium.com/opsops/ansible-default-ipv4-is-not-what-you-think-edb8ab154b10 -- name: Gather ansible_default_ipv4 from all hosts +- name: Gather ansible_default_ipv4 from all hosts or specific hosts setup: gather_subset: '!all,network' filter: "ansible_default_ipv4" delegate_to: "{{ item }}" - delegate_facts: yes + delegate_facts: true when: hostvars[item].ansible_default_ipv4 is not defined - loop: "{{ (groups['k8s_cluster'] | default([]) + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique }}" - run_once: yes + loop: "{{ (ansible_play_hosts_all + [groups['kube_control_plane'][0]]) | unique if ansible_limit is defined else (groups['k8s_cluster'] | default([]) + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique }}" + run_once: true ignore_unreachable: true tags: always @@ -19,15 +19,16 @@ set_fact: fallback_ips_base: | --- - {% for item in (groups['k8s_cluster'] | default([]) + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique %} + {% set search_hosts = (ansible_play_hosts_all + [groups['kube_control_plane'][0]]) | unique if ansible_limit is defined else (groups['k8s_cluster'] | default([]) + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique %} + {% for item in search_hosts %} {% set found = hostvars[item].get('ansible_default_ipv4') %} {{ item }}: "{{ found.get('address', '127.0.0.1') }}" {% endfor %} delegate_to: localhost connection: local - delegate_facts: yes - become: no - run_once: yes + delegate_facts: true + become: false + run_once: true - name: Set fallback_ips set_fact: diff --git a/kubespray/project/roles/kubespray-defaults/tasks/main.yaml b/kubespray/project/roles/kubespray-defaults/tasks/main.yaml index 0de87f1..0a9d987 100644 --- a/kubespray/project/roles/kubespray-defaults/tasks/main.yaml +++ b/kubespray/project/roles/kubespray-defaults/tasks/main.yaml @@ -3,7 +3,7 @@ # do not run gather facts when bootstrap-os in roles when: > ansible_play_role_names | - intersect(['bootstrap-os', 'kubernetes-sigs.kubespray.bootstrap-os']) | + intersect(['bootstrap-os', 'kubernetes_sigs.kubespray.bootstrap-os']) | length == 0 tags: - always diff --git a/kubespray/project/roles/kubespray-defaults/tasks/no_proxy.yml b/kubespray/project/roles/kubespray-defaults/tasks/no_proxy.yml index d2d5cc6..adec886 100644 --- a/kubespray/project/roles/kubespray-defaults/tasks/no_proxy.yml +++ b/kubespray/project/roles/kubespray-defaults/tasks/no_proxy.yml @@ -26,9 +26,9 @@ 127.0.0.1,localhost,{{ kube_service_addresses }},{{ kube_pods_subnet }},svc,svc.{{ dns_domain }} delegate_to: localhost connection: local - delegate_facts: yes - become: no - run_once: yes + delegate_facts: true + become: false + run_once: true - name: Populates no_proxy to all hosts set_fact: diff --git a/kubespray/project/roles/network_plugin/calico/rr/tasks/pre.yml b/kubespray/project/roles/network_plugin/calico/rr/tasks/pre.yml index d8dbd80..f8a9de6 100644 --- a/kubespray/project/roles/network_plugin/calico/rr/tasks/pre.yml +++ b/kubespray/project/roles/network_plugin/calico/rr/tasks/pre.yml @@ -3,7 +3,7 @@ service: name: calico-rr state: stopped - enabled: no + enabled: false failed_when: false - name: Calico-rr | Delete obsolete files diff --git a/kubespray/project/roles/network_plugin/calico/tasks/calico_apiserver_certs.yml b/kubespray/project/roles/network_plugin/calico/tasks/calico_apiserver_certs.yml index fc336e4..d42917c 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/calico_apiserver_certs.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/calico_apiserver_certs.yml @@ -9,7 +9,7 @@ template: src: "calico-apiserver-ns.yml.j2" dest: "{{ kube_config_dir }}/calico-apiserver-ns.yml" - mode: 0644 + mode: "0644" - name: Calico | Apply ns manifests kube: @@ -21,21 +21,21 @@ file: path: /etc/calico/certs state: directory - mode: 0755 + mode: "0755" when: calico_apiserver_secret.rc != 0 - name: Calico | Copy ssl script for apiserver certs template: src: make-ssl-calico.sh.j2 dest: "{{ bin_dir }}/make-ssl-apiserver.sh" - mode: 0755 + mode: "0755" when: calico_apiserver_secret.rc != 0 - name: Calico | Copy ssl config for apiserver certs copy: src: openssl.conf dest: /etc/calico/certs/openssl.conf - mode: 0644 + mode: "0644" when: calico_apiserver_secret.rc != 0 - name: Calico | Generate apiserver certs diff --git a/kubespray/project/roles/network_plugin/calico/tasks/check.yml b/kubespray/project/roles/network_plugin/calico/tasks/check.yml index de67b15..7f73a08 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/check.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/check.yml @@ -4,7 +4,7 @@ that: - ipip is not defined msg: "'ipip' configuration variable is deprecated, please configure your inventory with 'calico_ipip_mode' set to 'Always' or 'CrossSubnet' according to your specific needs" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: Stop if legacy encapsulation variables are detected (ipip_mode) @@ -12,7 +12,7 @@ that: - ipip_mode is not defined msg: "'ipip_mode' configuration variable is deprecated, please configure your inventory with 'calico_ipip_mode' set to 'Always' or 'CrossSubnet' according to your specific needs" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: Stop if legacy encapsulation variables are detected (calcio_ipam_autoallocateblocks) @@ -20,7 +20,7 @@ that: - calcio_ipam_autoallocateblocks is not defined msg: "'calcio_ipam_autoallocateblocks' configuration variable is deprecated, it's a typo, please configure your inventory with 'calico_ipam_autoallocateblocks' set to 'true' or 'false' according to your specific needs" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" @@ -32,7 +32,7 @@ msg: "When using cloud_provider azure and network_plugin calico calico_ipip_mode must be 'Never' and calico_vxlan_mode 'Always' or 'CrossSubnet'" when: - cloud_provider is defined and cloud_provider == 'azure' - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: Stop if supported Calico versions @@ -40,21 +40,21 @@ that: - "calico_version in calico_crds_archive_checksums.keys()" msg: "Calico version not supported {{ calico_version }} not in {{ calico_crds_archive_checksums.keys() }}" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: Check if calicoctl.sh exists stat: path: "{{ bin_dir }}/calicoctl.sh" register: calicoctl_sh_exists - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: Check if calico ready command: "{{ bin_dir }}/calicoctl.sh get ClusterInformation default" register: calico_ready - run_once: True - ignore_errors: True + run_once: true + ignore_errors: true retries: 5 delay: 10 until: calico_ready.rc == 0 @@ -62,7 +62,7 @@ when: calicoctl_sh_exists.stat.exists - name: Check that current calico version is enough for upgrade - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" when: calicoctl_sh_exists.stat.exists and calico_ready.rc == 0 block: @@ -82,15 +82,16 @@ Minimum version is {{ calico_min_version_required }} supported by the previous kubespray release. But current version is {{ calico_version_on_server.stdout }}. -- name: "Check that cluster_id is set if calico_rr enabled" +- name: "Check that cluster_id is set and a valid IPv4 address if calico_rr enabled" assert: that: - cluster_id is defined - msg: "A unique cluster_id is required if using calico_rr" + - cluster_id is ansible.utils.ipv4 + msg: "A unique cluster_id is required if using calico_rr, and it must be a valid IPv4 address" when: - peer_with_calico_rr - inventory_hostname == groups['kube_control_plane'][0] - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check that calico_rr nodes are in k8s_cluster group" @@ -100,7 +101,7 @@ msg: "calico_rr must be a child group of k8s_cluster group" when: - '"calico_rr" in group_names' - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check vars defined correctly" @@ -109,7 +110,7 @@ - "calico_pool_name is defined" - "calico_pool_name is match('^[a-zA-Z0-9-_\\\\.]{2,63}$')" msg: "calico_pool_name contains invalid characters" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check calico network backend defined correctly" @@ -117,11 +118,11 @@ that: - "calico_network_backend in ['bird', 'vxlan', 'none']" msg: "calico network backend is not 'bird', 'vxlan' or 'none'" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check ipip and vxlan mode defined correctly" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" assert: that: @@ -136,7 +137,7 @@ msg: "IP in IP and VXLAN mode is mutualy exclusive modes" when: - "calico_ipip_mode in ['Always', 'CrossSubnet']" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check ipip and vxlan mode if simultaneously enabled" @@ -146,23 +147,23 @@ msg: "IP in IP and VXLAN mode is mutualy exclusive modes" when: - "calico_vxlan_mode in ['Always', 'CrossSubnet']" - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Get Calico {{ calico_pool_name }} configuration" command: "{{ bin_dir }}/calicoctl.sh get ipPool {{ calico_pool_name }} -o json" - failed_when: False - changed_when: False - check_mode: no + failed_when: false + changed_when: false + check_mode: false register: calico - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Set calico_pool_conf" set_fact: calico_pool_conf: '{{ calico.stdout | from_json }}' when: calico.rc == 0 and calico.stdout - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check if inventory match current cluster configuration" @@ -175,7 +176,7 @@ msg: "Your inventory doesn't match the current cluster configuration" when: - calico_pool_conf is defined - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check kdd calico_datastore if calico_apiserver_enabled" @@ -184,7 +185,7 @@ msg: "When using calico apiserver you need to use the kubernetes datastore" when: - calico_apiserver_enabled - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check kdd calico_datastore if typha_enabled" @@ -193,7 +194,7 @@ msg: "When using typha you need to use the kubernetes datastore" when: - typha_enabled - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" - name: "Check ipip mode is Never for calico ipv6" @@ -203,5 +204,5 @@ msg: "Calico doesn't support ipip tunneling for the IPv6" when: - enable_dual_stack_networks - run_once: True + run_once: true delegate_to: "{{ groups['kube_control_plane'][0] }}" diff --git a/kubespray/project/roles/network_plugin/calico/tasks/install.yml b/kubespray/project/roles/network_plugin/calico/tasks/install.yml index 6b293dc..1d3b023 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/install.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/install.yml @@ -13,14 +13,14 @@ copy: src: "{{ downloads.calicoctl.dest }}" dest: "{{ bin_dir }}/calicoctl" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true - name: Calico | Create calico certs directory file: dest: "{{ calico_cert_dir }}" state: directory - mode: 0750 + mode: "0750" owner: root group: root when: calico_datastore == "etcd" @@ -30,8 +30,8 @@ src: "{{ etcd_cert_dir }}/{{ item.s }}" dest: "{{ calico_cert_dir }}/{{ item.d }}" state: hard - mode: 0640 - force: yes + mode: "0640" + force: true with_items: - {s: "{{ kube_etcd_cacert_file }}", d: "ca_cert.crt"} - {s: "{{ kube_etcd_cert_file }}", d: "cert.crt"} @@ -54,14 +54,14 @@ template: src: "calicoctl.{{ calico_datastore }}.sh.j2" dest: "{{ bin_dir }}/calicoctl.sh" - mode: 0755 + mode: "0755" owner: root group: root - name: Calico | wait for etcd uri: url: "{{ etcd_access_addresses.split(',') | first }}/health" - validate_certs: no + validate_certs: false client_cert: "{{ calico_cert_dir }}/cert.crt" client_key: "{{ calico_cert_dir }}/key.pem" register: result @@ -142,7 +142,7 @@ assemble: src: "{{ calico_kdd_path }}" dest: "{{ kube_config_dir }}/kdd-crds.yml" - mode: 0644 + mode: "0644" delimiter: "---\n" regexp: ".*\\.yaml" remote_src: true @@ -165,8 +165,8 @@ - name: Calico | Get existing FelixConfiguration command: "{{ bin_dir }}/calicoctl.sh get felixconfig default -o json" register: _felix_cmd - ignore_errors: True - changed_when: False + ignore_errors: true + changed_when: false - name: Calico | Set kubespray FelixConfiguration set_fact: @@ -201,7 +201,7 @@ command: cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" stdin: "{{ _felix_config is string | ternary(_felix_config, _felix_config | to_json) }}" - changed_when: False + changed_when: false - name: Calico | Configure Calico IP Pool when: @@ -210,8 +210,8 @@ - name: Calico | Get existing calico network pool command: "{{ bin_dir }}/calicoctl.sh get ippool {{ calico_pool_name }} -o json" register: _calico_pool_cmd - ignore_errors: True - changed_when: False + ignore_errors: true + changed_when: false - name: Calico | Set kubespray calico network pool set_fact: @@ -251,7 +251,7 @@ command: cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" stdin: "{{ _calico_pool is string | ternary(_calico_pool, _calico_pool | to_json) }}" - changed_when: False + changed_when: false - name: Calico | Configure Calico IPv6 Pool when: @@ -261,8 +261,8 @@ - name: Calico | Get existing calico ipv6 network pool command: "{{ bin_dir }}/calicoctl.sh get ippool {{ calico_pool_name }}-ipv6 -o json" register: _calico_pool_ipv6_cmd - ignore_errors: True - changed_when: False + ignore_errors: true + changed_when: false - name: Calico | Set kubespray calico network pool set_fact: @@ -302,19 +302,19 @@ command: cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" stdin: "{{ _calico_pool_ipv6 is string | ternary(_calico_pool_ipv6, _calico_pool_ipv6 | to_json) }}" - changed_when: False + changed_when: false - name: Populate Service External IPs set_fact: _service_external_ips: "{{ _service_external_ips | default([]) + [{'cidr': item}] }}" with_items: "{{ calico_advertise_service_external_ips }}" - run_once: yes + run_once: true - name: Populate Service LoadBalancer IPs set_fact: _service_loadbalancer_ips: "{{ _service_loadbalancer_ips | default([]) + [{'cidr': item}] }}" with_items: "{{ calico_advertise_service_loadbalancer_ips }}" - run_once: yes + run_once: true - name: "Determine nodeToNodeMesh needed state" set_fact: @@ -322,7 +322,7 @@ when: - peer_with_router | default(false) or peer_with_calico_rr | default(false) - inventory_hostname in groups['k8s_cluster'] - run_once: yes + run_once: true - name: Calico | Configure Calico BGP when: @@ -331,8 +331,8 @@ - name: Calico | Get existing BGP Configuration command: "{{ bin_dir }}/calicoctl.sh get bgpconfig default -o json" register: _bgp_config_cmd - ignore_errors: True - changed_when: False + ignore_errors: true + changed_when: false - name: Calico | Set kubespray BGP Configuration set_fact: @@ -366,13 +366,13 @@ command: cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" stdin: "{{ _bgp_config is string | ternary(_bgp_config, _bgp_config | to_json) }}" - changed_when: False + changed_when: false - name: Calico | Create calico manifests template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: calico-config, file: calico-config.yml, type: cm} - {name: calico-node, file: calico-node.yml, type: ds} @@ -389,7 +389,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: calico, file: calico-typha.yml, type: typha} register: calico_node_typha_manifest @@ -416,7 +416,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: calico, file: calico-apiserver.yml, type: calico-apiserver} register: calico_apiserver_manifest @@ -469,7 +469,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: calico, file: calico-ipamconfig.yml, type: ipam} when: diff --git a/kubespray/project/roles/network_plugin/calico/tasks/peer_with_router.yml b/kubespray/project/roles/network_plugin/calico/tasks/peer_with_router.yml index a29ca36..5c25f09 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/peer_with_router.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/peer_with_router.yml @@ -19,10 +19,42 @@ until: output.rc == 0 delay: "{{ retry_stagger | random + 3 }}" with_items: - - "{{ peers | selectattr('scope', 'defined') | selectattr('scope', 'equalto', 'global') | list | default([]) }}" + - "{{ peers | default([]) | selectattr('scope', 'defined') | selectattr('scope', 'equalto', 'global') | list }}" when: - inventory_hostname == groups['kube_control_plane'][0] +- name: Calico | Get node for per node peering + command: + cmd: "{{ bin_dir }}/calicoctl.sh get node {{ inventory_hostname }}" + register: output_get_node + when: + - inventory_hostname in groups['k8s_cluster'] + - local_as is defined + - groups['calico_rr'] | default([]) | length == 0 + delegate_to: "{{ groups['kube_control_plane'][0] }}" + +- name: Calico | Patch node asNumber for per node peering + command: + cmd: |- + {{ bin_dir }}/calicoctl.sh patch node "{{ inventory_hostname }}" --patch '{{ patch is string | ternary(patch, patch | to_json) }}' + vars: + patch: > + {"spec": { + "bgp": { + "asNumber": "{{ local_as }}" + }, + "orchRefs": [{"nodeName": "{{ inventory_hostname }}", "orchestrator": "k8s"}] + }} + register: output + retries: 0 + until: output.rc == 0 + delay: "{{ retry_stagger | random + 3 }}" + when: + - inventory_hostname in groups['k8s_cluster'] + - local_as is defined + - groups['calico_rr'] | default([]) | length == 0 + - output_get_node.rc == 0 + - name: Calico | Configure node asNumber for per node peering command: cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" @@ -48,6 +80,7 @@ - inventory_hostname in groups['k8s_cluster'] - local_as is defined - groups['calico_rr'] | default([]) | length == 0 + - output_get_node.rc != 0 - name: Calico | Configure peering with router(s) at node scope command: @@ -64,6 +97,9 @@ "asNumber": "{{ item.as }}", "node": "{{ inventory_hostname }}", "peerIP": "{{ item.router_id }}", + {% if calico_version is version('v3.26.0', '>=') and (item.filters | default([]) | length > 0) %} + "filters": {{ item.filters }}, + {% endif %} "sourceAddress": "{{ item.sourceaddress | default('UseNodeIP') }}" }} register: output @@ -71,7 +107,7 @@ until: output.rc == 0 delay: "{{ retry_stagger | random + 3 }}" with_items: - - "{{ peers | selectattr('scope', 'undefined') | list | default([]) | union(peers | selectattr('scope', 'defined') | selectattr('scope', 'equalto', 'node') | list | default([])) }}" + - "{{ peers | default([]) | selectattr('scope', 'undefined') | list | union(peers | default([]) | selectattr('scope', 'defined') | selectattr('scope', 'equalto', 'node') | list ) }}" delegate_to: "{{ groups['kube_control_plane'][0] }}" when: - inventory_hostname in groups['k8s_cluster'] diff --git a/kubespray/project/roles/network_plugin/calico/tasks/repos.yml b/kubespray/project/roles/network_plugin/calico/tasks/repos.yml index dd29f45..7eba916 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/repos.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/repos.yml @@ -10,11 +10,11 @@ file: _copr:copr.fedorainfracloud.org:jdoss:wireguard description: Copr repo for wireguard owned by jdoss baseurl: "{{ calico_wireguard_repo }}" - gpgcheck: yes + gpgcheck: true gpgkey: https://download.copr.fedorainfracloud.org/results/jdoss/wireguard/pubkey.gpg - skip_if_unavailable: yes - enabled: yes - repo_gpgcheck: no + skip_if_unavailable: true + enabled: true + repo_gpgcheck: false when: - ansible_os_family in ['RedHat'] - ansible_distribution not in ['Fedora'] diff --git a/kubespray/project/roles/network_plugin/calico/tasks/reset.yml b/kubespray/project/roles/network_plugin/calico/tasks/reset.yml index 8dab214..16c8509 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/reset.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/reset.yml @@ -2,9 +2,9 @@ - name: Reset | check vxlan.calico network device stat: path: /sys/class/net/vxlan.calico - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: vxlan - name: Reset | remove the network vxlan.calico device created by calico @@ -14,9 +14,9 @@ - name: Reset | check dummy0 network device stat: path: /sys/class/net/dummy0 - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: dummy0 - name: Reset | remove the network device created by calico diff --git a/kubespray/project/roles/network_plugin/calico/tasks/typha_certs.yml b/kubespray/project/roles/network_plugin/calico/tasks/typha_certs.yml index 5d3f279..ad87f5a 100644 --- a/kubespray/project/roles/network_plugin/calico/tasks/typha_certs.yml +++ b/kubespray/project/roles/network_plugin/calico/tasks/typha_certs.yml @@ -9,21 +9,22 @@ file: path: /etc/calico/certs state: directory - mode: 0755 + mode: "0755" when: typha_server_secret.rc != 0 - name: Calico | Copy ssl script for typha certs template: src: make-ssl-calico.sh.j2 dest: "{{ bin_dir }}/make-ssl-typha.sh" - mode: 0755 + mode: "0755" + when: typha_server_secret.rc != 0 - name: Calico | Copy ssl config for typha certs copy: src: openssl.conf dest: /etc/calico/certs/openssl.conf - mode: 0644 + mode: "0644" when: typha_server_secret.rc != 0 - name: Calico | Generate typha certs diff --git a/kubespray/project/roles/network_plugin/calico/templates/calico-apiserver.yml.j2 b/kubespray/project/roles/network_plugin/calico/templates/calico-apiserver.yml.j2 index 49f5918..769c78c 100644 --- a/kubespray/project/roles/network_plugin/calico/templates/calico-apiserver.yml.j2 +++ b/kubespray/project/roles/network_plugin/calico/templates/calico-apiserver.yml.j2 @@ -72,6 +72,15 @@ spec: initialDelaySeconds: 90 periodSeconds: 10 name: calico-apiserver +{% if calico_version is version('v3.28.0', '>=') %} + readinessProbe: + httpGet: + path: /readyz + port: 5443 + scheme: HTTPS + timeoutSeconds: 5 + periodSeconds: 60 +{% else %} readinessProbe: exec: command: @@ -79,6 +88,7 @@ spec: failureThreshold: 5 initialDelaySeconds: 5 periodSeconds: 10 +{% endif %} securityContext: privileged: false runAsUser: 0 @@ -157,6 +167,7 @@ rules: - networksets - bgpconfigurations - bgppeers + - bgpfilters - felixconfigurations - kubecontrollersconfigurations - ippools @@ -172,7 +183,16 @@ rules: - create - update - delete - +{% if calico_version is version('v3.28.0', '>=') %} +- apiGroups: + - policy + resourceNames: + - calico-apiserver + resources: + - podsecuritypolicies + verbs: + - use +{% endif %} --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/kubespray/project/roles/network_plugin/calico/templates/calico-config.yml.j2 b/kubespray/project/roles/network_plugin/calico/templates/calico-config.yml.j2 index 26983ec..d949af1 100644 --- a/kubespray/project/roles/network_plugin/calico/templates/calico-config.yml.j2 +++ b/kubespray/project/roles/network_plugin/calico/templates/calico-config.yml.j2 @@ -102,4 +102,3 @@ data: } ] } - diff --git a/kubespray/project/roles/network_plugin/calico/templates/calico-cr.yml.j2 b/kubespray/project/roles/network_plugin/calico/templates/calico-cr.yml.j2 index ac0331f..7ddec16 100644 --- a/kubespray/project/roles/network_plugin/calico/templates/calico-cr.yml.j2 +++ b/kubespray/project/roles/network_plugin/calico/templates/calico-cr.yml.j2 @@ -16,6 +16,11 @@ rules: - pods/status verbs: - patch + - apiGroups: [""] + resources: + - nodes/status + verbs: + - update - apiGroups: ["crd.projectcalico.org"] resources: - blockaffinities diff --git a/kubespray/project/roles/network_plugin/calico/templates/calico-node.yml.j2 b/kubespray/project/roles/network_plugin/calico/templates/calico-node.yml.j2 index 5092011..ff85a51 100644 --- a/kubespray/project/roles/network_plugin/calico/templates/calico-node.yml.j2 +++ b/kubespray/project/roles/network_plugin/calico/templates/calico-node.yml.j2 @@ -38,7 +38,7 @@ spec: # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. terminationGracePeriodSeconds: 0 initContainers: -{% if calico_datastore == "kdd" %} +{% if calico_datastore == "kdd" and not calico_ipam_host_local %} # This container performs upgrade from host-local IPAM to calico-ipam. # It can be deleted if this is a fresh installation, or if you have already # upgraded to use calico-ipam. @@ -310,6 +310,10 @@ spec: value: "{{ calico_node_ignorelooserpf }}" - name: CALICO_MANAGE_CNI value: "true" +{% if calico_ipam_host_local %} + - name: USE_POD_CIDR + value: "true" +{% endif %} {% if calico_node_extra_envs is defined %} {% for key in calico_node_extra_envs %} - name: {{ key }} @@ -407,9 +411,11 @@ spec: - name: var-run-calico hostPath: path: /var/run/calico + type: DirectoryOrCreate - name: var-lib-calico hostPath: path: /var/lib/calico + type: DirectoryOrCreate # Used to install CNI. - name: cni-net-dir hostPath: @@ -417,6 +423,7 @@ spec: - name: cni-bin-dir hostPath: path: /opt/cni/bin + type: DirectoryOrCreate {% if calico_datastore == "etcd" %} # Mount in the etcd TLS secrets. - name: etcd-certs @@ -428,7 +435,7 @@ spec: hostPath: path: /run/xtables.lock type: FileOrCreate -{% if calico_datastore == "kdd" %} +{% if calico_datastore == "kdd" and not calico_ipam_host_local %} # Mount in the directory for host-local IPAM allocations. This is # used when upgrading from host-local to calico-ipam, and can be removed # if not using the upgrade-ipam init container. diff --git a/kubespray/project/roles/network_plugin/calico/templates/calico-typha.yml.j2 b/kubespray/project/roles/network_plugin/calico/templates/calico-typha.yml.j2 index 2c6d510..d1f37aa 100644 --- a/kubespray/project/roles/network_plugin/calico/templates/calico-typha.yml.j2 +++ b/kubespray/project/roles/network_plugin/calico/templates/calico-typha.yml.j2 @@ -136,11 +136,10 @@ spec: name: cacert readOnly: true {% endif %} - # Needed for version >=3.7 when the 'host-local' ipam is used - # Should never happen given templates/cni-calico.conflist.j2 - # Configure route aggregation based on pod CIDR. - # - name: USE_POD_CIDR - # value: "true" +{% if calico_ipam_host_local %} + - name: USE_POD_CIDR + value: "true" +{% endif %} livenessProbe: httpGet: path: /liveness diff --git a/kubespray/project/roles/network_plugin/cilium/defaults/main.yml b/kubespray/project/roles/network_plugin/cilium/defaults/main.yml index f4c70e4..7e65e7f 100644 --- a/kubespray/project/roles/network_plugin/cilium/defaults/main.yml +++ b/kubespray/project/roles/network_plugin/cilium/defaults/main.yml @@ -7,6 +7,9 @@ cilium_mtu: "" cilium_enable_ipv4: true cilium_enable_ipv6: false +# Enable l2 announcement from cilium to replace Metallb Ref: https://docs.cilium.io/en/v1.14/network/l2-announcements/ +cilium_l2announcements: false + # Cilium agent health port cilium_agent_health_port: "{%- if cilium_version | regex_replace('v') is version('1.11.6', '>=') -%}9879{%- else -%}9876{%- endif -%}" @@ -39,6 +42,10 @@ cilium_cpu_requests: 100m # Overlay Network Mode cilium_tunnel_mode: vxlan + +# LoadBalancer Mode (snat/dsr/hybrid) Ref: https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/#dsr-mode +cilium_loadbalancer_mode: snat + # Optional features cilium_enable_prometheus: false # Enable if you want to make use of hostPort mappings @@ -152,6 +159,12 @@ cilium_hubble_install: false ### Enable auto generate certs if cilium_hubble_install: true cilium_hubble_tls_generate: false +### Capacity of Hubble events buffer. The provided value must be one less than an integer power of two and no larger than 65535 +### (ie: 1, 3, ..., 2047, 4095, ..., 65535) (default 4095) +# cilium_hubble_event_buffer_capacity: 4095 +### Buffer size of the channel to receive monitor events. +# cilium_hubble_event_queue_size: 50 + # The default IP address management mode is "Cluster Scope". # https://docs.cilium.io/en/stable/concepts/networking/ipam/ cilium_ipam_mode: cluster-pool diff --git a/kubespray/project/roles/network_plugin/cilium/tasks/check.yml b/kubespray/project/roles/network_plugin/cilium/tasks/check.yml index c65591f..34a5afe 100644 --- a/kubespray/project/roles/network_plugin/cilium/tasks/check.yml +++ b/kubespray/project/roles/network_plugin/cilium/tasks/check.yml @@ -61,3 +61,9 @@ when: - cilium_ipsec_enabled is defined - cilium_ipsec_enabled + +- name: Stop if cilium_hubble_event_buffer_capacity is not a power of 2 minus 1 and is not between 1 and 65535 + assert: + that: "cilium_hubble_event_buffer_capacity in [1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535]" + msg: "Error: cilium_hubble_event_buffer_capacity:{{ cilium_hubble_event_buffer_capacity }} is not a power of 2 minus 1 and it should be between 1 and 65535." + when: cilium_hubble_event_buffer_capacity is defined diff --git a/kubespray/project/roles/network_plugin/cilium/tasks/install.yml b/kubespray/project/roles/network_plugin/cilium/tasks/install.yml index d531d72..7da3964 100644 --- a/kubespray/project/roles/network_plugin/cilium/tasks/install.yml +++ b/kubespray/project/roles/network_plugin/cilium/tasks/install.yml @@ -10,7 +10,7 @@ file: dest: "{{ cilium_cert_dir }}" state: directory - mode: 0750 + mode: "0750" owner: root group: root when: @@ -20,9 +20,9 @@ file: src: "{{ etcd_cert_dir }}/{{ item.s }}" dest: "{{ cilium_cert_dir }}/{{ item.d }}" - mode: 0644 + mode: "0644" state: hard - force: yes + force: true loop: - {s: "{{ kube_etcd_cacert_file }}", d: "ca_cert.crt"} - {s: "{{ kube_etcd_cert_file }}", d: "cert.crt"} @@ -36,7 +36,7 @@ state: directory owner: root group: root - mode: 0755 + mode: "0755" when: - inventory_hostname == groups['kube_control_plane'][0] - cilium_hubble_install @@ -45,7 +45,7 @@ template: src: "{{ item.name }}/{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.name }}-{{ item.file }}" - mode: 0644 + mode: "0644" loop: - {name: cilium, file: config.yml, type: cm} - {name: cilium-operator, file: crb.yml, type: clusterrolebinding} @@ -66,7 +66,7 @@ template: src: "{{ item.name }}/{{ item.file }}.j2" dest: "{{ kube_config_dir }}/addons/hubble/{{ item.name }}-{{ item.file }}" - mode: 0644 + mode: "0644" loop: - {name: hubble, file: config.yml, type: cm} - {name: hubble, file: crb.yml, type: clusterrolebinding} @@ -86,12 +86,12 @@ template: src: 000-cilium-portmap.conflist.j2 dest: /etc/cni/net.d/000-cilium-portmap.conflist - mode: 0644 + mode: "0644" when: cilium_enable_portmap - name: Cilium | Copy Ciliumcli binary from download dir copy: src: "{{ local_release_dir }}/cilium" dest: "{{ bin_dir }}/cilium" - mode: 0755 - remote_src: yes + mode: "0755" + remote_src: true diff --git a/kubespray/project/roles/network_plugin/cilium/tasks/reset_iface.yml b/kubespray/project/roles/network_plugin/cilium/tasks/reset_iface.yml index e2f7c14..57a2d57 100644 --- a/kubespray/project/roles/network_plugin/cilium/tasks/reset_iface.yml +++ b/kubespray/project/roles/network_plugin/cilium/tasks/reset_iface.yml @@ -2,9 +2,9 @@ - name: "Reset | check if network device {{ iface }} is present" stat: path: "/sys/class/net/{{ iface }}" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: device_remains - name: "Reset | remove network device {{ iface }}" diff --git a/kubespray/project/roles/network_plugin/cilium/templates/cilium-operator/cr.yml.j2 b/kubespray/project/roles/network_plugin/cilium/templates/cilium-operator/cr.yml.j2 index 642a667..5bcc44d 100644 --- a/kubespray/project/roles/network_plugin/cilium/templates/cilium-operator/cr.yml.j2 +++ b/kubespray/project/roles/network_plugin/cilium/templates/cilium-operator/cr.yml.j2 @@ -97,6 +97,11 @@ rules: - ciliumloadbalancerippools/status - ciliumbgppeeringpolicies - ciliumenvoyconfigs +{% endif %} +{% if cilium_version | regex_replace('v') is version('1.15', '>=') %} + - ciliumbgppeerconfigs + - ciliumbgpadvertisements + - ciliumbgpnodeconfigs {% endif %} verbs: - '*' @@ -146,6 +151,20 @@ rules: - ciliumlocalredirectpolicies.cilium.io - ciliumnetworkpolicies.cilium.io - ciliumnodes.cilium.io +{% if cilium_version | regex_replace('v') is version('1.14', '>=') %} + - ciliumnodeconfigs.cilium.io + - ciliumcidrgroups.cilium.io + - ciliuml2announcementpolicies.cilium.io + - ciliumpodippools.cilium.io + - ciliumloadbalancerippools.cilium.io +{% endif %} +{% if cilium_version | regex_replace('v') is version('1.15', '>=') %} + - ciliumbgpclusterconfigs.cilium.io + - ciliumbgppeerconfigs.cilium.io + - ciliumbgpadvertisements.cilium.io + - ciliumbgpnodeconfigs.cilium.io + - ciliumbgpnodeconfigoverrides.cilium.io +{% endif %} {% endif %} {% for rules in cilium_clusterrole_rules_operator_extra_vars %} - apiGroups: diff --git a/kubespray/project/roles/network_plugin/cilium/templates/cilium/config.yml.j2 b/kubespray/project/roles/network_plugin/cilium/templates/cilium/config.yml.j2 index 9fb5f28..ed37f12 100644 --- a/kubespray/project/roles/network_plugin/cilium/templates/cilium/config.yml.j2 +++ b/kubespray/project/roles/network_plugin/cilium/templates/cilium/config.yml.j2 @@ -69,6 +69,13 @@ data: # custom-cni-conf to "true", otherwise Cilium may overwrite the configuration. custom-cni-conf: "false" +{% if cilium_version | regex_replace('v') is version('1.14.0', '>=') %} + # Tell the agent to generate and write a CNI configuration file + write-cni-conf-when-ready: /host/etc/cni/net.d/05-cilium.conflist + cni-exclusive: "{{ cilium_cni_exclusive }}" + cni-log-file: "{{ cilium_cni_log_file }}" +{% endif %} + # If you want cilium monitor to aggregate tracing for packets, set this level # to "low", "medium", or "maximum". The higher the level, the less packets # that will be seen in monitor output. @@ -124,6 +131,12 @@ data: tunnel-protocol: "{{ cilium_tunnel_mode }}" {% endif %} + ## DSR setting + bpf-lb-mode: "{{ cilium_loadbalancer_mode }}" + + # l2 + enable-l2-announcements: "{{ cilium_l2announcements }}" + # Enable Bandwidth Manager # Cilium’s bandwidth manager supports the kubernetes.io/egress-bandwidth Pod annotation. # Bandwidth enforcement currently does not work in combination with L7 Cilium Network Policies. @@ -179,6 +192,12 @@ data: {% for hubble_metrics_cycle in cilium_hubble_metrics %} {{ hubble_metrics_cycle }} {% endfor %} +{% endif %} +{% if cilium_hubble_event_buffer_capacity is defined %} + hubble-event-buffer-capacity: "{{ cilium_hubble_event_buffer_capacity }}" +{% endif %} +{% if cilium_hubble_event_queue_size is defined %} + hubble-event-queue-size: "{{ cilium_hubble_event_queue_size }}" {% endif %} hubble-listen-address: ":4244" {% if cilium_enable_hubble and cilium_hubble_install %} diff --git a/kubespray/project/roles/network_plugin/cilium/templates/cilium/cr.yml.j2 b/kubespray/project/roles/network_plugin/cilium/templates/cilium/cr.yml.j2 index 4ce747f..833076d 100644 --- a/kubespray/project/roles/network_plugin/cilium/templates/cilium/cr.yml.j2 +++ b/kubespray/project/roles/network_plugin/cilium/templates/cilium/cr.yml.j2 @@ -106,6 +106,15 @@ rules: - ciliumnodes/finalizers - ciliumidentities/finalizers - ciliumlocalredirectpolicies/finalizers +{% endif %} +{% if cilium_version | regex_replace('v') is version('1.14', '>=') %} + - ciliuml2announcementpolicies/status +{% endif %} +{% if cilium_version | regex_replace('v') is version('1.15', '>=') %} + - ciliumbgpnodeconfigs + - ciliumbgpnodeconfigs/status + - ciliumbgpadvertisements + - ciliumbgppeerconfigs {% endif %} verbs: - '*' @@ -125,7 +134,22 @@ rules: - cilium.io resources: - ciliumcidrgroups + - ciliuml2announcementpolicies + - ciliumpodippools + - ciliuml2announcementpolicies/status verbs: - list - watch +{% if cilium_version %} +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update + - list + - delete +{% endif %} {% endif %} diff --git a/kubespray/project/roles/network_plugin/cilium/templates/hubble/config.yml.j2 b/kubespray/project/roles/network_plugin/cilium/templates/hubble/config.yml.j2 index 888db41..f3af717 100644 --- a/kubespray/project/roles/network_plugin/cilium/templates/hubble/config.yml.j2 +++ b/kubespray/project/roles/network_plugin/cilium/templates/hubble/config.yml.j2 @@ -12,10 +12,10 @@ data: peer-service: "hubble-peer.kube-system.svc.{{ dns_domain }}:443" listen-address: :4245 metrics-listen-address: ":9966" - dial-timeout: - retry-timeout: - sort-buffer-len-max: - sort-buffer-drain-timeout: + dial-timeout: + retry-timeout: + sort-buffer-len-max: + sort-buffer-drain-timeout: tls-client-cert-file: /var/lib/hubble-relay/tls/client.crt tls-client-key-file: /var/lib/hubble-relay/tls/client.key tls-server-cert-file: /var/lib/hubble-relay/tls/server.crt diff --git a/kubespray/project/roles/network_plugin/cilium/templates/hubble/service.yml.j2 b/kubespray/project/roles/network_plugin/cilium/templates/hubble/service.yml.j2 index 0f862a9..48e90b8 100644 --- a/kubespray/project/roles/network_plugin/cilium/templates/hubble/service.yml.j2 +++ b/kubespray/project/roles/network_plugin/cilium/templates/hubble/service.yml.j2 @@ -102,4 +102,3 @@ spec: protocol: TCP targetPort: 4244 internalTrafficPolicy: Local - diff --git a/kubespray/project/roles/network_plugin/cni/tasks/main.yml b/kubespray/project/roles/network_plugin/cni/tasks/main.yml index bcab4ef..28376bd 100644 --- a/kubespray/project/roles/network_plugin/cni/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/cni/tasks/main.yml @@ -3,7 +3,7 @@ file: path: /opt/cni/bin state: directory - mode: 0755 + mode: "0755" owner: "{{ cni_bin_owner }}" recurse: true @@ -11,6 +11,6 @@ unarchive: src: "{{ downloads.cni.dest }}" dest: "/opt/cni/bin" - mode: 0755 + mode: "0755" owner: "{{ cni_bin_owner }}" - remote_src: yes + remote_src: true diff --git a/kubespray/project/roles/network_plugin/custom_cni/tasks/main.yml b/kubespray/project/roles/network_plugin/custom_cni/tasks/main.yml index 8f5b419..a1397c8 100644 --- a/kubespray/project/roles/network_plugin/custom_cni/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/custom_cni/tasks/main.yml @@ -12,7 +12,7 @@ template: src: "{{ item }}" dest: "{{ kube_config_dir }}/{{ item | basename | replace('.j2', '') }}" - mode: 0644 + mode: "0644" loop: "{{ custom_cni_manifests }}" delegate_to: "{{ groups['kube_control_plane'] | first }}" run_once: true diff --git a/kubespray/project/roles/network_plugin/flannel/tasks/main.yml b/kubespray/project/roles/network_plugin/flannel/tasks/main.yml index 2fd82e9..94603fc 100644 --- a/kubespray/project/roles/network_plugin/flannel/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/flannel/tasks/main.yml @@ -12,7 +12,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: flannel, file: cni-flannel-rbac.yml, type: sa} - {name: kube-flannel, file: cni-flannel.yml, type: ds} diff --git a/kubespray/project/roles/network_plugin/flannel/tasks/reset.yml b/kubespray/project/roles/network_plugin/flannel/tasks/reset.yml index 03d40a0..c4b1b88 100644 --- a/kubespray/project/roles/network_plugin/flannel/tasks/reset.yml +++ b/kubespray/project/roles/network_plugin/flannel/tasks/reset.yml @@ -2,9 +2,9 @@ - name: Reset | check cni network device stat: path: /sys/class/net/cni0 - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: cni - name: Reset | remove the network device created by the flannel @@ -14,9 +14,9 @@ - name: Reset | check flannel network device stat: path: /sys/class/net/flannel.1 - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: flannel - name: Reset | remove the network device created by the flannel diff --git a/kubespray/project/roles/network_plugin/kube-ovn/defaults/main.yml b/kubespray/project/roles/network_plugin/kube-ovn/defaults/main.yml index 44850e5..8b96207 100644 --- a/kubespray/project/roles/network_plugin/kube-ovn/defaults/main.yml +++ b/kubespray/project/roles/network_plugin/kube-ovn/defaults/main.yml @@ -115,4 +115,4 @@ kube_ovn_ls_dnat_mod_dl_dst: true kube_ovn_keep_vm_ip: true ## cni config priority, default: 01 -kube_ovn_cni_config_priority: 01 +kube_ovn_cni_config_priority: '01' diff --git a/kubespray/project/roles/network_plugin/kube-ovn/tasks/main.yml b/kubespray/project/roles/network_plugin/kube-ovn/tasks/main.yml index ab45b62..a8b9427 100644 --- a/kubespray/project/roles/network_plugin/kube-ovn/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/kube-ovn/tasks/main.yml @@ -9,7 +9,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: kube-ovn-crd, file: cni-kube-ovn-crd.yml} - {name: ovn, file: cni-ovn.yml} diff --git a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn-crd.yml.j2 b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn-crd.yml.j2 index 379381d..c531ffc 100644 --- a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn-crd.yml.j2 +++ b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn-crd.yml.j2 @@ -39,6 +39,10 @@ spec: type: string subnet: type: string + replicas: + type: integer + minimum: 1 + maximum: 3 status: type: object properties: @@ -129,6 +133,10 @@ spec: items: type: string type: array + endpoints: + items: + type: string + type: array status: type: object properties: @@ -165,23 +173,25 @@ spec: name: v1 served: true storage: true + subresources: + status: {} schema: openAPIV3Schema: type: object properties: - spec: + status: type: object properties: - lanIp: - type: string - subnet: - type: string - vpc: - type: string + externalSubnets: + items: + type: string + type: array selector: type: array items: type: string + qosPolicy: + type: string tolerations: type: array items: @@ -191,12 +201,600 @@ spec: type: string operator: type: string + enum: + - Equal + - Exists value: type: string effect: type: string + enum: + - NoExecute + - NoSchedule + - PreferNoSchedule tolerationSeconds: type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + spec: + type: object + properties: + lanIp: + type: string + subnet: + type: string + externalSubnets: + items: + type: string + type: array + vpc: + type: string + selector: + type: array + items: + type: string + qosPolicy: + type: string + tolerations: + type: array + items: + type: object + properties: + key: + type: string + operator: + type: string + enum: + - Equal + - Exists + value: + type: string + effect: + type: string + enum: + - NoExecute + - NoSchedule + - PreferNoSchedule + tolerationSeconds: + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + x-kubernetes-patch-strategy: merge + x-kubernetes-patch-merge-key: key + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -249,6 +847,8 @@ spec: type: string redo: type: string + qosPolicy: + type: string conditions: type: array items: @@ -277,6 +877,10 @@ spec: type: string natGwDp: type: string + qosPolicy: + type: string + externalSubnet: + type: string --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -334,6 +938,8 @@ spec: type: string redo: type: string + internalIp: + type: string conditions: type: array items: @@ -519,6 +1125,8 @@ spec: type: string redo: type: string + internalCIDR: + type: string conditions: type: array items: @@ -565,15 +1173,24 @@ spec: subresources: status: {} additionalPrinterColumns: - - jsonPath: .spec.v4ip - name: IP + - jsonPath: .status.v4Ip + name: V4IP type: string - - jsonPath: .spec.macAddress + - jsonPath: .status.v6Ip + name: V6IP + type: string + - jsonPath: .status.macAddress name: Mac type: string - - jsonPath: .spec.type + - jsonPath: .status.type name: Type type: string + - jsonPath: .status.nat + name: Nat + type: string + - jsonPath: .status.ready + name: Ready + type: boolean schema: openAPIV3Schema: type: object @@ -581,8 +1198,16 @@ spec: status: type: object properties: + type: + type: string + nat: + type: string + ready: + type: boolean v4Ip: type: string + v6Ip: + type: string macAddress: type: string conditions: @@ -609,7 +1234,9 @@ spec: type: string type: type: string - v4ip: + v4Ip: + type: string + v6Ip: type: string macAddress: type: string @@ -647,6 +1274,12 @@ spec: - jsonPath: .status.ready name: Ready type: boolean + - jsonPath: .spec.ipType + name: IpType + type: string + - jsonPath: .spec.ipName + name: IpName + type: string schema: openAPIV3Schema: type: object @@ -660,8 +1293,6 @@ spec: type: string v4Ip: type: string - macAddress: - type: string vpc: type: string conditions: @@ -686,8 +1317,14 @@ spec: properties: ovnEip: type: string + ipType: + type: string ipName: type: string + vpc: + type: string + v4Ip: + type: string --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -716,8 +1353,8 @@ spec: - jsonPath: .status.v4Eip name: V4Eip type: string - - jsonPath: .status.v4ipCidr - name: V4Ip + - jsonPath: .status.v4IpCidr + name: V4IpCidr type: string - jsonPath: .status.ready name: Ready @@ -733,7 +1370,7 @@ spec: type: boolean v4Eip: type: string - v4ipCidr: + v4IpCidr: type: string vpc: type: string @@ -763,6 +1400,118 @@ spec: type: string ipName: type: string + vpc: + type: string + v4IpCidr: + type: string +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: ovn-dnat-rules.kubeovn.io +spec: + group: kubeovn.io + names: + plural: ovn-dnat-rules + singular: ovn-dnat-rule + shortNames: + - odnat + kind: OvnDnatRule + listKind: OvnDnatRuleList + scope: Cluster + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.vpc + name: Vpc + type: string + - jsonPath: .spec.ovnEip + name: Eip + type: string + - jsonPath: .status.protocol + name: Protocol + type: string + - jsonPath: .status.v4Eip + name: V4Eip + type: string + - jsonPath: .status.v4Ip + name: V4Ip + type: string + - jsonPath: .status.internalPort + name: InternalPort + type: string + - jsonPath: .status.externalPort + name: ExternalPort + type: string + - jsonPath: .spec.ipName + name: IpName + type: string + - jsonPath: .status.ready + name: Ready + type: boolean + schema: + openAPIV3Schema: + type: object + properties: + status: + type: object + properties: + ready: + type: boolean + v4Eip: + type: string + v4Ip: + type: string + vpc: + type: string + externalPort: + type: string + internalPort: + type: string + protocol: + type: string + ipName: + type: string + conditions: + type: array + items: + type: object + properties: + type: + type: string + status: + type: string + reason: + type: string + message: + type: string + lastUpdateTime: + type: string + lastTransitionTime: + type: string + spec: + type: object + properties: + ovnEip: + type: string + ipType: + type: string + ipName: + type: string + externalPort: + type: string + internalPort: + type: string + protocol: + type: string + vpc: + type: string + v4Ip: + type: string --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -775,12 +1524,18 @@ spec: - jsonPath: .status.enableExternal name: EnableExternal type: boolean + - jsonPath: .status.enableBfd + name: EnableBfd + type: boolean - jsonPath: .status.standby name: Standby type: boolean - jsonPath: .status.subnets name: Subnets type: string + - jsonPath: .status.extraExternalSubnets + name: ExtraExternalSubnets + type: string - jsonPath: .spec.namespaces name: Namespaces type: string @@ -792,10 +1547,16 @@ spec: properties: enableExternal: type: boolean + enableBfd: + type: boolean namespaces: items: type: string type: array + extraExternalSubnets: + items: + type: string + type: array staticRoutes: items: properties: @@ -805,6 +1566,12 @@ spec: type: string nextHopIP: type: string + ecmpMode: + type: string + bfdId: + type: string + routeTable: + type: string type: object type: array policyRoutes: @@ -859,10 +1626,16 @@ spec: type: boolean enableExternal: type: boolean + enableBfd: + type: boolean subnets: items: type: string type: array + extraExternalSubnets: + items: + type: string + type: array vpcPeerings: items: type: string @@ -989,27 +1762,24 @@ spec: - name: V4IP type: string jsonPath: .status.v4ip - - name: PV4IP + - name: V6IP type: string - jsonPath: .spec.parentV4ip + jsonPath: .status.v6ip - name: Mac type: string jsonPath: .status.mac - name: PMac type: string jsonPath: .spec.parentMac - - name: V6IP - type: string - jsonPath: .status.v6ip - - name: PV6IP - type: string - jsonPath: .spec.parentV6ip - name: Subnet type: string jsonPath: .spec.subnet - jsonPath: .status.ready name: Ready type: boolean + - jsonPath: .status.type + name: Type + type: string schema: openAPIV3Schema: type: object @@ -1017,6 +1787,8 @@ spec: status: type: object properties: + type: + type: string ready: type: boolean v4ip: @@ -1055,6 +1827,8 @@ spec: type: string subnet: type: string + type: + type: string attachSubnets: type: array items: @@ -1131,6 +1905,12 @@ spec: openAPIV3Schema: type: object properties: + metadata: + type: object + properties: + name: + type: string + pattern: ^[^0-9] status: type: object properties: @@ -1150,6 +1930,35 @@ spec: type: string u2oInterconnectionIP: type: string + u2oInterconnectionVPC: + type: string + v4usingIPrange: + type: string + v4availableIPrange: + type: string + v6usingIPrange: + type: string + v6availableIPrange: + type: string + natOutgoingPolicyRules: + type: array + items: + type: object + properties: + ruleID: + type: string + action: + type: string + enum: + - nat + - forward + match: + type: object + properties: + srcIPs: + type: string + dstIPs: + type: string conditions: type: array items: @@ -1208,8 +2017,6 @@ spec: type: string natOutgoing: type: boolean - u2oRouting: - type: boolean externalEgressGateway: type: string policyRoutingPriority: @@ -1226,6 +2033,10 @@ spec: - 253 # default - 254 # main - 255 # local + mtu: + type: integer + minimum: 68 + maximum: 65535 private: type: boolean vlan: @@ -1270,8 +2081,35 @@ spec: - allow - drop - reject + natOutgoingPolicyRules: + type: array + items: + type: object + properties: + action: + type: string + enum: + - nat + - forward + match: + type: object + properties: + srcIPs: + type: string + dstIPs: + type: string u2oInterconnection: type: boolean + u2oInterconnectionIP: + type: string + enableLb: + type: boolean + enableEcmp: + type: boolean + enableMulticastSnoop: + type: boolean + routeTable: + type: string scope: Cluster names: plural: subnets @@ -1282,6 +2120,113 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + name: ippools.kubeovn.io +spec: + group: kubeovn.io + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - name: Subnet + type: string + jsonPath: .spec.subnet + - name: IPs + type: string + jsonPath: .spec.ips + - name: V4Used + type: number + jsonPath: .status.v4UsingIPs + - name: V4Available + type: number + jsonPath: .status.v4AvailableIPs + - name: V6Used + type: number + jsonPath: .status.v6UsingIPs + - name: V6Available + type: number + jsonPath: .status.v6AvailableIPs + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + subnet: + type: string + x-kubernetes-validations: + - rule: "self == oldSelf" + message: "This field is immutable." + namespaces: + type: array + x-kubernetes-list-type: set + items: + type: string + ips: + type: array + minItems: 1 + x-kubernetes-list-type: set + items: + type: string + anyOf: + - format: ipv4 + - format: ipv6 + - format: cidr + - pattern: ^(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.\.(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])$ + - pattern: ^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|:)))\.\.((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|:)))$ + required: + - subnet + - ips + status: + type: object + properties: + v4AvailableIPs: + type: number + v4UsingIPs: + type: number + v6AvailableIPs: + type: number + v6UsingIPs: + type: number + v4AvailableIPRange: + type: string + v4UsingIPRange: + type: string + v6AvailableIPRange: + type: string + v6UsingIPRange: + type: string + conditions: + type: array + items: + type: object + properties: + type: + type: string + status: + type: string + reason: + type: string + message: + type: string + lastUpdateTime: + type: string + lastTransitionTime: + type: string + scope: Cluster + names: + plural: ippools + singular: ippool + kind: IPPool + shortNames: + - ippool +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: name: vlans.kubeovn.io spec: @@ -1360,7 +2305,6 @@ spec: not: enum: - int - - external spec: type: object properties: @@ -1530,4 +2474,114 @@ spec: subresources: status: {} conversion: - strategy: None \ No newline at end of file + strategy: None +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: qos-policies.kubeovn.io +spec: + group: kubeovn.io + names: + plural: qos-policies + singular: qos-policy + shortNames: + - qos + kind: QoSPolicy + listKind: QoSPolicyList + scope: Cluster + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .spec.shared + name: Shared + type: string + - jsonPath: .spec.bindingType + name: BindingType + type: string + schema: + openAPIV3Schema: + type: object + properties: + status: + type: object + properties: + shared: + type: boolean + bindingType: + type: string + bandwidthLimitRules: + type: array + items: + type: object + properties: + name: + type: string + interface: + type: string + rateMax: + type: string + burstMax: + type: string + priority: + type: integer + direction: + type: string + matchType: + type: string + matchValue: + type: string + conditions: + type: array + items: + type: object + properties: + type: + type: string + status: + type: string + reason: + type: string + message: + type: string + lastUpdateTime: + type: string + lastTransitionTime: + type: string + spec: + type: object + properties: + shared: + type: boolean + bindingType: + type: string + bandwidthLimitRules: + type: array + items: + type: object + properties: + name: + type: string + interface: + type: string + rateMax: + type: string + burstMax: + type: string + priority: + type: integer + direction: + type: string + matchType: + type: string + matchValue: + type: string + required: + - name + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map diff --git a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn.yml.j2 b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn.yml.j2 index cee7ccb..f4acded 100644 --- a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn.yml.j2 +++ b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-kube-ovn.yml.j2 @@ -1,4 +1,190 @@ --- +kind: ConfigMap +apiVersion: v1 +metadata: + name: ovn-vpc-nat-config + namespace: kube-system + annotations: + kubernetes.io/description: | + kube-ovn vpc-nat common config +data: + image: {{ kube_ovn_vpc_container_image_repo }}:{{ kube_ovn_vpc_container_image_tag }} +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: ovn-vpc-nat-gw-config + namespace: kube-system +data: + enable-vpc-nat-gw: "true" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kube-ovn-cni + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + rbac.authorization.k8s.io/system-only: "true" + name: system:kube-ovn-cni +rules: + - apiGroups: + - "kubeovn.io" + resources: + - subnets + - vlans + - provider-networks + verbs: + - get + - list + - watch + - apiGroups: + - "" + - "kubeovn.io" + resources: + - ovn-eips + - ovn-eips/status + - nodes + - pods + - vlans + verbs: + - get + - list + - patch + - watch + - apiGroups: + - "kubeovn.io" + resources: + - ips + verbs: + - get + - update + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kube-ovn-cni +roleRef: + name: system:kube-ovn-cni + kind: ClusterRole + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: kube-ovn-cni + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-cni + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-cni + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kube-ovn-app + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + rbac.authorization.k8s.io/system-only: "true" + name: system:kube-ovn-app +rules: + - apiGroups: + - "" + resources: + - pods + - nodes + verbs: + - get + - list + - apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kube-ovn-app +roleRef: + name: system:kube-ovn-app + kind: ClusterRole + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: kube-ovn-app + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-app + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-app + namespace: kube-system +--- kind: Deployment apiVersion: apps/v1 metadata: @@ -25,8 +211,20 @@ spec: type: infra spec: tolerations: - - operator: Exists + - effect: NoSchedule + operator: Exists + - key: CriticalAddonsOnly + operator: Exists affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: "ovn.kubernetes.io/ic-gw" + operator: NotIn + values: + - "true" + weight: 100 podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: @@ -67,7 +265,12 @@ spec: - --log_file_max_size=0 - --enable-lb-svc=false - --keep-vm-ip={{ kube_ovn_keep_vm_ip }} - - --pod-default-fip-type="" + securityContext: + runAsUser: 0 + privileged: false + capabilities: + add: + - NET_BIND_SERVICE env: - name: ENABLE_SSL value: "{{ kube_ovn_enable_ssl | lower }}" @@ -85,6 +288,10 @@ spec: fieldPath: spec.nodeName - name: OVN_DB_IPS value: "{{ kube_ovn_central_ips }}" + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: @@ -96,18 +303,24 @@ spec: name: localtime - mountPath: /var/log/kube-ovn name: kube-ovn-log + - mountPath: /var/log/ovn + name: ovn-log - mountPath: /var/run/tls name: kube-ovn-tls readinessProbe: exec: command: - - /kube-ovn/kube-ovn-controller-healthcheck + - /kube-ovn/kube-ovn-healthcheck + - --port=10660 + - --tls=false periodSeconds: 3 timeoutSeconds: 45 livenessProbe: exec: command: - - /kube-ovn/kube-ovn-controller-healthcheck + - /kube-ovn/kube-ovn-healthcheck + - --port=10660 + - --tls=false initialDelaySeconds: 300 periodSeconds: 7 failureThreshold: 5 @@ -128,6 +341,9 @@ spec: - name: kube-ovn-log hostPath: path: /var/log/kube-ovn + - name: ovn-log + hostPath: + path: /var/log/ovn - name: kube-ovn-tls secret: optional: true @@ -161,7 +377,7 @@ spec: - key: CriticalAddonsOnly operator: Exists priorityClassName: system-node-critical - serviceAccountName: ovn + serviceAccountName: kube-ovn-cni hostNetwork: true hostPID: true initContainers: @@ -202,7 +418,13 @@ spec: - --log_file_max_size=0 securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - NET_RAW + - SYS_ADMIN env: - name: ENABLE_SSL value: "{{ kube_ovn_enable_ssl | lower }}" @@ -231,14 +453,15 @@ spec: mountPath: /lib/modules readOnly: true - name: shared-dir - mountPath: /var/lib/kubelet/pods + mountPath: $KUBELET_DIR/pods - mountPath: /etc/openvswitch name: systemid + readOnly: true - mountPath: /etc/cni/net.d name: cni-conf - mountPath: /run/openvswitch name: host-run-ovs - mountPropagation: Bidirectional + mountPropagation: HostToContainer - mountPath: /run/ovn name: host-run-ovn - mountPath: /host/var/run/dbus @@ -255,6 +478,7 @@ spec: name: host-log-ovn - mountPath: /etc/localtime name: localtime + readOnly: true - mountPath: /tmp name: tmp livenessProbe: @@ -262,17 +486,22 @@ spec: initialDelaySeconds: 30 periodSeconds: 7 successThreshold: 1 - tcpSocket: - port: 10665 - timeoutSeconds: 3 + exec: + command: + - /kube-ovn/kube-ovn-healthcheck + - --port=10665 + - --tls=false + timeoutSeconds: 5 readinessProbe: failureThreshold: 3 - initialDelaySeconds: 30 periodSeconds: 7 successThreshold: 1 - tcpSocket: - port: 10665 - timeoutSeconds: 3 + exec: + command: + - /kube-ovn/kube-ovn-healthcheck + - --port=10665 + - --tls=false + timeoutSeconds: 5 resources: requests: cpu: {{ kube_ovn_cni_server_cpu_request }} @@ -389,28 +618,23 @@ spec: fieldRef: fieldPath: spec.nodeName volumeMounts: - - mountPath: /lib/modules - name: host-modules - readOnly: true - - mountPath: /run/openvswitch - name: host-run-ovs - mountPath: /var/run/openvswitch name: host-run-ovs - mountPath: /var/run/ovn name: host-run-ovn - - mountPath: /sys - name: host-sys - readOnly: true - mountPath: /etc/openvswitch name: host-config-openvswitch - mountPath: /var/log/openvswitch name: host-log-ovs + readOnly: true - mountPath: /var/log/ovn name: host-log-ovn + readOnly: true - mountPath: /var/log/kube-ovn name: kube-ovn-log - mountPath: /etc/localtime name: localtime + readOnly: true - mountPath: /var/run/tls name: kube-ovn-tls resources: @@ -423,18 +647,12 @@ spec: nodeSelector: kubernetes.io/os: "linux" volumes: - - name: host-modules - hostPath: - path: /lib/modules - name: host-run-ovs hostPath: path: /run/openvswitch - name: host-run-ovn hostPath: path: /run/ovn - - name: host-sys - hostPath: - path: /sys - name: host-config-openvswitch hostPath: path: /etc/origin/openvswitch @@ -500,6 +718,12 @@ spec: image: {{ kube_ovn_container_image_repo }}:{{ kube_ovn_container_image_tag }} imagePullPolicy: {{ k8s_image_pull_policy }} command: ["/kube-ovn/start-ovn-monitor.sh"] + args: + - --secure-serving=false + - --log_file=/var/log/kube-ovn/kube-ovn-monitor.log + - --logtostderr=false + - --alsologtostderr=true + - --log_file_max_size=200 securityContext: runAsUser: 0 privileged: false @@ -510,6 +734,10 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: @@ -532,30 +760,38 @@ spec: name: host-config-openvswitch - mountPath: /etc/ovn name: host-config-ovn - - mountPath: /var/log/openvswitch - name: host-log-ovs - mountPath: /var/log/ovn name: host-log-ovn + readOnly: true - mountPath: /etc/localtime name: localtime + readOnly: true - mountPath: /var/run/tls name: kube-ovn-tls - readinessProbe: - exec: - command: - - cat - - /var/run/ovn/ovn-controller.pid - periodSeconds: 10 - timeoutSeconds: 45 + - mountPath: /var/log/kube-ovn + name: kube-ovn-log livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 7 + successThreshold: 1 exec: command: - - cat - - /var/run/ovn/ovn-controller.pid + - /kube-ovn/kube-ovn-healthcheck + - --port=10661 + - --tls=false + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 3 initialDelaySeconds: 30 - periodSeconds: 10 - failureThreshold: 5 - timeoutSeconds: 45 + periodSeconds: 7 + successThreshold: 1 + exec: + command: + - /kube-ovn/kube-ovn-healthcheck + - --port=10661 + - --tls=false + timeoutSeconds: 5 nodeSelector: kubernetes.io/os: "linux" kube-ovn/role: "master" @@ -585,6 +821,9 @@ spec: secret: optional: true secretName: kube-ovn-tls + - name: kube-ovn-log + hostPath: + path: /var/log/kube-ovn --- kind: Service apiVersion: v1 @@ -655,7 +894,7 @@ spec: ports: - port: 10665 name: metrics - {% if kube_ovn_ic_enable %} +{% if kube_ovn_ic_enable %} --- kind: ConfigMap apiVersion: v1 diff --git a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-ovn.yml.j2 b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-ovn.yml.j2 index d632f3b..453ac60 100644 --- a/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-ovn.yml.j2 +++ b/kubespray/project/roles/network_plugin/kube-ovn/templates/cni-ovn.yml.j2 @@ -1,6 +1,54 @@ --- apiVersion: v1 kind: ServiceAccount +metadata: + name: ovn-ovs + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + rbac.authorization.k8s.io/system-only: "true" + name: system:ovn-ovs +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - patch + - apiGroups: + - "" + resources: + - services + - endpoints + verbs: + - get + - apiGroups: + - apps + resources: + - controllerrevisions + verbs: + - get + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ovn-ovs +roleRef: + name: system:ovn-ovs + kind: ClusterRole + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: ovn-ovs + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount metadata: name: ovn namespace: kube-system @@ -18,8 +66,11 @@ rules: - vpcs - vpcs/status - vpc-nat-gateways + - vpc-nat-gateways/status - subnets - subnets/status + - ippools + - ippools/status - ips - vips - vips/status @@ -43,59 +94,98 @@ rules: - ovn-eips/status - ovn-fips/status - ovn-snat-rules/status + - ovn-dnat-rules + - ovn-dnat-rules/status - switch-lb-rules - switch-lb-rules/status - vpc-dnses - vpc-dnses/status + - qos-policies + - qos-policies/status verbs: - "*" - apiGroups: - "" resources: - pods - - pods/exec - namespaces - - nodes - - configmaps verbs: - - create - get - list + - patch - watch + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list - patch - update + - watch + - apiGroups: + - "" + resources: + - pods/exec + verbs: + - create - apiGroups: - "k8s.cni.cncf.io" resources: - network-attachment-definitions verbs: - - create - - delete - get - - list - - update - apiGroups: - "" - networking.k8s.io - - apps - - extensions resources: - networkpolicies - - services - - services/status - - endpoints - - statefulsets - - daemonsets - - deployments - - deployments/scale + - configmaps verbs: - - create - - delete - - update - - patch - get - list - watch + - apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - apiGroups: + - "" + resources: + - services + - services/status + verbs: + - get + - list + - update + - create + - delete + - watch + - apiGroups: + - "" + resources: + - endpoints + verbs: + - create + - update + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - deployments/scale + verbs: + - get + - list + - create + - delete + - update - apiGroups: - "" resources: @@ -118,6 +208,18 @@ rules: verbs: - get - list + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -132,6 +234,20 @@ subjects: name: ovn namespace: kube-system --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ovn + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: ovn + namespace: kube-system +--- kind: Service apiVersion: v1 metadata: @@ -218,7 +334,12 @@ spec: type: infra spec: tolerations: - - operator: Exists + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + - key: CriticalAddonsOnly + operator: Exists affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -227,7 +348,7 @@ spec: app: ovn-central topologyKey: kubernetes.io/hostname priorityClassName: system-cluster-critical - serviceAccountName: ovn + serviceAccountName: ovn-ovs hostNetwork: true containers: - name: ovn-central @@ -236,7 +357,9 @@ spec: command: ["/kube-ovn/start-db.sh"] securityContext: capabilities: - add: ["SYS_NICE"] + add: + - NET_BIND_SERVICE + - SYS_NICE env: - name: ENABLE_SSL value: "{{ kube_ovn_enable_ssl | lower }}" @@ -260,6 +383,12 @@ spec: fieldPath: status.podIPs - name: ENABLE_BIND_LOCAL_IP value: "{{ kube_ovn_bind_local_ip_enabled }}" + - name: PROBE_INTERVAL + value: "180000" + - name: OVN_NORTHD_PROBE_INTERVAL + value: "5000" + - name: OVN_LEADER_PROBE_INTERVAL + value: "5" resources: requests: cpu: {{ kube_ovn_db_cpu_request }} @@ -349,7 +478,10 @@ spec: matchLabels: app: ovs updateStrategy: - type: OnDelete + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 template: metadata: labels: @@ -358,9 +490,14 @@ spec: type: infra spec: tolerations: - - operator: Exists + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + - key: CriticalAddonsOnly + operator: Exists priorityClassName: system-node-critical - serviceAccountName: ovn + serviceAccountName: ovn-ovs hostNetwork: true hostPID: true containers: @@ -371,7 +508,13 @@ spec: command: [{% if kube_ovn_dpdk_enabled %}"/kube-ovn/start-ovs-dpdk.sh"{% else %}"/kube-ovn/start-ovs.sh"{% endif %}] securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - SYS_MODULE + - SYS_NICE env: - name: ENABLE_SSL value: "{{ kube_ovn_enable_ssl | lower }}" @@ -379,6 +522,14 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace {% if not kube_ovn_dpdk_enabled %} - name: HW_OFFLOAD value: "{{ kube_ovn_hw_offload | string | lower }}" @@ -425,6 +576,9 @@ spec: name: localtime - mountPath: /var/run/tls name: kube-ovn-tls + - mountPath: /var/run/containerd + name: cruntime + readOnly: true readinessProbe: exec: command: @@ -511,6 +665,9 @@ spec: - name: localtime hostPath: path: /etc/localtime + - name: cruntime + hostPath: + path: /var/run/containerd - name: kube-ovn-tls secret: optional: true diff --git a/kubespray/project/roles/network_plugin/kube-router/tasks/main.yml b/kubespray/project/roles/network_plugin/kube-router/tasks/main.yml index b6367f0..d47a0d1 100644 --- a/kubespray/project/roles/network_plugin/kube-router/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/kube-router/tasks/main.yml @@ -9,13 +9,13 @@ state: directory owner: "{{ kube_owner }}" recurse: true - mode: 0755 + mode: "0755" - name: Kube-router | Create kubeconfig template: src: kubeconfig.yml.j2 dest: /var/lib/kube-router/kubeconfig - mode: 0644 + mode: "0644" owner: "{{ kube_owner }}" notify: - Reset_kube_router @@ -43,7 +43,7 @@ template: src: cni-conf.json.j2 dest: /etc/cni/net.d/10-kuberouter.conflist - mode: 0644 + mode: "0644" owner: "{{ kube_owner }}" notify: - Reset_kube_router @@ -57,6 +57,6 @@ template: src: kube-router.yml.j2 dest: "{{ kube_config_dir }}/kube-router.yml" - mode: 0644 + mode: "0644" delegate_to: "{{ groups['kube_control_plane'] | first }}" run_once: true diff --git a/kubespray/project/roles/network_plugin/kube-router/tasks/reset.yml b/kubespray/project/roles/network_plugin/kube-router/tasks/reset.yml index ae9ee55..32f7075 100644 --- a/kubespray/project/roles/network_plugin/kube-router/tasks/reset.yml +++ b/kubespray/project/roles/network_plugin/kube-router/tasks/reset.yml @@ -2,9 +2,9 @@ - name: Reset | check kube-dummy-if network device stat: path: /sys/class/net/kube-dummy-if - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kube_dummy_if - name: Reset | remove the network device created by kube-router @@ -14,9 +14,9 @@ - name: Check kube-bridge exists stat: path: /sys/class/net/kube-bridge - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kube_bridge_if - name: Reset | donw the network bridge create by kube-router diff --git a/kubespray/project/roles/network_plugin/macvlan/tasks/main.yml b/kubespray/project/roles/network_plugin/macvlan/tasks/main.yml index f7c3027..6ffe334 100644 --- a/kubespray/project/roles/network_plugin/macvlan/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/macvlan/tasks/main.yml @@ -23,7 +23,7 @@ template: src: debian-network-macvlan.cfg.j2 dest: /etc/network/interfaces.d/60-mac0.cfg - mode: 0644 + mode: "0644" notify: Macvlan | restart network when: ansible_os_family in ["Debian"] @@ -53,7 +53,7 @@ template: src: "{{ item.src }}.j2" dest: "/etc/sysconfig/network-scripts/{{ item.dst }}" - mode: 0644 + mode: "0644" with_items: - {src: centos-network-macvlan.cfg, dst: ifcfg-mac0 } - {src: centos-routes-macvlan.cfg, dst: route-mac0 } @@ -67,7 +67,7 @@ template: src: coreos-service-nat_ouside.j2 dest: /etc/systemd/system/enable_nat_ouside.service - mode: 0644 + mode: "0644" when: enable_nat_default_gateway - name: Macvlan | Enable service nat via gateway on Flatcar Container Linux @@ -81,7 +81,7 @@ template: src: "{{ item.src }}.j2" dest: "/etc/systemd/network/{{ item.dst }}" - mode: 0644 + mode: "0644" with_items: - {src: coreos-device-macvlan.cfg, dst: macvlan.netdev } - {src: coreos-interface-macvlan.cfg, dst: output.network } @@ -92,19 +92,19 @@ template: src: 10-macvlan.conf.j2 dest: /etc/cni/net.d/10-macvlan.conf - mode: 0644 + mode: "0644" - name: Macvlan | Install loopback definition for Macvlan template: src: 99-loopback.conf.j2 dest: /etc/cni/net.d/99-loopback.conf - mode: 0644 + mode: "0644" - name: Enable net.ipv4.conf.all.arp_notify in sysctl ansible.posix.sysctl: name: net.ipv4.conf.all.arp_notify value: 1 - sysctl_set: yes + sysctl_set: true sysctl_file: "{{ sysctl_file_path }}" state: present - reload: yes + reload: true diff --git a/kubespray/project/roles/network_plugin/multus/tasks/main.yml b/kubespray/project/roles/network_plugin/multus/tasks/main.yml index 1428929..0869da7 100644 --- a/kubespray/project/roles/network_plugin/multus/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/multus/tasks/main.yml @@ -3,7 +3,7 @@ copy: src: "{{ item.file }}" dest: "{{ kube_config_dir }}" - mode: 0644 + mode: "0644" with_items: - {name: multus-crd, file: multus-crd.yml, type: customresourcedefinition} - {name: multus-serviceaccount, file: multus-serviceaccount.yml, type: serviceaccount} @@ -20,7 +20,7 @@ template: src: multus-daemonset.yml.j2 dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: multus-daemonset-containerd, file: multus-daemonset-containerd.yml, type: daemonset, engine: containerd } - {name: multus-daemonset-docker, file: multus-daemonset-docker.yml, type: daemonset, engine: docker } diff --git a/kubespray/project/roles/network_plugin/ovn4nfv/tasks/main.yml b/kubespray/project/roles/network_plugin/ovn4nfv/tasks/main.yml index 777fd9a..a16f3ec 100644 --- a/kubespray/project/roles/network_plugin/ovn4nfv/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/ovn4nfv/tasks/main.yml @@ -9,7 +9,7 @@ template: src: "{{ item.file }}.j2" dest: "{{ kube_config_dir }}/{{ item.file }}" - mode: 0644 + mode: "0644" with_items: - {name: ovn-daemonset, file: ovn-daemonset.yml} - {name: ovn4nfv-k8s-plugin, file: ovn4nfv-k8s-plugin.yml} diff --git a/kubespray/project/roles/network_plugin/weave/tasks/main.yml b/kubespray/project/roles/network_plugin/weave/tasks/main.yml index ae4a5a4..ccb4313 100644 --- a/kubespray/project/roles/network_plugin/weave/tasks/main.yml +++ b/kubespray/project/roles/network_plugin/weave/tasks/main.yml @@ -3,10 +3,10 @@ template: src: weave-net.yml.j2 dest: "{{ kube_config_dir }}/weave-net.yml" - mode: 0644 + mode: "0644" - name: Weave | Fix nodePort for Weave template: src: 10-weave.conflist.j2 dest: /etc/cni/net.d/10-weave.conflist - mode: 0644 + mode: "0644" diff --git a/kubespray/project/roles/recover_control_plane/etcd/tasks/main.yml b/kubespray/project/roles/recover_control_plane/etcd/tasks/main.yml index 599f56b..6291ea3 100644 --- a/kubespray/project/roles/recover_control_plane/etcd/tasks/main.yml +++ b/kubespray/project/roles/recover_control_plane/etcd/tasks/main.yml @@ -4,7 +4,7 @@ register: etcd_endpoint_health ignore_errors: true # noqa ignore-errors changed_when: false - check_mode: no + check_mode: false environment: ETCDCTL_API: "3" ETCDCTL_ENDPOINTS: "{{ etcd_access_addresses }}" @@ -64,7 +64,7 @@ command: "{{ bin_dir }}/etcdctl member list" register: member_list changed_when: false - check_mode: no + check_mode: false environment: ETCDCTL_API: "3" ETCDCTL_ENDPOINTS: "{{ etcd_access_addresses }}" diff --git a/kubespray/project/roles/recover_control_plane/etcd/tasks/recover_lost_quorum.yml b/kubespray/project/roles/recover_control_plane/etcd/tasks/recover_lost_quorum.yml index 3889628..7c8b0e9 100644 --- a/kubespray/project/roles/recover_control_plane/etcd/tasks/recover_lost_quorum.yml +++ b/kubespray/project/roles/recover_control_plane/etcd/tasks/recover_lost_quorum.yml @@ -13,11 +13,11 @@ copy: src: "{{ etcd_snapshot }}" dest: /tmp/snapshot.db - mode: 0640 + mode: "0640" when: etcd_snapshot is defined - name: Stop etcd - systemd: + systemd_service: name: etcd state: stopped @@ -54,6 +54,6 @@ replace: '\1{{ etcd_member_name }}={{ etcd_peer_url }}' - name: Start etcd - systemd: + systemd_service: name: etcd state: started diff --git a/kubespray/project/roles/remove-node/remove-etcd-node/tasks/main.yml b/kubespray/project/roles/remove-node/remove-etcd-node/tasks/main.yml index 0279018..f0f0e17 100644 --- a/kubespray/project/roles/remove-node/remove-etcd-node/tasks/main.yml +++ b/kubespray/project/roles/remove-node/remove-etcd-node/tasks/main.yml @@ -26,13 +26,13 @@ - inventory_hostname in groups['etcd'] - name: Lookup etcd member id - shell: "set -o pipefail && {{ bin_dir }}/etcdctl member list | grep {{ node_ip }} | cut -d, -f1" + shell: "set -o pipefail && {{ bin_dir }}/etcdctl member list | grep -w {{ node_ip }} | cut -d, -f1" args: executable: /bin/bash register: etcd_member_id ignore_errors: true # noqa ignore-errors changed_when: false - check_mode: no + check_mode: false tags: - facts environment: diff --git a/kubespray/project/roles/reset/defaults/main.yml b/kubespray/project/roles/reset/defaults/main.yml index b63f2e2..1e84da7 100644 --- a/kubespray/project/roles/reset/defaults/main.yml +++ b/kubespray/project/roles/reset/defaults/main.yml @@ -6,12 +6,13 @@ reset_restart_network_service_name: >- {% if ansible_os_family == "RedHat" -%} {%- if ansible_distribution_major_version | int >= 8 - or is_fedora_coreos or ansible_distribution == "Fedora" -%} + or is_fedora_coreos or ansible_distribution in ["Fedora", "Kylin Linux Advanced Server", "TencentOS"] -%} NetworkManager {%- else -%} network {%- endif -%} - {%- elif ansible_distribution == "Ubuntu" -%} + {%- elif ansible_distribution == "Ubuntu" + or (ansible_distribution == "Debian" and ansible_distribution_major_version | int == 12 ) -%} systemd-networkd {%- elif ansible_os_family == "Debian" -%} networking diff --git a/kubespray/project/roles/reset/tasks/main.yml b/kubespray/project/roles/reset/tasks/main.yml index a0fa409..acafb5a 100644 --- a/kubespray/project/roles/reset/tasks/main.yml +++ b/kubespray/project/roles/reset/tasks/main.yml @@ -7,6 +7,8 @@ - kubelet.service - cri-dockerd.service - cri-dockerd.socket + - etcd.service + - etcd-events.service failed_when: false tags: - services @@ -24,6 +26,8 @@ - crio.service.d/http-proxy.conf - k8s-certs-renew.service - k8s-certs-renew.timer + - etcd.service + - etcd-events.service register: services_removed tags: - services @@ -39,16 +43,16 @@ - docker - name: Reset | systemctl daemon-reload # noqa no-handler - systemd: + systemd_service: daemon_reload: true when: services_removed.changed - name: Reset | check if crictl is present stat: path: "{{ bin_dir }}/crictl" - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: crictl - name: Reset | stop all cri containers @@ -134,28 +138,6 @@ ignore_errors: true # noqa ignore-errors changed_when: true -- name: Reset | stop etcd services - service: - name: "{{ item }}" - state: stopped - with_items: - - etcd - - etcd-events - failed_when: false - tags: - - services - -- name: Reset | remove etcd services - file: - path: "/etc/systemd/system/{{ item }}.service" - state: absent - with_items: - - etcd - - etcd-events - register: services_removed - tags: - - services - - name: Reset | remove containerd when: container_manager == 'containerd' block: @@ -179,7 +161,7 @@ shell: set -o pipefail && mount | grep /var/lib/kubelet/ | awk '{print $3}' | tac args: executable: /bin/bash - check_mode: no + check_mode: false register: mounted_dirs failed_when: false changed_when: false @@ -200,7 +182,7 @@ - name: Flush iptables iptables: table: "{{ item }}" - flush: yes + flush: true with_items: - filter - nat @@ -213,7 +195,7 @@ - name: Flush ip6tables iptables: table: "{{ item }}" - flush: yes + flush: true ip_version: ipv6 with_items: - filter @@ -233,9 +215,9 @@ - name: Reset | check kube-ipvs0 network device stat: path: /sys/class/net/kube-ipvs0 - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: kube_ipvs0 - name: Reset | Remove kube-ipvs0 @@ -247,9 +229,9 @@ - name: Reset | check nodelocaldns network device stat: path: /sys/class/net/nodelocaldns - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: nodelocaldns_device - name: Reset | Remove nodelocaldns @@ -261,13 +243,13 @@ - name: Reset | Check whether /var/lib/kubelet directory exists stat: path: /var/lib/kubelet - get_attributes: no - get_checksum: no - get_mime: no + get_attributes: false + get_checksum: false + get_mime: false register: var_lib_kubelet_directory - name: Reset | Find files/dirs with immutable flag in /var/lib/kubelet - command: lsattr -laR /var/lib/kubelet + command: lsattr -laR /var/lib/kubelet/ become: true register: var_lib_kubelet_files_dirs_w_attrs changed_when: false @@ -279,7 +261,7 @@ path: "{{ filedir_path }}" state: touch attributes: "-i" - mode: 0644 + mode: "0644" loop: "{{ var_lib_kubelet_files_dirs_w_attrs.stdout_lines | select('search', 'Immutable') | list }}" loop_control: loop_var: file_dir_line @@ -318,6 +300,7 @@ - /etc/etcd.env - /etc/calico - /etc/NetworkManager/conf.d/calico.conf + - /etc/NetworkManager/conf.d/dns.conf - /etc/NetworkManager/conf.d/k8s.conf - /etc/weave.env - /opt/cni diff --git a/kubespray/project/roles/upgrade/post-upgrade/tasks/main.yml b/kubespray/project/roles/upgrade/post-upgrade/tasks/main.yml index 434ef1e..467ff05 100644 --- a/kubespray/project/roles/upgrade/post-upgrade/tasks/main.yml +++ b/kubespray/project/roles/upgrade/post-upgrade/tasks/main.yml @@ -13,7 +13,7 @@ - name: Confirm node uncordon pause: - echo: yes + echo: true prompt: "Ready to uncordon node?" when: - upgrade_node_post_upgrade_confirm @@ -25,6 +25,10 @@ - not upgrade_node_post_upgrade_confirm - upgrade_node_post_upgrade_pause_seconds != 0 +- name: Run post upgrade hooks before uncordon + loop: "{{ post_upgrade_hooks | default([]) }}" + ansible.builtin.include_tasks: "{{ item }}" + - name: Uncordon node command: "{{ kubectl }} uncordon {{ kube_override_hostname | default(inventory_hostname) }}" delegate_to: "{{ groups['kube_control_plane'][0] }}" diff --git a/kubespray/project/roles/upgrade/pre-upgrade/tasks/main.yml b/kubespray/project/roles/upgrade/pre-upgrade/tasks/main.yml index 8d5d99c..6e3cdd2 100644 --- a/kubespray/project/roles/upgrade/pre-upgrade/tasks/main.yml +++ b/kubespray/project/roles/upgrade/pre-upgrade/tasks/main.yml @@ -2,7 +2,7 @@ # Wait for upgrade - name: Confirm node upgrade pause: - echo: yes + echo: true prompt: "Ready to upgrade node? (Press Enter to continue or Ctrl+C for other options)" when: - upgrade_node_confirm diff --git a/kubespray/project/roles/win_nodes/kubernetes_patch/tasks/main.yml b/kubespray/project/roles/win_nodes/kubernetes_patch/tasks/main.yml index 880c58c..1dd504e 100644 --- a/kubespray/project/roles/win_nodes/kubernetes_patch/tasks/main.yml +++ b/kubespray/project/roles/win_nodes/kubernetes_patch/tasks/main.yml @@ -4,7 +4,7 @@ file: path: "{{ kubernetes_user_manifests_path }}/kubernetes" state: directory - recurse: yes + recurse: true tags: [init, cni] - name: Apply kube-proxy nodeselector diff --git a/kubespray/project/scale.yml b/kubespray/project/scale.yml index 171e378..ef09366 100644 --- a/kubespray/project/scale.yml +++ b/kubespray/project/scale.yml @@ -7,7 +7,7 @@ - name: Generate the etcd certificates beforehand hosts: etcd:kube_control_plane - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -24,7 +24,7 @@ - name: Download images to ansible host cache via first kube_control_plane node hosts: kube_control_plane[0] - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -34,7 +34,7 @@ - name: Target only workers to get kubelet installed and checking in on any new nodes(engine) hosts: kube_node - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -53,7 +53,7 @@ - name: Target only workers to get kubelet installed and checking in on any new nodes(node) hosts: kube_node - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -63,7 +63,7 @@ - name: Upload control plane certs and retrieve encryption key hosts: kube_control_plane | first environment: "{{ proxy_disable_env }}" - gather_facts: False + gather_facts: false tags: kubeadm roles: - { role: kubespray-defaults } @@ -84,7 +84,7 @@ - name: Target only workers to get kubelet installed and checking in on any new nodes(network) hosts: kube_node - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -96,7 +96,7 @@ - name: Apply resolv.conf changes now that cluster DNS is up hosts: k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: diff --git a/kubespray/project/upgrade_cluster.yml b/kubespray/project/upgrade_cluster.yml index 3180fec..99511a8 100644 --- a/kubespray/project/upgrade_cluster.yml +++ b/kubespray/project/upgrade_cluster.yml @@ -7,7 +7,7 @@ - name: Download images to ansible host cache via first kube_control_plane node hosts: kube_control_plane[0] - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -17,7 +17,7 @@ - name: Prepare nodes for upgrade hosts: k8s_cluster:etcd:calico_rr - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -27,7 +27,7 @@ - name: Upgrade container engine on non-cluster nodes hosts: etcd:calico_rr:!k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" serial: "{{ serial | default('20%') }}" @@ -39,7 +39,7 @@ import_playbook: install_etcd.yml - name: Handle upgrades to master components first to maintain backwards compat. - gather_facts: False + gather_facts: false hosts: kube_control_plane any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" @@ -62,7 +62,7 @@ - name: Upgrade calico and external cloud provider on all masters, calico-rrs, and nodes hosts: kube_control_plane:calico_rr:kube_node - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" serial: "{{ serial | default('20%') }}" environment: "{{ proxy_disable_env }}" @@ -75,7 +75,7 @@ - name: Finally handle worker upgrades, based on given batch size hosts: kube_node:calico_rr:!kube_control_plane - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" serial: "{{ serial | default('20%') }}" @@ -93,7 +93,7 @@ - name: Patch Kubernetes for Windows hosts: kube_control_plane[0] - gather_facts: False + gather_facts: false any_errors_fatal: true environment: "{{ proxy_disable_env }}" roles: @@ -102,7 +102,7 @@ - name: Install Calico Route Reflector hosts: calico_rr - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -111,7 +111,7 @@ - name: Install Kubernetes apps hosts: kube_control_plane - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: @@ -122,7 +122,7 @@ - name: Apply resolv.conf changes now that cluster DNS is up hosts: k8s_cluster - gather_facts: False + gather_facts: false any_errors_fatal: "{{ any_errors_fatal | default(true) }}" environment: "{{ proxy_disable_env }}" roles: